Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace IsTrimmable with IsAotCompatible which contains all necessary analyzers #267

Merged
merged 1 commit into from
Jun 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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