Exemple #1
0
        public IEnumerable <SyntaxNode> GenerateImplementation(IMethodSymbol methodSymbol, SyntaxGenerator generator, SemanticModel semanticModel)
        {
            var mappingEngine = new MappingEngine(semanticModel, generator, methodSymbol.ContainingAssembly);
            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(targets, new SingleSourceMatcher(sourceFinder)));
        }
Exemple #2
0
        public IEnumerable <SyntaxNode> GenerateImplementation(IMethodSymbol methodSymbol, SyntaxGenerator generator,
                                                               SemanticModel semanticModel, MappingContext mappingContext)
        {
            var mappingEngine = new MappingEngine(semanticModel, generator);
            var source        = methodSymbol.Parameters[0];
            var sourceFinder  = new ObjectMembersMappingSourceFinder(new AnnotatedType(source.Type), generator.IdentifierName(source.Name), generator);
            var targets       = MappingTargetHelper.GetFieldsThaCanBeSetPrivately(methodSymbol.ContainingType, mappingContext);

            return(mappingEngine.MapUsingSimpleAssignment(targets, new SingleSourceMatcher(sourceFinder), mappingContext));
        }
        private async Task<Document> InitializeWithLambdaParameter(Document document, LambdaExpressionSyntax lambdaSyntax, InitializerExpressionSyntax objectInitializer, CancellationToken cancellationToken)
        {
            var semanticModel = await document.GetSemanticModelAsync(cancellationToken);
            var generator = SyntaxGenerator.GetGenerator(document);

            var lambdaSymbol = semanticModel.GetSymbolInfo(lambdaSyntax).Symbol as IMethodSymbol;
            var firstArgument = lambdaSymbol.Parameters.First();
            var mappingSourceFinder = new ObjectMembersMappingSourceFinder(new AnnotatedType(firstArgument.Type), generator.IdentifierName(firstArgument.Name), generator);
            return await ReplaceEmptyInitializationBlock(document, objectInitializer, semanticModel, new SingleSourceMatcher(mappingSourceFinder), cancellationToken);
        }
        public IEnumerable <SyntaxNode> GenerateImplementation(IMethodSymbol methodSymbol, SyntaxGenerator generator, SemanticModel semanticModel)
        {
            var mappingEngine = new MappingEngine(semanticModel, generator, methodSymbol.ContainingAssembly);
            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)));
        }
Exemple #5
0
        public async Task <IReadOnlyList <SyntaxNode> > GenerateImplementation(IMethodSymbol methodSymbol, SyntaxGenerator generator,
                                                                               SemanticModel semanticModel, MappingContext mappingContext)
        {
            var mappingEngine       = new MappingEngine(semanticModel, generator);
            var sourceParameter     = methodSymbol.Parameters[0];
            var sourceFinder        = new ObjectMembersMappingSourceFinder(new AnnotatedType(sourceParameter.Type), generator.IdentifierName(sourceParameter.Name));
            var mappingTargetHelper = new MappingTargetHelper();
            var targets             = mappingTargetHelper.GetFieldsThaCanBeSetFromConstructor(methodSymbol.ContainingType, mappingContext);

            return(await mappingEngine.MapUsingSimpleAssignment(targets, new SingleSourceMatcher(sourceFinder), mappingContext).ConfigureAwait(false));
        }
        protected virtual MappingElement TryToCreateMappingExpression(MappingElement source, ITypeSymbol targetType, MappingPath mappingPath)
        {
            //TODO: If source expression is method or constructor invocation then we should extract local variable and use it im mappings as a reference
            var namedTargetType = targetType as INamedTypeSymbol;

            if (namedTargetType != null)
            {
                var directlyMappingConstructor = namedTargetType.Constructors.FirstOrDefault(c => c.Parameters.Length == 1 && c.Parameters[0].Type.Equals(source.ExpressionType));
                if (directlyMappingConstructor != null)
                {
                    var constructorParameters = SyntaxFactory.ArgumentList().AddArguments(SyntaxFactory.Argument(source.Expression));
                    var creationExpression    = syntaxGenerator.ObjectCreationExpression(targetType, constructorParameters.Arguments);
                    return(new MappingElement()
                    {
                        ExpressionType = targetType,
                        Expression = (ExpressionSyntax)creationExpression
                    });
                }
            }

            if (MappingHelper.IsMappingBetweenCollections(targetType, source.ExpressionType))
            {
                return(new MappingElement()
                {
                    ExpressionType = targetType,
                    Expression = MapCollections(source.Expression, source.ExpressionType, targetType, mappingPath.Clone()) as ExpressionSyntax
                });
            }

            var subMappingSourceFinder = new ObjectMembersMappingSourceFinder(source.ExpressionType, source.Expression, syntaxGenerator);

            if (namedTargetType != null)
            {
                //maybe there is constructor that accepts parameter matching source properties
                var constructorOverloadParameterSets = namedTargetType.Constructors.Select(x => x.Parameters);
                var matchedOverload = MethodHelper.FindBestParametersMatch(subMappingSourceFinder, constructorOverloadParameterSets);

                if (matchedOverload != null)
                {
                    var creationExpression = ((ObjectCreationExpressionSyntax)syntaxGenerator.ObjectCreationExpression(targetType, matchedOverload.ToArgumentListSyntax(this).Arguments));
                    var matchedSources     = matchedOverload.GetMatchedSources();
                    var restSourceFinder   = new IgnorableMappingSourceFinder(subMappingSourceFinder, foundElement =>
                    {
                        return(matchedSources.Any(x => x.Expression.IsEquivalentTo(foundElement.Expression)));
                    });
                    var mappingMatcher = new SingleSourceMatcher(restSourceFinder);
                    return(new MappingElement()
                    {
                        ExpressionType = targetType,
                        Expression = AddInitializerWithMapping(creationExpression, mappingMatcher, targetType, mappingPath)
                    });
                }
            }


            var objectCreationExpressionSyntax = ((ObjectCreationExpressionSyntax)syntaxGenerator.ObjectCreationExpression(targetType));
            var subMappingMatcher = new SingleSourceMatcher(subMappingSourceFinder);

            return(new MappingElement()
            {
                ExpressionType = targetType,
                Expression = AddInitializerWithMapping(objectCreationExpressionSyntax, subMappingMatcher, targetType, mappingPath)
            });
        }
