refactor creation of syntax provider
This commit is contained in:
@@ -5,6 +5,7 @@ using System.Collections.Generic;
|
|||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||||
using Microsoft.CodeAnalysis.Text;
|
using Microsoft.CodeAnalysis.Text;
|
||||||
@@ -23,6 +24,8 @@ namespace mROA.Codegen
|
|||||||
[Generator]
|
[Generator]
|
||||||
public class mROAGenerator : IIncrementalGenerator
|
public class mROAGenerator : IIncrementalGenerator
|
||||||
{
|
{
|
||||||
|
private const string SharedObjectInterfaceAttributeName = "SharedObjectInterface";
|
||||||
|
|
||||||
private static readonly Predicate<IParameterSymbol> ParameterFilter =
|
private static readonly Predicate<IParameterSymbol> ParameterFilter =
|
||||||
i => i.Type.Name is "CancellationToken" or "RequestContext";
|
i => i.Type.Name is "CancellationToken" or "RequestContext";
|
||||||
|
|
||||||
@@ -30,7 +33,7 @@ namespace mROA.Codegen
|
|||||||
i => i.Name is "CancellationToken" or "RequestContext";
|
i => i.Name is "CancellationToken" or "RequestContext";
|
||||||
|
|
||||||
private readonly CodeTemplate _codeTemplate = new();
|
private readonly CodeTemplate _codeTemplate = new();
|
||||||
|
|
||||||
private int _currentInternalCallIndex;
|
private int _currentInternalCallIndex;
|
||||||
|
|
||||||
public void Initialize(IncrementalGeneratorInitializationContext context)
|
public void Initialize(IncrementalGeneratorInitializationContext context)
|
||||||
@@ -38,14 +41,31 @@ namespace mROA.Codegen
|
|||||||
_codeTemplate.LoadTemplates();
|
_codeTemplate.LoadTemplates();
|
||||||
|
|
||||||
var syntaxes = context.SyntaxProvider.CreateSyntaxProvider(
|
var syntaxes = context.SyntaxProvider.CreateSyntaxProvider(
|
||||||
(static (node, _) => node is InterfaceDeclarationSyntax),
|
NodeIsInterfaceWithSharedObjectInterfaceAttribute,
|
||||||
static (node, _) => CodegenUtilities.ContainsSoiAttribute(node)).Where(i => i.usefull)
|
TransformToInterfaceDeclarationSyntax);
|
||||||
.Select((node, _) => node.node);
|
|
||||||
|
|
||||||
context.RegisterSourceOutput(context.CompilationProvider.Combine(syntaxes.Collect()),
|
var incrementalValueProvider = context.CompilationProvider.Combine(syntaxes.Collect());
|
||||||
|
context.RegisterSourceOutput(incrementalValueProvider,
|
||||||
(productionContext, pair) => GenerateCode(productionContext, pair.Left, pair.Right));
|
(productionContext, pair) => GenerateCode(productionContext, pair.Left, pair.Right));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static InterfaceDeclarationSyntax TransformToInterfaceDeclarationSyntax(GeneratorSyntaxContext context,
|
||||||
|
CancellationToken _)
|
||||||
|
{
|
||||||
|
if (context.Node is not InterfaceDeclarationSyntax interfaceSyntax)
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
return interfaceSyntax;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool NodeIsInterfaceWithSharedObjectInterfaceAttribute(SyntaxNode node, CancellationToken _)
|
||||||
|
{
|
||||||
|
if (node is not InterfaceDeclarationSyntax interfaceSyntax)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var attributes = interfaceSyntax.AttributeLists.SelectMany(list => list.Attributes);
|
||||||
|
return attributes.Any(attribute => attribute.ToFullString() == SharedObjectInterfaceAttributeName);
|
||||||
|
}
|
||||||
|
|
||||||
private void GenerateCode(SourceProductionContext context, Compilation compilation,
|
private void GenerateCode(SourceProductionContext context, Compilation compilation,
|
||||||
ImmutableArray<InterfaceDeclarationSyntax> classes)
|
ImmutableArray<InterfaceDeclarationSyntax> classes)
|
||||||
{
|
{
|
||||||
@@ -166,19 +186,20 @@ namespace mROA.Codegen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GenerateEventImplementation(TemplateDocument classTemplate,INamedTypeSymbol classSymbol, List<string> invokers,
|
private void GenerateEventImplementation(TemplateDocument classTemplate, INamedTypeSymbol classSymbol,
|
||||||
SourceProductionContext context)
|
List<string> invokers, SourceProductionContext context)
|
||||||
{
|
{
|
||||||
var events = classSymbol.AllInterfaces.Add(classSymbol).SelectMany(i => i.GetMembers())
|
var events = classSymbol.AllInterfaces.Add(classSymbol).SelectMany(i => i.GetMembers())
|
||||||
.OfType<IEventSymbol>().ToList();
|
.OfType<IEventSymbol>().ToList();
|
||||||
if (events.Count == 0)
|
if (events.Count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var interfaceTemplate = (TemplateDocument)_codeTemplate.PartialInterface.Clone();
|
var interfaceTemplate = (TemplateDocument)_codeTemplate.PartialInterface.Clone();
|
||||||
interfaceTemplate.AddDefine("name", classSymbol.Name);
|
interfaceTemplate.AddDefine("name", classSymbol.Name);
|
||||||
interfaceTemplate.AddDefine("namespace", classSymbol.ContainingNamespace.ToDisplayString());
|
interfaceTemplate.AddDefine("namespace", classSymbol.ContainingNamespace.ToDisplayString());
|
||||||
var objectBinderTemplate =
|
var objectBinderTemplate =
|
||||||
(TemplateDocument)((InnerTemplateSection)_codeTemplate.RemoteTypeBinder["objectBinderTemplate"]!).InnerTemplate
|
(TemplateDocument)((InnerTemplateSection)_codeTemplate.RemoteTypeBinder["objectBinderTemplate"]!)
|
||||||
|
.InnerTemplate
|
||||||
.Clone();
|
.Clone();
|
||||||
foreach (var currentEvent in events)
|
foreach (var currentEvent in events)
|
||||||
{
|
{
|
||||||
@@ -218,7 +239,8 @@ namespace mROA.Codegen
|
|||||||
return caller;
|
return caller;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GenerateDeclaredMethod(TemplateDocument classTemplate, IMethodSymbol method, List<string> invokers, INamedTypeSymbol baseInterface)
|
private void GenerateDeclaredMethod(TemplateDocument classTemplate, IMethodSymbol method, List<string> invokers,
|
||||||
|
INamedTypeSymbol baseInterface)
|
||||||
{
|
{
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
|
|
||||||
@@ -581,28 +603,6 @@ namespace mROA.Codegen
|
|||||||
return generics.Length == 0 ? "void" : generics[0].ToUnityString();
|
return generics.Length == 0 ? "void" : generics[0].ToUnityString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static (InterfaceDeclarationSyntax node, bool usefull) ContainsSoiAttribute(
|
|
||||||
GeneratorSyntaxContext context)
|
|
||||||
{
|
|
||||||
var ids = (InterfaceDeclarationSyntax)context.Node;
|
|
||||||
|
|
||||||
// Go through all attributes of the class.
|
|
||||||
foreach (var attributeSyntax in ids.AttributeLists.SelectMany(attributeListSyntax =>
|
|
||||||
attributeListSyntax.Attributes))
|
|
||||||
{
|
|
||||||
if (context.SemanticModel.GetSymbolInfo(attributeSyntax).Symbol is not IMethodSymbol attributeSymbol)
|
|
||||||
continue; // if we can't get the symbol, ignore it
|
|
||||||
|
|
||||||
var attributeName = attributeSymbol.ContainingType.ToDisplayString();
|
|
||||||
|
|
||||||
// Check the full name of the [Report] attribute.
|
|
||||||
if (attributeName == $"mROA.Implementation.Attributes.SharedObjectInterfaceAttribute")
|
|
||||||
return (ids, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (ids, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<IMethodSymbol> CollectMembers(INamedTypeSymbol type)
|
public static List<IMethodSymbol> CollectMembers(INamedTypeSymbol type)
|
||||||
{
|
{
|
||||||
var methods = type.GetMembers().OfType<IMethodSymbol>().ToList();
|
var methods = type.GetMembers().OfType<IMethodSymbol>().ToList();
|
||||||
|
|||||||
Reference in New Issue
Block a user