Skip to content

Commit

Permalink
Merge pull request #2063 from microsoft/mk/implement-AOT
Browse files Browse the repository at this point in the history
feat: configure AOT for trimming compatibility
  • Loading branch information
MaggieKimani1 authored Jan 16, 2025
2 parents d88c36f + 7a82174 commit b4f9c3e
Show file tree
Hide file tree
Showing 9 changed files with 52 additions and 22 deletions.
15 changes: 15 additions & 0 deletions .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net6.0;</TargetFrameworks>
<TargetFrameworks>netstandard2.0;net8.0;</TargetFrameworks>
<!-- net6.0 target is present because of the conditional build in OpenApiYamlReader.Read -->
<LangVersion>latest</LangVersion>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Version>2.0.0-preview4</Version>
<Description>OpenAPI.NET Readers for JSON and YAML documents</Description>
<SignAssembly>true</SignAssembly>
<IsTrimmable Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)','net5.0'))">true</IsTrimmable>
<IsAotCompatible Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)','net8.0'))">true</IsAotCompatible>
<!-- https://github.com/dotnet/sourcelink/blob/main/docs/README.md#embeduntrackedsources -->
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<NoWarn>NU5048</NoWarn>
Expand Down
4 changes: 2 additions & 2 deletions src/Microsoft.OpenApi/Extensions/StringExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ internal static class StringExtensions
{
var type = typeof(T);

var displayMap = EnumDisplayCache.GetOrAdd(type, GetEnumValues<T>);
var displayMap = EnumDisplayCache.GetOrAdd(type, _=> GetEnumValues<T>(type));

if (displayMap.TryGetValue(displayName, out var cachedValue))
{
Expand All @@ -45,7 +45,7 @@ internal static class StringExtensions
result = default;
return false;
}
private static ReadOnlyDictionary<string, object> GetEnumValues<T>(Type enumType) where T : Enum
private static ReadOnlyDictionary<string, object> GetEnumValues<T>([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] Type enumType) where T : Enum
{
var result = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
foreach (var field in enumType.GetFields(BindingFlags.Public | BindingFlags.Static))
Expand Down
2 changes: 2 additions & 0 deletions src/Microsoft.OpenApi/Microsoft.OpenApi.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
<Version>2.0.0-preview4</Version>
<Description>.NET models with JSON and YAML writers for OpenAPI specification</Description>
<SignAssembly>true</SignAssembly>
<IsTrimmable Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)','net5.0'))">true</IsTrimmable>
<IsAotCompatible Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)','net8.0'))">true</IsAotCompatible>
<!-- https://github.com/dotnet/sourcelink/blob/main/docs/README.md#embeduntrackedsources -->
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<NoWarn>NU5048</NoWarn>
Expand Down
4 changes: 4 additions & 0 deletions src/Microsoft.OpenApi/Models/OpenApiSchema.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<JsonSchemaType>();
#else
private static readonly Array jsonSchemaTypeValues = System.Enum.GetValues(typeof(JsonSchemaType));
#endif

private void DowncastTypeArrayToV2OrV3(JsonSchemaType schemaType, IOpenApiWriter writer, OpenApiSpecVersion version)
{
Expand Down
6 changes: 5 additions & 1 deletion src/Microsoft.OpenApi/Reader/ParseNodes/MapNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -176,4 +177,7 @@ public override JsonNode CreateAny()
return _node;
}
}

[JsonSerializable(typeof(JsonObject))]
internal partial class SourceGenerationContext : JsonSerializerContext { }
}
32 changes: 16 additions & 16 deletions src/Microsoft.OpenApi/Validations/Rules/RuleHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,15 @@ 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;
var nullable = schema.Nullable;

// 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;
}
Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand Down
Original file line number Diff line number Diff line change
@@ -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")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,19 @@
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PublishTrimmed>true</PublishTrimmed>
<PublishAot>true</PublishAot>
<TrimmerSingleWarn>false</TrimmerSingleWarn>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<NoWarn>NU1903</NoWarn>
<NoWarn>NU1903; IL3000</NoWarn>
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Microsoft.OpenApi\Microsoft.OpenApi.csproj" />
<TrimmerRootAssembly Include="Microsoft.OpenApi" />
<!-- TODO: Microsoft.OpenApi.Readers has not been configured for native AoT. -->
<ProjectReference Include="..\..\src\Microsoft.OpenApi.Readers\Microsoft.OpenApi.Readers.csproj" />
<TrimmerRootAssembly Include="Microsoft.OpenApi.Readers" />
</ItemGroup>

</Project>

0 comments on commit b4f9c3e

Please sign in to comment.