Exemple #7
0
        protected virtual async Task <MappingElement> TryToCreateMappingExpression(MappingElement source, AnnotatedType targetType, MappingPath mappingPath, MappingContext mappingContext)
        {
            //TODO: If source expression is method or constructor invocation then we should extract local variable and use it im mappings as a reference
            var namedTargetType = targetType.Type as INamedTypeSymbol;

            if (namedTargetType != null)
            {
                var directlyMappingConstructor = namedTargetType.Constructors.FirstOrDefault(c => c.Parameters.Length == 1 && c.Parameters[0].Type.Equals(source.ExpressionType.Type));
                if (directlyMappingConstructor != null)
                {
                    var creationExpression       = CreateObject(targetType.Type, SyntaxFactory.ArgumentList().AddArguments(SyntaxFactory.Argument(source.Expression)));
                    var shouldProtectAgainstNull = directlyMappingConstructor.Parameters[0].Type.CanBeNull() == false && source.ExpressionType.CanBeNull;
                    return(new MappingElement
                    {
                        ExpressionType = targetType,
                        Expression = shouldProtectAgainstNull ? HandleSafeNull(source, targetType, creationExpression) : creationExpression
                    });
                }
            }

            if (MappingHelper.IsMappingBetweenCollections(targetType.Type, source.ExpressionType.Type))
            {
                var shouldProtectAgainstNull = source.ExpressionType.CanBeNull && targetType.CanBeNull == false;
                var collectionMapping        = (await MapCollectionsAsync(source, targetType, mappingPath.Clone(), mappingContext).ConfigureAwait(false)) as ExpressionSyntax;
                return(new MappingElement
                {
                    ExpressionType = targetType,
                    Expression = shouldProtectAgainstNull ? OrFailWhenArgumentNull(collectionMapping, source.Expression.ToFullString()) : collectionMapping,
                });
            }

            var subMappingSourceFinder = new ObjectMembersMappingSourceFinder(source.ExpressionType.AsNotNull(), source.Expression);

            if (namedTargetType != null)
            {
                //maybe there is constructor that accepts parameter matching source properties
                var constructorOverloadParameterSets = namedTargetType.Constructors.Select(x => x.Parameters);
                var matchedOverload = await MethodHelper.FindBestParametersMatch(subMappingSourceFinder, constructorOverloadParameterSets, mappingContext).ConfigureAwait(false);

                if (matchedOverload != null)
                {
                    var argumentListSyntaxAsync = await matchedOverload.ToArgumentListSyntaxAsync(this, mappingContext).ConfigureAwait(false);

                    var creationExpression = CreateObject(targetType.Type, argumentListSyntaxAsync);
                    var matchedSources     = matchedOverload.GetMatchedSources();
                    var restSourceFinder   = new IgnorableMappingSourceFinder(subMappingSourceFinder, foundElement =>
                    {
                        return(matchedSources.Any(x => x.Expression.IsEquivalentTo(foundElement.Expression)));
                    });
                    var mappingMatcher = new SingleSourceMatcher(restSourceFinder);
                    return(new MappingElement()
                    {
                        ExpressionType = new AnnotatedType(targetType.Type),
                        Expression = await AddInitializerWithMappingAsync(creationExpression, mappingMatcher, targetType.Type, mappingContext, mappingPath).ConfigureAwait(false),
                    });
                }
            }

            var objectCreationExpressionSyntax = CreateObject(targetType.Type);
            var subMappingMatcher             = new SingleSourceMatcher(subMappingSourceFinder);
            var objectCreationWithInitializer = await AddInitializerWithMappingAsync(objectCreationExpressionSyntax, subMappingMatcher, targetType.Type, mappingContext, mappingPath).ConfigureAwait(false);

            return(new MappingElement()
            {
                ExpressionType = new AnnotatedType(targetType.Type),
                Expression = HandleSafeNull(source, targetType, objectCreationWithInitializer)
            });
        }