public void VisitBlock(BlockSyntax node) { var tokens = node.DescendantTokens().ToList(); var dictionary = ParseTokens(tokens, Operands.All); var dictionary2 = ParseTokens(tokens, Operators.All); var metrics = new HalsteadMetrics( numOperands: dictionary.Values.Sum(x => x.Count), numUniqueOperands: dictionary.Values.SelectMany(x => x).Distinct().Count(), numOperators: dictionary2.Values.Sum(x => x.Count), numUniqueOperators: dictionary2.Values.SelectMany(x => x).Distinct().Count()); _metrics = metrics; }
public override void VisitBlock(BlockSyntax node) { base.VisitBlock(node); IEnumerable <SyntaxToken> list = node.DescendantTokens(null, false).ToList <SyntaxToken>(); IDictionary <SyntaxKind, IList <string> > syntaxKinds = HalsteadAnalyzer.ParseTokens(list, HalsteadOperands.All); IDictionary <SyntaxKind, IList <string> > syntaxKinds1 = HalsteadAnalyzer.ParseTokens(list, HalsteadOperators.All); HalsteadMetrics halsteadMetric = new HalsteadMetrics() { NumOperands = syntaxKinds.Values.SelectMany <IList <string>, string>((IList <string> x) => x).Count <string>(), NumUniqueOperands = syntaxKinds.Values.SelectMany <IList <string>, string>((IList <string> x) => x).Distinct <string>().Count <string>(), NumOperators = syntaxKinds1.Values.SelectMany <IList <string>, string>((IList <string> x) => x).Count <string>(), NumUniqueOperators = syntaxKinds1.Values.SelectMany <IList <string>, string>((IList <string> x) => x).Distinct <string>().Count <string>() }; this.metrics = halsteadMetric; }
private bool WouldCauseDefiniteAssignmentErrors( SemanticModel semanticModel, VariableDeclaratorSyntax localDeclarator, BlockSyntax enclosingBlock, ISymbol outSymbol, CancellationToken cancellationToken) { // See if we have something like: // // int i = 0; // if (Foo() || Bar(out i)) // { // Console.WriteLine(i); // } // // In this case, inlining the 'i' would cause it to longer be definitely // assigned in the WriteLine invocation. if (localDeclarator.Initializer == null) { // Don't need to examine this unless the variable has an initializer. return false; } // Find all the current read-references to the local. var query = from t in enclosingBlock.DescendantTokens() where t.Kind() == SyntaxKind.IdentifierToken where t.ValueText == outSymbol.Name let id = t.Parent as IdentifierNameSyntax where id != null where !id.IsOnlyWrittenTo() let symbol = semanticModel.GetSymbolInfo(id).GetAnySymbol() where outSymbol.Equals(symbol) select id; var references = query.ToImmutableArray<SyntaxNode>(); var root = semanticModel.SyntaxTree.GetCompilationUnitRoot(cancellationToken); // Ensure we can track the references and the local variable as we make edits // to the tree. var rootWithTrackedNodes = root.TrackNodes(references.Concat(localDeclarator).Concat(enclosingBlock)); // Now, take the local variable and remove it's initializer. Then go to all // the locations where we read from it. If they're definitely assigned, then // that means the out-var did it's work and assigned the variable across all // paths. If it's not definitely assigned, then we can't inline this variable. var currentLocalDeclarator = rootWithTrackedNodes.GetCurrentNode(localDeclarator); var rootWithoutInitializer = rootWithTrackedNodes.ReplaceNode( currentLocalDeclarator, currentLocalDeclarator.WithInitializer(null)); // Fork the compilation so we can do this analysis. var newCompilation = semanticModel.Compilation.ReplaceSyntaxTree( root.SyntaxTree, rootWithoutInitializer.SyntaxTree); var newSemanticModel = newCompilation.GetSemanticModel(rootWithoutInitializer.SyntaxTree); // NOTE: there is no current compiler API to determine if a variable is definitely // assigned or not. So, for now, we just get diagnostics for this block and see if // we get any definite assigment errors where we have a reference to the symbol. If // so, then we don't offer the fix. var currentBlock = rootWithoutInitializer.GetCurrentNode(enclosingBlock); var diagnostics = newSemanticModel.GetDiagnostics(currentBlock.Span, cancellationToken); var diagnosticSpans = diagnostics.Where(d => d.Id == CS0165) .Select(d => d.Location.SourceSpan) .Distinct(); var newReferenceSpans = rootWithoutInitializer.GetCurrentNodes<SyntaxNode>(references) .Select(n => n.Span) .Distinct(); return diagnosticSpans.Intersect(newReferenceSpans).Any(); }
internal static void Run(SyntaxNodeAnalysisContext context, ExpressionSyntax token) { string id = token.ToFullString(); if (string.IsNullOrWhiteSpace(id)) { return; } BlockSyntax method = context.Node.FirstAncestorOrSelf <BlockSyntax>(); if (method == null) { return; } try { if (token.IsKind(SyntaxKind.InvocationExpression)) { var nodes = method.DescendantNodes(); string s = string.Empty; foreach (SyntaxNode n in nodes) { if (n.IsKind(SyntaxKind.ExpressionStatement) && id.Contains(n.GetFirstToken().Text) && n.ToFullString().Contains("Append(")) { string rm = n.GetFirstToken().Text + ".Append("; s += n.GetText().ToString().Replace(rm, "").Replace(@""")", "").Replace("\r\n", "").Replace(";", "") + " "; s = s.Replace(" \"", string.Empty); } } s = Helper.BuildSqlStringFromIdString(context, s); List <string> errorlist = SqlParser.Parse(s); string errorlistText = String.Join("\r\n", errorlist); var diagnostic2 = Diagnostic.Create(RuleParam, context.Node.GetLocation(), errorlistText); context.ReportDiagnostic(diagnostic2); return; } var t = method.DescendantTokens().Where <SyntaxToken>(tk => tk.ValueText != null && tk.IsKind(SyntaxKind.IdentifierToken) && tk.ValueText == id).First <SyntaxToken>(); if (string.IsNullOrWhiteSpace(t.ValueText)) { return; } string sql = t.GetNextToken().GetNextToken().Value.ToString(); if (string.IsNullOrWhiteSpace(sql)) { return; } List <string> errors = SqlParser.Parse(sql); if (errors.Count == 0) { var binaryExpressions = method.DescendantNodesAndSelf().OfType <BinaryExpressionSyntax>().First <BinaryExpressionSyntax>(); if (binaryExpressions != null) { BinaryExpressionDiagnostic.Run(context, binaryExpressions); return; } return; } string errorText = String.Join("\r\n", errors); var diagnostic = Diagnostic.Create(RuleParam, t.GetNextToken().GetNextToken().GetLocation(), errorText); context.ReportDiagnostic(diagnostic); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine("don't handle syntax yet: " + ex.Message); } }
public BlockSyntax AddVariablesToBlock(BlockSyntax block) { //block = block. int totalVariables = Variables.Count; int currentVariable = 0; //SyntaxToken insertAfter = block.GetFirstToken(); SyntaxNode insertNode = null; bool insertIsAfter = true; int insertSpanStart = 0; foreach (var variable in Variables.OrderBy(n => n.Key)) { currentVariable++; if (currentVariable < 3) { continue; } if (variable.Value.Static && variable.Value.Used == true) { if (variable.Value.Used == false) { Console.WriteLine(); } //SyntaxToken firstToken = block.DescendantTokens().Where(n => n.HasAnnotation(new SyntaxAnnotation("StaticVar", variable.Key.ToString()))).Single(); //find the static value object staticValue = GetCurrentValue(variable.Key); //SyntaxKind literalKind; //if (staticValue is string) //{ // staticValue = "\"" + (string)staticValue + "\""; //} //foreach (var node in block.DescendantNodes().OfType<LiteralExpressionSyntax>().Where(n => n.GetText().ToString() == staticValue.ToString())) //{ // Console.WriteLine(); // //insertAfter = node.DescendantNodes().Where(n => n.Kind() == SyntaxKind.SemicolonToken).First(); // break; //} //SyntaxNode fromNode = null; //if (insertAfterNode == null) //{ // fromNode = block; //} //else //{ // fromNode = insertAfterNode; //} //foreach (var token in block.DescendantTokens().Where(n => n.ValueText == staticValue.ToString()).Where(o => o.SpanStart > insertSpanStart).First()) //{ var tokens = block.DescendantTokens().Where(n => n.ValueText == staticValue.ToString() && n.SpanStart > insertSpanStart); if (tokens.Count() > 0) { var token = tokens.First(); SyntaxToken insertToken = FindNextSemi(token); if (insertToken.Kind() == SyntaxKind.SemicolonToken) { insertNode = insertToken.Parent; insertIsAfter = true; } else { if (insertToken.Parent.ChildNodes().Count() > 0) { insertNode = insertToken.Parent.ChildNodes().First(); insertIsAfter = false; } else { insertNode = insertToken.Parent; insertIsAfter = true; } } insertSpanStart = token.SpanStart; // break; //} } } else { //SyntaxTokenList newTokens = new SyntaxTokenList(); //newTokens = newTokens.Add(insertAfter); LocalDeclarationStatementSyntax localDeclarationStatementSyntax = GetVariableDeclaration(variable.Value); //newTokens.Add(variableToken.DescendantNodesAndTokensAndSelf); //block = block.ReplaceToken(insertAfter, insertAfter); //StatementSyntax statementSyntax = localDeclarationStatementSyntax as StatementSyntax; //var varNode = SyntaxFactory.("\"valid regex\""); //SyntaxAnnotation syntaxAnnotation = new SyntaxAnnotation("Variable", variable.Key.ToString()); BlockSyntax addBlock = SyntaxFactory.Block(localDeclarationStatementSyntax); //.WithAdditionalAnnotations(syntaxAnnotation); if (insertNode == null) { block = block.InsertNodesBefore(block.ChildNodes().First(), addBlock.ChildNodes()); } else { if (insertIsAfter) { block = block.InsertNodesAfter(insertNode, addBlock.ChildNodes()); } else { block = block.InsertNodesBefore(insertNode, addBlock.ChildNodes()); } } //insertAfterNode = block.DescendantNodes().OfType<LocalDeclarationStatementSyntax>().Where(n => n.HasAnnotation(syntaxAnnotation)).Single(); insertNode = block.DescendantNodes().OfType <LocalDeclarationStatementSyntax>().Last(); insertSpanStart = insertNode.SpanStart; insertIsAfter = true; } } return(block); }