Skip to content

Commit

Permalink
Replace IsTrimmable with IsAotCompatible which contains all necessary…
Browse files Browse the repository at this point in the history
… analyzers (#267)
  • Loading branch information
mburumaxwell authored Jun 5, 2024
1 parent d2f51a3 commit d20a162
Show file tree
Hide file tree
Showing 16 changed files with 42 additions and 31 deletions.
2 changes: 1 addition & 1 deletion src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<Deterministic>true</Deterministic>
<!--<IsPackable>true</IsPackable>-->
<Company>Tingle Software</Company>
<IsTrimmable Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net6.0'))">true</IsTrimmable>
<IsAotCompatible>true</IsAotCompatible>
</PropertyGroup>

<PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class SharedKeyEvents
public Func<AuthenticationFailedContext, Task> OnAuthenticationFailed { get; set; } = context => Task.CompletedTask;

/// <summary>
/// Invoked if Authorization fails and results in a Forbidden response
/// Invoked if Authorization fails and results in a Forbidden response
/// </summary>
public Func<ForbiddenContext, Task> OnForbidden { get; set; } = context => Task.CompletedTask;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<PropertyGroup>
<Description>JSON Patch support for AspNetCore using System.Text.Json</Description>
<GenerateDocumentationFile>false</GenerateDocumentationFile>
<IsTrimmable>false</IsTrimmable>
<IsAotCompatible>false</IsAotCompatible>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<PropertyGroup>
<Description>Usability extensions for Swagger middleware including smaller ReDoc support</Description>
<TargetFrameworks>net8.0</TargetFrameworks>
<IsTrimmable>false</IsTrimmable>
<IsAotCompatible>false</IsAotCompatible>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ModelBinding.Binders;
using System.Diagnostics.CodeAnalysis;

namespace Tingle.AspNetCore.Tokens.Binders;

Expand All @@ -12,6 +13,7 @@ namespace Tingle.AspNetCore.Tokens.Binders;
/// </list>
/// if applicable.
/// </summary>
[RequiresDynamicCode(MessageStrings.ModelBindingGenericsRequiresDynamicCodeMessage)]
internal class ContinuationTokenModelBinderProvider : IModelBinderProvider
{
/// <inheritdoc/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics.CodeAnalysis;
using Tingle.AspNetCore.Tokens;
using Tingle.AspNetCore.Tokens.Binders;
using Tingle.AspNetCore.Tokens.Protection;

Expand All @@ -25,6 +27,7 @@ public static class IMvcBuilderExtensions
/// </summary>
/// <param name="builder">The application's MVC builder.</param>
/// <returns>The modified builder.</returns>
[RequiresDynamicCode(MessageStrings.ModelBindingGenericsRequiresDynamicCodeMessage)]
public static IMvcBuilder AddTokens(this IMvcBuilder builder)
{
// Register the protector services
Expand Down
2 changes: 2 additions & 0 deletions src/Tingle.AspNetCore.Tokens/MessageStrings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ internal class MessageStrings
{
public const string SerializationUnreferencedCodeMessage = "JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.";
public const string SerializationRequiresDynamicCodeMessage = "JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.";

public const string ModelBindingGenericsRequiresDynamicCodeMessage = "Model binding for generic types requires dynamic code generation which is not support for native AOT applications.";
}
4 changes: 3 additions & 1 deletion src/Tingle.AspNetCore.Tokens/Mvc/ContinuationTokenResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public override void OnFormatting(ActionContext context)
{
base.OnFormatting(context); // required so that it can write the statusCode

// we can only set the header if
// we can only set the header if
// 1) the provided token instance is not null
// 2) the underlying value is not null
// 3) the protected value is not null or empty
Expand All @@ -64,6 +64,7 @@ public override void OnFormatting(ActionContext context)
var protector = context.HttpContext.RequestServices.GetRequiredService<ITokenProtector<T>>();

#pragma warning disable IL2026 // Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code
#pragma warning disable IL3050 // Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling.
// generate a new protected value based on the type of token
string protected_val;
var value = token.GetValue();
Expand All @@ -85,6 +86,7 @@ public override void OnFormatting(ActionContext context)
if (!string.IsNullOrWhiteSpace(protected_val))
context.HttpContext.Response.Headers[headerName] = protected_val;
}
#pragma warning restore IL3050 // Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling.
#pragma warning restore IL2026 // Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code
}
}
2 changes: 2 additions & 0 deletions src/Tingle.Extensions.EntityFrameworkCore/DatabaseSetup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System.Diagnostics.CodeAnalysis;

namespace Tingle.Extensions.EntityFrameworkCore;

/// <summary>
/// Helper for performing migrations or creation.
/// </summary>
/// <typeparam name="TContext">The type of context to be used.</typeparam>
[RequiresDynamicCode(MessageStrings.MigrationsRequiresDynamicCodeMessage)]
public class DatabaseSetup<TContext> : IHostedService where TContext : DbContext
{
private readonly IServiceScopeFactory scopeFactory;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Hosting;
using System.Diagnostics.CodeAnalysis;
using Tingle.Extensions.EntityFrameworkCore;

namespace Microsoft.Extensions.DependencyInjection;
Expand All @@ -17,9 +18,7 @@ public static class IServiceCollectionExtensions
/// Migrations are done when the configuration value <c>EFCORE_PERFORM_MIGRATIONS</c> is set to <see langword="true"/>.
/// Database creation is done when configuration value <c>EFCORE_CREATE_DATABASE</c> is set to <see langword="true"/>.
/// </remarks>
public static IServiceCollection AddDatabaseSetup<TContext>(this IServiceCollection services)
where TContext : DbContext
{
return services.AddHostedService<DatabaseSetup<TContext>>();
}
[RequiresDynamicCode(MessageStrings.MigrationsRequiresDynamicCodeMessage)]
public static IServiceCollection AddDatabaseSetup<TContext>(this IServiceCollection services) where TContext : DbContext
=> services.AddHostedService<DatabaseSetup<TContext>>();
}
2 changes: 2 additions & 0 deletions src/Tingle.Extensions.EntityFrameworkCore/MessageStrings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ internal class MessageStrings
{
public const string SerializationUnreferencedCodeMessage = "JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.";
public const string SerializationRequiresDynamicCodeMessage = "JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.";

public const string MigrationsRequiresDynamicCodeMessage = "Migration operations are not supported with Native AOT. Use a migration bundle or an alternate way of executing migration operations.";
}
Original file line number Diff line number Diff line change
@@ -1,29 +1,28 @@
using System.Text.Json;
using System.Diagnostics.CodeAnalysis;
using System.Text.Json;
using System.Text.Json.Serialization;
using Tingle.Extensions.JsonPatch.Operations;

namespace Tingle.Extensions.JsonPatch.Converters;

[RequiresUnreferencedCode(MessageStrings.SerializationUnreferencedCodeMessage)]
[RequiresDynamicCode(MessageStrings.SerializationRequiresDynamicCodeMessage)]
public class JsonPatchDocumentConverter : JsonConverter<JsonPatchDocument>
{
/// <inheritdoc/>
public override JsonPatchDocument? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.Null) return default;

#pragma warning disable IL2026 // Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code
var targetOperations = JsonSerializer.Deserialize<List<Operation>>(ref reader, options);
#pragma warning restore IL2026 // Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code
var operations = JsonSerializer.Deserialize<List<Operation>>(ref reader, options);

return new JsonPatchDocument(targetOperations ?? []);
return new JsonPatchDocument(operations ?? []);
}

