diff --git a/src/Riok.Mapperly/MapperGenerator.cs b/src/Riok.Mapperly/MapperGenerator.cs index fc85fc8fff..9e3a3e779a 100644 --- a/src/Riok.Mapperly/MapperGenerator.cs +++ b/src/Riok.Mapperly/MapperGenerator.cs @@ -14,43 +14,17 @@ namespace Riok.Mapperly; public class MapperGenerator : IIncrementalGenerator { private const string GeneratedFileSuffix = ".g.cs"; - private static readonly string _mapperAttributeName = typeof(MapperAttribute).FullName; + + public static readonly string MapperAttributeName = typeof(MapperAttribute).FullName; public void Initialize(IncrementalGeneratorInitializationContext context) { - var mapperClassDeclarations = context.SyntaxProvider - .CreateSyntaxProvider( - static (s, _) => IsSyntaxTargetForGeneration(s), - static (ctx, _) => GetSemanticTargetForGeneration(ctx)) - .WhereNotNull(); + var mapperClassDeclarations = SyntaxProvider.GetClassDeclarations(context); var compilationAndMappers = context.CompilationProvider.Combine(mapperClassDeclarations.Collect()); context.RegisterImplementationSourceOutput(compilationAndMappers, static (spc, source) => Execute(source.Left, source.Right, spc)); } - private static bool IsSyntaxTargetForGeneration(SyntaxNode node) - => node is ClassDeclarationSyntax { AttributeLists.Count: > 0 }; - - private static ClassDeclarationSyntax? GetSemanticTargetForGeneration(GeneratorSyntaxContext ctx) - { - var classDeclaration = (ClassDeclarationSyntax)ctx.Node; - foreach (var attributeListSyntax in classDeclaration.AttributeLists) - { - foreach (var attributeSyntax in attributeListSyntax.Attributes) - { - if (ctx.SemanticModel.GetSymbolInfo(attributeSyntax).Symbol is not IMethodSymbol attributeSymbol) - continue; - - var attributeContainingTypeSymbol = attributeSymbol.ContainingType; - var fullName = attributeContainingTypeSymbol.ToDisplayString(); - if (fullName == _mapperAttributeName) - return classDeclaration; - } - } - - return null; - } - private static void Execute(Compilation compilation, ImmutableArray mappers, SourceProductionContext ctx) { if (mappers.IsDefaultOrEmpty) @@ -59,8 +33,7 @@ private static void Execute(Compilation compilation, ImmutableArray GetClassDeclarations(IncrementalGeneratorInitializationContext context) + { + return context.SyntaxProvider + .CreateSyntaxProvider( + static (s, _) => IsSyntaxTargetForGeneration(s), + static (ctx, _) => GetSemanticTargetForGeneration(ctx)) + .WhereNotNull(); + } + + private static bool IsSyntaxTargetForGeneration(SyntaxNode node) + => node is ClassDeclarationSyntax { AttributeLists.Count: > 0 }; + + private static ClassDeclarationSyntax? GetSemanticTargetForGeneration(GeneratorSyntaxContext ctx) + { + var classDeclaration = (ClassDeclarationSyntax)ctx.Node; + foreach (var attributeListSyntax in classDeclaration.AttributeLists) + { + foreach (var attributeSyntax in attributeListSyntax.Attributes) + { + if (ctx.SemanticModel.GetSymbolInfo(attributeSyntax).Symbol is not IMethodSymbol attributeSymbol) + continue; + + var attributeContainingTypeSymbol = attributeSymbol.ContainingType; + var fullName = attributeContainingTypeSymbol.ToDisplayString(); + if (fullName == MapperGenerator.MapperAttributeName) + return classDeclaration; + } + } + + return null; + } +} +#endif diff --git a/src/Riok.Mapperly/SyntaxProvider.Roslyn4.4.cs b/src/Riok.Mapperly/SyntaxProvider.Roslyn4.4.cs new file mode 100644 index 0000000000..7c3165f743 --- /dev/null +++ b/src/Riok.Mapperly/SyntaxProvider.Roslyn4.4.cs @@ -0,0 +1,22 @@ +#if ROSLYN4_4_OR_GREATER + +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Riok.Mapperly.Helpers; + +namespace Riok.Mapperly; + +internal static class SyntaxProvider +{ + + public static IncrementalValuesProvider GetClassDeclarations(IncrementalGeneratorInitializationContext context) + { + return context.SyntaxProvider + .ForAttributeWithMetadataName(MapperGenerator.MapperAttributeName, + static (s, _) => s is ClassDeclarationSyntax, + static (ctx, _) => ctx.TargetNode as ClassDeclarationSyntax) + .WhereNotNull(); + } + +} +#endif