Add generator attribute source
This commit is contained in:
parent
9257d389ba
commit
3917d231a2
|
@ -0,0 +1,41 @@
|
|||
using static MapTo.Sources.Constants;
|
||||
|
||||
namespace MapTo.Sources
|
||||
{
|
||||
public class EfGeneratorAttributeSource
|
||||
{
|
||||
internal const string AttributeName = "EfGenerator";
|
||||
internal const string AttributeClassName = AttributeName + "Attribute";
|
||||
internal const string FullyQualifiedName = RootNamespace + "." + AttributeClassName;
|
||||
|
||||
internal static SourceCode Generate(SourceGenerationOptions options)
|
||||
{
|
||||
using var builder = new SourceBuilder()
|
||||
.WriteLine(GeneratedFilesHeader)
|
||||
.WriteLine("using System;")
|
||||
.WriteLine()
|
||||
.WriteLine($"namespace {RootNamespace}")
|
||||
.WriteOpeningBracket();
|
||||
|
||||
if (options.GenerateXmlDocument)
|
||||
{
|
||||
builder
|
||||
.WriteLine("/// <summary>")
|
||||
.WriteLine("/// Generate Add methods for interacting with the entity")
|
||||
.WriteLine("/// </summary>");
|
||||
}
|
||||
|
||||
builder
|
||||
.WriteLine("[AttributeUsage(AttributeTargets.Class)]")
|
||||
.WriteLine($"public sealed class {AttributeName}Attribute : Attribute")
|
||||
.WriteOpeningBracket()
|
||||
.WriteLine();
|
||||
|
||||
builder
|
||||
.WriteClosingBracket() // class
|
||||
.WriteClosingBracket(); // namespace
|
||||
|
||||
return new(builder.ToString(), $"{AttributeName}Attribute.g.cs");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using MapTo.Extensions;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
|
||||
namespace MapTo.Sources.EfMethods
|
||||
{
|
||||
public static class EfGeneratorExtensionMethods
|
||||
{
|
||||
public static void InitializeEfGenerator(this ISourceGenerator sourceGenerator, GeneratorInitializationContext context)
|
||||
{
|
||||
context.RegisterForSyntaxNotifications(() => new EfMethodsSyntaxReceiver());
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public static void ExecuteEfGenerator(this ISourceGenerator sourceGenerator, GeneratorExecutionContext context)
|
||||
{
|
||||
try
|
||||
{
|
||||
var options = SourceGenerationOptions.From(context);
|
||||
|
||||
var compilation = context.Compilation
|
||||
.AddSource(ref context, EfAddMethodsAttributeSource.Generate(options))
|
||||
.AddSource(ref context, EfUpdateMethodsAttributeSource.Generate(options));
|
||||
|
||||
|
||||
if (context.SyntaxReceiver is EfMethodsSyntaxReceiver receiver && receiver.CandidateMembers.Any())
|
||||
{
|
||||
AddGeneratedExtensions(context, compilation, receiver.CandidateMembers, options);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddGeneratedExtensions( GeneratorExecutionContext context, Compilation compilation, IEnumerable<CandidateMember> candidateMembers, SourceGenerationOptions options)
|
||||
{
|
||||
//SpinWait.SpinUntil(() => Debugger.IsAttached);
|
||||
|
||||
foreach (var candidateMember in candidateMembers)
|
||||
{
|
||||
string addSourceTemplate = context.AdditionalFiles
|
||||
.FirstOrDefault(x => x.Path.Contains("AddToEntityTemplate"))?
|
||||
.GetText()?
|
||||
.ToString() ?? string.Empty;
|
||||
|
||||
string updateSourceTemplate = context.AdditionalFiles
|
||||
.FirstOrDefault(x => x.Path.Contains("UpdateEntityTemplate"))?
|
||||
.GetText()?
|
||||
.ToString() ?? string.Empty;
|
||||
|
||||
|
||||
var mappingContext = EfGeneratorContext.Create(compilation, options, candidateMember.MemberDeclarationSyntax);
|
||||
|
||||
mappingContext.Diagnostics.ForEach(context.ReportDiagnostic);
|
||||
|
||||
if (mappingContext.Model is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var (source, hintName) = candidateMember.MemberDeclarationSyntax switch
|
||||
{
|
||||
PropertyDeclarationSyntax => EfMethodsSource.Generate(mappingContext.Model, addSourceTemplate, updateSourceTemplate),
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
};
|
||||
|
||||
context.AddSource(hintName, source);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -30,6 +30,7 @@ namespace MapTo
|
|||
var options = SourceGenerationOptions.From(context);
|
||||
|
||||
var compilation = context.Compilation
|
||||
.AddSource(ref context, EfGeneratorAttributeSource.Generate(options))
|
||||
.AddSource(ref context, EfAddMethodsAttributeSource.Generate(options))
|
||||
.AddSource(ref context, EfUpdateMethodsAttributeSource.Generate(options));
|
||||
|
Loading…
Reference in New Issue