/// <inheritdoc/>
public override void Write(Utf8JsonWriter writer, JsonPatchDocument value, JsonSerializerOptions options)
{
// we write an array of the operations
#pragma warning disable IL2026 // Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code
JsonSerializer.Serialize(writer, value.Operations, options);
#pragma warning restore IL2026 // Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,10 @@
using System.Text.Json.Serialization;
using Tingle.Extensions.JsonPatch.Operations;

#if NETCOREAPP
#else
#pragma warning disable IDE0079 // Remove unnecessary suppression
#endif

namespace Tingle.Extensions.JsonPatch.Converters;

[RequiresUnreferencedCode(MessageStrings.SerializationUnreferencedCodeMessage)]
[RequiresDynamicCode(MessageStrings.SerializationRequiresDynamicCodeMessage)]
public class TypedJsonPatchDocumentConverter : JsonConverterFactory
{
public override bool CanConvert(Type typeToConvert)
Expand All @@ -20,22 +17,20 @@ public override bool CanConvert(Type typeToConvert)
public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
{
var modelType = typeToConvert.GetGenericArguments()[0];
#pragma warning disable IL2055 // Either the type on which the MakeGenericType is called can't be statically determined, or the type parameters to be used for generic arguments can't be statically determined.
var conveterType = typeof(TypedJsonPatchDocumentConverterInner<>).MakeGenericType(modelType);
#pragma warning restore IL2055 // Either the type on which the MakeGenericType is called can't be statically determined, or the type parameters to be used for generic arguments can't be statically determined.
return (JsonConverter?)Activator.CreateInstance(conveterType);
}

[RequiresUnreferencedCode(MessageStrings.SerializationUnreferencedCodeMessage)]
[RequiresDynamicCode(MessageStrings.SerializationRequiresDynamicCodeMessage)]
public class TypedJsonPatchDocumentConverterInner<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] T> : JsonConverter<JsonPatchDocument<T>> where T : class
{
/// <inheritdoc/>
public override JsonPatchDocument<T>? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.Null) return default;

#pragma warning disable IL2026 // Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code
var ops = JsonSerializer.Deserialize<List<Operation>>(ref reader, options);
#pragma warning restore IL2026 // Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code
var operations = ops?.Select(o => new Operation<T>
{
path = o.path,
Expand All @@ -51,9 +46,7 @@ public override void Write(Utf8JsonWriter writer, JsonPatchDocument<T> value, Js
{
// we write an array of the operations
var ops = value.Operations.Select(o => (Operation)o).ToList();
#pragma warning disable IL2026 // Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code
JsonSerializer.Serialize(writer, ops, options);
#pragma warning restore IL2026 // Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code
}
}
}
7 changes: 7 additions & 0 deletions src/Tingle.Extensions.JsonPatch/MessageStrings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Tingle.Extensions.JsonPatch;

internal class MessageStrings
{
public const string SerializationUnreferencedCodeMessage = "JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.";
public const string SerializationRequiresDynamicCodeMessage = "JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.";
}
2 changes: 1 addition & 1 deletion src/Tingle.Extensions.MongoDB/MongoDbContextOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ public MongoDbContextOptionsBuilder() : this(new MongoDbContextOptions<TContext>
/// </param>
/// <param name="instrumentationOptions">The options to use for instrumentation.</param>
/// <returns></returns>
public new virtual MongoDbContextOptionsBuilder<TContext> UseMongoConnectionString(string connectionString, InstrumentationOptions? instrumentationOptions=null)
public new virtual MongoDbContextOptionsBuilder<TContext> UseMongoConnectionString(string connectionString, InstrumentationOptions? instrumentationOptions = null)
=> (MongoDbContextOptionsBuilder<TContext>)base.UseMongoConnectionString(connectionString, instrumentationOptions);

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ public EnumConverterHelper(JsonNamingPolicy? namingPolicy, bool allowIntegerValu
enumTypeCode = Type.GetTypeCode(type);
isFlags = type.IsDefined(typeof(FlagsAttribute), true);

var names = type.GetEnumNames();
var builtInValues = type.GetEnumValues();
var names = Enum.GetNames<TEnum>();
var builtInValues = Enum.GetValues<TEnum>();

int numberOfNames = names.Length;

Expand Down

0 comments on commit d20a162

Please sign in to comment.