private IEnumerable <StatementSyntax> GetInnerStatements(StatementSyntax statement) { return(statement.DescendantNodesAndSelf() .OfType <StatementSyntax>() .Where(s => !IsExcludedFromCount(s))); bool IsExcludedFromCount(StatementSyntax s) { switch (s.Kind()) { // Blocks are excluded because they contain statements (duplicating the interesting part) case SyntaxKind.CatchBlock: case SyntaxKind.DoLoopUntilBlock: case SyntaxKind.DoLoopWhileBlock: case SyntaxKind.DoUntilLoopBlock: case SyntaxKind.DoWhileLoopBlock: case SyntaxKind.ElseBlock: case SyntaxKind.ElseIfBlock: case SyntaxKind.FinallyBlock: case SyntaxKind.ForBlock: case SyntaxKind.ForEachBlock: case SyntaxKind.MultiLineIfBlock: case SyntaxKind.SelectBlock: case SyntaxKind.SimpleDoLoopBlock: case SyntaxKind.SyncLockBlock: case SyntaxKind.TryBlock: case SyntaxKind.UsingBlock: case SyntaxKind.WhileBlock: case SyntaxKind.WithBlock: // Don't count End statements case SyntaxKind.EndIfStatement: case SyntaxKind.EndSelectStatement: case SyntaxKind.EndSyncLockStatement: case SyntaxKind.EndTryStatement: case SyntaxKind.EndUsingStatement: case SyntaxKind.EndWhileStatement: case SyntaxKind.EndWithStatement: // Don't count the Do from Do...While and Do...Until case SyntaxKind.SimpleDoStatement: // Don't count the Next from For...Next case SyntaxKind.NextStatement: // Don't count single line if statements // We will count the next statement on the line anyway // Example: // If foo Then bar = 2 case SyntaxKind.SingleLineIfStatement: return(true); default: return(false); } } }
private static ISet <ISymbol> GetReturnedSymbols(StatementSyntax usingStatement, SemanticModel semanticModel) { var enclosingSymbol = semanticModel.GetEnclosingSymbol(usingStatement.SpanStart); return(usingStatement.DescendantNodesAndSelf() .OfType <ReturnStatementSyntax>() .Where(ret => semanticModel.GetEnclosingSymbol(ret.SpanStart).Equals(enclosingSymbol)) .Select(ret => ret.Expression) .OfType <IdentifierNameSyntax>() .Select(identifier => semanticModel.GetSymbolInfo(identifier).Symbol) .WhereNotNull() .ToHashSet()); }
/// <summary> /// Analyzes the data-flow information in the statement. /// </summary> private void AnalyzeStatement(StatementSyntax statement, IDataFlowNode node) { var localDecl = statement?.DescendantNodesAndSelf(). OfType <LocalDeclarationStatementSyntax>().FirstOrDefault(); var expr = statement?.DescendantNodesAndSelf(). OfType <ExpressionStatementSyntax>().FirstOrDefault(); var ret = statement?.DescendantNodesAndSelf(). OfType <ReturnStatementSyntax>().FirstOrDefault(); if (localDecl != null) { var varDecl = (statement as LocalDeclarationStatementSyntax).Declaration; this.AnalyzeVariableDeclaration(varDecl, node); } else if (expr != null) { if (expr.Expression is AssignmentExpressionSyntax) { var assignment = expr.Expression as AssignmentExpressionSyntax; this.AnalyzeAssignmentExpression(assignment, node); } else if (expr.Expression is IdentifierNameSyntax || expr.Expression is MemberAccessExpressionSyntax) { this.AnalyzeBinaryExpression(expr.Expression, node); } else if (expr.Expression is InvocationExpressionSyntax || expr.Expression is ObjectCreationExpressionSyntax) { this.AnalyzeMethodCall(expr.Expression, node); } } else if (ret != null) { this.AnalyzeReturnStatement(ret, node); } }
private static bool ContainsPossibleUpdate(StatementSyntax statement, ExpressionSyntax expression, SemanticModel semanticModel) { var checkedSymbols = expression.DescendantNodesAndSelf() .Select(node => semanticModel.GetSymbolInfo(node).Symbol) .Where(symbol => symbol != null) .ToImmutableHashSet(); var statementDescendents = statement.DescendantNodesAndSelf().ToList(); var assignmentExpressions = statementDescendents .OfType <AssignmentExpressionSyntax>() .Any(expressionSyntax => { var symbol = semanticModel.GetSymbolInfo(expressionSyntax.Left).Symbol; return(symbol != null && checkedSymbols.Contains(symbol)); }); if (assignmentExpressions) { return(true); } var postfixUnaryExpression = statementDescendents .OfType <PostfixUnaryExpressionSyntax>() .Any(expressionSyntax => { var symbol = semanticModel.GetSymbolInfo(expressionSyntax.Operand).Symbol; return(symbol != null && checkedSymbols.Contains(symbol)); }); if (postfixUnaryExpression) { return(true); } var prefixUnaryExpression = statementDescendents .OfType <PrefixUnaryExpressionSyntax>() .Any(expressionSyntax => { var symbol = semanticModel.GetSymbolInfo(expressionSyntax.Operand).Symbol; return(symbol != null && checkedSymbols.Contains(symbol)); }); return(prefixUnaryExpression); }
private static ImmutableHashSet<ISymbol> GetReturnedSymbols(StatementSyntax usingStatement, SemanticModel semanticModel) { var enclosingSymbol = semanticModel.GetEnclosingSymbol(usingStatement.SpanStart); return usingStatement.DescendantNodesAndSelf() .OfType<ReturnStatementSyntax>() .Where(ret => semanticModel.GetEnclosingSymbol(ret.SpanStart).Equals(enclosingSymbol)) .Select(ret => ret.Expression) .OfType<IdentifierNameSyntax>() .Select(identifier => semanticModel.GetSymbolInfo(identifier).Symbol) .Where(symbol => symbol != null) .ToImmutableHashSet(); }
private IEnumerable <StatementSyntax> GetSubStatements(StatementSyntax statement) => statement.DescendantNodesAndSelf() .OfType <StatementSyntax>() .Where(s => !(s is BlockSyntax));