예제 #1
0
		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 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;
        }
예제 #3
0
        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);
            }
        }
예제 #6
0
        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);
        }