ef update wip
This commit is contained in:
parent
340a89bbd2
commit
c34da98ad8
|
@ -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>
|
||||||
|
|
|
@ -46,11 +46,11 @@ namespace MapTo
|
||||||
|
|
||||||
protected ImmutableArray<string> Usings { get; private set; }
|
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()
|
_ => throw new ArgumentOutOfRangeException()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -10,15 +10,6 @@ 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>
|
||||||
|
@ -34,12 +25,15 @@ namespace MapTo
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void Execute(GeneratorExecutionContext context)
|
public void Execute(GeneratorExecutionContext context)
|
||||||
{
|
{
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var options = SourceGenerationOptions.From(context);
|
var options = SourceGenerationOptions.From(context);
|
||||||
|
|
||||||
var compilation = context.Compilation
|
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())
|
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);
|
//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),
|
PropertyDeclarationSyntax => EfMethodsSource.Generate(mappingContext.Model),
|
||||||
_ => 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