Beispiel #1
0
        private void AnalyzeLoop(BlockSyntax blockSyntax)
        {
            var context = new AnalyzeContext(_efAnalyzer.Project,
                                             _efAnalyzer.Document);

            _efAnalyzer.AnalyzedContexts.Add(context);

            var methodInvocations = blockSyntax.DescendantNodes()
                                    .Where(q => q.Kind() == SyntaxKind.InvocationExpression)
                                    .OfType <InvocationExpressionSyntax>()
                                    .ToArray();

            foreach (var methodInvocation in methodInvocations)
            {
                var detectAddRemoveInsideLoopAnalyzer = new DetectAddRemoveInsideLoopAnalyzer(_efAnalyzer.DocumentSemanticModel);
                context.RuleViolations.AddRange(detectAddRemoveInsideLoopAnalyzer.AnalyzeSyntaxNode(methodInvocation));

                var detectSaveInsideLoopAnalyzer = new DetectSaveInsideLoopAnalyzer(_efAnalyzer.DocumentSemanticModel);
                context.RuleViolations.AddRange(detectSaveInsideLoopAnalyzer.AnalyzeSyntaxNode(methodInvocation));
            }

            var objectCreations = blockSyntax.DescendantNodes()
                                  .Where(q => q.Kind() == SyntaxKind.ObjectCreationExpression)
                                  .OfType <ObjectCreationExpressionSyntax>()
                                  .ToArray();

            foreach (var objectCreation in objectCreations)
            {
                var detectDbContextCreationInsideLoopAnalyzer = new DetectDbContextCreationInsideLoopAnalyzer(_efAnalyzer.DocumentSemanticModel);
                context.RuleViolations.AddRange(detectDbContextCreationInsideLoopAnalyzer.AnalyzeSyntaxNode(objectCreation));
            }
        }
Beispiel #2
0
        public static IReadOnlyList <ExpressionSyntax> GetAllThrowExpressions(this BlockSyntax codeBlock)
        {
            var expressionFromThrowStatements  = codeBlock.DescendantNodes().OfType <ThrowStatementSyntax>().Select(x => x.Expression);
            var expressionFromThrowExpressions = codeBlock.DescendantNodes().OfType <ThrowExpressionSyntax>().Select(x => x.Expression);

            return(expressionFromThrowStatements.Concat(expressionFromThrowExpressions).ToList());
        }
Beispiel #3
0
            private static void GetLabelSymbols(
                BlockSyntax body,
                SemanticModel model,
                List <ISymbol> list
                )
            {
                var labels = body.DescendantNodes().OfType <LabeledStatementSyntax>();

                foreach (var n in labels)
                {
                    // Label: -> 'Label' is token
                    var sym = model.GetDeclaredSymbol(n);
                    list.Add(sym);
                }

                var swlabels = body.DescendantNodes().OfType <SwitchLabelSyntax>();

                foreach (var n in swlabels)
                {
                    // label value has NO symbol, Type is expr's type
                    // e.g. case "A": -> string type
                    // var info1 = model.GetTypeInfo(n.Value);
                    // var info2 = model.GetSymbolInfo(n.Value);
                    var sym = model.GetDeclaredSymbol(n);
                    list.Add(sym);
                }
            }
    private static IReadOnlyList <ExpressionSyntax> GetAllThrowExpressions(BlockSyntax codeBlock)
    {
        IEnumerable <ExpressionSyntax> expressionFromThrowStatements = codeBlock.DescendantNodes()
                                                                       .OfType <ThrowStatementSyntax>()
                                                                       .Select(x => x.Expression)
                                                                       .RemoveNulls();
        IEnumerable <ExpressionSyntax> expressionFromThrowExpressions = codeBlock.DescendantNodes()
                                                                        .OfType <ThrowExpressionSyntax>()
                                                                        .Select(x => x.Expression);

        return(expressionFromThrowStatements.Concat(expressionFromThrowExpressions)
               .ToArray());
    }
        private static void ComputeRefactoring(
            RefactoringContext context,
            SyntaxNode node,
            BlockSyntax body,
            SemanticModel semanticModel)
        {
            if (body?
                .DescendantNodes(body.Span, f => !f.IsNestedMethod())
                .Any(f => f.IsKind(SyntaxKind.YieldReturnStatement)) == true)
            {
                var symbol = (IMethodSymbol)semanticModel.GetDeclaredSymbol(node, context.CancellationToken);

                if (symbol?.IsErrorType() == false)
                {
                    ITypeSymbol type = GetElementType(symbol.ReturnType, semanticModel);

                    if (type?.IsErrorType() == false)
                    {
                        context.RegisterRefactoring(
                            "Use List<T> instead of yield",
                            cancellationToken => RefactorAsync(context.Document, type, body, body.Statements, cancellationToken));
                    }
                }
            }
        }
