From d7a098b75e39c84db552aa620e4bd34d2d448758 Mon Sep 17 00:00:00 2001 From: Steven He Date: Sat, 16 Apr 2022 15:51:05 +0800 Subject: [PATCH] Avoid reparse source in codegen stage --- .../SubtypesFactoryGenerator.cs | 30 ++++++++----------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/src/Avalonia.SourceGenerator/SubtypesFactoryGenerator.cs b/src/Avalonia.SourceGenerator/SubtypesFactoryGenerator.cs index 10c18580b3..4fc9397e7a 100644 --- a/src/Avalonia.SourceGenerator/SubtypesFactoryGenerator.cs +++ b/src/Avalonia.SourceGenerator/SubtypesFactoryGenerator.cs @@ -11,7 +11,7 @@ namespace Avalonia.SourceGenerator [Generator(LanguageNames.CSharp)] public class SubtypesFactoryGenerator : IIncrementalGenerator { - private record struct MethodTarget(IMethodSymbol Method, ITypeSymbol BaseType, string Namespace); + private record struct MethodTarget(IMethodSymbol Method, string MethodDecl, ITypeSymbol BaseType, string Namespace); private static readonly string s_attributeName = typeof(SubtypesFactoryAttribute).FullName; private static bool IsSubtypeOf(ITypeSymbol type, ITypeSymbol baseType) @@ -21,26 +21,12 @@ namespace Avalonia.SourceGenerator private static void GenerateSubTypes(SourceProductionContext context, MethodTarget methodTarget, ImmutableArray types) { - var (method, baseType, @namespace) = methodTarget; + var (method, methodDecl, baseType, @namespace) = methodTarget; var candidateTypes = types.Where(i => IsSubtypeOf(i, baseType)).Where(i => $"{i.ContainingNamespace}.".StartsWith($"{@namespace}.")).ToArray(); var type = method.ContainingType; var isGeneric = type.TypeParameters.Length > 0; var isClass = type.TypeKind == TypeKind.Class; - if (method.DeclaringSyntaxReferences.FirstOrDefault()?.GetSyntax() is not MethodDeclarationSyntax methodDecl) - { - return; - } - - var parameters = new SeparatedSyntaxList().AddRange(methodDecl.ParameterList.Parameters.Select(i => i.WithAttributeLists(new SyntaxList()))); - - var methodDeclText = methodDecl - .WithAttributeLists(new SyntaxList()) - .WithParameterList(methodDecl.ParameterList.WithParameters(parameters)) - .WithBody(null) - .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.None)) - .WithoutTrivia().ToString(); - var typeDecl = $"partial {(isClass ? "class" : "struct")} {type.Name}{(isGeneric ? $"<{string.Join(", ", type.TypeParameters)}>" : "")}"; var source = $@"using System; using System.Collections.Generic; @@ -49,7 +35,7 @@ namespace {method.ContainingNamespace} {{ {typeDecl} {{ - {methodDeclText} + {methodDecl} {{ var hasMatch = false; (hasMatch, {method.Parameters[1].Name}) = {method.Parameters[0].Name} switch @@ -109,7 +95,15 @@ namespace {method.ContainingNamespace} continue; } - return new MethodTarget(methodSymbol, baseType, nsValue); + var parameters = new SeparatedSyntaxList().AddRange(method.ParameterList.Parameters.Select(i => i.WithAttributeLists(new SyntaxList()))); + var methodDecl = method + .WithAttributeLists(new SyntaxList()) + .WithParameterList(method.ParameterList.WithParameters(parameters)) + .WithBody(null) + .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.None)) + .WithoutTrivia().ToString(); + + return new MethodTarget(methodSymbol, methodDecl, baseType, nsValue); } }