Esempio n. 1
0
        private async Task <string> GetArgumentListWithLocalVariables(Document document, IInvocation invocation, bool generateNamedParameters, SemanticModel semanticModel)
        {
            var mappingSourceFinder = LocalScopeMappingSourceFinder.FromScope(semanticModel, invocation.SourceNode, AllowedSymbolsForCompletion);

            mappingSourceFinder.AllowMatchOnlyByTypeWhenSingleCandidate = true;

            var syntaxGenerator       = SyntaxGenerator.GetGenerator(document);
            var overloadParameterSets = invocation.GetOverloadParameterSets(semanticModel);

            if (overloadParameterSets != null)
            {
                var mappingEngine   = new MappingEngine(semanticModel, syntaxGenerator);
                var mappingContext  = new MappingContext(invocation.SourceNode, semanticModel);
                var parametersMatch = await MethodHelper.FindBestParametersMatch(mappingSourceFinder, overloadParameterSets, mappingContext).ConfigureAwait(false);

                if (parametersMatch != null)
                {
                    var argumentList = await parametersMatch.ToArgumentListSyntaxAsync(mappingEngine, mappingContext, generateNamedParameters).ConfigureAwait(false);

                    var chunks = argumentList.Arguments.Select(a => a.ToString());
                    return(string.Join(", ", chunks));
                }
            }

            return(null);
        }
        private static MatchedParameterList FindParametersMatch(ArgumentListSyntax invalidArgumentList, IEnumerable <ImmutableArray <IParameterSymbol> > overloadParameterSets, SemanticModel semanticModel, SyntaxGenerator syntaxGenerator)
        {
            var sourceFinder    = CreateSourceFinderBasedOnInvalidArgument(invalidArgumentList, semanticModel, syntaxGenerator);
            var parametersMatch = MethodHelper.FindBestParametersMatch(sourceFinder, overloadParameterSets);

            return(parametersMatch);
        }
Esempio n. 3
0
        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 mappingContext  = new MappingContext(invocation.SourceNode, semanticModel);
                var mappingEngine   = new MappingEngine(semanticModel, syntaxGenerator);
                var parametersMatch = await MethodHelper.FindBestParametersMatch(mappingSourceFinder, overloadParameterSets, mappingContext).ConfigureAwait(false);

                if (parametersMatch != null)
                {
                    var argumentList = await parametersMatch.ToArgumentListSyntaxAsync(mappingEngine, mappingContext, generateNamedParameters).ConfigureAwait(false);

                    return(await document.ReplaceNodes(invocation.SourceNode, invocation.WithArgumentList(argumentList), cancellationToken).ConfigureAwait(false));
                }
            }

            return(document);
        }
        private static async Task <MatchedParameterList> FindParametersMatch(ArgumentListSyntax invalidArgumentList,
                                                                             IEnumerable <ImmutableArray <IParameterSymbol> > overloadParameterSets, SemanticModel semanticModel,
                                                                             MappingContext mappingContext)
        {
            var sourceFinder    = CreateSourceFinderBasedOnInvalidArgument(invalidArgumentList, semanticModel);
            var parametersMatch = await MethodHelper.FindBestParametersMatch(sourceFinder, overloadParameterSets, mappingContext).ConfigureAwait(false);

            return(parametersMatch);
        }
Esempio n. 5
0
        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)
            });
        }
Esempio n. 6
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)
            });
        }