Exemplo n.º 1
0
        public static IEnumerable <ExpressionSyntax> MapUsingSimpleAssignment(SyntaxGenerator generator,
                                                                              SemanticModel semanticModel, IEnumerable <IPropertySymbol> targets, IMappingSourceFinder sourceFinder,
                                                                              MappingPath mappingPath = null, SyntaxNode globalTargetAccessor = null)
        {
            if (mappingPath == null)
            {
                mappingPath = new MappingPath();
            }
            var mappingEngine = new MappingEngine(semanticModel, generator);

            return(targets.Select(property => new
            {
                source = sourceFinder.FindMappingSource(property.Name, property.Type),
                target = new MappingElement()
                {
                    Expression = (ExpressionSyntax)CreateAccessPropertyExpression(globalTargetAccessor, property, generator),
                    ExpressionType = property.Type
                }
            })
                   .Where(x => x.source != null)
                   .Select(pair =>
            {
                var sourceExpression = mappingEngine.MapExpression(pair.source, pair.target.ExpressionType, mappingPath.Clone()).Expression;
                return (ExpressionSyntax)generator.AssignmentStatement(pair.target.Expression, sourceExpression);
            }).ToList());
        }
        private static async Task <Document> CreateMappingLambda(Document document, InvocationExpressionSyntax invocation, CancellationToken cancellationToken)
        {
            var semanticModel = await document.GetSemanticModelAsync(cancellationToken);

            var syntaxGenerator        = SyntaxGenerator.GetGenerator(document);
            var methodInvocationSymbol = semanticModel.GetSymbolInfo(invocation.Expression);
            var mappingOverload        = methodInvocationSymbol.CandidateSymbols.OfType <IMethodSymbol>().FirstOrDefault(IsMappingMethod);

            if (mappingOverload == null)
            {
                return(document);
            }

            var sourceElementType = ((INamedTypeSymbol)mappingOverload.Parameters[0].Type).TypeArguments[0];
            var targetElementType = GetExpressionType(semanticModel, invocation);

            if (targetElementType == null)
            {
                return(document);
            }

            var contextAssembly = semanticModel.FindContextAssembly(invocation);
            var mappingEngine   = new MappingEngine(semanticModel, syntaxGenerator, contextAssembly);
            var mappingLambda   = mappingEngine.CreateMappingLambda("x", sourceElementType, targetElementType, new MappingPath());

            return(await document.ReplaceNodes(invocation, invocation.WithArgumentList(SyntaxFactory.ArgumentList().AddArguments(SyntaxFactory.Argument((ExpressionSyntax)mappingLambda))), cancellationToken));
        }
Exemplo n.º 3
0
        private async Task <Document> GenerateExplicitConversion(Document document, YieldStatementSyntax yieldStatement, CancellationToken cancellationToken)
        {
            var mappingEngine = await MappingEngine.Create(document, cancellationToken);

            var returnExpressionTypeInfo = mappingEngine.GetExpressionTypeInfo(yieldStatement.Expression);
            var mappingExpression        = mappingEngine.MapExpression(yieldStatement.Expression, returnExpressionTypeInfo.Type, returnExpressionTypeInfo.ConvertedType);

            return(await ReplaceNode(document, yieldStatement, yieldStatement.WithExpression(mappingExpression), cancellationToken));
        }
        private static async Task <MappingEngine> CreateMappingEngine(Document document, SyntaxNode node,
                                                                      CancellationToken cancellationToken)
        {
            var semanticModel = await document.GetSemanticModelAsync(cancellationToken);

            var contextAssembly = semanticModel.FindContextAssembly(node);
            var mappingEngine   = await MappingEngine.Create(document, cancellationToken, contextAssembly);

            return(mappingEngine);
        }
Exemplo n.º 5
0
        private async Task <Document> GenerateExplicitConversion(Document document, AssignmentExpressionSyntax assignmentExpression, CancellationToken cancellationToken)
        {
            var mappingEngine = await MappingEngine.Create(document, cancellationToken);

            var sourceType        = mappingEngine.GetExpressionTypeInfo(assignmentExpression.Right).Type;
            var destimationType   = mappingEngine.GetExpressionTypeInfo(assignmentExpression.Left).Type;
            var mappingExpression = mappingEngine.MapExpression(assignmentExpression.Right, sourceType, destimationType);

            return(await ReplaceNode(document, assignmentExpression, assignmentExpression.WithRight(mappingExpression), cancellationToken));
        }