Beispiel #6
0
        public void CreateNthPrimeOperation_ShouldUseALambdaExpression()
        {
            BlockSyntax body         = GetMethodBody(nameof(MathOperationFactory.CreateNthPrimeOperation));
            var         lambdaSyntax = body.DescendantNodes().OfType <LambdaExpressionSyntax>().FirstOrDefault();

            Assert.That(lambdaSyntax, Is.Not.Null);
        }
Beispiel #7
0
        private static bool ContainsOtherAwaitOrReturnWithoutAwait(BlockSyntax body, HashSet <AwaitExpressionSyntax> awaitExpressions)
        {
            foreach (SyntaxNode descendant in body.DescendantNodes(body.Span, f => !f.IsNestedMethod() && !f.IsKind(SyntaxKind.ReturnStatement)))
            {
                switch (descendant.Kind())
                {
                case SyntaxKind.ReturnStatement:
                {
                    ExpressionSyntax expression = ((ReturnStatementSyntax)descendant).Expression;

                    if (expression?.IsKind(SyntaxKind.AwaitExpression) == true)
                    {
                        if (!awaitExpressions.Contains((AwaitExpressionSyntax)expression))
                        {
                            return(true);
                        }
                    }
                    else
                    {
                        return(true);
                    }

                    break;
                }

                case SyntaxKind.AwaitExpression:
                {
                    return(true);
                }
                }
            }

            return(false);
        }
        /// <summary>
        /// Checks whether a block has an assignment of a syntax token with a given name.
        /// </summary>
        /// <param name="blockSyntax">The block syntax.</param>
        /// <param name="checkIdentifierName">The syntax token.</param>
        /// <param name="memberName">Name of the assignment.</param>
        /// <param name="assignmentExpression">The assignment expression.</param>
        /// <returns></returns>
        public static bool AssignsMemberWithName(this BlockSyntax blockSyntax, SyntaxToken checkIdentifierName,
                                                 string memberName, out AssignmentExpressionSyntax assignmentExpression)
        {
            assignmentExpression = default(AssignmentExpressionSyntax);

            var s = blockSyntax?.DescendantNodes().OfType <AssignmentExpressionSyntax>().ToList();

            if (s == null || !s.Any())
            {
                return(false);
            }
            foreach (var assignment in s)
            {
                if (assignment.Left is MemberAccessExpressionSyntax memberAccess)
                {
                    if (memberAccess.Expression is IdentifierNameSyntax identifierName)
                    {
                        if (identifierName.Identifier.Value == checkIdentifierName.Value)
                        {
                            if (memberAccess.Name.Identifier.Value.Equals(memberName))
                            {
                                assignmentExpression = assignment;
                                return(true);
                            }
                        }
                    }
                }
            }

            return(false);
        }
