using System.Collections.Immutable; using System.Text; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; namespace Nebula.SourceGenerators; //[Generator] public class ViewConstructGenerator : IIncrementalGenerator { public static string ViewForModelAttributeName = "ViewForModelAttribute"; public void Initialize(IncrementalGeneratorInitializationContext context) { var provider = context.SyntaxProvider .CreateSyntaxProvider( (s, _) => s is ClassDeclarationSyntax, (ctx, _) => SourceHelper.GetClassDeclarationForSourceGen(ctx,ViewForModelAttributeName) ) .Where(t => t.reportAttributeFound) .Select((t,_) => t.Item1); context.RegisterSourceOutput(context.CompilationProvider.Combine(provider.Collect()), (ctx,t)=> GenerateCode(ctx, t.Left, t.Right)); } private void GenerateCode(SourceProductionContext context, Compilation compilation, ImmutableArray syntaxes) { foreach (var classDeclarationSyntax in syntaxes) { var semanticModel = compilation.GetSemanticModel(classDeclarationSyntax.SyntaxTree); if(semanticModel.GetDeclaredSymbol(classDeclarationSyntax) is not INamedTypeSymbol classSymbol) continue; var namespaceName = classSymbol.ContainingNamespace.ToDisplayString(); var className = classDeclarationSyntax.Identifier.Text; var code = $@"// using System; using System.Collections.Generic; namespace {namespaceName}; partial class {className} {{ public {className}() : base(){{ }} }} "; // Add the source code to the compilation. context.AddSource($"{className}.g.cs", SourceText.From(code, Encoding.UTF8)); } } }