diff --git a/src/BlueWest.MapTo/EfMethods/AttributeSources/EfGeneratorAttributeSource.cs b/src/BlueWest.MapTo/EfMethods/AttributeSources/EfGeneratorAttributeSource.cs deleted file mode 100644 index a742cf3..0000000 --- a/src/BlueWest.MapTo/EfMethods/AttributeSources/EfGeneratorAttributeSource.cs +++ /dev/null @@ -1,41 +0,0 @@ -using static MapTo.Sources.Constants; - -namespace MapTo.Sources -{ - public class EfGeneratorAttributeSource - { - internal const string AttributeName = "EfGenerator"; - 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("/// ") - .WriteLine("/// Generate Add methods for interacting with the entity") - .WriteLine("/// "); - } - - builder - .WriteLine("[AttributeUsage(AttributeTargets.Class)]") - .WriteLine($"public sealed class {AttributeName}Attribute : Attribute") - .WriteOpeningBracket() - .WriteLine(); - - builder - .WriteClosingBracket() // class - .WriteClosingBracket(); // namespace - - return new(builder.ToString(), $"{AttributeName}Attribute.g.cs"); - } - } -} \ No newline at end of file diff --git a/src/BlueWest.MapTo/EfMethods/AttributeSources/EfGetManyAttributeSource.cs b/src/BlueWest.MapTo/EfMethods/AttributeSources/EfGetManyAttributeSource.cs deleted file mode 100644 index 5e854ec..0000000 --- a/src/BlueWest.MapTo/EfMethods/AttributeSources/EfGetManyAttributeSource.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using static MapTo.Sources.Constants; - -namespace MapTo.Sources -{ - internal static class EfGetManyAttributeSource - { - internal const string AttributeName = "EfGetMany"; - 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("/// ") - .WriteLine("/// Attribute for generating a function to get one EF entity with a predicate as argument and a return type for the projection.") - .WriteLine("/// "); - } - - builder - .WriteLine("[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]") - .WriteLine($"public sealed class {AttributeName}Attribute : Attribute") - .WriteOpeningBracket(); - - builder - .WriteLine($"public {AttributeName}Attribute(Type returnType){"{}"}") - .WriteLine(); - - builder - .WriteClosingBracket() // class - .WriteClosingBracket(); // namespace - - return new(builder.ToString(), $"{AttributeName}Attribute.g.cs"); - } - } -} diff --git a/src/BlueWest.MapTo/EfMethods/AttributeSources/EfGetOneByAttributeSource.cs b/src/BlueWest.MapTo/EfMethods/AttributeSources/EfGetOneByAttributeSource.cs deleted file mode 100644 index aa14c77..0000000 --- a/src/BlueWest.MapTo/EfMethods/AttributeSources/EfGetOneByAttributeSource.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using static MapTo.Sources.Constants; - -namespace MapTo.Sources -{ - internal class EfGetOneByAttributeSource - { - internal const string AttributeName = "EfGetOneBy"; - 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("/// ") - .WriteLine("/// Generate Add methods for interacting with the entity") - .WriteLine("/// "); - } - - builder - .WriteLine("[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]") - .WriteLine($"public sealed class {AttributeName}Attribute : Attribute") - .WriteOpeningBracket(); - - builder - .WriteLine($"public {AttributeName}Attribute(string bynameof, Type returnType)") - .WriteOpeningBracket() - .WriteClosingBracket() - .WriteLine(); - - builder - .WriteClosingBracket() // class - .WriteClosingBracket(); // namespace - - return new(builder.ToString(), $"{AttributeName}Attribute.g.cs"); - } - } -} diff --git a/src/BlueWest.MapTo/EfMethods/AttributeSources/EfUpdateMethodsAttributeSource.cs b/src/BlueWest.MapTo/EfMethods/AttributeSources/EfUpdateMethodsAttributeSource.cs deleted file mode 100644 index f112fa5..0000000 --- a/src/BlueWest.MapTo/EfMethods/AttributeSources/EfUpdateMethodsAttributeSource.cs +++ /dev/null @@ -1,46 +0,0 @@ -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("/// ") - .WriteLine("/// Generate Add methods for interacting with the entity") - .WriteLine("/// "); - } - - builder - .WriteLine("[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]") - .WriteLine($"public sealed class {AttributeName}Attribute : Attribute") - .WriteOpeningBracket(); - - builder - .WriteLine($"public {AttributeName}Attribute(Type updateType, Type returnType, string keyPropertyMemberName)") - .WriteOpeningBracket() - .WriteClosingBracket() - .WriteLine(); - - builder - .WriteClosingBracket() // class - .WriteClosingBracket(); // namespace - - return new(builder.ToString(), $"{AttributeName}Attribute.g.cs"); - } - } -} \ No newline at end of file diff --git a/src/BlueWest.MapTo/EfMethods/AttributeSources/GetOneWIthAttributeSource.cs b/src/BlueWest.MapTo/EfMethods/AttributeSources/GetOneWIthAttributeSource.cs deleted file mode 100644 index 6482796..0000000 --- a/src/BlueWest.MapTo/EfMethods/AttributeSources/GetOneWIthAttributeSource.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using static MapTo.Sources.Constants; - -namespace MapTo.Sources -{ - internal static class EfGetOneAttributeSource - { - internal const string AttributeName = "EfGetOne"; - 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("/// ") - .WriteLine("/// Attribute for generating a function to get one EF entity with a predicate as argument and a return type for the projection.") - .WriteLine("/// "); - } - - builder - .WriteLine("[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]") - .WriteLine($"public sealed class {AttributeName}Attribute : Attribute") - .WriteOpeningBracket(); - - builder - .WriteLine($"public {AttributeName}Attribute(Type returnType){"{}"}") - .WriteLine(); - - builder - .WriteClosingBracket() // class - .WriteClosingBracket(); // namespace - - return new(builder.ToString(), $"{AttributeName}Attribute.g.cs"); - } - } -} diff --git a/src/BlueWest.MapTo/EfMethods/EfAddMethodsAttributeSource.cs b/src/BlueWest.MapTo/EfMethods/EfAddMethodsAttributeSource.cs deleted file mode 100644 index 552213d..0000000 --- a/src/BlueWest.MapTo/EfMethods/EfAddMethodsAttributeSource.cs +++ /dev/null @@ -1,45 +0,0 @@ -using static MapTo.Sources.Constants; - - -namespace MapTo.Sources -{ - internal static class EfAddMethodsAttributeSource - { - internal const string AttributeName = "EfAddMethods"; - 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("/// ") - .WriteLine("/// Generate Add methods for interacting with the entity") - .WriteLine("/// "); - } - - builder - .WriteLine("[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]") - .WriteLine($"public sealed class {AttributeName}Attribute : Attribute") - .WriteOpeningBracket(); - - builder - .WriteLine($"public {AttributeName}Attribute(Type createType = null, Type returnType = null){"{}"}") - .WriteLine(); - - builder - .WriteClosingBracket() // class - .WriteClosingBracket(); // namespace - - return new(builder.ToString(), $"{AttributeName}Attribute.g.cs"); - } - } -} \ No newline at end of file diff --git a/src/BlueWest.MapTo/EfMethods/EfGeneratorContext.cs b/src/BlueWest.MapTo/EfMethods/EfGeneratorContext.cs deleted file mode 100644 index c9aa572..0000000 --- a/src/BlueWest.MapTo/EfMethods/EfGeneratorContext.cs +++ /dev/null @@ -1,495 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Diagnostics; -using System.Linq; -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 -{ - internal class EfGeneratorContext - { - private readonly List _ignoredNamespaces; - - - public ImmutableArray Diagnostics { get; private set; } - public EfMethodsModel? Model { get; private set; } - protected Compilation Compilation { get; } - protected INamedTypeSymbol MappingContextTypeSymbol { get; } - protected SourceGenerationOptions SourceGenerationOptions { get; } - protected TypeDeclarationSyntax TypeSyntax { get; } - - protected ImmutableArray Usings { get; private set; } - protected INamedTypeSymbol EfUpdateMethodsTypeSymbol { get; } - protected INamedTypeSymbol EfAddMethodsTypeSymbol { get; } - - - - protected EfGeneratorContext( - Compilation compilation, - SourceGenerationOptions sourceGenerationOptions, - TypeDeclarationSyntax typeSyntax) - { - Compilation = compilation; - _ignoredNamespaces = new(); - Diagnostics = ImmutableArray.Empty; - Usings = ImmutableArray.Create("System", Constants.RootNamespace); - SourceGenerationOptions = sourceGenerationOptions; - TypeSyntax = typeSyntax; - EfUpdateMethodsTypeSymbol = compilation.GetTypeByMetadataNameOrThrow(EfUpdateMethodsAttributeSource.FullyQualifiedName); - EfAddMethodsTypeSymbol = compilation.GetTypeByMetadataNameOrThrow(EfAddMethodsAttributeSource.FullyQualifiedName); - AddUsingIfRequired(sourceGenerationOptions.SupportNullableStaticAnalysis, "System.Diagnostics.CodeAnalysis"); - } - - public static EfGeneratorContext Create( - Compilation compilation, - SourceGenerationOptions sourceGenerationOptions, - TypeDeclarationSyntax typeSyntax) - { - EfGeneratorContext context = typeSyntax switch - { - ClassDeclarationSyntax => new EfGeneratorContext(compilation, sourceGenerationOptions, typeSyntax), - _ => throw new ArgumentOutOfRangeException() - }; - - context.Model = context.CreateMappingModel(); - - return context; - } - - protected void AddDiagnostic(Diagnostic diagnostic) - { - Diagnostics = Diagnostics.Add(diagnostic); - } - - protected void AddUsingIfRequired(ISymbol? namedTypeSymbol) => - AddUsingIfRequired(namedTypeSymbol?.ContainingNamespace.IsGlobalNamespace == false, namedTypeSymbol?.ContainingNamespace); - - protected void AddUsingIfRequired(bool condition, INamespaceSymbol? ns) => - AddUsingIfRequired(condition && ns is not null && !_ignoredNamespaces.Contains(ns.ToDisplayParts().First()), ns?.ToDisplayString()); - - protected void AddUsingIfRequired(bool condition, string? ns) - { - if (ns is not null && condition && ns != TypeSyntax.GetNamespace() && !Usings.Contains(ns)) - { - Usings = Usings.Add(ns); - } - } - - protected ImmutableArray GetEntityTypeSymbol(MemberDeclarationSyntax memberDeclarationSyntax, string attributeName, SemanticModel? semanticModel = null) - { - var attributeData = memberDeclarationSyntax.GetAttribute(attributeName); - var sourceSymbol = GetEntityTypeSymbols(attributeData, semanticModel); - return sourceSymbol; - } - - protected ImmutableArray GetEntityStringLiteralSymbol(MemberDeclarationSyntax memberDeclarationSyntax, string attributeName, SemanticModel? semanticModel = null) - { - var attributeData = memberDeclarationSyntax.GetAttribute(attributeName); - var sourceSymbol = GetEntityStringLiteralSymbol(attributeData); - return sourceSymbol; - } - - protected TypeInfo FindSecondTypeInfoOfMemberExpressionSyntax(SemanticModel semanticModel, SyntaxNode attributeSyntax) - { - semanticModel ??= Compilation.GetSemanticModel(attributeSyntax.SyntaxTree); - var descendentNodes = attributeSyntax - .DescendantNodes(); - - var expression = descendentNodes.OfType().FirstOrDefault()?.Expression; - if (expression != null) - { - return semanticModel.GetTypeInfo(expression); - } - - return new TypeInfo(); - } - - protected TypeInfo? FindFirstTypeInfoOfMemberExpressionSyntax(SemanticModel semanticModel, SyntaxNode attributeSyntax) - { - semanticModel ??= Compilation.GetSemanticModel(attributeSyntax.SyntaxTree); - var descendentNodes = attributeSyntax - .DescendantNodes(); - - // Get the type of the key member id - var expression = descendentNodes.OfType().FirstOrDefault(); - if (expression != null) - { - return semanticModel.GetTypeInfo(expression); - } - - return null; - } - - - protected string ExtractNameOfMemberName(MemberDeclarationSyntax memberDeclarationSyntax, string attributeName, SemanticModel? semanticModel = null) - { - var attributeData = memberDeclarationSyntax.GetAttribute(attributeName); - var sourceSymbol = ExtractNameOfMemberName(attributeData, semanticModel); - return sourceSymbol; - } - - protected ImmutableArray GetEntityTypeSymbols(SyntaxNode? attributeSyntax, SemanticModel? semanticModel = null) - { - if (attributeSyntax is null) - { - return new ImmutableArray(){}; - } - - semanticModel ??= Compilation.GetSemanticModel(attributeSyntax.SyntaxTree); - var descendentNodes = attributeSyntax - .DescendantNodes(); - - var sourceTypeExpressionSyntax = descendentNodes - .OfType() - .ToImmutableArray(); - - // cast - var resultList = new List(); - for (int i = 0; i < sourceTypeExpressionSyntax.Length; i++) - { - var sourceTypeExpression = sourceTypeExpressionSyntax[i]; - if (semanticModel.GetTypeInfo(sourceTypeExpression.Type).Type is INamedTypeSymbol namedTypeSymbol) - { - resultList.Add(namedTypeSymbol); - } - } - - return resultList.ToImmutableArray(); - } - - protected ImmutableArray GetEntityStringLiteralSymbol(SyntaxNode? attributeSyntax) - { - if (attributeSyntax is null) - { - return new ImmutableArray(){}; - } - - var descendentNodes = attributeSyntax - .DescendantNodes(); - - var sourceTypeExpressionSyntax = descendentNodes - .OfType() - .ToImmutableArray(); - - - return sourceTypeExpressionSyntax; - } - - protected string ExtractNameOfMemberName(SyntaxNode? attributeSyntax, SemanticModel semanticModel) - { - 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) - { - if (!property.TryGetTypeSymbol(out var propertyType)) - { - AddDiagnostic(DiagnosticsFactory.NoMatchingPropertyTypeFoundError(property)); - namedTypeSymbolResult = null; - return false; - } - - if ( - propertyType is INamedTypeSymbol namedTypeSymbol && - !propertyType.IsPrimitiveType() && - (Compilation.IsGenericEnumerable(propertyType) || propertyType.AllInterfaces.Any(i => Compilation.IsGenericEnumerable(i)))) - { - namedTypeSymbolResult = namedTypeSymbol; - return true; - } - namedTypeSymbolResult = null; - return false; - } - - private ImmutableArray GetAllowedMemberSyntaxes(string attributeName) - { - var classDeclarationSyntax = TypeSyntax; - - var syntaxes = classDeclarationSyntax.DescendantNodes() - .OfType() - .Where(x => x - .DescendantNodes() - .OfType().Any(syntax => - syntax.Name.ToString() == attributeName)) - .ToImmutableArray(); - - return syntaxes; - } - - private EfMethodsModel? CreateMappingModel() - { - var semanticModel = Compilation.GetSemanticModel(TypeSyntax.SyntaxTree); - - // get containing class type information - ClassDeclarationSyntax classDeclarationSyntax = TypeSyntax as ClassDeclarationSyntax; - - // context name - var dbContextName = classDeclarationSyntax.Identifier.ValueText; - var namespaceDeclaration = classDeclarationSyntax.Parent as NamespaceDeclarationSyntax; - var contextNamespace = namespaceDeclaration.Name.ToString(); - var contextTypeFullName = $"{contextNamespace}.{dbContextName}"; - - - - // handles different attributes - var addAttributeSymbols = GetAllowedMemberSyntaxes(EfAddMethodsAttributeSource.AttributeName); - var updateAttributesMembers = GetAllowedMemberSyntaxes(EfUpdateMethodsAttributeSource.AttributeName); - var getOneAttributesMembers = GetAllowedMemberSyntaxes(EfGetOneByAttributeSource.AttributeName); - var getOneWithAttributesMembers = GetAllowedMemberSyntaxes(EfGetOneAttributeSource.AttributeName); - var getManyWithAttributesMembers = GetAllowedMemberSyntaxes(EfGetManyAttributeSource.AttributeName); - - - - List methodsModels = new List(); - - foreach (var uProperty in getOneAttributesMembers) - { - var entityDataModel = GetEntityData(uProperty, semanticModel); - var newUpdateModel = ExtractEfGetEntityByModel(uProperty, semanticModel, entityDataModel); - methodsModels.Add(newUpdateModel); - } - - - foreach (var uProperty in addAttributeSymbols) - { - var entityDataModel = GetEntityData(uProperty, semanticModel); - var newAddModel = ExtractEfAddMethodsModel(semanticModel, uProperty, entityDataModel); - methodsModels.Add(newAddModel); - } - - foreach (var uProperty in updateAttributesMembers) - { - var entityDataModel = GetEntityData(uProperty, semanticModel); - var newUpdateModel = ExtractEfUpdateMethodsModel(uProperty, semanticModel, entityDataModel); - methodsModels.Add(newUpdateModel); - } - - - foreach (var uProperty in getOneWithAttributesMembers) - { - var entityDataModel = GetEntityData(uProperty, semanticModel); - var newUpdateModel = ExtractEfGetEntityWithModel(uProperty, semanticModel, entityDataModel); - methodsModels.Add(newUpdateModel); - } - - - foreach (var uProperty in getManyWithAttributesMembers) - { - var entityDataModel = GetEntityData(uProperty, semanticModel); - var newUpdateModel = ExtractEfGetManyModel(uProperty, semanticModel, entityDataModel); - methodsModels.Add(newUpdateModel); - } - - - //SpinWait.SpinUntil(() => Debugger.IsAttached); - - return new EfMethodsModel( - SourceGenerationOptions, - contextNamespace, - dbContextName, contextTypeFullName, - methodsModels.ToImmutableArray(), - Usings); - } - - private static EfEntityDataModel GetEntityData(MemberDeclarationSyntax uProperty, SemanticModel semanticModel) - { - var entityTypeData = GetEntityTypeData(uProperty, semanticModel); - string entityIdentifierName = entityTypeData.Name; - string entityFullName = entityTypeData.ToDisplayString(); - var propertyNamex = (uProperty as PropertyDeclarationSyntax).Identifier.ValueText; - return new EfEntityDataModel(propertyNamex, entityFullName, entityIdentifierName); - } - - private EfAddMethodsModel ExtractEfAddMethodsModel(SemanticModel semanticModel, MemberDeclarationSyntax memberSyntax, EfEntityDataModel efEntityDataModel) - { - var efAddAttributeTypeSymbols = - GetEntityTypeSymbol(memberSyntax, EfAddMethodsAttributeSource.AttributeName, semanticModel); - - string createTypeIdentifierName = efEntityDataModel.EntityTypeIdentifierName; - string createTypeFullName = efEntityDataModel.EntityTypeFullName; - string returnTypeIdentifierName = efEntityDataModel.EntityTypeIdentifierName; - string returnTypeFullName = efEntityDataModel.EntityTypeFullName; - - - if (efAddAttributeTypeSymbols.Length > 0) - { - createTypeIdentifierName = efAddAttributeTypeSymbols[0].Name; - createTypeFullName = efAddAttributeTypeSymbols[0].ToDisplayString(); - } - - if (efAddAttributeTypeSymbols.Length > 1) - { - returnTypeIdentifierName = efAddAttributeTypeSymbols[1].Name; - returnTypeFullName = efAddAttributeTypeSymbols[1].ToDisplayString(); - } - - - return new EfAddMethodsModel(efEntityDataModel, createTypeFullName, createTypeIdentifierName, returnTypeFullName, - returnTypeIdentifierName); - } - - private EfUpdateMethodsModel ExtractEfUpdateMethodsModel(MemberDeclarationSyntax uProperty, SemanticModel semanticModel, EfEntityDataModel entityDataModel) - { - var efAddAttributeTypeSymbols = - GetEntityTypeSymbol(uProperty, EfUpdateMethodsAttributeSource.AttributeName, semanticModel); - - var keyPropertyName = ExtractNameOfMemberName(uProperty, EfUpdateMethodsAttributeSource.AttributeName, semanticModel); - var keyMemberType = FindFirstTypeInfoOfMemberExpressionSyntax(semanticModel, TypeSyntax); - //var secondTypeInfo = FindSecondTypeInfoOfMemberExpressionSyntax(semanticModel, TypeSyntax); - - var keyMemberFullName = keyMemberType.Value.Type.ToDisplayString(); - //var keyMemberName = keyMemberType.Value.Type.Name; - - // Try grabbing string literal if there's no nameof in it - if (keyPropertyName == string.Empty) - { - keyPropertyName = GetEntityStringLiteralSymbol(TypeSyntax, EfUpdateMethodsAttributeSource.AttributeName, semanticModel) - .FirstOrDefault()? - .Token.ValueText ?? "Id"; - } - - if (efAddAttributeTypeSymbols == null) return null; - - string updateTypeIdentifierName = entityDataModel.EntityTypeIdentifierName; - string updateTypeFullName = entityDataModel.EntityTypeFullName; - string returnTypeIdentifierName = entityDataModel.EntityTypeIdentifierName; - string returnTypeFullName = entityDataModel.EntityTypeFullName; - - if (efAddAttributeTypeSymbols.Length > 0) - { - updateTypeIdentifierName = efAddAttributeTypeSymbols[0].Name; - updateTypeFullName = efAddAttributeTypeSymbols[0].ToDisplayString(); - } - - // Grab return type from attribute argument - if (efAddAttributeTypeSymbols.Length > 1) - { - returnTypeIdentifierName = efAddAttributeTypeSymbols[1].Name; - returnTypeFullName = efAddAttributeTypeSymbols[1].ToDisplayString(); - } - - - return new EfUpdateMethodsModel(entityDataModel, updateTypeFullName, updateTypeIdentifierName, returnTypeFullName, - returnTypeIdentifierName, keyPropertyName, keyMemberFullName); - } - - private EfGetOneWithModel ExtractEfGetEntityWithModel(MemberDeclarationSyntax uProperty, SemanticModel semanticModel, EfEntityDataModel entityDataModel) - { - - var efTypeofSymbols =GetEntityTypeSymbol(uProperty, EfGetOneByAttributeSource.AttributeName, semanticModel); - if (efTypeofSymbols == null) return null; - - string returnTypeIdentifierName = entityDataModel.EntityTypeIdentifierName; - string returnTypeFullName = entityDataModel.EntityTypeFullName; - - - // Grab return type from attribute argument - if (efTypeofSymbols.Length > 0) - { - returnTypeIdentifierName = efTypeofSymbols[0].Name; - returnTypeFullName = efTypeofSymbols[0].ToDisplayString(); - } - - - return new EfGetOneWithModel(entityDataModel, returnTypeFullName, returnTypeIdentifierName); - } - - - private EfGetManyModel ExtractEfGetManyModel(MemberDeclarationSyntax uProperty, SemanticModel semanticModel, EfEntityDataModel entityDataModel) - { - - var efTypeofSymbols =GetEntityTypeSymbol(uProperty, EfGetOneByAttributeSource.AttributeName, semanticModel); - if (efTypeofSymbols == null) return null; - - string returnTypeIdentifierName = entityDataModel.EntityTypeIdentifierName; - string returnTypeFullName = entityDataModel.EntityTypeFullName; - - - // Grab return type from attribute argument - if (efTypeofSymbols.Length > 0) - { - returnTypeIdentifierName = efTypeofSymbols[0].Name; - returnTypeFullName = efTypeofSymbols[0].ToDisplayString(); - } - - - return new EfGetManyModel(entityDataModel, returnTypeFullName, returnTypeIdentifierName); - } - - - - private EfGetOneByModel ExtractEfGetEntityByModel(MemberDeclarationSyntax uProperty, SemanticModel semanticModel, EfEntityDataModel entityDataModel) - { - - var efTypeofSymbols = GetEntityTypeSymbol(uProperty, EfGetOneByAttributeSource.AttributeName, semanticModel); - var byParamPropertyName = ExtractNameOfMemberName(uProperty, EfGetOneByAttributeSource.AttributeName, semanticModel); - var keyMemberType = FindFirstTypeInfoOfMemberExpressionSyntax(semanticModel, TypeSyntax); - - var byParamFullTypeName = keyMemberType.Value.Type.ToDisplayString(); - - // Try grabbing string literal if there's no nameof in it - if (byParamPropertyName == string.Empty) - { - byParamPropertyName = GetEntityStringLiteralSymbol(TypeSyntax, EfGetOneByAttributeSource.AttributeName, semanticModel) - .FirstOrDefault()? - .Token.ValueText ?? "Id"; - } - - if (efTypeofSymbols == null) return null; - - string returnTypeIdentifierName = entityDataModel.EntityTypeIdentifierName; - string returnTypeFullName = entityDataModel.EntityTypeFullName; - - - // Grab return type from attribute argument - if (efTypeofSymbols.Length > 0) - { - returnTypeIdentifierName = efTypeofSymbols[0].Name; - returnTypeFullName = efTypeofSymbols[0].ToDisplayString(); - } - - - return new EfGetOneByModel(entityDataModel, byParamPropertyName, byParamFullTypeName, returnTypeFullName, returnTypeIdentifierName); - } - - - private static ITypeSymbol GetEntityTypeData(MemberDeclarationSyntax memberDeclarationSyntax, SemanticModel? semanticModel = null) - { - var member = (memberDeclarationSyntax as PropertyDeclarationSyntax).Type; - var genericSyntax = member as GenericNameSyntax; - var typeInfo = semanticModel.GetTypeInfo( genericSyntax); - var firstTypeArgument = (typeInfo.ConvertedType as INamedTypeSymbol).TypeArguments[0]; - return firstTypeArgument; - } - - } -} \ No newline at end of file diff --git a/src/BlueWest.MapTo/EfMethods/EfMethodsGenerator.cs b/src/BlueWest.MapTo/EfMethods/EfMethodsGenerator.cs deleted file mode 100644 index 8685271..0000000 --- a/src/BlueWest.MapTo/EfMethods/EfMethodsGenerator.cs +++ /dev/null @@ -1,101 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Threading; -using MapTo.Extensions; -using MapTo.Sources; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp.Syntax; - -namespace MapTo -{ - /// - /// Ef methods source generator - /// - [Generator] - public class EfMethodsGenerator: ISourceGenerator - { - /// - public void Initialize(GeneratorInitializationContext context) - { - context.RegisterForSyntaxNotifications(() => new EfMethodsSyntaxReceiver()); - } - - /// - public void Execute(GeneratorExecutionContext context) - { - try - { - var options = SourceGenerationOptions.From(context); - - var compilation = context.Compilation - .AddSource(ref context, EfGeneratorAttributeSource.Generate(options)) - .AddSource(ref context, EfAddMethodsAttributeSource.Generate(options)) - .AddSource(ref context, EfUpdateMethodsAttributeSource.Generate(options)) - .AddSource(ref context, EfGetOneByAttributeSource.Generate(options)) - .AddSource(ref context, EfGetOneAttributeSource.Generate(options)) - .AddSource(ref context, EfGetManyAttributeSource.Generate(options)); - - - if (context.SyntaxReceiver is EfMethodsSyntaxReceiver receiver && receiver.CandidateTypes.Any()) - { - AddGeneratedExtensions(context, compilation, receiver.CandidateTypes, options); - } - } - catch (Exception ex) - { - Console.WriteLine(ex); - throw; - } - } - - private static void AddGeneratedExtensions(GeneratorExecutionContext context, Compilation compilation, IEnumerable candidateMembers, SourceGenerationOptions options) - { - string addSourceTemplate = GetCsxMethodTemplate(context, "AddToEntityTemplate"); - string updateSourceTemplate = GetCsxMethodTemplate(context, "UpdateEntityTemplate"); - string getOneByTemplate = GetCsxMethodTemplate(context, "GetOneByTemplate"); - string getOneWithByTemplate = GetCsxMethodTemplate(context, "GetOneTemplate"); - string getManyWithTemplate = GetCsxMethodTemplate(context, "GetManyTemplate"); - - - - foreach (var candidateMember in candidateMembers) - { - - var mappingContext = EfGeneratorContext.Create(compilation, options, candidateMember); - - mappingContext.Diagnostics.ForEach(context.ReportDiagnostic); - - if (mappingContext.Model is null) - { - continue; - } - - var (source, hintName) = candidateMember switch - { - ClassDeclarationSyntax => EfMethodsSource.Generate( - mappingContext.Model, - addSourceTemplate, - updateSourceTemplate, - getOneByTemplate, - getOneWithByTemplate, - getManyWithTemplate), - _ => throw new ArgumentOutOfRangeException() - }; - - context.AddSource(hintName, source); - } - } - - private static string GetCsxMethodTemplate(GeneratorExecutionContext context, string templateName) - { - return context - .AdditionalFiles - .FirstOrDefault(x => x.Path.Contains(templateName))? - .GetText()? - .ToString() ?? string.Empty; - } - - } -} \ No newline at end of file diff --git a/src/BlueWest.MapTo/EfMethods/EfMethodsSource.cs b/src/BlueWest.MapTo/EfMethods/EfMethodsSource.cs deleted file mode 100644 index d4886f2..0000000 --- a/src/BlueWest.MapTo/EfMethods/EfMethodsSource.cs +++ /dev/null @@ -1,113 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using MapTo.Extensions; -using Microsoft.CodeAnalysis.CSharp; -using static MapTo.Sources.Constants; - -namespace MapTo.Sources -{ - internal static class EfMethodsSource - { - internal static SourceCode Generate(EfMethodsModel model, - string addSourceTemplate, - string updateSourceTemplate, - string getOneBySourceTemplate, - string getOneWithSourceTemplate, - string getManyWithSourceTemplate - ) - { - using var builder = new SourceBuilder(); - - - var contextFullName = model.ContextFullType; - - builder - .WriteLine(GeneratedFilesHeader) - .WriteUsings(model.Usings) - .WriteLine("using Microsoft.EntityFrameworkCore;") - .WriteLine("using System.Linq;") - .WriteLine("using System.Linq.Expressions;") - .WriteLine("using System.Threading.Tasks;") - - .WriteLine() - // Namespace declaration - .WriteLine($"namespace {model.Namespace}") - .WriteOpeningBracket() - // Class declaration - .WriteLine($"public static partial class {model.ContextTypeName}Extensions") - .WriteOpeningBracket() - .WriteLine(); - - - foreach (var methodModel in model.MethodsModels.OrderBy(x => x.PropertyName)) - { - switch (methodModel) - { - case EfAddMethodsModel modl: - builder - .EfAddAddEntityMethod(model, modl, addSourceTemplate) - .WriteLine(); - break; - - case EfUpdateMethodsModel modl: - builder - .EfAddUpdateEntityMethod(model, modl, updateSourceTemplate) - .WriteLine(); - break; - - case EfGetOneByModel modl: - builder - .EfAddGetOneEntityByMethod(model, modl, getOneBySourceTemplate) - .WriteLine(); - break; - case EfGetManyModel modl: - builder - .EfAddGetManyWithMethod(model, modl, getManyWithSourceTemplate) - .WriteLine(); - break; - case EfGetOneWithModel modl: - builder - .EfAddGetOneEntityWithMethod(model, modl, getOneWithSourceTemplate) - .WriteLine(); - break; - - - - } - - - } - - builder - // End class declaration - .WriteClosingBracket() - .WriteLine() - // End namespace declaration - .WriteClosingBracket(); - - var generatedCode = builder.ToString(); - var hintName = $"{model.ContextTypeName}Extensions.g.cs"; - return new(generatedCode, hintName); - } - - internal static SourceBuilder ParseTemplate(this SourceBuilder builder, string finalTemplate) - { - string[] array = finalTemplate.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries); - - for (var i = 0; i < array.Length; i++) - { - var line = array[i]; - builder.WriteLine(line); - } - - return builder; - } - - - - - } -} \ No newline at end of file diff --git a/src/BlueWest.MapTo/EfMethods/EfMethodsSource/EfAddEntityTemplateSource.cs b/src/BlueWest.MapTo/EfMethods/EfMethodsSource/EfAddEntityTemplateSource.cs deleted file mode 100644 index a75441a..0000000 --- a/src/BlueWest.MapTo/EfMethods/EfMethodsSource/EfAddEntityTemplateSource.cs +++ /dev/null @@ -1,60 +0,0 @@ -using MapTo.Extensions; -using System; -using System.Collections.Generic; -using System.Text; - -namespace MapTo.Sources -{ - internal static class EfAddEntityTemplateSource - { - internal static SourceBuilder EfAddAddEntityMethod(this SourceBuilder builder, EfMethodsModel methodsModel, EfAddMethodsModel model, string addSourceTemplate) - { - var returnTypeFullName = model.ReturnTypeFullName; - var createTypeFullName = model.CreateTypeFullName; - var newEntityVarName = $"new{model.EntityTypeIdentifierName}"; - var toCreateVarName = $"{model.EntityTypeIdentifierName.ToCamelCase()}ToCreate"; - - var entityTypeName = model.EntityTypeIdentifierName; - var contextFullName = methodsModel.ContextFullType; - var propertyName = model.PropertyName; - - if (!addSourceTemplate.IsEmpty()) - { - var templateToSourceBuilder = new StringBuilder(addSourceTemplate); - templateToSourceBuilder - .Replace("{entityTypeName}", model.EntityTypeIdentifierName) - .Replace("{returnTypeFullName}", returnTypeFullName) - .Replace("{createTypeFullName}", createTypeFullName) - .Replace("{contextFullName}", contextFullName) - .Replace("{toCreateVarName}", toCreateVarName) - .Replace("{newEntityVarName}", newEntityVarName) - .Replace("{entityTypeFullName}", model.EntityTypeFullName) - .Replace("{propertyName}", propertyName); - - builder - .ParseTemplate(templateToSourceBuilder.ToString()); - } - - if (addSourceTemplate.IsEmpty()) - { - builder - .WriteComment("Generated body") - //.WriteLine(GeneratedFilesHeader) - .WriteLine($"public static (bool, {model.ReturnTypeFullName}) Add{entityTypeName}(") - .WriteLine($"this {contextFullName} dbContext,") - .WriteLine($"{createTypeFullName} {toCreateVarName})") - .WriteOpeningBracket() - .WriteLine($"var {newEntityVarName} = new {model.EntityTypeFullName}({toCreateVarName});") - .WriteLine($"dbContext.{propertyName}.Add({newEntityVarName});") - .WriteLine($"var success = dbContext.SaveChanges() >= 0;") - .WriteLine($"return (success, new {returnTypeFullName}({newEntityVarName}));") - .WriteClosingBracket(); - - builder - .WriteLine(); - } - - return builder; - } - } -} diff --git a/src/BlueWest.MapTo/EfMethods/EfMethodsSource/EfGetOneEntityByTemplate.cs b/src/BlueWest.MapTo/EfMethods/EfMethodsSource/EfGetOneEntityByTemplate.cs deleted file mode 100644 index 5ed311f..0000000 --- a/src/BlueWest.MapTo/EfMethods/EfMethodsSource/EfGetOneEntityByTemplate.cs +++ /dev/null @@ -1,63 +0,0 @@ -using MapTo.Extensions; -using MapTo.Sources; -using System; -using System.Collections.Generic; -using System.Text; - -namespace MapTo -{ - internal static class EfGetOneEntityByTemplate - { - internal static SourceBuilder EfAddGetOneEntityByMethod(this SourceBuilder builder, EfMethodsModel methodsModel, EfGetOneByModel model, string addSourceTemplate) - { - var returnTypeFullName = model.ReturnTypeFullName; - var entityTypeName = model.EntityTypeIdentifierName; - var byParamPropertyName = model.ByParamPropertyName; - var byParamFullType = model.ByParamFullTypeName; - - var contextFullName = methodsModel.ContextFullType; - var byParamVarName = model.ByParamPropertyName.ToCamelCase(); - var findEntityVarName = model.EntityTypeIdentifierName.ToCamelCase(); - var propertyName = model.PropertyName; - - if (!addSourceTemplate.IsEmpty()) - { - var templateToSourceBuilder = new StringBuilder(addSourceTemplate); - templateToSourceBuilder - .Replace("{returnTypeFullName}", returnTypeFullName) - .Replace("{entityTypeName}", entityTypeName) - .Replace("{byParamPropertyName}", byParamPropertyName) - .Replace("{contextFullName}", contextFullName) - .Replace("{contextFullName}", contextFullName) - - .Replace("{byParamFullType}", byParamFullType) - .Replace("{byParamVarName}", byParamVarName) - .Replace("{findEntityVarName}", findEntityVarName) - .Replace("{propertyName}", propertyName); - - builder - .ParseTemplate(templateToSourceBuilder.ToString()); - } - - if (addSourceTemplate.IsEmpty()) - { - builder - .WriteComment("Generated body") - //.WriteLine(GeneratedFilesHeader) - .WriteLine($"public static (bool, {returnTypeFullName}) GetOne{entityTypeName}By{byParamPropertyName} (this {contextFullName} dbContext, {byParamFullType} {byParamVarName})") - .WriteOpeningBracket() - .WriteLine($"var {findEntityVarName} = dbContext.{propertyName}") - .WriteLine($".Where(x => x.{byParamPropertyName} == {byParamVarName})") - .WriteLine($".Select(x => new {returnTypeFullName}(x))") - .WriteLine($".FirstOrDefault();") - .WriteLine($"return ({findEntityVarName} != null, {findEntityVarName});") - .WriteClosingBracket(); - - builder - .WriteLine(); - } - - return builder; - } - } -} diff --git a/src/BlueWest.MapTo/EfMethods/EfMethodsSource/EfGetOneWithTemplateSource.cs b/src/BlueWest.MapTo/EfMethods/EfMethodsSource/EfGetOneWithTemplateSource.cs deleted file mode 100644 index 29a1c00..0000000 --- a/src/BlueWest.MapTo/EfMethods/EfMethodsSource/EfGetOneWithTemplateSource.cs +++ /dev/null @@ -1,107 +0,0 @@ -using MapTo.Extensions; -using MapTo.Sources; -using System; -using System.Collections.Generic; -using System.Text; - -namespace MapTo -{ - internal static class EfGetOneWithTemplateSource - { - internal static SourceBuilder EfAddGetOneEntityWithMethod(this SourceBuilder builder, EfMethodsModel methodsModel, EfGetOneWithModel model, string addSourceTemplate) - { - var returnTypeFullName = model.ReturnTypeFullName; - var entityTypeName = model.EntityTypeIdentifierName; - - var contextFullName = methodsModel.ContextFullType; - var findEntityVarName = model.EntityTypeIdentifierName.ToCamelCase(); - var propertyName = model.PropertyName; - - if (!addSourceTemplate.IsEmpty()) - { - var templateToSourceBuilder = new StringBuilder(addSourceTemplate); - templateToSourceBuilder - .Replace("{returnTypeFullName}", returnTypeFullName) - .Replace("{entityTypeName}", entityTypeName) - .Replace("{contextFullName}", contextFullName) - .Replace("{contextFullName}", contextFullName) - .Replace("{findEntityVarName}", findEntityVarName) - .Replace("{propertyName}", propertyName); - - builder - .ParseTemplate(templateToSourceBuilder.ToString()); - } - - if (addSourceTemplate.IsEmpty()) - { - builder - .WriteComment("Generated body") - //.WriteLine(GeneratedFilesHeader) - .WriteLine($"public static (bool, {returnTypeFullName}) GetOne{entityTypeName}With (this {contextFullName} dbContext, Expression> with) ") - .WriteOpeningBracket() - .WriteLine($"var {findEntityVarName} =") - .WriteLine($".Select(x => new {returnTypeFullName}(x))") - .WriteLine($".FirstOrDefault(with);") - .WriteLine() - .WriteLine($"return ({findEntityVarName} != null, {findEntityVarName});") - .WriteClosingBracket(); - - builder - .WriteLine(); - } - - return builder; - } - - internal static SourceBuilder EfAddGetManyWithMethod(this SourceBuilder builder, EfMethodsModel methodsModel, EfGetManyModel model, string addSourceTemplate) - { - var returnTypeFullName = model.ReturnTypeFullName; - var entityTypeName = model.EntityTypeIdentifierName; - - var contextFullName = methodsModel.ContextFullType; - var findEntityVarName = model.EntityTypeIdentifierName.ToCamelCase(); - var propertyName = model.PropertyName; - - if (!addSourceTemplate.IsEmpty()) - { - var templateToSourceBuilder = new StringBuilder(addSourceTemplate); - templateToSourceBuilder - .Replace("{returnTypeFullName}", returnTypeFullName) - .Replace("{entityTypeName}", entityTypeName) - .Replace("{contextFullName}", contextFullName) - .Replace("{contextFullName}", contextFullName) - .Replace("{findEntityVarName}", findEntityVarName) - .Replace("{propertyName}", propertyName); - - builder - .ParseTemplate(templateToSourceBuilder.ToString()); - } - - if (addSourceTemplate.IsEmpty()) - { - builder - .WriteComment("Generated body") - //.WriteLine(GeneratedFilesHeader) - .WriteLine($"public static (bool, ImmutableArray<{returnTypeFullName}>) Get{propertyName}(this {contextFullName}dbContext, Expression > where = null,") - .WriteLine($"Expression > orderBy = null, int skip = 0, int take = 50, int orderDir = 1)") - .WriteOpeningBracket() - .WriteLine($"var query = dbContext") - .WriteLine($".{propertyName}") - .WriteLine($".Select(x => new {returnTypeFullName}(x));") - .WriteComment("limit take by 200 records") - .WriteLine("if (take > 200) take = 200;") - .WriteLine("query.Skip(skip).Take(take);") - .WriteLine("if (where != null) query.Where(where);") - .WriteLine("if (orderDir == 1) query.OrderBy(orderBy);") - .WriteLine("else query.OrderByDescending(orderBy);") - .WriteLine($"return query.ToImmutableArray();") - .WriteClosingBracket(); - - builder - .WriteLine(); - } - - return builder; - } - } -} diff --git a/src/BlueWest.MapTo/EfMethods/EfMethodsSource/EfUpdateEntityTemplateSource.cs b/src/BlueWest.MapTo/EfMethods/EfMethodsSource/EfUpdateEntityTemplateSource.cs deleted file mode 100644 index c87eae6..0000000 --- a/src/BlueWest.MapTo/EfMethods/EfMethodsSource/EfUpdateEntityTemplateSource.cs +++ /dev/null @@ -1,62 +0,0 @@ -using MapTo.Extensions; -using System; -using System.Collections.Generic; -using System.Text; - -namespace MapTo.Sources -{ - internal static class EfUpdateEntityTemplateSource - { - internal static SourceBuilder EfAddUpdateEntityMethod(this SourceBuilder builder, EfMethodsModel methodsModel, EfUpdateMethodsModel model, string updateSourceTemplate) - { - var entityTypeName = model.EntityTypeIdentifierName; - var contextFullName = methodsModel.ContextFullType; - var propertyName = model.PropertyName; - var returnTypeFullName = model.ReturnTypeFullName; - var updateTypeFullName = model.UpdateTypeFullName; - var updateVarName = $"{entityTypeName.ToCamelCase()}ToUpdate"; - var keyPropertyName = model.KeyPropertyName; - var keyTypeFullName = model.KeyFullTypeName; - var existingVarName = entityTypeName.ToCamelCase(); - var keyVarName = entityTypeName.ToCamelCase() + model.KeyPropertyName; - if (!updateSourceTemplate.IsEmpty()) - { - var templateToSourceBuilder = new StringBuilder(updateSourceTemplate); - templateToSourceBuilder - .Replace("{entityTypeName}", entityTypeName) - .Replace("{returnTypeFullName}", returnTypeFullName) - .Replace("{updateTypeFullName}", updateTypeFullName) - .Replace("{updateVarName}", updateVarName) - .Replace("{contextFullName}", contextFullName) - .Replace("{propertyName}", propertyName) - .Replace("{keyTypeFullName}", keyTypeFullName) - .Replace("{keyPropertyName}", keyPropertyName) - .Replace("{keyVarName}", keyVarName) - .Replace("{existingEntityVarName}", existingVarName); - builder - .ParseTemplate(templateToSourceBuilder.ToString()); - } - - if (updateSourceTemplate.IsEmpty()) - { - builder - .WriteComment("Generated body") - .WriteLine($"public static (bool, {returnTypeFullName}) Update{entityTypeName}(") - .WriteLine($"this {contextFullName} dbContext,") - .WriteLine($"{updateTypeFullName} {updateVarName},") - .WriteLine($"{keyTypeFullName} {keyVarName})") - .WriteOpeningBracket() - .WriteLine($"var {existingVarName} = dbContext.{propertyName}.FirstOrDefault(x => x.{keyPropertyName} == {keyVarName});") - .WriteLine($"if ({existingVarName} == null) return (false, null);") - .WriteLine($"var success = dbContext.SaveChanges() >= 0;") - .WriteLine($"return (success, new {returnTypeFullName}({existingVarName}));") - .WriteClosingBracket(); - - builder - .WriteLine(); - } - - return builder; - } - } -} diff --git a/src/BlueWest.MapTo/EfMethodsSyntaxReceiver.cs b/src/BlueWest.MapTo/EfMethodsSyntaxReceiver.cs deleted file mode 100644 index b3f253c..0000000 --- a/src/BlueWest.MapTo/EfMethodsSyntaxReceiver.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using MapTo.Sources; -using Microsoft.CodeAnalysis; -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 CandidateTypes { get; } = new(); - - /// - public void OnVisitSyntaxNode(SyntaxNode syntaxNode) - { - if (syntaxNode is not TypeDeclarationSyntax { AttributeLists: { Count: >= 1 } attributes } typeDeclarationSyntax) - { - return; - } - - var attributeSyntax = attributes - .SelectMany(a => a.Attributes) - .FirstOrDefault(a => a.Name is - IdentifierNameSyntax { Identifier: { ValueText: EfGeneratorAttributeSource.AttributeName } } - or - QualifiedNameSyntax - { - Left: IdentifierNameSyntax { Identifier: { ValueText: Constants.RootNamespace } }, - Right: IdentifierNameSyntax { Identifier: { ValueText: EfGeneratorAttributeSource.AttributeName } } - } - ); - - if (attributeSyntax is not null) - { - CandidateTypes.Add(typeDeclarationSyntax); - } - } - - } -} \ No newline at end of file diff --git a/test/BlueWest.MapTo.Tests/Infrastructure/CSharpGenerator.cs b/test/BlueWest.MapTo.Tests/Infrastructure/CSharpGenerator.cs index b43e274..a1b9d44 100644 --- a/test/BlueWest.MapTo.Tests/Infrastructure/CSharpGenerator.cs +++ b/test/BlueWest.MapTo.Tests/Infrastructure/CSharpGenerator.cs @@ -50,7 +50,7 @@ namespace MapTo.Tests.Infrastructure } var driver = CSharpGeneratorDriver.Create( - new List() { new MapToGenerator(), new EfMethodsGenerator() }, + new List() { new MapToGenerator()}, optionsProvider: new TestAnalyzerConfigOptionsProvider(analyzerConfigOptions), parseOptions: new CSharpParseOptions(languageVersion) );