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

View File

@ -7,7 +7,10 @@ using System.Threading;
using MapTo.Extensions;
using MapTo.Sources;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using CSharpExtensions = Microsoft.CodeAnalysis.CSharpExtensions;
#pragma warning disable CS8602
namespace MapTo
@ -93,7 +96,14 @@ namespace MapTo
protected ImmutableArray<LiteralExpressionSyntax> GetEntityStringLiteralSymbol(MemberDeclarationSyntax memberDeclarationSyntax, string attributeName, SemanticModel? semanticModel = null)
{
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;
}
@ -126,14 +136,13 @@ namespace MapTo
return resultList.ToImmutableArray();
}
protected ImmutableArray<LiteralExpressionSyntax> GetEntityStringLiteralSymbol(SyntaxNode? attributeSyntax, SemanticModel? semanticModel = null)
protected ImmutableArray<LiteralExpressionSyntax> GetEntityStringLiteralSymbol(SyntaxNode? attributeSyntax)
{
if (attributeSyntax is null)
{
return new ImmutableArray<LiteralExpressionSyntax>(){};
}
semanticModel ??= Compilation.GetSemanticModel(attributeSyntax.SyntaxTree);
var descendentNodes = attributeSyntax
.DescendantNodes();
@ -145,6 +154,30 @@ namespace MapTo
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)
{
@ -272,10 +305,16 @@ namespace MapTo
var efAddAttributeTypeSymbols =
GetEntityTypeSymbol(MemberSyntax, EfUpdateMethodsAttributeSource.AttributeName, semanticModel);
var keyPropertyName = GetEntityStringLiteralSymbol(MemberSyntax, EfUpdateMethodsAttributeSource.AttributeName, semanticModel)
.FirstOrDefault()?
.Token.ValueText ?? "Id";
var keyPropertyName = ExtractNameOfMemberName(MemberSyntax, EfUpdateMethodsAttributeSource.AttributeName, semanticModel);
// 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;
string updateTypeIdentifierName = entityTypeName;
@ -313,7 +352,7 @@ namespace MapTo
{
var member = (memberDeclarationSyntax as PropertyDeclarationSyntax).Type;
var genericSyntax = member as GenericNameSyntax;
var typeInfo = semanticModel.GetTypeInfo(genericSyntax);
var typeInfo = ModelExtensions.GetTypeInfo(semanticModel, genericSyntax);
var firstTypeArgument = (typeInfo.ConvertedType as INamedTypeSymbol).TypeArguments[0];
return firstTypeArgument;
}

View File

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