This repository has been archived on 2023-02-02. You can view files and clone it, but cannot push or open issues or pull requests.
mfgames-nitride-cil/src/MfGames.Nitride.Generators/ClassAttributeSyntaxReceive...

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,
});
}
}
}