Exemplo n.º 6
0
        private static IEnumerable<SyntaxNode> GenerateMappingCode(IMethodSymbol methodSymbol, SyntaxGenerator generator, SemanticModel semanticModel)
        {
            var mappingEngine = new MappingEngine(semanticModel, generator);

            if (SymbolHelper.IsPureMappingFunction(methodSymbol))
            {
                var source = methodSymbol.Parameters[0];
                var targetType = methodSymbol.ReturnType;
                var newExpression = mappingEngine.MapExpression((ExpressionSyntax)generator.IdentifierName(source.Name), source.Type, targetType);
                return new[] { generator.ReturnStatement(newExpression) };
            }

            //TODO: Pure mapping with multiple parameters

            if (SymbolHelper.IsUpdateParameterFunction(methodSymbol))
            {
                var source = methodSymbol.Parameters[0];
                var target = methodSymbol.Parameters[1];
                var targets = ObjectHelper.GetFieldsThaCanBeSetPublicly(target.Type);
                var sourceFinder = new ObjectMembersMappingSourceFinder(source.Type, generator.IdentifierName(source.Name), generator);
                return MappingHelper.MapUsingSimpleAssignment(generator, semanticModel, targets, sourceFinder, globalTargetAccessor: generator.IdentifierName(target.Name));
            }

            if (SymbolHelper.IsUpdateThisObjectFunction(methodSymbol))
            {
                var source = methodSymbol.Parameters[0];
                var sourceFinder = new ObjectMembersMappingSourceFinder(source.Type, generator.IdentifierName(source.Name), generator);
                var targets = ObjectHelper.GetFieldsThaCanBeSetPrivately(methodSymbol.ContainingType);
                return MappingHelper.MapUsingSimpleAssignment(generator, semanticModel, targets, sourceFinder);
            }

            if (SymbolHelper.IsMultiParameterUpdateThisObjectFunction(methodSymbol))
            {
                var sourceFinder = new LocalScopeMappingSourceFinder(semanticModel, methodSymbol.Parameters);
                var targets = ObjectHelper.GetFieldsThaCanBeSetPrivately(methodSymbol.ContainingType);
                return MappingHelper.MapUsingSimpleAssignment(generator, semanticModel, targets, sourceFinder);
            }

            if (SymbolHelper.IsMappingConstructor(methodSymbol))
            {
                var source = methodSymbol.Parameters[0];
                var sourceFinder = new ObjectMembersMappingSourceFinder(source.Type, generator.IdentifierName(source.Name), generator);
                var targets = ObjectHelper.GetFieldsThaCanBeSetFromConstructor(methodSymbol.ContainingType);
                return MappingHelper.MapUsingSimpleAssignment(generator, semanticModel, targets, sourceFinder);
            }

            if (SymbolHelper.IsMultiParameterMappingConstructor(methodSymbol))
            {
                var sourceFinder = new LocalScopeMappingSourceFinder(semanticModel, methodSymbol.Parameters);
                var targets = ObjectHelper.GetFieldsThaCanBeSetFromConstructor(methodSymbol.ContainingType);
                return MappingHelper.MapUsingSimpleAssignment(generator, semanticModel, targets, sourceFinder);
            }
            return Enumerable.Empty<SyntaxNode>();
        }
        private static async Task <Document> ReplaceEmptyInitializationBlock(Document document,
                                                                             InitializerExpressionSyntax objectInitializer, SemanticModel semanticModel,
                                                                             IMappingSourceFinder mappingSourceFinder, CancellationToken cancellationToken)
        {
            var oldObjCreation    = objectInitializer.FindContainer <ObjectCreationExpressionSyntax>();
            var createdObjectType = ModelExtensions.GetTypeInfo(semanticModel, oldObjCreation).Type;
            var mappingEngine     = await MappingEngine.Create(document, cancellationToken, semanticModel.FindContextAssembly(objectInitializer));

            var newObjectCreation = mappingEngine.AddInitializerWithMapping(oldObjCreation, mappingSourceFinder, createdObjectType);

            return(await document.ReplaceNodes(oldObjCreation, newObjectCreation, cancellationToken));
        }
        public ArgumentListSyntax ToArgumentListSyntax(MappingEngine mappingEngine, bool generateNamedParameters = true)
        {
            return(Matches.Aggregate(SyntaxFactory.ArgumentList(), (list, match) =>
            {
                if (match.Source?.Expression == null && match.Parameter.IsOptional)
                {
                    generateNamedParameters = true;
                    return list;
                }

                var parameterType = match.Parameter.Type;
                var expression = mappingEngine.MapExpression(match.Source, parameterType)?.Expression ?? mappingEngine.CreateDefaultExpression(parameterType);
                var argument = generateNamedParameters
                    ? SyntaxFactory.Argument(SyntaxFactory.NameColon(match.Parameter.Name), SyntaxFactory.Token(SyntaxKind.None), expression)
                    : SyntaxFactory.Argument(expression);
                return list.AddArguments(argument);
            }));
        }
        private async Task <Document> UseLocalVariablesAsParameters(Document document, IInvocation invocation, bool generateNamedParameters, CancellationToken cancellationToken)
        {
            var semanticModel = await document.GetSemanticModelAsync(cancellationToken);

            var syntaxGenerator       = SyntaxGenerator.GetGenerator(document);
            var mappingSourceFinder   = new LocalScopeMappingSourceFinder(semanticModel, invocation.SourceNode);
            var overloadParameterSets = invocation.GetOverloadParameterSets(semanticModel);

            if (overloadParameterSets != null)
            {
                var mappingEngine   = new MappingEngine(semanticModel, syntaxGenerator);
                var parametersMatch = MethodHelper.FindBestParametersMatch(mappingSourceFinder, overloadParameterSets);
                if (parametersMatch != null)
                {
                    var argumentList = parametersMatch.ToArgumentListSyntax(mappingEngine, generateNamedParameters);
                    return(await document.ReplaceNodes(invocation.SourceNode, invocation.WithArgumentList(argumentList), cancellationToken));
                }
            }
            return(document);
        }
