Skip to content

Commit

Permalink
Fix compilation errors
Browse files Browse the repository at this point in the history
  • Loading branch information
hadashiA committed Jun 13, 2024
1 parent f230848 commit 4b07342
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 68 deletions.
50 changes: 25 additions & 25 deletions VContainer.SourceGenerator.Roslyn3/SyntaxCollector.cs
Original file line number Diff line number Diff line change
@@ -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<string> Log { get; } = new();
public List<WorkItem> WorkItems { get; } = new();
public List<string> Log { get; } = new();
public List<WorkItem> 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));
}
}
}
}
}
}
40 changes: 30 additions & 10 deletions VContainer.SourceGenerator.Roslyn3/VContainerSourceGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
}
}
31 changes: 6 additions & 25 deletions VContainer.SourceGenerator.Roslyn3/WorkItem.cs
Original file line number Diff line number Diff line change
@@ -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;
}
}
24 changes: 17 additions & 7 deletions VContainer.SourceGenerator/Analyzer.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System;
using System.Collections.Generic;
using System.Threading;
using Microsoft.CodeAnalysis;
Expand All @@ -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;
}
Expand All @@ -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;
}
}

Expand Down Expand Up @@ -98,4 +108,4 @@ public IEnumerable<TypeMeta> Analyze(ReferenceSymbols referenceSymbols, Cancella
}
}
}
}
}
3 changes: 2 additions & 1 deletion VContainer.SourceGenerator/Emitter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 4b07342

Please sign in to comment.