Beispiel #1
0
        private async Task <Document> GenerateExplicitConversion(Document document, YieldStatementSyntax yieldStatement, CancellationToken cancellationToken)
        {
            var semanticModel = await document.GetSemanticModelAsync(cancellationToken);

            var syntaxGenerator     = SyntaxGenerator.GetGenerator(document);
            var mappingGenerator    = new MappingGenerator(syntaxGenerator, semanticModel);
            var yieldExpressionType = semanticModel.GetTypeInfo(yieldStatement.Expression);
            var mappingStatements   = mappingGenerator.MapTypes(yieldExpressionType.Type, yieldExpressionType.ConvertedType, yieldStatement.Expression, generatorContext: true);

            return(await ReplaceStatement(document, yieldStatement, mappingStatements, cancellationToken));
        }
        private async Task <Document> GenerateMappingMethodBody(Document document, BaseMethodDeclarationSyntax methodSyntax, CancellationToken cancellationToken)
        {
            var semanticModel = await document.GetSemanticModelAsync(cancellationToken);

            var methodSymbol       = semanticModel.GetDeclaredSymbol(methodSyntax);
            var generator          = SyntaxGenerator.GetGenerator(document);
            var mappingGenerator   = new MappingGenerator(generator, semanticModel);
            var mappingExpressions = GenerateMappingCode(methodSymbol, generator, mappingGenerator, semanticModel);

            return(await document.ReplaceNodes(methodSyntax.Body, ((BaseMethodDeclarationSyntax)generator.MethodDeclaration(methodSymbol, mappingExpressions)).Body, cancellationToken));
        }
Beispiel #3
0
        private async Task <Document> GenerateExplicitConversion(Document document, AssignmentExpressionSyntax assignmentExpression, CancellationToken cancellationToken)
        {
            var semanticModel = await document.GetSemanticModelAsync(cancellationToken);

            var syntaxGenerator  = SyntaxGenerator.GetGenerator(document);
            var mappingGenerator = new MappingGenerator(syntaxGenerator, semanticModel);
            var sourceType       = semanticModel.GetTypeInfo(assignmentExpression.Right).Type;
            var destimationType  = semanticModel.GetTypeInfo(assignmentExpression.Left).Type;
            //WARN: cheap speaculation, no idea how to deal with it in more generic way
            var targetExists        = assignmentExpression.Left.Kind() == SyntaxKind.IdentifierName && semanticModel.GetSymbolInfo(assignmentExpression.Left).Symbol.Kind != SymbolKind.Property;
            var mappingStatements   = mappingGenerator.MapTypes(sourceType, destimationType, assignmentExpression.Right, assignmentExpression.Left, targetExists: targetExists).ToList();
            var assignmentStatement = assignmentExpression.Parent;

            return(await ReplaceStatement(document, assignmentStatement, mappingStatements, cancellationToken));
        }
        private static IEnumerable <SyntaxNode> GenerateMappingCode(IMethodSymbol methodSymbol, SyntaxGenerator generator, MappingGenerator mappingGenerator)
        {
            if (SymbolHelper.IsPureMappingFunction(methodSymbol))
            {
                var source     = methodSymbol.Parameters[0];
                var targetType = methodSymbol.ReturnType;
                return(mappingGenerator.MapTypes(source.Type, targetType, generator.IdentifierName(source.Name)));
            }

            if (SymbolHelper.IsUpdateThisObjectFunction(methodSymbol) || SymbolHelper.IsMappingConstructor(methodSymbol))
            {
                var source     = methodSymbol.Parameters[0];
                var targetType = methodSymbol.ContainingType;
                return(mappingGenerator.MapTypes(source.Type, targetType, generator.IdentifierName(source.Name), generator.ThisExpression(), targetExists: true));
            }

            if (SymbolHelper.IsUpdateParameterFunction(methodSymbol))
            {
                var source = methodSymbol.Parameters[0];
                var target = methodSymbol.Parameters[1];
                return(mappingGenerator.MapTypes(source.Type, target.Type, generator.IdentifierName(source.Name), generator.IdentifierName(target.Name), targetExists: true));
            }

            return(Enumerable.Empty <SyntaxNode>());
        }
        private static IEnumerable <SyntaxNode> GenerateMappingCode(IMethodSymbol methodSymbol,
                                                                    SyntaxGenerator generator, MappingGenerator mappingGenerator, SemanticModel semanticModel)
        {
            if (SymbolHelper.IsPureMappingFunction(methodSymbol))
            {
                var source     = methodSymbol.Parameters[0];
                var targetType = methodSymbol.ReturnType;
                return(mappingGenerator.MapTypes(source.Type, targetType, generator.IdentifierName(source.Name)));
            }

            var isMappingConstructor = SymbolHelper.IsMappingConstructor(methodSymbol);

            if (SymbolHelper.IsUpdateThisObjectFunction(methodSymbol) || isMappingConstructor)
            {
                var source     = methodSymbol.Parameters[0];
                var targetType = methodSymbol.ContainingType;
                return(mappingGenerator.MapTypes(source.Type, targetType, generator.IdentifierName(source.Name), generator.ThisExpression(), targetExists: true, isConstructorContext: isMappingConstructor));
            }

            if (SymbolHelper.IsUpdateParameterFunction(methodSymbol))
            {
                var source = methodSymbol.Parameters[0];
                var target = methodSymbol.Parameters[1];
                return(mappingGenerator.MapTypes(source.Type, target.Type, generator.IdentifierName(source.Name), generator.IdentifierName(target.Name), targetExists: true));
            }

            var isMultiParameterConstructor = SymbolHelper.IsMultiParameterUpdateThisObjectFunction(methodSymbol);

            if (isMultiParameterConstructor || SymbolHelper.IsMultiParameterMappingConstructor(methodSymbol))
            {
                var sourceFinder = new LocalScopeMappingSourceFinder(semanticModel, methodSymbol.Parameters);
                return(ObjectHelper.GetPublicPropertySymbols(methodSymbol.ContainingType)
                       .Where(property => property.SetMethod != null || (property.CanBeSetOnlyFromConstructor() && isMultiParameterConstructor))
                       .Select(property => new
                {
                    source = sourceFinder.FindMappingSource(property.Name, property.Type),
                    target = new MappingElement()
                    {
                        Expression = SyntaxFactory.IdentifierName(property.Name),
                        ExpressionType = property.Type
                    }
                })
                       .Where(x => x.source != null)
                       .SelectMany(pair => mappingGenerator.Map(pair.source, pair.target)));
            }
            return(Enumerable.Empty <SyntaxNode>());
        }