Exemplo n.º 10
0
        private async Task <Document> GenerateSplatting(Document document, IInvocation invocation, bool generateNamedParameters, CancellationToken cancellationToken)
        {
            var semanticModel = await document.GetSemanticModelAsync(cancellationToken);

            var overloadParameterSets = invocation.GetOverloadParameterSets(semanticModel);

            if (overloadParameterSets != null)
            {
                var syntaxGenerator     = SyntaxGenerator.GetGenerator(document);
                var mappingEngine       = new MappingEngine(semanticModel, syntaxGenerator);
                var invalidArgumentList = invocation.Arguments;
                var parametersMatch     = FindParametersMatch(invalidArgumentList, overloadParameterSets, semanticModel, syntaxGenerator);
                if (parametersMatch != null)
                {
                    var argumentList = parametersMatch.ToArgumentListSyntax(mappingEngine, generateNamedParameters);
                    return(await document.ReplaceNodes(invocation.SourceNode, invocation.WithArgumentList(argumentList), cancellationToken));
                }
            }

            return(document);
        }
        private string GetArgumentListWithLocalVariables(Document document, IInvocation invocation, bool generateNamedParameters, SemanticModel semanticModel)
        {
            var mappingSourceFinder   = new LocalScopeMappingSourceFinder(semanticModel, invocation.SourceNode);
            var syntaxGenerator       = SyntaxGenerator.GetGenerator(document);
            var overloadParameterSets = invocation.GetOverloadParameterSets(semanticModel);

            if (overloadParameterSets != null)
            {
                var contextAssembly = semanticModel.FindContextAssembly(invocation.SourceNode);
                var mappingEngine   = new MappingEngine(semanticModel, syntaxGenerator, contextAssembly);
                var parametersMatch = MethodHelper.FindBestParametersMatch(mappingSourceFinder, overloadParameterSets);
                if (parametersMatch != null)
                {
                    var argumentList = parametersMatch.ToArgumentListSyntax(mappingEngine, generateNamedParameters);
                    var chunks       = argumentList.Arguments.Select(a => a.ToString());
                    return(string.Join(", ", chunks));
                }
            }

            return(null);
        }
        public static async Task <Document> FixInvocationWithParameters(Document document,
                                                                        IInvocation invocation,
                                                                        bool generateNamedParameters,
                                                                        SemanticModel semanticModel,
                                                                        IMappingSourceFinder mappingSourceFinder,
                                                                        CancellationToken cancellationToken)
        {
            var syntaxGenerator       = SyntaxGenerator.GetGenerator(document);
            var overloadParameterSets = invocation.GetOverloadParameterSets(semanticModel);

            if (overloadParameterSets != null)
            {
                var contextAssembly = semanticModel.FindContextAssembly(invocation.SourceNode);
                var mappingEngine   = new MappingEngine(semanticModel, syntaxGenerator, contextAssembly);
                var parametersMatch = MethodHelper.FindBestParametersMatch(mappingSourceFinder, overloadParameterSets);
                if (parametersMatch != null)
                {
                    var argumentList = parametersMatch.ToArgumentListSyntax(mappingEngine, generateNamedParameters);
                    return(await document.ReplaceNodes(invocation.SourceNode, invocation.WithArgumentList(argumentList), cancellationToken));
                }
            }

            return(document);
        }
