From 4b07342fc4ecb077eaa25872fd055a4408a8f3ac Mon Sep 17 00:00:00 2001 From: hadashiA Date: Thu, 13 Jun 2024 15:51:02 +0900 Subject: [PATCH] Fix compilation errors --- .../SyntaxCollector.cs | 50 +++++++++---------- .../VContainerSourceGenerator.cs | 40 +++++++++++---- .../WorkItem.cs | 31 +++--------- VContainer.SourceGenerator/Analyzer.cs | 24 ++++++--- VContainer.SourceGenerator/Emitter.cs | 3 +- 5 files changed, 80 insertions(+), 68 deletions(-) diff --git a/VContainer.SourceGenerator.Roslyn3/SyntaxCollector.cs b/VContainer.SourceGenerator.Roslyn3/SyntaxCollector.cs index 49cb9a3a..a70f7fe0 100644 --- a/VContainer.SourceGenerator.Roslyn3/SyntaxCollector.cs +++ b/VContainer.SourceGenerator.Roslyn3/SyntaxCollector.cs @@ -1,44 +1,44 @@ -using System; using System.Collections.Generic; using System.Linq; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; -namespace VContainer.SourceGenerator +namespace VContainer.SourceGenerator; + +class SyntaxCollector : ISyntaxReceiver { - class SyntaxCollector : ISyntaxReceiver - { - public List Log { get; } = new(); - public List WorkItems { get; } = new(); + public List Log { get; } = new(); + public List WorkItems { get; } = new(); - public void OnVisitSyntaxNode(SyntaxNode syntaxNode) + public void OnVisitSyntaxNode(SyntaxNode syntaxNode) + { + if (syntaxNode.IsKind(SyntaxKind.ClassDeclaration)) { - if (syntaxNode.IsKind(SyntaxKind.ClassDeclaration)) + if (syntaxNode is ClassDeclarationSyntax classDeclarationSyntax) { - if (syntaxNode is ClassDeclarationSyntax classDeclarationSyntax) + if (!classDeclarationSyntax.Modifiers.Any(modifier => modifier.IsKind(SyntaxKind.AbstractKeyword) || + modifier.IsKind(SyntaxKind.StaticKeyword))) { - if (!classDeclarationSyntax.Modifiers.Any(modifier => modifier.IsKind(SyntaxKind.AbstractKeyword) || - { - WorkItems.Add(new WorkItem(classDeclarationSyntax)); - } + WorkItems.Add(new WorkItem(classDeclarationSyntax)); } } - else if (syntaxNode.IsKind(SyntaxKind.InvocationExpression)) - { - if (syntaxNode is InvocationExpressionSyntax - { - Expression: MemberAccessExpressionSyntax - { - Expression: IdentifierNameSyntax - } memberAccess - }) + } + else if (syntaxNode.IsKind(SyntaxKind.InvocationExpression)) + { + if (syntaxNode is InvocationExpressionSyntax { - if (memberAccess.Name.Identifier.Text.StartsWith("Register")) + Expression: MemberAccessExpressionSyntax { - } + Expression: IdentifierNameSyntax + } memberAccess + } invocationExpressionSyntax) + { + if (memberAccess.Name.Identifier.Text.StartsWith("Register")) + { + WorkItems.Add(new WorkItem(invocationExpressionSyntax)); } } } } -} \ No newline at end of file +} diff --git a/VContainer.SourceGenerator.Roslyn3/VContainerSourceGenerator.cs b/VContainer.SourceGenerator.Roslyn3/VContainerSourceGenerator.cs index aa34059d..80fb785f 100644 --- a/VContainer.SourceGenerator.Roslyn3/VContainerSourceGenerator.cs +++ b/VContainer.SourceGenerator.Roslyn3/VContainerSourceGenerator.cs @@ -25,19 +25,39 @@ public void Execute(GeneratorExecutionContext context) var syntaxCollector = (SyntaxCollector)context.SyntaxReceiver!; foreach (var workItem in syntaxCollector.WorkItems) { - var typeMeta = workItem.Analyze(in context, references); - if (typeMeta is null) continue; - - if (Emitter.TryEmitGeneratedInjector(typeMeta, codeWriter, references, in context)) + if (workItem.TypeDeclarationSyntax is { } typeDeclarationSyntax) + { + var semanticModel = context.Compilation.GetSemanticModel(typeDeclarationSyntax.SyntaxTree); + var typeDeclarationCandidate = new TypeDeclarationCandidate(typeDeclarationSyntax, semanticModel); + if (typeDeclarationCandidate.Analyze(references) is { } typeMeta) + { + Execute(typeMeta, codeWriter, references, in context); + codeWriter.Clear(); + } + } + else if (workItem.RegisterInvocationSyntax is { } registerInvocationSyntax) { - var fullType = typeMeta.FullTypeName - .Replace("global::", "") - .Replace("<", "_") - .Replace(">", "_"); - context.AddSource($"{fullType}GeneratedInjector.g.cs", codeWriter.ToString()); + var semanticModel = context.Compilation.GetSemanticModel(registerInvocationSyntax.SyntaxTree); + var registerInvocationCandidate = new RegisterInvocationCandidate(registerInvocationSyntax, semanticModel); + var typeMetas = registerInvocationCandidate.Analyze(references); + foreach (var typeMeta in typeMetas) + { + Execute(typeMeta, codeWriter, references, in context); + codeWriter.Clear(); + } } + } + } - codeWriter.Clear(); + static void Execute(TypeMeta typeMeta, CodeWriter codeWriter, ReferenceSymbols referenceSymbols, in GeneratorExecutionContext context) + { + if (Emitter.TryEmitGeneratedInjector(typeMeta, codeWriter, referenceSymbols, in context)) + { + var fullType = typeMeta.FullTypeName + .Replace("global::", "") + .Replace("<", "_") + .Replace(">", "_"); + context.AddSource($"{fullType}GeneratedInjector.g.cs", codeWriter.ToString()); } } } \ No newline at end of file diff --git a/VContainer.SourceGenerator.Roslyn3/WorkItem.cs b/VContainer.SourceGenerator.Roslyn3/WorkItem.cs index cb2d365a..ab95a516 100644 --- a/VContainer.SourceGenerator.Roslyn3/WorkItem.cs +++ b/VContainer.SourceGenerator.Roslyn3/WorkItem.cs @@ -1,38 +1,19 @@ -using System.Linq; -using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; namespace VContainer.SourceGenerator; class WorkItem { - public TypeDeclarationSyntax Syntax { get; } + public TypeDeclarationSyntax? TypeDeclarationSyntax { get; } + public InvocationExpressionSyntax? RegisterInvocationSyntax { get; } - public WorkItem(TypeDeclarationSyntax syntax) + public WorkItem(TypeDeclarationSyntax typeDeclarationSyntax) { - Syntax = syntax; + TypeDeclarationSyntax = typeDeclarationSyntax; } - public TypeMeta? Analyze(in GeneratorExecutionContext context, ReferenceSymbols references) + public WorkItem(InvocationExpressionSyntax registerInvocationCandidate) { - var semanticModel = context.Compilation.GetSemanticModel(Syntax.SyntaxTree); - var symbol = semanticModel.GetDeclaredSymbol(Syntax, context.CancellationToken); - if (symbol is not INamedTypeSymbol typeSymbol) - { - return null; - } - var isAttribute = typeSymbol.GetAllBaseTypes().Any(x => SymbolEqualityComparer.Default.Equals(x, references.AttributeBase)); - if (isAttribute) - { - return null; - } - - var injectIgnore = symbol.GetAttributes().Any(attr => SymbolEqualityComparer.Default.Equals(attr.AttributeClass, references.VContainerInjectIgnoreAttribute)); - if (injectIgnore) - { - return null; - } - - return new TypeMeta(typeSymbol, references, Syntax); + RegisterInvocationSyntax = registerInvocationCandidate; } } \ No newline at end of file diff --git a/VContainer.SourceGenerator/Analyzer.cs b/VContainer.SourceGenerator/Analyzer.cs index 95f52d3f..80c42dd4 100644 --- a/VContainer.SourceGenerator/Analyzer.cs +++ b/VContainer.SourceGenerator/Analyzer.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Threading; using Microsoft.CodeAnalysis; @@ -21,9 +20,7 @@ static class Analyzer foreach (var baseTypeSymbol in typeSymbol.GetAllBaseTypes()) { - var name = baseTypeSymbol.ToDisplayString(); - // Ignore - if (name == "System.Attributes") + if (SymbolEqualityComparer.Default.Equals(baseTypeSymbol, referenceSymbols.AttributeBase)) { return null; } @@ -34,12 +31,25 @@ static class Analyzer if (attributeData.AttributeClass != null) { // Ignore - if (attributeData.AttributeClass.ToDisplayString() == "VContainer.InjectIgnoreAttribute") + if (SymbolEqualityComparer.Default.Equals( + attributeData.AttributeClass, + referenceSymbols.VContainerInjectIgnoreAttribute)) + { return null; + } } } - return new TypeMeta(typeSymbol, referenceSymbols, syntax); + var typeMeta = new TypeMeta(typeSymbol, referenceSymbols, syntax); + if (typeMeta.ExplictInjectConstructors.Count <= 0 && + typeMeta.InjectFields.Count <= 0 && + typeMeta.InjectProperties.Count <= 0 && + typeMeta.InjectMethods.Count <= 0) + { + return null; + } + + return typeMeta; } } @@ -98,4 +108,4 @@ public IEnumerable Analyze(ReferenceSymbols referenceSymbols, Cancella } } } -} \ No newline at end of file +} diff --git a/VContainer.SourceGenerator/Emitter.cs b/VContainer.SourceGenerator/Emitter.cs index df643d41..69dfa462 100644 --- a/VContainer.SourceGenerator/Emitter.cs +++ b/VContainer.SourceGenerator/Emitter.cs @@ -61,8 +61,9 @@ public static bool TryEmitGeneratedInjector( .Replace(">", "_"); var generateTypeName = $"{typeName}GeneratedInjector"; - using (codeWriter.BeginBlockScope($"class {generateTypeName} : IInjector")) + using (codeWriter.BeginBlockScope("[Preserve]")) { + codeWriter.AppendLine($"class {generateTypeName} : IInjector"); if (!TryEmitCreateInstanceMethod(typeMeta, codeWriter, references, in context)) { return false;