ef update wip
This commit is contained in:
parent
340a89bbd2
commit
c34da98ad8
|
@ -45,6 +45,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<Folder Include="bin\Release\netstandard2.0" />
|
||||
<Folder Include="Sources\EntityFramework" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -46,11 +46,11 @@ namespace MapTo
|
|||
|
||||
protected ImmutableArray<string> Usings { get; private set; }
|
||||
|
||||
public static EfGeneratorContext Create(Compilation compilation, SourceGenerationOptions sourceGenerationOptions, MemberDeclarationSyntax typeSyntax)
|
||||
public static EfGeneratorContext Create(Compilation compilation, SourceGenerationOptions sourceGenerationOptions, CandidateMember candidateMember)
|
||||
{
|
||||
EfGeneratorContext context = typeSyntax switch
|
||||
EfGeneratorContext context = candidateMember.MemberDeclarationSyntax switch
|
||||
{
|
||||
PropertyDeclarationSyntax => new EfGeneratorContext(compilation, sourceGenerationOptions, typeSyntax),
|
||||
PropertyDeclarationSyntax => new EfGeneratorContext(compilation, sourceGenerationOptions, candidateMember.MemberDeclarationSyntax),
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
};
|
||||
|
||||
|
|
|
@ -10,15 +10,6 @@ using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|||
|
||||
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>
|
||||
/// Ef methods source generator
|
||||
/// </summary>
|
||||
|
@ -34,12 +25,15 @@ namespace MapTo
|
|||
/// <inheritdoc />
|
||||
public void Execute(GeneratorExecutionContext context)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
var options = SourceGenerationOptions.From(context);
|
||||
|
||||
var compilation = context.Compilation
|
||||
.AddSource(ref context, EfAddMethodsAttributeSource.Generate(options));
|
||||
.AddSource(ref context, EfAddMethodsAttributeSource.Generate(options))
|
||||
.AddSource(ref context, EfUpdateMethodsAttributeSource.Generate(options));
|
||||
|
||||
|
||||
if (context.SyntaxReceiver is EfMethodsSyntaxReceiver receiver && receiver.CandidateMembers.Any())
|
||||
{
|
||||
|
@ -53,7 +47,7 @@ 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> candidateTypes, SourceGenerationOptions options)
|
||||
{
|
||||
//SpinWait.SpinUntil(() => Debugger.IsAttached);
|
||||
|
||||
|
@ -68,7 +62,7 @@ namespace MapTo
|
|||
}
|
||||
|
||||
|
||||
var (source, hintName) = memberDeclarationSyntax switch
|
||||
var (source, hintName) = memberDeclarationSyntax.MemberDeclarationSyntax switch
|
||||
{
|
||||
PropertyDeclarationSyntax => EfMethodsSource.Generate(mappingContext.Model),
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
|
|
|
@ -6,9 +6,22 @@ using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|||
|
||||
namespace MapTo
|
||||
{
|
||||
internal enum EfMethodsAttributeType
|
||||
{
|
||||
Add,
|
||||
Update,
|
||||
Invalid
|
||||
}
|
||||
|
||||
internal record CandidateMember(
|
||||
MemberDeclarationSyntax MemberDeclarationSyntax,
|
||||
EfMethodsAttributeType AttributeType
|
||||
);
|
||||
|
||||
|
||||
internal class EfMethodsSyntaxReceiver : ISyntaxReceiver
|
||||
{
|
||||
public List<MemberDeclarationSyntax> CandidateMembers { get; } = new();
|
||||
public List<CandidateMember> CandidateMembers { get; } = new();
|
||||
|
||||
public void OnVisitSyntaxNode(SyntaxNode syntaxNode)
|
||||
{
|
||||
|
@ -17,22 +30,44 @@ namespace MapTo
|
|||
return;
|
||||
}
|
||||
|
||||
var syntaxAttributeState = EfMethodsAttributeType.Invalid;
|
||||
|
||||
var attributeSyntax = attributes
|
||||
.SelectMany(a => a.Attributes)
|
||||
.FirstOrDefault(a => a.Name is
|
||||
IdentifierNameSyntax { Identifier: { ValueText: EfAddMethodsAttributeSource.AttributeName } } // For: [EfAddMethods]
|
||||
or
|
||||
QualifiedNameSyntax // For: [MapTo.EfAddMethods]
|
||||
.FirstOrDefault(a =>
|
||||
{
|
||||
Left: IdentifierNameSyntax { Identifier: { ValueText: Constants.RootNamespace } },
|
||||
Right: IdentifierNameSyntax { Identifier: { ValueText: EfAddMethodsAttributeSource.AttributeName } }
|
||||
}
|
||||
);
|
||||
syntaxAttributeState = IsValidAttributeType(a);
|
||||
return syntaxAttributeState != EfMethodsAttributeType.Invalid;
|
||||
});
|
||||
|
||||
|
||||
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