Exemplo n.º 13
0
        private static IEnumerable <SyntaxNode> GenerateMappingCode(IMethodSymbol methodSymbol, SyntaxGenerator generator, SemanticModel semanticModel)
        {
            if (SymbolHelper.IsIdentityMappingFunction(methodSymbol))
            {
                var cloneMappingEngine = new CloneMappingEngine(semanticModel, generator, methodSymbol.ContainingAssembly);
                var source             = methodSymbol.Parameters[0];
                var targetType         = methodSymbol.ReturnType;
                var newExpression      = cloneMappingEngine.MapExpression((ExpressionSyntax)generator.IdentifierName(source.Name), source.Type, targetType);
                return(new[] { generator.ReturnStatement(newExpression).WithAdditionalAnnotations(Formatter.Annotation) });
            }

            var mappingEngine = new MappingEngine(semanticModel, generator, methodSymbol.ContainingAssembly);

            if (SymbolHelper.IsPureMappingFunction(methodSymbol))
            {
                var source        = methodSymbol.Parameters[0];
                var targetType    = methodSymbol.ReturnType;
                var newExpression = mappingEngine.MapExpression((ExpressionSyntax)generator.IdentifierName(source.Name), source.Type, targetType);
                return(new[] { generator.ReturnStatement(newExpression).WithAdditionalAnnotations(Formatter.Annotation) });
            }

            if (SymbolHelper.IsMultiParameterPureFunction(methodSymbol))
            {
                var targetType    = methodSymbol.ReturnType;
                var sourceFinder  = new LocalScopeMappingSourceFinder(semanticModel, methodSymbol);
                var newExpression = mappingEngine.AddInitializerWithMapping((ObjectCreationExpressionSyntax)generator.ObjectCreationExpression(targetType), sourceFinder, targetType);
                return(new[] { generator.ReturnStatement(newExpression).WithAdditionalAnnotations(Formatter.Annotation) });
            }

            if (SymbolHelper.IsUpdateParameterFunction(methodSymbol))
            {
                var source       = methodSymbol.Parameters[0];
                var target       = methodSymbol.Parameters[1];
                var targets      = ObjectHelper.GetFieldsThaCanBeSetPublicly(target.Type, methodSymbol.ContainingAssembly);
                var sourceFinder = new ObjectMembersMappingSourceFinder(source.Type, generator.IdentifierName(source.Name), generator);
                return(mappingEngine.MapUsingSimpleAssignment(generator, targets, sourceFinder, globalTargetAccessor: generator.IdentifierName(target.Name)));
            }

            if (SymbolHelper.IsUpdateThisObjectFunction(methodSymbol))
            {
                var source       = methodSymbol.Parameters[0];
                var sourceFinder = new ObjectMembersMappingSourceFinder(source.Type, generator.IdentifierName(source.Name), generator);
                var targets      = ObjectHelper.GetFieldsThaCanBeSetPrivately(methodSymbol.ContainingType);
                return(mappingEngine.MapUsingSimpleAssignment(generator, targets, sourceFinder));
            }

            if (SymbolHelper.IsMultiParameterUpdateThisObjectFunction(methodSymbol))
            {
                var sourceFinder = new LocalScopeMappingSourceFinder(semanticModel, methodSymbol.Parameters);
                var targets      = ObjectHelper.GetFieldsThaCanBeSetPrivately(methodSymbol.ContainingType);
                return(mappingEngine.MapUsingSimpleAssignment(generator, targets, sourceFinder));
            }

            if (SymbolHelper.IsMappingConstructor(methodSymbol))
            {
                var source       = methodSymbol.Parameters[0];
                var sourceFinder = new ObjectMembersMappingSourceFinder(source.Type, generator.IdentifierName(source.Name), generator);
                var targets      = ObjectHelper.GetFieldsThaCanBeSetFromConstructor(methodSymbol.ContainingType);
                return(mappingEngine.MapUsingSimpleAssignment(generator, targets, sourceFinder));
            }

            if (SymbolHelper.IsMultiParameterMappingConstructor(methodSymbol))
            {
                var sourceFinder = new LocalScopeMappingSourceFinder(semanticModel, methodSymbol.Parameters);
                var targets      = ObjectHelper.GetFieldsThaCanBeSetFromConstructor(methodSymbol.ContainingType);
                return(mappingEngine.MapUsingSimpleAssignment(generator, targets, sourceFinder));
            }
            return(Enumerable.Empty <SyntaxNode>());
        }