示例#1
0
        private IEnumerable <Diagnostic> AnalyzeNormalInvocationExpression(InvocationExpressionSyntax node, SemanticModel semanticModel)
        {
            var argumentList = node.ArgumentList;

            foreach (var lambda in node.AncestorsAndSelf().OfType <SimpleLambdaExpressionSyntax>())
            {
                if (lambda.Parent is ArgumentSyntax a && a.Parent?.Parent is InvocationExpressionSyntax i && i.Expression is MemberAccessExpressionSyntax m)
                {
                    switch (m.GetName())
                    {
                    case "Setup":
                    case "SetupGet":
                    case "SetupSet":
                    case "SetupSequence":
                    case "Verify":
                    case "VerifyGet":
                    case "VerifySet":
                    {
                        // here we assume that we have a Moq call
                        return(Enumerable.Empty <Diagnostic>());
                    }

                    case "Of" when m.Expression is IdentifierNameSyntax ins && ins.GetName() == "Mock":
                    {
                        // here we assume that we have a Moq call
                        return(Enumerable.Empty <Diagnostic>());
                    }
                    }
                }
            }

            var method = node.GetEnclosingMethod(semanticModel);

            return(AnalyzeArguments(method, argumentList));
        }
示例#2
0
        private ExpressionSyntax VisitInvocation(InvocationExpressionSyntax node)
        {
            if (!_data.CurrentRewrite)
            {
                return(node);
            }
            if (!(node.Expression is MemberAccessExpressionSyntax) && !(node.Expression is MemberBindingExpressionSyntax))
            {
                return(null);
            }

            var ownerNode = node.AncestorsAndSelf().FirstOrDefault(x => x is MethodDeclarationSyntax);

            if (ownerNode == null)
            {
                return(null);
            }

            _data.CurrentMethodIsStatic          = _data.Semantic.GetDeclaredSymbol((MethodDeclarationSyntax)ownerNode).IsStatic;
            _data.CurrentMethodName              = ((MethodDeclarationSyntax)ownerNode).Identifier.ValueText;
            _data.CurrentMethodTypeParameters    = ((MethodDeclarationSyntax)ownerNode).TypeParameterList;
            _data.CurrentMethodConstraintClauses = ((MethodDeclarationSyntax)ownerNode).ConstraintClauses;

            if (!IsSupportedMethod(node))
            {
                return(node);
            }
            var chainList = GetInvocationStepChain(node, out var lastNode);

            var(rewrite, collection) = CheckIfRewriteInvocation(node, lastNode);
            if (!rewrite)
            {
                return(null);
            }

            var returnType = _data.Semantic.GetTypeFromExpression(node);

            return(InvocationRewriter.TryRewrite(collection, returnType, chainList, node)
                   .WithLeadingTrivia(node.GetLeadingTrivia())
                   .WithTrailingTrivia(node.GetTrailingTrivia()));
        }
        private ExpressionSyntax TryVisitInvocationExpression(InvocationExpressionSyntax node, ForEachStatementSyntax containingForEach)
        {
            var memberAccess = node.Expression as MemberAccessExpressionSyntax;

            if (memberAccess != null)
            {
                var symbol = semantic.GetSymbolInfo(memberAccess).Symbol as IMethodSymbol;
                var owner  = node.AncestorsAndSelf().OfType <MethodDeclarationSyntax>().FirstOrDefault();
                if (owner != null)
                {
                    currentMethodIsStatic          = semantic.GetDeclaredSymbol(owner).IsStatic;
                    currentMethodName              = owner.Identifier.ValueText;
                    currentMethodTypeParameters    = owner.TypeParameterList;
                    currentMethodConstraintClauses = owner.ConstraintClauses;
                }
                else
                {
                    var accessor = node.AncestorsAndSelf().OfType <AccessorDeclarationSyntax>().FirstOrDefault();
                    if (accessor == null)
                    {
                        return(null);
                    }
                    var parent = accessor.Parent?.Parent;
                    if (parent == null)
                    {
                        throw new NotSupportedException("Accessors must be in a property or event block");
                    }
                    currentMethodIsStatic          = semantic.GetDeclaredSymbol(parent).IsStatic;
                    currentMethodTypeParameters    = null;
                    currentMethodConstraintClauses = new SyntaxList <TypeParameterConstraintClauseSyntax>();

                    var property = parent as PropertyDeclarationSyntax;
                    if (property != null)
                    {
                        currentMethodName = property.Identifier.ValueText;
                    }
                    else
                    {
                        var ev = parent as EventDeclarationSyntax;
                        if (ev == null)
                        {
                            throw new NotSupportedException("Accessors must be in properties or events. Not supported: " + parent);
                        }
                        currentMethodName = ev.Identifier.ValueText;
                    }
                }

                if (IsSupportedMethod(node))
                {
                    var chain = new List <LinqStep>();
                    chain.Add(new LinqStep(GetMethodFullName(node), node.ArgumentList.Arguments.Select(x => x.Expression).ToList(), node));
                    var c        = node;
                    var lastNode = node;
                    while (c.Expression is MemberAccessExpressionSyntax)
                    {
                        c = ((MemberAccessExpressionSyntax)c.Expression).Expression as InvocationExpressionSyntax;
                        if (c != null && IsSupportedMethod(c))
                        {
                            chain.Add(new LinqStep(GetMethodFullName(c), c.ArgumentList.Arguments.Select(x => x.Expression).ToList(), c));
                            lastNode = c;
                        }
                        else
                        {
                            break;
                        }
                    }
                    if (containingForEach != null)
                    {
                        chain.Insert(0, new LinqStep(IEnumerableForEachMethod, new[] { SyntaxFactory.SimpleLambdaExpression(SyntaxFactory.Parameter(containingForEach.Identifier), containingForEach.Statement) })
                        {
                            Lambda = new Lambda(containingForEach.Statement, new[] { CreateParameter(containingForEach.Identifier, semantic.GetTypeInfo(containingForEach.Type).ConvertedType) })
                        });
                    }
                    if (!chain.Any(x => x.Arguments.Any(y => y is AnonymousFunctionExpressionSyntax)))
                    {
                        return(null);
                    }
                    if (chain.Count == 1 && RootMethodsThatRequireYieldReturn.Contains(chain[0].MethodName))
                    {
                        return(null);
                    }


                    var flowsIn  = new List <ISymbol>();
                    var flowsOut = new List <ISymbol>();
                    foreach (var item in chain)
                    {
                        foreach (var arg in item.Arguments)
                        {
                            if (item.Lambda != null)
                            {
                                var dataFlow = semantic.AnalyzeDataFlow(item.Lambda.Body);
                                var pname    = item.Lambda.Parameters.Single().Identifier.ValueText;
                                foreach (var k in dataFlow.DataFlowsIn)
                                {
                                    if (k.Name == pname)
                                    {
                                        continue;
                                    }
                                    if (!flowsIn.Contains(k))
                                    {
                                        flowsIn.Add(k);
                                    }
                                }
                                foreach (var k in dataFlow.DataFlowsOut)
                                {
                                    if (k.Name == pname)
                                    {
                                        continue;
                                    }
                                    if (!flowsOut.Contains(k))
                                    {
                                        flowsOut.Add(k);
                                    }
                                }
                            }
                            else
                            {
                                var dataFlow = semantic.AnalyzeDataFlow(arg);
                                foreach (var k in dataFlow.DataFlowsIn)
                                {
                                    if (!flowsIn.Contains(k))
                                    {
                                        flowsIn.Add(k);
                                    }
                                }
                                foreach (var k in dataFlow.DataFlowsOut)
                                {
                                    if (!flowsOut.Contains(k))
                                    {
                                        flowsOut.Add(k);
                                    }
                                }
                            }
                        }
                    }

                    currentFlow = flowsIn
                                  .Union(flowsOut)
                                  .Where(x => (x as IParameterSymbol)?.IsThis != true)
                                  .Select(x => CreateVariableCapture(x, flowsOut)) ?? Enumerable.Empty <VariableCapture>();

                    var collection = ((MemberAccessExpressionSyntax)lastNode.Expression).Expression;

                    if (IsAnonymousType(semantic.GetTypeInfo(collection).Type))
                    {
                        return(null);
                    }


                    var semanticReturnType = semantic.GetTypeInfo(node).Type;
                    if (IsAnonymousType(semanticReturnType) || currentFlow.Any(x => IsAnonymousType(GetSymbolType(x.Symbol))))
                    {
                        return(null);
                    }



                    return(TryRewrite(chain.First().MethodName, collection, semanticReturnType, chain, node)
                           .WithLeadingTrivia(((CSharpSyntaxNode)containingForEach ?? node).GetLeadingTrivia())
                           .WithTrailingTrivia(((CSharpSyntaxNode)containingForEach ?? node).GetTrailingTrivia()));
                }
            }
            return(null);
        }
        private async Task<Document> CorrectArgumentsAsync(Document document, InvocationExpressionSyntax declaration, CancellationToken c)
        {
            SyntaxGenerator generator = SyntaxGenerator.GetGenerator(document);

            string methodName = "AnalyzeIfStatement";
            bool useExistingAnalysis = false;

            var argList = declaration.ArgumentList;
            if (argList != null)
            {
                var args = argList.Arguments;
                if (args != null)
                {
                    if (args.Count > 0)
                    {
                        var nameArg = args[0];
                        var name = nameArg.Expression as IdentifierNameSyntax;
                        if (name != null)
                        {
                            methodName = name.Identifier.Text;
                        }
                        else
                        {
                            useExistingAnalysis = true;
                        }
                    }
                    else if (args.Count == 0)
                    {
                        useExistingAnalysis = true;
                    }
                }
            }
            if (useExistingAnalysis)
            {
                ClassDeclarationSyntax classDeclaration = declaration.AncestorsAndSelf().OfType<ClassDeclarationSyntax>().First();
                methodName = CodeFixNodeCreator.ExistingAnalysisMethod(classDeclaration);
            }
            if (methodName == null)
            {
                methodName = "AnalyzeIfStatement";
            }

            SyntaxNode statement = CodeFixNodeCreator.CreateRegister(generator, declaration.Parent.Parent.Parent as MethodDeclarationSyntax, methodName);
            SyntaxNode expression = generator.ExpressionStatement(statement);

            return await ReplaceNode(declaration.Parent, expression.WithLeadingTrivia(SyntaxFactory.TriviaList(SyntaxFactory.ParseLeadingTrivia("// Calls the method (first argument) to perform analysis whenever this is a change to a SyntaxNode of kind IfStatement").ElementAt(0), SyntaxFactory.EndOfLine("\r\n"))), document);
        }
        // puts the correct arguments in the register statement
        private async Task<Document> CorrectArgumentsAsync(Document document, InvocationExpressionSyntax declaration, CancellationToken c)
        {
            SyntaxGenerator generator = SyntaxGenerator.GetGenerator(document);

            string methodName = CodeFixHelper.GetRegisterMethodName(declaration);

            ClassDeclarationSyntax classDeclaration = declaration.AncestorsAndSelf().OfType<ClassDeclarationSyntax>().First();
            methodName = CodeFixHelper.GetExistingAnalysisMethodName(classDeclaration);

            if (methodName == null)
            {
                methodName = "AnalyzeIfStatement";
            }

            SyntaxNode statement = CodeFixHelper.CreateRegister(generator, declaration.Ancestors().OfType<MethodDeclarationSyntax>().First(), methodName);
            SyntaxNode expression = generator.ExpressionStatement(statement);

            return await ReplaceNode(declaration.Parent, expression.WithLeadingTrivia(SyntaxFactory.TriviaList(SyntaxFactory.ParseLeadingTrivia("// Calls the method (first argument) to perform analysis whenever a SyntaxNode of kind IfStatement is found").ElementAt(0), SyntaxFactory.EndOfLine("\r\n"))), document);
        }