109 lines
3.1 KiB
C#
109 lines
3.1 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
using Microsoft.CodeAnalysis;
|
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|
|
|
namespace MfGames.Nitride.Generators;
|
|
|
|
public abstract class ClassAttributeSyntaxReceiverBase : ISyntaxReceiver
|
|
{
|
|
private readonly string attributeName;
|
|
|
|
private readonly GeneratorInitializationContext context;
|
|
|
|
public ClassAttributeSyntaxReceiverBase(
|
|
GeneratorInitializationContext context,
|
|
string attributeName)
|
|
{
|
|
this.context = context;
|
|
this.attributeName = attributeName;
|
|
this.ReferenceList = new List<ClassAttributeReference>();
|
|
this.Messages = new List<string>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets a value indicating whether we should debug parsing attributes.
|
|
/// </summary>
|
|
public bool DebugAttributes { get; set; }
|
|
|
|
public List<string> Messages { get; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the name of the analyzed namespace.
|
|
/// </summary>
|
|
public string? Namespace { get; private set; }
|
|
|
|
public List<ClassAttributeReference> ReferenceList { get; }
|
|
|
|
public List<UsingDirectiveSyntax> UsingDirectiveList { get; set; } = new();
|
|
|
|
public void OnVisitSyntaxNode(SyntaxNode syntaxNode)
|
|
{
|
|
// Check for namespaces.
|
|
switch (syntaxNode)
|
|
{
|
|
case CompilationUnitSyntax:
|
|
// Reset everything.
|
|
this.Namespace = null!;
|
|
this.UsingDirectiveList = new List<UsingDirectiveSyntax>();
|
|
|
|
break;
|
|
case NamespaceDeclarationSyntax syntax:
|
|
this.Namespace = syntax.Name.ToString();
|
|
|
|
return;
|
|
case FileScopedNamespaceDeclarationSyntax syntax:
|
|
this.Namespace = syntax.Name.ToString();
|
|
|
|
return;
|
|
case UsingDirectiveSyntax syntax:
|
|
this.UsingDirectiveList.Add(syntax);
|
|
|
|
return;
|
|
case ClassDeclarationSyntax:
|
|
break;
|
|
default:
|
|
return;
|
|
}
|
|
|
|
// We only care about class declarations.
|
|
if (syntaxNode is not ClassDeclarationSyntax cds)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// See if the class has our set properties attribute.
|
|
var attributes = cds.AttributeLists
|
|
.AsEnumerable()
|
|
.SelectMany(x => x.Attributes)
|
|
.Select(x => x.Name.ToString())
|
|
.ToList();
|
|
bool found = attributes
|
|
.Any(
|
|
x => x == this.attributeName
|
|
|| x == $"{this.attributeName}Attribute");
|
|
|
|
if (this.DebugAttributes)
|
|
{
|
|
this.Messages.Add(
|
|
string.Format(
|
|
"Parsing {0} found? {1} from attributes [{2}]",
|
|
cds.Identifier,
|
|
found,
|
|
string.Join(", ", attributes)));
|
|
}
|
|
|
|
if (found)
|
|
{
|
|
this.ReferenceList.Add(
|
|
new ClassAttributeReference
|
|
{
|
|
Namespace = this.Namespace!,
|
|
UsingDirectiveList = this.UsingDirectiveList,
|
|
ClassDeclaration = cds,
|
|
});
|
|
}
|
|
}
|
|
}
|