I have following Attribute:
[AttributeUsage(AttributeTargets.Class)]
public class EventApplyAttribute : Attribute
{
public string Aggregate { get; }
public EventApplyAttribute(string aggregate)
{
Aggregate = aggregate;
}
}
I use the Attribute like this:
[EventApplyAttribute(nameof(BaseClass))]
public class Test : BaseEvent{}
I use this source generator:
[Generator]
public class SourceGeneration : IIncrementalGenerator
{
private const string EventApplyAttribute = "DomainLibrary.EventApplyAttribute";
public void Initialize(IncrementalGeneratorInitializationContext context)
{
IncrementalValuesProvider<ClassDeclarationSyntax> classDeclarations = context.SyntaxProvider
.ForAttributeWithMetadataName(
EventApplyAttribute,
predicate: (node, _) => node is ClassDeclarationSyntax,
transform: (ctx, ct) => GetSemanticTargetForGeneration(ctx, ct))
.Where(static m => m is not null);
IncrementalValueProvider<(Compilation, ImmutableArray<ClassDeclarationSyntax>)> compilationAndClasses
= context.CompilationProvider.Combine(classDeclarations.Collect());
context.RegisterSourceOutput(compilationAndClasses,
static (spc, source) => Execute(source.Item1, source.Item2, spc));
}
private static void Execute(Compilation compilation, ImmutableArray<ClassDeclarationSyntax> classes, SourceProductionContext context)
{
}
private static ClassDeclarationSyntax? GetSemanticTargetForGeneration(GeneratorAttributeSyntaxContext context, CancellationToken ct)
{
string fullName = context.Attributes.First().AttributeClass.ToDisplayString();
if (fullName == EventApplyAttribute)
{
if (context.TargetNode is not ClassDeclarationSyntax classDeclaration)
return null;
return classDeclaration;
}
return null;
}
}
The classes array in the Execute method has the expected classes. If I loop through the array I get a lot of information. Is there a way to access also attribute property value. In this case it would be "BaseClass"? I can't find anything...
You could extract the attribute from the
ClassDeclarationSyntaxobject using theAttributeListproperty, which contains the syntax of the attribute list. But that's tedious and very low-level.To make it easier and make the generator more efficient, you should do as @Youssef13 says and transform the value in
GetSemanticTargetForGeneration. TheGeneratorAttributeSyntaxContextalready has the attribute:Now we're returning pairs of the class declaration and the attribute data. You can process that in the
Executemethod; I don't know what your goal is, so here I'm just generating a file containing a comment with the class name you're looking for, to show that it works:For completeness, you need to change the main
Initializemethod thusly: