From e23d932d13d1bee2d11acddf7945db6fe9dff5d9 Mon Sep 17 00:00:00 2001 From: Wvader <34067397+wvader@users.noreply.github.com> Date: Mon, 29 Aug 2022 17:30:32 +0100 Subject: [PATCH] update template using nameof to specify id --- src/BlueWest.MapTo/BlueWest.MapTo.csproj | 3 +- src/BlueWest.MapTo/EfAddGeneratorContext.cs | 53 ++++++++++++++++--- src/BlueWest.MapTo/Sources/EfMethodsSource.cs | 5 +- 3 files changed, 50 insertions(+), 11 deletions(-) diff --git a/src/BlueWest.MapTo/BlueWest.MapTo.csproj b/src/BlueWest.MapTo/BlueWest.MapTo.csproj index 04ec218..79694ed 100644 --- a/src/BlueWest.MapTo/BlueWest.MapTo.csproj +++ b/src/BlueWest.MapTo/BlueWest.MapTo.csproj @@ -28,7 +28,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -45,7 +45,6 @@ - diff --git a/src/BlueWest.MapTo/EfAddGeneratorContext.cs b/src/BlueWest.MapTo/EfAddGeneratorContext.cs index b8ffceb..5150473 100644 --- a/src/BlueWest.MapTo/EfAddGeneratorContext.cs +++ b/src/BlueWest.MapTo/EfAddGeneratorContext.cs @@ -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 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 GetEntityStringLiteralSymbol(SyntaxNode? attributeSyntax, SemanticModel? semanticModel = null) + protected ImmutableArray GetEntityStringLiteralSymbol(SyntaxNode? attributeSyntax) { if (attributeSyntax is null) { return new ImmutableArray(){}; } - 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() + .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; } diff --git a/src/BlueWest.MapTo/Sources/EfMethodsSource.cs b/src/BlueWest.MapTo/Sources/EfMethodsSource.cs index c2a567c..91d2661 100644 --- a/src/BlueWest.MapTo/Sources/EfMethodsSource.cs +++ b/src/BlueWest.MapTo/Sources/EfMethodsSource.cs @@ -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; }