using System.Collections.Generic; using System.Linq; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; namespace MfGames.Nitride.Generators; internal class WithPropertySyntaxReceiver : ISyntaxReceiver { private readonly GeneratorInitializationContext context; public WithPropertySyntaxReceiver(GeneratorInitializationContext context) { this.context = context; this.ClassList = new List(); this.Messages = new List(); } public List ClassList { get; } public List Messages { get; } /// /// Gets or sets the name of the analyzed namespace. /// public string? Namespace { get; private set; } public List 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(); 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. bool found = cds.AttributeLists.AsEnumerable() .SelectMany(x => x.Attributes) .Select(x => x.Name.ToString()) .Any( x => x switch { "WithProperties" => true, "WithPropertiesAttribute" => true, _ => false, }); if (found) { this.ClassList.Add( new WithPropertyClass { Namespace = this.Namespace!, UsingDirectiveList = this.UsingDirectiveList, ClassDeclaration = cds, }); } } }