diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 13a34f171..2ddce58b7 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -36,3 +36,18 @@ jobs: shell: pwsh run: | dotnet test Microsoft.OpenApi.sln -c Release -v n + + validate-trimming: + name: Validate Project for Trimming + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 8.x + + - name: Validate Trimming warnings + run: dotnet publish -c Release -r win-x64 /p:TreatWarningsAsErrors=true /warnaserror -f net8.0 + working-directory: ./test/Microsoft.OpenApi.Trimming.Tests diff --git a/src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj b/src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj index 94f633208..0bcee86ba 100644 --- a/src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj +++ b/src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj @@ -1,12 +1,14 @@ - netstandard2.0;net6.0; + netstandard2.0;net8.0; latest true 2.0.0-preview4 OpenAPI.NET Readers for JSON and YAML documents true + true + true true NU5048 diff --git a/src/Microsoft.OpenApi/Extensions/StringExtensions.cs b/src/Microsoft.OpenApi/Extensions/StringExtensions.cs index 1678f26dd..b644050ab 100644 --- a/src/Microsoft.OpenApi/Extensions/StringExtensions.cs +++ b/src/Microsoft.OpenApi/Extensions/StringExtensions.cs @@ -34,7 +34,7 @@ internal static class StringExtensions { var type = typeof(T); - var displayMap = EnumDisplayCache.GetOrAdd(type, GetEnumValues); + var displayMap = EnumDisplayCache.GetOrAdd(type, _=> GetEnumValues(type)); if (displayMap.TryGetValue(displayName, out var cachedValue)) { @@ -45,7 +45,7 @@ internal static class StringExtensions result = default; return false; } - private static ReadOnlyDictionary GetEnumValues(Type enumType) where T : Enum + private static ReadOnlyDictionary GetEnumValues([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] Type enumType) where T : Enum { var result = new Dictionary(StringComparer.OrdinalIgnoreCase); foreach (var field in enumType.GetFields(BindingFlags.Public | BindingFlags.Static)) diff --git a/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj b/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj index 8753755ac..4156863b5 100644 --- a/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj +++ b/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj @@ -6,6 +6,8 @@ 2.0.0-preview4 .NET models with JSON and YAML writers for OpenAPI specification true + true + true true NU5048 diff --git a/src/Microsoft.OpenApi/Models/OpenApiSchema.cs b/src/Microsoft.OpenApi/Models/OpenApiSchema.cs index 0ebe9eab9..d2ffa88ed 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiSchema.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiSchema.cs @@ -846,7 +846,11 @@ where Type.Value.HasFlag(flag) writer.WriteOptionalCollection(OpenApiConstants.Type, list, (w, s) => w.WriteValue(s)); } +#if NET5_0_OR_GREATER + private static readonly Array jsonSchemaTypeValues = System.Enum.GetValues(); +#else private static readonly Array jsonSchemaTypeValues = System.Enum.GetValues(typeof(JsonSchemaType)); +#endif private void DowncastTypeArrayToV2OrV3(JsonSchemaType schemaType, IOpenApiWriter writer, OpenApiSpecVersion version) { diff --git a/src/Microsoft.OpenApi/Reader/ParseNodes/MapNode.cs b/src/Microsoft.OpenApi/Reader/ParseNodes/MapNode.cs index ddaef6b6a..f39d9c345 100644 --- a/src/Microsoft.OpenApi/Reader/ParseNodes/MapNode.cs +++ b/src/Microsoft.OpenApi/Reader/ParseNodes/MapNode.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Text.Json; using System.Text.Json.Nodes; +using System.Text.Json.Serialization; using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Exceptions; using Microsoft.OpenApi.Interfaces; @@ -114,7 +115,7 @@ IEnumerator IEnumerable.GetEnumerator() public override string GetRaw() { - var x = JsonSerializer.Serialize(_node); + var x = JsonSerializer.Serialize(_node, SourceGenerationContext.Default.JsonObject); return x; } @@ -176,4 +177,7 @@ public override JsonNode CreateAny() return _node; } } + + [JsonSerializable(typeof(JsonObject))] + internal partial class SourceGenerationContext : JsonSerializerContext { } } diff --git a/src/Microsoft.OpenApi/Validations/Rules/RuleHelpers.cs b/src/Microsoft.OpenApi/Validations/Rules/RuleHelpers.cs index 4e05c44fd..61b9d3a0c 100644 --- a/src/Microsoft.OpenApi/Validations/Rules/RuleHelpers.cs +++ b/src/Microsoft.OpenApi/Validations/Rules/RuleHelpers.cs @@ -52,7 +52,7 @@ public static void ValidateDataTypeMismatch( } // convert value to JsonElement and access the ValueKind property to determine the type. - var jsonElement = JsonDocument.Parse(JsonSerializer.Serialize(value)).RootElement; + var valueKind = value.GetValueKind(); var type = schema.Type.ToIdentifier(); var format = schema.Format; @@ -60,7 +60,7 @@ public static void ValidateDataTypeMismatch( // Before checking the type, check first if the schema allows null. // If so and the data given is also null, this is allowed for any type. - if (nullable && jsonElement.ValueKind is JsonValueKind.Null) + if (nullable && valueKind is JsonValueKind.Null) { return; } @@ -70,7 +70,7 @@ public static void ValidateDataTypeMismatch( // It is not against the spec to have a string representing an object value. // To represent examples of media types that cannot naturally be represented in JSON or YAML, // a string value can contain the example with escaping where necessary - if (jsonElement.ValueKind is JsonValueKind.String) + if (valueKind is JsonValueKind.String) { return; } @@ -110,7 +110,7 @@ public static void ValidateDataTypeMismatch( // It is not against the spec to have a string representing an array value. // To represent examples of media types that cannot naturally be represented in JSON or YAML, // a string value can contain the example with escaping where necessary - if (jsonElement.ValueKind is JsonValueKind.String) + if (valueKind is JsonValueKind.String) { return; } @@ -138,7 +138,7 @@ public static void ValidateDataTypeMismatch( if (type is "integer" or "number" && format is "int32") { - if (jsonElement.ValueKind is not JsonValueKind.Number) + if (valueKind is not JsonValueKind.Number) { context.CreateWarning( ruleName, @@ -150,7 +150,7 @@ public static void ValidateDataTypeMismatch( if (type is "integer" or "number" && format is "int64") { - if (jsonElement.ValueKind is not JsonValueKind.Number) + if (valueKind is not JsonValueKind.Number) { context.CreateWarning( ruleName, @@ -162,7 +162,7 @@ public static void ValidateDataTypeMismatch( if (type is "integer") { - if (jsonElement.ValueKind is not JsonValueKind.Number) + if (valueKind is not JsonValueKind.Number) { context.CreateWarning( ruleName, @@ -174,7 +174,7 @@ public static void ValidateDataTypeMismatch( if (type is "number" && format is "float") { - if (jsonElement.ValueKind is not JsonValueKind.Number) + if (valueKind is not JsonValueKind.Number) { context.CreateWarning( ruleName, @@ -186,7 +186,7 @@ public static void ValidateDataTypeMismatch( if (type is "number" && format is "double") { - if (jsonElement.ValueKind is not JsonValueKind.Number) + if (valueKind is not JsonValueKind.Number) { context.CreateWarning( ruleName, @@ -198,7 +198,7 @@ public static void ValidateDataTypeMismatch( if (type is "number") { - if (jsonElement.ValueKind is not JsonValueKind.Number) + if (valueKind is not JsonValueKind.Number) { context.CreateWarning( ruleName, @@ -210,7 +210,7 @@ public static void ValidateDataTypeMismatch( if (type is "string" && format is "byte") { - if (jsonElement.ValueKind is not JsonValueKind.String) + if (valueKind is not JsonValueKind.String) { context.CreateWarning( ruleName, @@ -222,7 +222,7 @@ public static void ValidateDataTypeMismatch( if (type is "string" && format is "date") { - if (jsonElement.ValueKind is not JsonValueKind.String) + if (valueKind is not JsonValueKind.String) { context.CreateWarning( ruleName, @@ -234,7 +234,7 @@ public static void ValidateDataTypeMismatch( if (type is "string" && format is "date-time") { - if (jsonElement.ValueKind is not JsonValueKind.String) + if (valueKind is not JsonValueKind.String) { context.CreateWarning( ruleName, @@ -246,7 +246,7 @@ public static void ValidateDataTypeMismatch( if (type is "string" && format is "password") { - if (jsonElement.ValueKind is not JsonValueKind.String) + if (valueKind is not JsonValueKind.String) { context.CreateWarning( ruleName, @@ -258,7 +258,7 @@ public static void ValidateDataTypeMismatch( if (type is "string") { - if (jsonElement.ValueKind is not JsonValueKind.String) + if (valueKind is not JsonValueKind.String) { context.CreateWarning( ruleName, @@ -270,7 +270,7 @@ public static void ValidateDataTypeMismatch( if (type is "boolean") { - if (jsonElement.ValueKind is not JsonValueKind.True && jsonElement.ValueKind is not JsonValueKind.False) + if (valueKind is not JsonValueKind.True && valueKind is not JsonValueKind.False) { context.CreateWarning( ruleName, diff --git a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt index 8d8c89243..fe5ad5bad 100644 --- a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt +++ b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt @@ -1,3 +1,4 @@ +[assembly: System.Reflection.AssemblyMetadata("IsTrimmable", "True")] [assembly: System.Reflection.AssemblyMetadata("RepositoryUrl", "https://github.com/Microsoft/OpenAPI.NET")] [assembly: System.Runtime.CompilerServices.InternalsVisibleTo(@"Microsoft.OpenApi.Readers.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100957cb48387b2a5f54f5ce39255f18f26d32a39990db27cf48737afc6bc62759ba996b8a2bfb675d4e39f3d06ecb55a178b1b4031dcb2a767e29977d88cce864a0d16bfc1b3bebb0edf9fe285f10fffc0a85f93d664fa05af07faa3aad2e545182dbf787e3fd32b56aca95df1a3c4e75dec164a3f1a4c653d971b01ffc39eb3c4")] [assembly: System.Runtime.CompilerServices.InternalsVisibleTo(@"Microsoft.OpenApi.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100957cb48387b2a5f54f5ce39255f18f26d32a39990db27cf48737afc6bc62759ba996b8a2bfb675d4e39f3d06ecb55a178b1b4031dcb2a767e29977d88cce864a0d16bfc1b3bebb0edf9fe285f10fffc0a85f93d664fa05af07faa3aad2e545182dbf787e3fd32b56aca95df1a3c4e75dec164a3f1a4c653d971b01ffc39eb3c4")] diff --git a/test/Microsoft.OpenApi.Trimming.Tests/Microsoft.OpenApi.Trimming.Tests.csproj b/test/Microsoft.OpenApi.Trimming.Tests/Microsoft.OpenApi.Trimming.Tests.csproj index 08f51d715..fad2dc289 100644 --- a/test/Microsoft.OpenApi.Trimming.Tests/Microsoft.OpenApi.Trimming.Tests.csproj +++ b/test/Microsoft.OpenApi.Trimming.Tests/Microsoft.OpenApi.Trimming.Tests.csproj @@ -4,17 +4,19 @@ net8.0 enable enable + true true false true - NU1903 + NU1903; IL3000 false - + +