mirror of
https://github.com/chylex/.NET-Community-Toolkit.git
synced 2025-02-28 00:46:01 +01:00
Generate [DynamicallyAccessedMembers] for __IMessengerExtensions
This commit is contained in:
parent
fa9114b3ed
commit
e78e9c8250
CommunityToolkit.Mvvm.SourceGenerators/Messaging
@ -67,19 +67,54 @@ public static RecipientInfo GetInfo(INamedTypeSymbol typeSymbol, ImmutableArray<
|
||||
/// Gets the head <see cref="CompilationUnitSyntax"/> instance.
|
||||
/// </summary>
|
||||
/// <returns>The head <see cref="CompilationUnitSyntax"/> instance with the type attributes.</returns>
|
||||
public static CompilationUnitSyntax GetSyntax()
|
||||
public static CompilationUnitSyntax GetSyntax(bool isDynamicallyAccessedMembersAttributeAvailable)
|
||||
{
|
||||
int numberOfAttributes = 5 + (isDynamicallyAccessedMembersAttributeAvailable ? 1 : 0);
|
||||
ImmutableArray<AttributeListSyntax>.Builder attributes = ImmutableArray.CreateBuilder<AttributeListSyntax>(numberOfAttributes);
|
||||
|
||||
// Prepare the base attributes with are always present:
|
||||
//
|
||||
// [global::System.CodeDom.Compiler.GeneratedCode("...", "...")]
|
||||
// [global::System.Diagnostics.DebuggerNonUserCode]
|
||||
// [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
|
||||
// [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
|
||||
// [global::System.Obsolete("This type is not intended to be used directly by user code")]
|
||||
attributes.Add(
|
||||
AttributeList(SingletonSeparatedList(
|
||||
Attribute(IdentifierName($"global::System.CodeDom.Compiler.GeneratedCode")).AddArgumentListArguments(
|
||||
AttributeArgument(LiteralExpression(SyntaxKind.StringLiteralExpression, Literal(typeof(IMessengerRegisterAllGenerator).FullName))),
|
||||
AttributeArgument(LiteralExpression(SyntaxKind.StringLiteralExpression, Literal(typeof(IMessengerRegisterAllGenerator).Assembly.GetName().Version.ToString())))))));
|
||||
attributes.Add(AttributeList(SingletonSeparatedList(Attribute(IdentifierName("global::System.Diagnostics.DebuggerNonUserCode")))));
|
||||
attributes.Add(AttributeList(SingletonSeparatedList(Attribute(IdentifierName("global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage")))));
|
||||
attributes.Add(
|
||||
AttributeList(SingletonSeparatedList(
|
||||
Attribute(IdentifierName("global::System.ComponentModel.EditorBrowsable")).AddArgumentListArguments(
|
||||
AttributeArgument(ParseExpression("global::System.ComponentModel.EditorBrowsableState.Never"))))));
|
||||
attributes.Add(
|
||||
AttributeList(SingletonSeparatedList(
|
||||
Attribute(IdentifierName("global::System.Obsolete")).AddArgumentListArguments(
|
||||
AttributeArgument(LiteralExpression(
|
||||
SyntaxKind.StringLiteralExpression,
|
||||
Literal("This type is not intended to be used directly by user code")))))));
|
||||
|
||||
if (isDynamicallyAccessedMembersAttributeAvailable)
|
||||
{
|
||||
// Conditionally add the attribute to inform trimming, if the type is available:
|
||||
//
|
||||
// [global::System.CodeDom.Compiler.DynamicallyAccessedMembersAttribute(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods)]
|
||||
attributes.Add(
|
||||
AttributeList(SingletonSeparatedList(
|
||||
Attribute(IdentifierName("global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute")).AddArgumentListArguments(
|
||||
AttributeArgument(ParseExpression("global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods"))))));
|
||||
}
|
||||
|
||||
// This code produces a compilation unit as follows:
|
||||
//
|
||||
// // <auto-generated/>
|
||||
// #pragma warning disable
|
||||
// namespace CommunityToolkit.Mvvm.Messaging.__Internals
|
||||
// {
|
||||
// [global::System.CodeDom.Compiler.GeneratedCode("...", "...")]
|
||||
// [global::System.Diagnostics.DebuggerNonUserCode]
|
||||
// [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
|
||||
// [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
|
||||
// [global::System.Obsolete("This type is not intended to be used directly by user code")]
|
||||
// <ATTRIBUTES>
|
||||
// internal static partial class __IMessengerExtensions
|
||||
// {
|
||||
// }
|
||||
@ -93,21 +128,7 @@ public static CompilationUnitSyntax GetSyntax()
|
||||
Token(SyntaxKind.InternalKeyword),
|
||||
Token(SyntaxKind.StaticKeyword),
|
||||
Token(SyntaxKind.PartialKeyword))
|
||||
.AddAttributeLists(
|
||||
AttributeList(SingletonSeparatedList(
|
||||
Attribute(IdentifierName($"global::System.CodeDom.Compiler.GeneratedCode")).AddArgumentListArguments(
|
||||
AttributeArgument(LiteralExpression(SyntaxKind.StringLiteralExpression, Literal(typeof(IMessengerRegisterAllGenerator).FullName))),
|
||||
AttributeArgument(LiteralExpression(SyntaxKind.StringLiteralExpression, Literal(typeof(IMessengerRegisterAllGenerator).Assembly.GetName().Version.ToString())))))),
|
||||
AttributeList(SingletonSeparatedList(Attribute(IdentifierName("global::System.Diagnostics.DebuggerNonUserCode")))),
|
||||
AttributeList(SingletonSeparatedList(Attribute(IdentifierName("global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage")))),
|
||||
AttributeList(SingletonSeparatedList(
|
||||
Attribute(IdentifierName("global::System.ComponentModel.EditorBrowsable")).AddArgumentListArguments(
|
||||
AttributeArgument(ParseExpression("global::System.ComponentModel.EditorBrowsableState.Never"))))),
|
||||
AttributeList(SingletonSeparatedList(
|
||||
Attribute(IdentifierName("global::System.Obsolete")).AddArgumentListArguments(
|
||||
AttributeArgument(LiteralExpression(
|
||||
SyntaxKind.StringLiteralExpression,
|
||||
Literal("This type is not intended to be used directly by user code")))))))))
|
||||
.AddAttributeLists(attributes.MoveToImmutable().ToArray())))
|
||||
.NormalizeWhitespace();
|
||||
}
|
||||
|
||||
|
@ -57,14 +57,22 @@ item.Symbol.DeclaringSyntaxReferences[0] is SyntaxReference syntaxReference &&
|
||||
.Collect()
|
||||
.Select(static (item, _) => item.Length > 0);
|
||||
|
||||
// Generate the header file with the attributes
|
||||
context.RegisterConditionalImplementationSourceOutput(isHeaderFileNeeded, static context =>
|
||||
{
|
||||
CompilationUnitSyntax compilationUnit = Execute.GetSyntax();
|
||||
// Check whether [DynamicallyAccessedMembers] is available
|
||||
IncrementalValueProvider<bool> isDynamicallyAccessedMembersAttributeAvailable =
|
||||
context.CompilationProvider
|
||||
.Select(static (item, _) => item.GetTypeByMetadataName("System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute") is { DeclaredAccessibility: Accessibility.Public });
|
||||
|
||||
context.AddSource(
|
||||
hintName: "__IMessengerExtensions.cs",
|
||||
sourceText: SourceText.From(compilationUnit.ToFullString(), Encoding.UTF8));
|
||||
// Generate the header file with the attributes
|
||||
context.RegisterImplementationSourceOutput(isHeaderFileNeeded.Combine(isDynamicallyAccessedMembersAttributeAvailable), static (context, item) =>
|
||||
{
|
||||
if (item.Left)
|
||||
{
|
||||
CompilationUnitSyntax compilationUnit = Execute.GetSyntax(item.Right);
|
||||
|
||||
context.AddSource(
|
||||
hintName: "__IMessengerExtensions.cs",
|
||||
sourceText: SourceText.From(compilationUnit.ToFullString(), Encoding.UTF8));
|
||||
}
|
||||
});
|
||||
|
||||
// Generate the class with all registration methods
|
||||
|
Loading…
Reference in New Issue
Block a user