End merge Add with template and Update
This commit is contained in:
commit
4d9cc4b029
|
@ -45,6 +45,7 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="bin\Release\netstandard2.0" />
|
<Folder Include="bin\Release\netstandard2.0" />
|
||||||
|
<Folder Include="Sources\EntityFramework" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -10,11 +10,20 @@ using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||||
|
|
||||||
namespace MapTo
|
namespace MapTo
|
||||||
{
|
{
|
||||||
|
/*/// <summary>
|
||||||
|
/// Base source code generator typed class.
|
||||||
|
/// </summary>
|
||||||
|
public class SourceCodeGenerator : ISourceGenerator
|
||||||
|
{
|
||||||
|
public virtual void Initialize(GeneratorInitializationContext context) {}
|
||||||
|
public virtual void Execute(GeneratorExecutionContext context) {}
|
||||||
|
}*/
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Ef methods source generator
|
/// Ef methods source generator
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Generator]
|
[Generator]
|
||||||
public class EfAddMethodsGenerator: ISourceGenerator
|
public class EfMethodsGenerator: ISourceGenerator
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void Initialize(GeneratorInitializationContext context)
|
public void Initialize(GeneratorInitializationContext context)
|
||||||
|
@ -44,11 +53,11 @@ namespace MapTo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AddGeneratedExtensions(GeneratorExecutionContext context, Compilation compilation, IEnumerable<MemberDeclarationSyntax> candidateTypes, SourceGenerationOptions options)
|
private static void AddGeneratedExtensions(GeneratorExecutionContext context, Compilation compilation, IEnumerable<CandidateMember> candidateMembers, SourceGenerationOptions options)
|
||||||
{
|
{
|
||||||
//SpinWait.SpinUntil(() => Debugger.IsAttached);
|
//SpinWait.SpinUntil(() => Debugger.IsAttached);
|
||||||
|
|
||||||
foreach (var memberDeclarationSyntax in candidateTypes)
|
foreach (var candidateMember in candidateMembers)
|
||||||
{
|
{
|
||||||
string addSourceTemplate = string.Empty;
|
string addSourceTemplate = string.Empty;
|
||||||
|
|
||||||
|
@ -60,7 +69,7 @@ namespace MapTo
|
||||||
.ToString() ?? string.Empty;
|
.ToString() ?? string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
var mappingContext = EfAddGeneratorContext.Create(compilation, options, memberDeclarationSyntax, addSourceTemplate);
|
var mappingContext = EfAddGeneratorContext.Create(compilation, options, candidateMember.MemberDeclarationSyntax, addSourceTemplate);
|
||||||
|
|
||||||
mappingContext.Diagnostics.ForEach(context.ReportDiagnostic);
|
mappingContext.Diagnostics.ForEach(context.ReportDiagnostic);
|
||||||
|
|
||||||
|
@ -69,7 +78,7 @@ namespace MapTo
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var (source, hintName) = memberDeclarationSyntax switch
|
var (source, hintName) = candidateMember.MemberDeclarationSyntax switch
|
||||||
{
|
{
|
||||||
PropertyDeclarationSyntax => EfMethodsSource.Generate(mappingContext.Model, addSourceTemplate),
|
PropertyDeclarationSyntax => EfMethodsSource.Generate(mappingContext.Model, addSourceTemplate),
|
||||||
_ => throw new ArgumentOutOfRangeException()
|
_ => throw new ArgumentOutOfRangeException()
|
||||||
|
|
|
@ -6,9 +6,22 @@ using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||||
|
|
||||||
namespace MapTo
|
namespace MapTo
|
||||||
{
|
{
|
||||||
|
internal enum EfMethodsAttributeType
|
||||||
|
{
|
||||||
|
Add,
|
||||||
|
Update,
|
||||||
|
Invalid
|
||||||
|
}
|
||||||
|
|
||||||
|
internal record CandidateMember(
|
||||||
|
MemberDeclarationSyntax MemberDeclarationSyntax,
|
||||||
|
EfMethodsAttributeType AttributeType
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
internal class EfMethodsSyntaxReceiver : ISyntaxReceiver
|
internal class EfMethodsSyntaxReceiver : ISyntaxReceiver
|
||||||
{
|
{
|
||||||
public List<MemberDeclarationSyntax> CandidateMembers { get; } = new();
|
public List<CandidateMember> CandidateMembers { get; } = new();
|
||||||
|
|
||||||
public void OnVisitSyntaxNode(SyntaxNode syntaxNode)
|
public void OnVisitSyntaxNode(SyntaxNode syntaxNode)
|
||||||
{
|
{
|
||||||
|
@ -17,22 +30,44 @@ namespace MapTo
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var syntaxAttributeState = EfMethodsAttributeType.Invalid;
|
||||||
|
|
||||||
var attributeSyntax = attributes
|
var attributeSyntax = attributes
|
||||||
.SelectMany(a => a.Attributes)
|
.SelectMany(a => a.Attributes)
|
||||||
.FirstOrDefault(a => a.Name is
|
.FirstOrDefault(a =>
|
||||||
IdentifierNameSyntax { Identifier: { ValueText: EfAddMethodsAttributeSource.AttributeName } } // For: [EfAddMethods]
|
{
|
||||||
or
|
syntaxAttributeState = IsValidAttributeType(a);
|
||||||
QualifiedNameSyntax // For: [MapTo.EfAddMethods]
|
return syntaxAttributeState != EfMethodsAttributeType.Invalid;
|
||||||
{
|
});
|
||||||
Left: IdentifierNameSyntax { Identifier: { ValueText: Constants.RootNamespace } },
|
|
||||||
Right: IdentifierNameSyntax { Identifier: { ValueText: EfAddMethodsAttributeSource.AttributeName } }
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
if (attributeSyntax is not null)
|
if (attributeSyntax is not null)
|
||||||
{
|
{
|
||||||
CandidateMembers.Add(typeDeclarationSyntax);
|
CandidateMembers.Add(new CandidateMember(typeDeclarationSyntax, syntaxAttributeState));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static EfMethodsAttributeType IsValidAttributeType(AttributeSyntax a)
|
||||||
|
{
|
||||||
|
return a.Name switch
|
||||||
|
{
|
||||||
|
IdentifierNameSyntax { Identifier: { ValueText: EfAddMethodsAttributeSource.AttributeName } } // For: [EfAddMethods]
|
||||||
|
or QualifiedNameSyntax // For: [MapTo.EfAddMethods]
|
||||||
|
{
|
||||||
|
Left: IdentifierNameSyntax { Identifier: { ValueText: Constants.RootNamespace } },
|
||||||
|
Right: IdentifierNameSyntax { Identifier: { ValueText: EfAddMethodsAttributeSource.AttributeName } }
|
||||||
|
} => EfMethodsAttributeType.Add,
|
||||||
|
|
||||||
|
IdentifierNameSyntax { Identifier: { ValueText: EfUpdateMethodsAttributeSource.AttributeName } } // For: [EfAddMethods]
|
||||||
|
or QualifiedNameSyntax // For: [MapTo.EfUpdateMethods]
|
||||||
|
{
|
||||||
|
Left: IdentifierNameSyntax { Identifier: { ValueText: Constants.RootNamespace } },
|
||||||
|
Right: IdentifierNameSyntax { Identifier: { ValueText: EfUpdateMethodsAttributeSource.AttributeName } }
|
||||||
|
} => EfMethodsAttributeType.Update,
|
||||||
|
|
||||||
|
_ => EfMethodsAttributeType.Invalid
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
using static MapTo.Sources.Constants;
|
||||||
|
|
||||||
|
namespace MapTo.Sources
|
||||||
|
{
|
||||||
|
public class EfUpdateMethodsAttributeSource
|
||||||
|
{
|
||||||
|
internal const string AttributeName = "EfUpdateMethods";
|
||||||
|
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.Property | AttributeTargets.Field)]")
|
||||||
|
.WriteLine($"public sealed class {AttributeName}Attribute : Attribute")
|
||||||
|
.WriteOpeningBracket();
|
||||||
|
|
||||||
|
builder
|
||||||
|
.WriteLine($"public {AttributeName}Attribute(Type updateType = null, Type returnType = null, string keyPropertyMemberName, Type keyPropertyMemberType)")
|
||||||
|
.WriteOpeningBracket()
|
||||||
|
.WriteClosingBracket()
|
||||||
|
.WriteLine();
|
||||||
|
|
||||||
|
builder
|
||||||
|
.WriteClosingBracket() // class
|
||||||
|
.WriteClosingBracket(); // namespace
|
||||||
|
|
||||||
|
return new(builder.ToString(), $"{AttributeName}Attribute.g.cs");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue