- tweak: View autogenerator
This commit is contained in:
@@ -71,7 +71,7 @@ partial class {className}
|
||||
";
|
||||
|
||||
// Add the source code to the compilation.
|
||||
context.AddSource($"{className}.g.cs", SourceText.From(code, Encoding.UTF8));
|
||||
context.AddSource($"{className}_dependencyAuto.g.cs", SourceText.From(code, Encoding.UTF8));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,24 +7,6 @@ namespace Nebula.SourceGenerators;
|
||||
|
||||
public static class SourceHelper
|
||||
{
|
||||
public static void GenerateAttribute(string attributeName, string usage,
|
||||
IncrementalGeneratorInitializationContext context)
|
||||
{
|
||||
var attributeSourceCode = $@"// <auto-generated/>
|
||||
|
||||
namespace SourceGen
|
||||
{{
|
||||
[System.AttributeUsage(System.AttributeTargets.{usage})]
|
||||
public class {attributeName} : System.Attribute
|
||||
{{
|
||||
}}
|
||||
}}";
|
||||
|
||||
context.RegisterPostInitializationOutput(ctx => ctx.AddSource(
|
||||
$"{attributeName}.g.cs",
|
||||
SourceText.From(attributeSourceCode, Encoding.UTF8)));
|
||||
}
|
||||
|
||||
public static bool HasAttribute(ISymbol type, string attributeName)
|
||||
{
|
||||
foreach (var attribute in type.GetAttributes())
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
@@ -6,53 +8,82 @@ using Microsoft.CodeAnalysis.Text;
|
||||
|
||||
namespace Nebula.SourceGenerators;
|
||||
|
||||
//[Generator]
|
||||
public class ViewConstructGenerator : IIncrementalGenerator
|
||||
|
||||
[Generator]
|
||||
public class ViewConstructorGenerator : IIncrementalGenerator
|
||||
{
|
||||
public static string ViewForModelAttributeName = "ViewForModelAttribute";
|
||||
|
||||
private static readonly string ViewModelAttribute = "Nebula.Shared.ViewHelper.ViewModelRegisterAttribute";
|
||||
public void Initialize(IncrementalGeneratorInitializationContext context)
|
||||
{
|
||||
var provider = context.SyntaxProvider
|
||||
.CreateSyntaxProvider(
|
||||
(s, _) => s is ClassDeclarationSyntax, (ctx, _) =>
|
||||
SourceHelper.GetClassDeclarationForSourceGen(ctx,ViewForModelAttributeName)
|
||||
)
|
||||
(s, _) => s is ClassDeclarationSyntax,
|
||||
(ctx, _) => SourceHelper.GetClassDeclarationForSourceGen(ctx,ViewModelAttribute))
|
||||
.Where(t => t.reportAttributeFound)
|
||||
.Select((t,_) => t.Item1);
|
||||
|
||||
context.RegisterSourceOutput(context.CompilationProvider.Combine(provider.Collect()), (ctx,t)=> GenerateCode(ctx, t.Left, t.Right));
|
||||
.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<ClassDeclarationSyntax> syntaxes)
|
||||
private void GenerateCode(SourceProductionContext context, Compilation compilation,
|
||||
ImmutableArray<ClassDeclarationSyntax> classDeclarations)
|
||||
{
|
||||
foreach (var classDeclarationSyntax in syntaxes)
|
||||
foreach (var classDeclarationSyntax in classDeclarations)
|
||||
{
|
||||
var semanticModel = compilation.GetSemanticModel(classDeclarationSyntax.SyntaxTree);
|
||||
if(semanticModel.GetDeclaredSymbol(classDeclarationSyntax) is not INamedTypeSymbol classSymbol)
|
||||
if (semanticModel.GetDeclaredSymbol(classDeclarationSyntax) is not INamedTypeSymbol classSymbol)
|
||||
continue;
|
||||
|
||||
var namespaceName = classSymbol.ContainingNamespace.ToDisplayString();
|
||||
var className = classDeclarationSyntax.Identifier.Text;
|
||||
var viewModelName = classSymbol.Name;
|
||||
var viewModelNamespace = classSymbol.ContainingNamespace.ToDisplayString();
|
||||
|
||||
var code = $@"// <auto-generated/>
|
||||
var viewModelRegisterAttr = classSymbol.GetAttributes()
|
||||
.FirstOrDefault(attr => attr.AttributeClass?.ToDisplayString() == ViewModelAttribute);
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
var viewTypeArg = viewModelRegisterAttr?.ConstructorArguments.FirstOrDefault();
|
||||
if (viewTypeArg?.Value is not INamedTypeSymbol viewTypeSymbol)
|
||||
continue;
|
||||
|
||||
namespace {namespaceName};
|
||||
|
||||
partial class {className}
|
||||
try
|
||||
{
|
||||
var viewName = viewTypeSymbol.Name;
|
||||
var viewNamespace = viewTypeSymbol.ContainingNamespace.ToDisplayString();
|
||||
|
||||
var code = $@"
|
||||
namespace {viewNamespace}
|
||||
{{
|
||||
public {className}() : base(){{
|
||||
|
||||
|
||||
public partial class {viewName}
|
||||
{{
|
||||
public {viewName}({viewModelNamespace}.{viewModelName} viewModel)
|
||||
: this()
|
||||
{{
|
||||
DataContext = viewModel;
|
||||
}}
|
||||
}}
|
||||
}}
|
||||
";
|
||||
}}";
|
||||
|
||||
// Add the source code to the compilation.
|
||||
context.AddSource($"{viewName}_viewConstructAuto.g.cs", SourceText.From(code, Encoding.UTF8));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
var coder1 = $@"
|
||||
// <auto-generated/>
|
||||
// Error!
|
||||
namespace {viewModelNamespace}
|
||||
{{
|
||||
public partial class {viewModelName}
|
||||
{{
|
||||
// {e.Message}
|
||||
}}
|
||||
}}";
|
||||
|
||||
// Add the source code to the compilation.
|
||||
context.AddSource($"{className}.g.cs", SourceText.From(code, Encoding.UTF8));
|
||||
// Add the source code to the compilation.
|
||||
context.AddSource($"{viewModelName}_viewError.g.cs", SourceText.From(coder1, Encoding.UTF8));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user