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)); }
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); }