update template using nameof to specify id

This commit is contained in:
Wvader 2022-08-29 17:30:32 +01:00
parent 654a54d5ef
commit e23d932d13
3 changed files with 50 additions and 11 deletions

View File

@ -28,7 +28,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.2"> <PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.3">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
@ -45,7 +45,6 @@
<ItemGroup> <ItemGroup>
<Folder Include="bin\Release\netstandard2.0" /> <Folder Include="bin\Release\netstandard2.0" />
<Folder Include="Sources\EntityFramework" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -7,7 +7,10 @@ using System.Threading;
using MapTo.Extensions; using MapTo.Extensions;
using MapTo.Sources; using MapTo.Sources;
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Syntax;
using CSharpExtensions = Microsoft.CodeAnalysis.CSharpExtensions;
#pragma warning disable CS8602 #pragma warning disable CS8602
namespace MapTo namespace MapTo
@ -93,7 +96,14 @@ namespace MapTo
protected ImmutableArray<LiteralExpressionSyntax> GetEntityStringLiteralSymbol(MemberDeclarationSyntax memberDeclarationSyntax, string attributeName, SemanticModel? semanticModel = null) protected ImmutableArray<LiteralExpressionSyntax> GetEntityStringLiteralSymbol(MemberDeclarationSyntax memberDeclarationSyntax, string attributeName, SemanticModel? semanticModel = null)
{ {
var attributeData = memberDeclarationSyntax.GetAttribute(attributeName); var attributeData = memberDeclarationSyntax.GetAttribute(attributeName);
var sourceSymbol = GetEntityStringLiteralSymbol(attributeData, semanticModel); var sourceSymbol = GetEntityStringLiteralSymbol(attributeData);
return sourceSymbol;
}
protected string ExtractNameOfMemberName(MemberDeclarationSyntax memberDeclarationSyntax, string attributeName, SemanticModel? semanticModel = null)
{
var attributeData = memberDeclarationSyntax.GetAttribute(attributeName);
var sourceSymbol = ExtractNameOfMemberName(attributeData);
return sourceSymbol; return sourceSymbol;
} }
@ -126,14 +136,13 @@ namespace MapTo
return resultList.ToImmutableArray(); return resultList.ToImmutableArray();
} }
protected ImmutableArray<LiteralExpressionSyntax> GetEntityStringLiteralSymbol(SyntaxNode? attributeSyntax, SemanticModel? semanticModel = null) protected ImmutableArray<LiteralExpressionSyntax> GetEntityStringLiteralSymbol(SyntaxNode? attributeSyntax)
{ {
if (attributeSyntax is null) if (attributeSyntax is null)
{ {
return new ImmutableArray<LiteralExpressionSyntax>(){}; return new ImmutableArray<LiteralExpressionSyntax>(){};
} }
semanticModel ??= Compilation.GetSemanticModel(attributeSyntax.SyntaxTree);
var descendentNodes = attributeSyntax var descendentNodes = attributeSyntax
.DescendantNodes(); .DescendantNodes();
@ -145,6 +154,30 @@ namespace MapTo
return sourceTypeExpressionSyntax; return sourceTypeExpressionSyntax;
} }
protected string ExtractNameOfMemberName(SyntaxNode? attributeSyntax)
{
if (attributeSyntax is null)
{
return string.Empty;
}
var descendentNodes = attributeSyntax
.DescendantNodes();
var idNode = descendentNodes.OfType<InvocationExpressionSyntax>()
.FirstOrDefault()
?.ChildNodesAndTokens()
.FirstOrDefault(x => x.IsKind(SyntaxKind.ArgumentList))
.ChildNodesAndTokens()
.FirstOrDefault(x => x.IsKind(SyntaxKind.Argument))
.ChildNodesAndTokens()
.FirstOrDefault()
.ChildNodesAndTokens()
.LastOrDefault();
return idNode != null ? idNode.ToString() : String.Empty;
}
protected bool IsEnumerable(ISymbol property, out INamedTypeSymbol? namedTypeSymbolResult) protected bool IsEnumerable(ISymbol property, out INamedTypeSymbol? namedTypeSymbolResult)
{ {
@ -272,10 +305,16 @@ namespace MapTo
var efAddAttributeTypeSymbols = var efAddAttributeTypeSymbols =
GetEntityTypeSymbol(MemberSyntax, EfUpdateMethodsAttributeSource.AttributeName, semanticModel); GetEntityTypeSymbol(MemberSyntax, EfUpdateMethodsAttributeSource.AttributeName, semanticModel);
var keyPropertyName = GetEntityStringLiteralSymbol(MemberSyntax, EfUpdateMethodsAttributeSource.AttributeName, semanticModel) var keyPropertyName = ExtractNameOfMemberName(MemberSyntax, EfUpdateMethodsAttributeSource.AttributeName, semanticModel);
.FirstOrDefault()?
.Token.ValueText ?? "Id";
// Try grabbing string literal if there's no nameof in it
if (keyPropertyName == string.Empty)
{
keyPropertyName = GetEntityStringLiteralSymbol(MemberSyntax, EfUpdateMethodsAttributeSource.AttributeName, semanticModel)
.FirstOrDefault()?
.Token.ValueText ?? "Id";
}
if (efAddAttributeTypeSymbols == null) return null; if (efAddAttributeTypeSymbols == null) return null;
string updateTypeIdentifierName = entityTypeName; string updateTypeIdentifierName = entityTypeName;
@ -313,7 +352,7 @@ namespace MapTo
{ {
var member = (memberDeclarationSyntax as PropertyDeclarationSyntax).Type; var member = (memberDeclarationSyntax as PropertyDeclarationSyntax).Type;
var genericSyntax = member as GenericNameSyntax; var genericSyntax = member as GenericNameSyntax;
var typeInfo = semanticModel.GetTypeInfo(genericSyntax); var typeInfo = ModelExtensions.GetTypeInfo(semanticModel, genericSyntax);
var firstTypeArgument = (typeInfo.ConvertedType as INamedTypeSymbol).TypeArguments[0]; var firstTypeArgument = (typeInfo.ConvertedType as INamedTypeSymbol).TypeArguments[0];
return firstTypeArgument; return firstTypeArgument;
} }

View File

@ -3,6 +3,7 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using MapTo.Extensions; using MapTo.Extensions;
using Microsoft.CodeAnalysis.CSharp;
using static MapTo.Sources.Constants; using static MapTo.Sources.Constants;
namespace MapTo.Sources namespace MapTo.Sources
@ -19,6 +20,7 @@ namespace MapTo.Sources
var propertyName = model.PropertyName; var propertyName = model.PropertyName;
builder builder
.WriteLine(GeneratedFilesHeader)
.WriteUsings(model.Usings) .WriteUsings(model.Usings)
.WriteLine("using Microsoft.EntityFrameworkCore;") .WriteLine("using Microsoft.EntityFrameworkCore;")
.WriteLine("using System.Linq;") .WriteLine("using System.Linq;")
@ -40,6 +42,7 @@ namespace MapTo.Sources
contextFullName, contextFullName,
entityTypeFullName, entityTypeFullName,
propertyName) propertyName)
.WriteLine()
.EfAddUpdateEntityMethod(model, updateSourceTemplate, .EfAddUpdateEntityMethod(model, updateSourceTemplate,
entityTypeName, entityTypeName,
contextFullName, contextFullName,
@ -134,7 +137,6 @@ namespace MapTo.Sources
if (updateSourceTemplate.IsEmpty()) if (updateSourceTemplate.IsEmpty())
{ {
builder builder
.WriteLine(GeneratedFilesHeader)
.WriteLine($"public static (bool, {returnTypeFullName}) Update{entityTypeName}(") .WriteLine($"public static (bool, {returnTypeFullName}) Update{entityTypeName}(")
.WriteLine($"this {contextFullName} dbContext,") .WriteLine($"this {contextFullName} dbContext,")
.WriteLine($"{updateTypeFullName} {updateVarName},") .WriteLine($"{updateTypeFullName} {updateVarName},")
@ -149,7 +151,6 @@ namespace MapTo.Sources
builder builder
.WriteLine(); .WriteLine();
} }
builder.Indent();
return builder; return builder;
} }