Beispiel #9
0
        private bool IsWrittenAfter(
            SemanticModel semanticModel, ISymbol local, BlockSyntax block,
            AnonymousFunctionExpressionSyntax anonymousFunction, CancellationToken cancellationToken)
        {
            var anonymousFunctionStart = anonymousFunction.SpanStart;

            foreach (var descendentNode in block.DescendantNodes())
            {
                var descendentStart = descendentNode.Span.Start;
                if (descendentStart <= anonymousFunctionStart)
                {
                    // This node is before the local declaration.  Can ignore it entirely as it could
                    // not be an access to the local.
                    continue;
                }

                if (descendentNode.IsKind(SyntaxKind.IdentifierName))
                {
                    var identifierName = (IdentifierNameSyntax)descendentNode;
                    if (identifierName.Identifier.ValueText == local.Name &&
                        identifierName.IsWrittenTo() &&
                        local.Equals(semanticModel.GetSymbolInfo(identifierName, cancellationToken).GetAnySymbol()))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
        private static BlockSyntax UpdateStatementsForAsyncMethod(BlockSyntax body, SemanticModel semanticModel, bool hasResultValue, bool returnTypeChanged, CancellationToken cancellationToken)
        {
            var fixedUpBlock = body.ReplaceNodes(
                body.DescendantNodes().OfType <ReturnStatementSyntax>(),
                (f, n) =>
            {
                if (hasResultValue)
                {
                    return(returnTypeChanged
                            ? n
                            : n.WithExpression(SyntaxFactory.AwaitExpression(n.Expression).TrySimplify(f.Expression, semanticModel, cancellationToken)));
                }

                if (body.Statements.Last() == f)
                {
                    // If it is the last statement in the method, we can remove it since a return is implied.
                    return(null);
                }

                return(n
                       .WithExpression(null)                                                                // don't return any value
                       .WithReturnKeyword(n.ReturnKeyword.WithTrailingTrivia(SyntaxFactory.TriviaList()))); // remove the trailing space after the keyword
            });

            return(fixedUpBlock);
        }
Beispiel #11
0
        static bool HasReturnContract(BlockSyntax bodyStatement, string parameterName)
        {
            var workspace = new AdhocWorkspace();

            foreach (var expression in bodyStatement.DescendantNodes().OfType <ExpressionStatementSyntax>())
            {
                var formatted = Formatter.Format(expression, workspace).ToString();

                if (formatted == $"Contract.Requires(string.IsNullOrEmpty({parameterName}) == false);")
                {
                    return(true);
                }

                if (formatted == $"Contract.Requires(false == string.IsNullOrEmpty({parameterName}));")
                {
                    return(true);
                }

                if (formatted == $"Contract.Requires(!string.IsNullOrEmpty({parameterName}));")
                {
                    return(true);
                }
            }
            return(false);
        }
        /// <summary>
        /// Declares any "discard"ed variables - i.e. MyFunc(out _) - for this block and all nested blocks.
        /// </summary>
        private string DeclareDiscardedVariables(BlockSyntax block)
        {
            StringBuilder sb = new StringBuilder();

            SemanticModel semanticModel = GetModel(block);

            IEnumerable <ISymbol> discardedVariables = block
                                                       .DescendantNodes()
                                                       .Where(x => x.IsKind(SyntaxKind.IdentifierName))
                                                       .Select(x => semanticModel.GetSymbolInfo(x).Symbol)
                                                       .Where(x => x.Kind == SymbolKind.Discard)
                                                       .Cast <IDiscardSymbol>();

            List <ISymbol> alreadyWrittenTypes = new List <ISymbol>();

            foreach (IDiscardSymbol discardedVariable in discardedVariables)
            {
                if (alreadyWrittenTypes.Contains(discardedVariable.Type))
                {
                    continue;
                }

                sb.Append("    ");
                sb.Append(GetDiscardedVariableType(discardedVariable));
                sb.Append(' ');
                sb.Append(GetDiscardedVariableName(discardedVariable));
                sb.AppendLine(";");

                alreadyWrittenTypes.Add(discardedVariable.Type);
            }

            return(sb.ToString());
        }
Beispiel #13
0
        public int RecurseBlockUsageCount(BlockSyntax block, SyntaxToken methodID, int initialCount)
        {
            int usages = initialCount;

            foreach (var statement in block.Statements)
            {
                foreach (var token in statement.DescendantTokens())
                {
                    try {
                        if (token.Value.Equals(methodID.Value))
                        {
                            usages += 1;
                        }
                    }
                    catch (NullReferenceException) // raised when parsing the 'null' C# token
                    {
                        // 'null' token parse, ignore it
                    }
                }
            }
            foreach (var childBlock in block.DescendantNodes().OfType <BlockSyntax>().ToList())
            {
                usages += RecurseBlockUsageCount(childBlock, methodID, 0);
            }
            return(usages);
        }
 private IEnumerable <String> GetNameLocalVaraibleExpectedCreatedClass(SemanticModel semanticModel, BlockSyntax blockSyntax)
 {
     foreach (var node in blockSyntax.DescendantNodes())
     {
         var localDeclarationStatement = node as LocalDeclarationStatementSyntax;
         if (localDeclarationStatement == null)
         {
             continue;
         }
         if (localDeclarationStatement.Declaration == null)
         {
             continue;
         }
         var variableDeclaration = localDeclarationStatement.Declaration as VariableDeclarationSyntax;
         if (variableDeclaration == null || !variableDeclaration.Variables.Any())
         {
             continue;
         }
         var declarator     = variableDeclaration.Variables.First();
         var objectCreation = declarator.DescendantNodes().FirstOrDefault(n => n is ObjectCreationExpressionSyntax) as ObjectCreationExpressionSyntax;
         if (objectCreation == null)
         {
             continue;
         }
         var typeInfo = semanticModel.GetTypeInfo(objectCreation);
         if (TypeIsExist(typeInfo))
         {
             continue;
         }
         yield return(declarator.GetFirstToken().Text);
     }
 }
Beispiel #15
0
        private ArgumentSyntax FindThreadArgument(string variableName, BlockSyntax block)
        {
            var creationNodes = block.DescendantNodes().OfType <ObjectCreationExpressionSyntax>();

            foreach (var creation in creationNodes)
            {
                if (creation.AncestorsAndSelf().OfType <VariableDeclaratorSyntax>().Any())
                {
                    if (creation.AncestorsAndSelf().OfType <VariableDeclaratorSyntax>().First().Identifier.ToString() ==
                        variableName)
                    {
                        return(creation.DescendantNodes().OfType <ArgumentSyntax>().First());
                    }
                }
                else if (creation.AncestorsAndSelf().OfType <AssignmentExpressionSyntax>().Any())
                {
                    if (creation.AncestorsAndSelf().OfType <AssignmentExpressionSyntax>().First().Left.ToString() ==
                        variableName)
                    {
                        return(creation.DescendantNodes().OfType <ArgumentSyntax>().First());
                    }
                }
            }
            return(null);
        }
 private static IEnumerable <ReturnStatementSyntax> GetReturnNullStatements(BlockSyntax methodBlock)
 {
     return(methodBlock.DescendantNodes()
            .OfType <ReturnStatementSyntax>()
            .Where(returnStatement =>
                   returnStatement.Expression.IsKind(SyntaxKind.NullLiteralExpression) &&
                   returnStatement.FirstAncestorOrSelf <ParenthesizedLambdaExpressionSyntax>() == null));
 }
        private static bool ContainsOtherYieldStatement(BlockSyntax block, StatementSyntax statement)
        {
            TextSpan span = TextSpan.FromBounds(block.SpanStart, statement.FullSpan.Start);

            return(block
                   .DescendantNodes(span, f => !f.IsNestedMethod())
                   .Any(f => f.IsKind(SyntaxKind.YieldBreakStatement, SyntaxKind.YieldReturnStatement)));
        }
Beispiel #18
0
            private void GetAnonymousTypeOrFuncSymbols(BlockSyntax body, SemanticModel model, List <ISymbol> list)
            {
                IEnumerable <ExpressionSyntax> exprs = body.DescendantNodes().OfType <SimpleLambdaExpressionSyntax>();
                IEnumerable <ExpressionSyntax> tmp   = body.DescendantNodes().OfType <ParenthesizedLambdaExpressionSyntax>();

                exprs = exprs.Concat(tmp);
                tmp   = body.DescendantNodes().OfType <AnonymousMethodExpressionSyntax>();
                exprs = exprs.Concat(tmp);

                tmp   = body.DescendantNodes().OfType <AnonymousObjectCreationExpressionSyntax>();
                exprs = exprs.Concat(tmp);

                foreach (var expr in exprs)
                {
                    GetAnonymousExprSymbols(expr, model, list);
                }
            }
Beispiel #19
0
 private static bool IsThreadDeclaredInBlock(BlockSyntax block, ExpressionSyntax identifier)
 {
     return
         (block
          .DescendantNodes()
          .OfType <VariableDeclaratorSyntax>()
          .Any(v => v.Identifier.ToString() == identifier.ToString()));
 }
Beispiel #20
0
        private static bool IsAccessed(
            SemanticModel semanticModel,
            ISymbol outSymbol,
            BlockSyntax enclosingBlockOfLocalStatement,
            LocalDeclarationStatementSyntax localStatement,
            ArgumentSyntax argumentNode,
            CancellationToken cancellationToken
            )
        {
            var localStatementStart = localStatement.Span.Start;
            var argumentNodeStart   = argumentNode.Span.Start;
            var variableName        = outSymbol.Name;

            // Walk the block that the local is declared in looking for accesses.
            // We can ignore anything prior to the actual local declaration point,
            // and we only need to check up until we reach the out-argument.
            foreach (var descendentNode in enclosingBlockOfLocalStatement.DescendantNodes())
            {
                var descendentStart = descendentNode.Span.Start;
                if (descendentStart <= localStatementStart)
                {
                    // This node is before the local declaration.  Can ignore it entirely as it could
                    // not be an access to the local.
                    continue;
                }

                if (descendentStart >= argumentNodeStart)
                {
                    // We reached the out-var.  We can stop searching entirely.
                    break;
                }

                if (
                    descendentNode.IsKind(
                        SyntaxKind.IdentifierName,
                        out IdentifierNameSyntax identifierName
                        )
                    )
                {
                    // See if this looks like an accessor to the local variable syntactically.
                    if (identifierName.Identifier.ValueText == variableName)
                    {
                        // Confirm that it is a access of the local.
                        var symbol =
                            semanticModel.GetSymbolInfo(identifierName, cancellationToken).Symbol;
                        if (outSymbol.Equals(symbol))
                        {
                            // We definitely accessed the local before the out-argument.  We
                            // can't inline this local.
                            return(true);
                        }
                    }
                }
            }

            // No accesses detected
            return(false);
        }
        private static ExpressionStatementSyntax ReinitializeTargetArrayy(BlockSyntax currentBlock, List <LiteralExpressionSyntax> initializationExpressions)
        {
            var declarator = currentBlock.DescendantNodes().OfType <VariableDeclaratorSyntax>()
                             .FirstOrDefault();
            var init = declarator.Initializer;

            var initializationExpression = currentBlock.DescendantNodes()
                                           .OfType <ImplicitArrayCreationExpressionSyntax>().FirstOrDefault();

            initializationExpression =
                initializationExpression.AddInitializerExpressions(initializationExpressions.ToArray());
            var variableIdentifier = SyntaxFactory.IdentifierName("target");
            var assignment         = SyntaxFactory.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression,
                                                                        variableIdentifier, initializationExpression);
            var assignmentStatement = SyntaxFactory.ExpressionStatement(assignment);

            return(assignmentStatement);
        }
Beispiel #22
0
 private static IEnumerable <ReturnStatementSyntax> GetReturnNullStatements(BlockSyntax methodBlock)
 {
     return(methodBlock.DescendantNodes(n =>
                                        !n.IsAnyKind(SyntaxKindEx.LocalFunctionStatement,
                                                     SyntaxKind.SimpleLambdaExpression,
                                                     SyntaxKind.ParenthesizedLambdaExpression))
            .OfType <ReturnStatementSyntax>()
            .Where(returnStatement => returnStatement.Expression.RemoveParentheses().IsNullLiteral()));
 }
Beispiel #23
0
        public static void AnalyzeCatchClause(SyntaxNodeAnalysisContext context)
        {
            var catchClause = (CatchClauseSyntax)context.Node;

            BlockSyntax block = catchClause.Block;

            if (block == null)
            {
                return;
            }

            CatchDeclarationSyntax declaration = catchClause.Declaration;

            if (declaration == null)
            {
                return;
            }

            SemanticModel     semanticModel     = context.SemanticModel;
            CancellationToken cancellationToken = context.CancellationToken;

            ILocalSymbol symbol = semanticModel.GetDeclaredSymbol(declaration, cancellationToken);

            if (symbol?.IsErrorType() != false)
            {
                return;
            }

            //TODO: SyntaxWalker
            foreach (SyntaxNode node in block.DescendantNodes(descendIntoChildren: f => f.Kind() != SyntaxKind.CatchClause))
            {
                if (node.Kind() != SyntaxKind.ThrowStatement)
                {
                    continue;
                }

                var throwStatement          = (ThrowStatementSyntax)node;
                ExpressionSyntax expression = throwStatement.Expression;

                if (expression == null)
                {
                    continue;
                }

                ISymbol expressionSymbol = semanticModel.GetSymbol(expression, cancellationToken);

                if (!symbol.Equals(expressionSymbol))
                {
                    continue;
                }

                context.ReportDiagnostic(
                    DiagnosticDescriptors.RemoveOriginalExceptionFromThrowStatement,
                    expression);
            }
        }
Beispiel #24
0
        public int RecurseBlockStatementCount(BlockSyntax block)
        {
            int statements = block.Statements.Count;

            foreach (var childBlock in block.DescendantNodes().OfType <BlockSyntax>().ToList())
            {
                statements += RecurseBlockStatementCount(childBlock);
            }
            return(statements);
        }
Beispiel #25
0
        public static LocalDeclarationStatementSyntax GetDelarationOfVariable(BlockSyntax bodyBlock, string variableName)
        {
            var declarator = bodyBlock.DescendantNodes()
                             .OfType <VariableDeclaratorSyntax>()
                             .Where(x => x.Identifier.ToString() == variableName)
                             .Single();

            var declaration = declarator.Ancestors().OfType <LocalDeclarationStatementSyntax>().First();

            return(declaration);
        }
Beispiel #26
0
        private static ExpressionSyntax GetVariableAssignmentExpression(
            BlockSyntax block,
            string variableName)
        {
            var field = from assignmentExpression in block.DescendantNodes().OfType <AssignmentExpressionSyntax>()
                        where (assignmentExpression.Left as IdentifierNameSyntax) != null &&
                        ((IdentifierNameSyntax)assignmentExpression.Left).Identifier.ValueText == variableName
                        select assignmentExpression.Right;

            return(field.First());
        }
        static bool HasReturnContract(BlockSyntax bodyStatement, string returnType)
        {
            var rhsEnsures = SyntaxFactory.ParseStatement($"Contract.Ensures(Contract.Result<{returnType}>() != null);");
            var lhsEnsures = SyntaxFactory.ParseStatement($"Contract.Ensures(null != Contract.Result<{returnType}>());");

            foreach (var expression in bodyStatement.DescendantNodes().OfType <ExpressionStatementSyntax>())
            {
                var ies = expression.Expression as InvocationExpressionSyntax;
                if (ies == null)
                {
                    continue;
                }

                var access = ies.Expression as MemberAccessExpressionSyntax;
                if (access == null)
                {
                    continue;
                }

                if (!ValidateContractAccess(access, "Ensures", null))
                {
                    continue;
                }

                if (ies.ArgumentList.Arguments.Count != 1)
                {
                    continue;
                }

                var arg = ies.ArgumentList.Arguments[0].Expression as BinaryExpressionSyntax;
                if (arg == null || !arg.OperatorToken.IsKind(SyntaxKind.ExclamationEqualsToken))
                {
                    continue;
                }

                if (arg.Left.IsKind(SyntaxKind.NullLiteralExpression))
                {
                    ies = arg.Right as InvocationExpressionSyntax;
                }
                else if (arg.Right.IsKind(SyntaxKind.NullLiteralExpression))
                {
                    ies = arg.Left as InvocationExpressionSyntax;
                }
                access = ies?.Expression as MemberAccessExpressionSyntax;
                if (!ValidateContractAccess(access, "Result", returnType))
                {
                    continue;
                }
                return(true);
            }
            return(false);
        }
Beispiel #28
0
        private static HashSet <AwaitExpressionSyntax> CollectAwaitExpressions(BlockSyntax body, TextSpan span)
        {
            HashSet <AwaitExpressionSyntax> awaitExpressions = null;

            foreach (SyntaxNode node in body.DescendantNodes(span, f => !f.IsNestedMethod()))
            {
                if (node.IsKind(SyntaxKind.AwaitExpression))
                {
                    (awaitExpressions ?? (awaitExpressions = new HashSet <AwaitExpressionSyntax>())).Add((AwaitExpressionSyntax)node);
                }
            }

            return(awaitExpressions);
        }
Beispiel #29
0
 private static void Analyze(
     SyntaxNodeAnalysisContext context,
     BlockSyntax body,
     SyntaxToken asyncKeyword,
     HashSet <AwaitExpressionSyntax> awaitExpressions)
 {
     if (awaitExpressions != null &&
         !body
         .DescendantNodes(body.Span, f => !f.IsNestedMethod())
         .Any(f => f.IsKind(SyntaxKind.AwaitExpression) && !awaitExpressions.Contains((AwaitExpressionSyntax)f)))
     {
         ReportDiagnostic(context, asyncKeyword, awaitExpressions);
     }
 }
Beispiel #30
0
        private static bool ContainsOtherAwait(BlockSyntax body, SyntaxList <StatementSyntax> statements, StatementSyntax statement)
        {
            int index = statements.IndexOf(statement);

            if (index > 0)
            {
                TextSpan span = TextSpan.FromBounds(body.SpanStart, statements[index - 1].Span.End);

                return(body
                       .DescendantNodes(span, f => !f.IsNestedMethod())
                       .Any(f => f.IsKind(SyntaxKind.AwaitExpression)));
            }

            return(false);
        }
        static bool HasReturnContract(BlockSyntax bodyStatement, string returnType)
        {
            var workspace = new AdhocWorkspace();

            foreach (var expression in bodyStatement.DescendantNodes().OfType<ExpressionStatementSyntax>())
            {
                var formatted = Formatter.Format(expression, workspace).ToString();

                if (formatted == $"Contract.Ensures(Contract.Result<{returnType}>() != null);")
                    return true;

                if (formatted == $"Contract.Ensures(null != Contract.Result<{returnType}>());")
                    return true;
            }
            return false;
        }
        private BlockSyntax UpdateMethodBody(BlockSyntax blockSyntax, TypeSyntax returnTypeSyntax, ParameterListSyntax parameterListSyntax)
        {
            if (blockSyntax != null)
            {
                //var specialType = _typeTranslation.FirstOrDefault(tt => ExtractRoslynSymbol(tt.ActualType).ToDisplayString() == returnTypeSyntax.ToFullString().Replace("global::", ""));
                var specialType = _typeTranslation.FirstOrDefault(tt => PrettyTypeName(tt.ActualType) == returnTypeSyntax.ToFullString().Replace("global::", ""));

                if (specialType != null)
                {
                    blockSyntax = SyntaxFactory.Block(
                        blockSyntax.Statements.Select(s => s.IsKind(SyntaxKind.ReturnStatement) ?
                           WrapReturnStatement(s as ReturnStatementSyntax, specialType) :
                           s
                    ).ToArray());
                }

                var parameterIdentifierNodes = blockSyntax.DescendantNodes()
                    .OfType<IdentifierNameSyntax>()
                    .Where(i => parameterListSyntax.Parameters
                        .Any(p => p.Identifier.ToFullString() == i.ToFullString()));
                blockSyntax = blockSyntax.ReplaceNodes(parameterIdentifierNodes, (originalNode, rewrittenNode) => WrapForwardedIdentifier(rewrittenNode, parameterListSyntax));
            }

            return blockSyntax;
        }
        private bool IsAccessed(
            SemanticModel semanticModel,
            ISymbol outSymbol, 
            BlockSyntax enclosingBlockOfLocalStatement,
            LocalDeclarationStatementSyntax localStatement, 
            ArgumentSyntax argumentNode,
            CancellationToken cancellationToken)
        {
            var localStatementStart = localStatement.Span.Start;
            var argumentNodeStart = argumentNode.Span.Start;
            var variableName = outSymbol.Name;

            // Walk the block that the local is declared in looking for accesses.
            // We can ignore anything prior to the actual local declaration point,
            // and we only need to check up until we reach the out-argument.
            foreach (var descendentNode in enclosingBlockOfLocalStatement.DescendantNodes())
            {
                var descendentStart = descendentNode.Span.Start;
                if (descendentStart <= localStatementStart)
                {
                    // This node is before the local declaration.  Can ignore it entirely as it could
                    // not be an access to the local.
                    continue;
                }

                if (descendentStart >= argumentNodeStart)
                {
                    // We reached the out-var.  We can stop searching entirely.
                    break;
                }

                if (descendentNode.IsKind(SyntaxKind.IdentifierName))
                {
                    // See if this looks like an accessor to the local variable syntactically.
                    var identifierName = (IdentifierNameSyntax)descendentNode;
                    if (identifierName.Identifier.ValueText == variableName)
                    {
                        // Confirm that it is a access of the local.
                        var symbol = semanticModel.GetSymbolInfo(identifierName, cancellationToken).Symbol;
                        if (outSymbol.Equals(symbol))
                        {
                            // We definitely accessed the local before the out-argument.  We 
                            // can't inline this local.
                            return true;
                        }
                    }
                }
            }

            // No accesses detected
            return false;
        }
 private static bool IsIterationVariableWritten(SemanticModel semanticModel, BlockSyntax forBlock, List<ILocalSymbol> iterableSymbols)
 {
     var forDescendants = forBlock.DescendantNodes();
     var assignments = (from assignmentExpression in forDescendants.OfType<AssignmentExpressionSyntax>()
                        let assignmentLeftSymbol = semanticModel.GetSymbolInfo(assignmentExpression.Left).Symbol
                        where iterableSymbols.Any(i => i.Equals(assignmentLeftSymbol))
                        select assignmentExpression).ToList();
     if (assignments.Any()) return true;
     var refs = (from argument in forDescendants.OfType<ArgumentSyntax>()
                 where argument.RefOrOutKeyword != null
                 let argumentExpressionSymbol = semanticModel.GetSymbolInfo(argument.Expression).Symbol
                 where iterableSymbols.Any(i => i.Equals(argumentExpressionSymbol))
                 select argument).ToList();
     if (refs.Any()) return true;
     var postfixUnaries = (from postfixUnaryExpression in forDescendants.OfType<PostfixUnaryExpressionSyntax>()
                           let operandSymbol = semanticModel.GetSymbolInfo(postfixUnaryExpression.Operand).Symbol
                           where iterableSymbols.Any(i => i.Equals(operandSymbol))
                           select postfixUnaryExpression).ToList();
     if (postfixUnaries.Any()) return true;
     var prefixUnaries = (from postfixUnaryExpression in forDescendants.OfType<PrefixUnaryExpressionSyntax>()
                           let operandSymbol = semanticModel.GetSymbolInfo(postfixUnaryExpression.Operand).Symbol
                           where iterableSymbols.Any(i => i.Equals(operandSymbol))
                           select postfixUnaryExpression).ToList();
     if (prefixUnaries.Any()) return true;
     return false;
 }
        private static InvocationExpressionSyntax TryFindEndAPMCallSyntaxNode(BlockSyntax lambdaBlock, string methodNameBase)
        {
            // TODO: Check for correct signature, etc.
            // This can be done much smarter by e.g. using the BeginXxx method symbol, looking up the corresponding EndXxx symobl, and filtering on that.

            try
            {
                // TODO: Also considier IdentifierName EndXxx instances.
                var endXxxExpression = lambdaBlock.DescendantNodes()
                                                  .OfType<MemberAccessExpressionSyntax>()
                                                  .Where(node => NodeIsNotContainedInLambdaExpression(node, lambdaBlock))
                                                  .First(stmt => stmt.Name.ToString().Equals("End" + methodNameBase));

                return (InvocationExpressionSyntax)endXxxExpression.Parent;
            }
            catch (InvalidOperationException)
            {
                return null;
            }
        }
        static bool HasNotNullContract(SemanticModel semanticModel, IParameterSymbol parameterSymbol, BlockSyntax bodyStatement)
        {
            foreach (var expressions in bodyStatement.DescendantNodes().OfType<ExpressionStatementSyntax>())
            {
                var identifiers = expressions.DescendantNodes().OfType<IdentifierNameSyntax>();

                if (Enumerable.SequenceEqual(identifiers.Select(i => i.Identifier.Text), new List<string>() { "Contract", "Requires", parameterSymbol.Name }))
                {
                    return true;
                }
            }
            return false;
        }
Beispiel #37
0
            private void GetAnonymousTypeOrFuncSymbols(BlockSyntax body, SemanticModel model, List<ISymbol> list)
            {
                IEnumerable<ExpressionSyntax> exprs = body.DescendantNodes().OfType<SimpleLambdaExpressionSyntax>();
                IEnumerable<ExpressionSyntax> tmp = body.DescendantNodes().OfType<ParenthesizedLambdaExpressionSyntax>();
                exprs = exprs.Concat(tmp);
                tmp = body.DescendantNodes().OfType<AnonymousMethodExpressionSyntax>();
                exprs = exprs.Concat(tmp);

                tmp = body.DescendantNodes().OfType<AnonymousObjectCreationExpressionSyntax>();
                exprs = exprs.Concat(tmp);

                foreach (var expr in exprs)
                {
                    GetAnonymousExprSymbols(expr, model, list);
                }
            }
Beispiel #38
0
            private void GetLabelSymbols(BlockSyntax body, SemanticModel model, List<ISymbol> list)
            {
                var labels = body.DescendantNodes().OfType<LabeledStatementSyntax>();
                foreach (var n in labels)
                {
                    // Label: -> 'Label' is token
                    var sym = model.GetDeclaredSymbol(n);
                    list.Add(sym);
                }

                var swlabels = body.DescendantNodes().OfType<SwitchLabelSyntax>();
                foreach (var n in swlabels)
                {
                    // label value has NO symbol, Type is expr's type
                    // e.g. case "A": -> string type
                    // var info1 = model.GetTypeInfo(n.Value);
                    // var info2 = model.GetSymbolInfo(n.Value);
                    var sym = model.GetDeclaredSymbol(n);
                    list.Add(sym);
                }
            }