Beispiel #1
0
        /// <summary>
        /// Parse code containing a list of statements.
        /// </summary>
        public Block ParseBlock(string code, Block block)
        {
            var reader = new BlockParser(code);
            var analyzer = new BlockAnalyzer(block);
            foreach (CodeSegment sc in reader)
            {
                TokenStream t = TokenReader.Read(sc);

                LaxExpression s = analyzer.AnalyzeStatement(t);

                if (s == null)
                    continue;

                block.Statements.Add(s);
            }

            var unitEval = new TypeEvaluator(block);
            var constEval = new ConstEvaluater(block);

            foreach (var c in block.Constants.Values)
            {
                unitEval.Eval(c.Value);

                constEval.Eval(c);
            }

            foreach (var e in block.Statements)
            {
                unitEval.Eval(e);
            }

            return block;
        }
Beispiel #2
0
        public void ExpressionCountAndOr()
        {
            string code = "((x > 2) && (y>2) || (b))";

            LookAheadLangParser parser = LookAheadLangParser.CreateCppParser(TestUtil.GetTextStream(code));

            BlockAnalyzer analyzer = new BlockAnalyzer(parser);

            Assert.AreEqual(2, analyzer.CalcNumExpressionConditions());
        }
Beispiel #3
0
        public void EmptyStatement()
        {
            string code = "{ }";

            LookAheadLangParser parser = LookAheadLangParser.CreateCppParser(TestUtil.GetTextStream(code));

            BlockAnalyzer analyzer = new BlockAnalyzer(parser);

            Assert.AreEqual(0, analyzer.ConsumeBlockCalculateAdditionalComplexity()); // I'm not adding a CC value based on { and }
        }
Beispiel #4
0
        public void ReturnWithCreate()
        {
            string code = "{  " +
                          " return new ParentOCModifiedEventArgs(items) { IsCommitResult = contextInCommitStage }; " +
                          "}";

            LookAheadLangParser parser = LookAheadLangParser.CreateCppParser(TestUtil.GetTextStream(code));

            BlockAnalyzer analyzer = new BlockAnalyzer(parser);

            Assert.AreEqual(0, analyzer.ConsumeBlockCalculateAdditionalComplexity());
        }
Beispiel #5
0
        public void PragmasRemoved()
        {
            string code = "{             " +
                          "  #pragma warning (disable: 333) \r\n  " +
                          "  int j; \r\n " +
                          "  return j; \r\n " +
                          "}";

            LookAheadLangParser parser   = LookAheadLangParser.CreateCppParser(TestUtil.GetTextStream(code));
            BlockAnalyzer       analyzer = new BlockAnalyzer(parser);

            Assert.AreEqual(0, analyzer.ConsumeBlockCalculateAdditionalComplexity());
        }
Beispiel #6
0
        public void ExpressionCounterConsumes()
        {
            string code = "(x)\r\n" +
                          "more";

            LookAheadLangParser parser = LookAheadLangParser.CreateCppParser(TestUtil.GetTextStream(code));

            BlockAnalyzer analyzer = new BlockAnalyzer(parser);

            analyzer.CalcNumExpressionConditions();

            Assert.AreEqual("more", parser.NextKeyword());
        }
Beispiel #7
0
        public void ConditionalExpressionEmbeddedCalls()
        {
            string code = "" +
                          "(x != this.parser.PeekNext()) \r\n" +
                          "this.parser.NextKeyword()";

            LookAheadLangParser parser   = LookAheadLangParser.CreateCppParser(TestUtil.GetTextStream(code));
            BlockAnalyzer       analyzer = new BlockAnalyzer(parser);

            analyzer.CalcNumExpressionConditions();

            Assert.AreEqual("this.parser.NextKeyword", parser.NextKeyword());
        }
Beispiel #8
0
        public void StructInitializationAndAssignment()
        {
            string code = "" +
                          "{ \r\n" +
                          " RECT rect = { 0, 0, 0, 0 }; \r\n" +
                          " if (x) return; \r\n" +
                          "}";

            LookAheadLangParser parser = LookAheadLangParser.CreateCppParser(TestUtil.GetTextStream(code));

            BlockAnalyzer analyzer = new BlockAnalyzer(parser);

            Assert.AreEqual(1, analyzer.ConsumeBlockCalculateAdditionalComplexity());
        }
Beispiel #9
0
        public void CatchCountedAsPath()
        {
            string code = "{             " +
                          "  try { \r\n  " +
                          "  } " +
                          "  catch (const ex&){} " +
                          "}";

            LookAheadLangParser parser = LookAheadLangParser.CreateCppParser(TestUtil.GetTextStream(code));

            BlockAnalyzer analyzer = new BlockAnalyzer(parser);

            Assert.AreEqual(1, analyzer.ConsumeBlockCalculateAdditionalComplexity());
        }
Beispiel #10
0
        public void ConditionalBranchConsumesBranchOnly()
        {
            string code = "" +
                          "if (x > 2) \r\n" +
                          "{ y = x; } \r\n" +
                          "else";

            LookAheadLangParser parser = LookAheadLangParser.CreateCppParser(TestUtil.GetTextStream(code));

            BlockAnalyzer analyzer = new BlockAnalyzer(parser);

            analyzer.CalcCCOnConditionalBranch();

            Assert.AreEqual("else", parser.PeekNextKeyword());
        }
Beispiel #11
0
        public void SwitchStatementCalcsCases()
        {
            string code = "" +
                          "{ switch(x)   \r\n" +
                          " {           \r\n" +
                          "   case 1: return 2; \r\n" +
                          "   case 2: return 3; \r\n" +
                          " } } } \r\n";

            LookAheadLangParser parser = LookAheadLangParser.CreateCppParser(TestUtil.GetTextStream(code));

            BlockAnalyzer analyzer = new BlockAnalyzer(parser);

            Assert.AreEqual(2, analyzer.ConsumeBlockCalculateAdditionalComplexity());
        }
Beispiel #12
0
        public void TestCaseInsideSwitchNotCounted_WhenSwitchBehaviorIgnoreCases()
        {
            string code = "{             " +
                          "  switch(x)) {   " +
                          "     case 3: break; " +
                          "     case 4: break; " +
                          "     default: break; " +
                          "  } " +
                          "}";

            LookAheadLangParser parser   = LookAheadLangParser.CreateCppParser(TestUtil.GetTextStream(code));
            BlockAnalyzer       analyzer = new BlockAnalyzer(parser, null, null, ParserSwitchBehavior.IgnoreCases);

            Assert.AreEqual(0, analyzer.ConsumeBlockCalculateAdditionalComplexity());
        }
Beispiel #13
0
        private void Process()
        {
            var size     = 8192 * 4;
            var analyzer = new BlockAnalyzer(size, _rate);

            do
            {
                if (_block.ProcessAndShowBlockReadyness())
                {
                    var amp      = _block.GetBlock();
                    var analysis = analyzer.AnalyzeBlock(amp);
                    ResultReady(analysis);
                }
            } while (_work);
        }
Beispiel #14
0
        public void WhileWithoutScoping()
        {
            string code = "" +
                          "{           " +
                          "  while(true)\r\n" +
                          "    if (this.x.y)\r\n" +
                          "      return u;\r\n" +
                          "  return x;\r\n" +
                          "} ";

            LookAheadLangParser parser = LookAheadLangParser.CreateCppParser(TestUtil.GetTextStream(code));

            BlockAnalyzer analyzer = new BlockAnalyzer(parser);

            Assert.AreEqual(2, analyzer.ConsumeBlockCalculateAdditionalComplexity());
        }
Beispiel #15
0
        public void IfStatements()
        {
            string code = "" +
                          "{          \r\n" +
                          "if (x > 2) \r\n" +
                          "{ y = x; } \r\n" +
                          "else if (x > 3)\r\n" +
                          " y = 4; \r\n" +
                          "}";

            LookAheadLangParser parser = LookAheadLangParser.CreateCppParser(TestUtil.GetTextStream(code));

            BlockAnalyzer analyzer = new BlockAnalyzer(parser);

            Assert.AreEqual(2, analyzer.ConsumeBlockCalculateAdditionalComplexity()); // I'm not adding a CC value based on { and }
        }
Beispiel #16
0
        public void VariablesWithInitializationLists()
        {
            string code = "" +
                          "{           " +
                          "  this.x = new List<string>( new string[] { \"if\", \"while\" } ); \r\n" +
                          "  if (this.x.y) " +
                          "    return u; " +
                          "} more";

            LookAheadLangParser parser = LookAheadLangParser.CreateCppParser(TestUtil.GetTextStream(code));

            BlockAnalyzer analyzer = new BlockAnalyzer(parser);

            Assert.AreEqual(1, analyzer.ConsumeBlockCalculateAdditionalComplexity());
            Assert.AreEqual("more", parser.NextKeyword());
        }
Beispiel #17
0
        public void SwitchCaseWithEmbeddedConditionals()
        {
            string code = "" +
                          "{ switch(x)   \r\n" +
                          " {           \r\n" +
                          "   case 1: return 2; break;\r\n" +
                          "   case 2:          " +
                          "           if (x > u) return 3; \r\n" +
                          "           break;" +
                          " } } }\r\n";

            LookAheadLangParser parser = LookAheadLangParser.CreateCppParser(TestUtil.GetTextStream(code));

            BlockAnalyzer analyzer = new BlockAnalyzer(parser);

            Assert.AreEqual(3, analyzer.ConsumeBlockCalculateAdditionalComplexity());
        }
Beispiel #18
0
        public void AnalyzerConsumesNestedBlocks()
        {
            string code = "" +
                          "{              \r\n" +
                          "  { int x = 0; } \r\n" +
                          "}              \r\n" +
                          "{}";

            LookAheadLangParser parser = LookAheadLangParser.CreateCppParser(TestUtil.GetTextStream(code));

            BlockAnalyzer analyzer = new BlockAnalyzer(parser);

            analyzer.ConsumeBlockCalculateAdditionalComplexity();

            Assert.AreEqual("{", parser.NextKeyword());
            Assert.AreEqual("}", parser.NextKeyword());
        }
Beispiel #19
0
        public void TestBranchInCaseIncludedButNotCaseStatements_WhenSwitchBehaviorIgnoreCases()
        {
            // with ParserSwitchBehavior.IgnoreCases we ignore switch cases and just include branches inside of case statements

            string code = "{             " +
                          "  switch(x)) {   " +
                          "     case 3: if (a) { // do something } ; " +
                          "     case 4: break; " +
                          "     default: break; " +
                          "  } " +
                          "}";

            LookAheadLangParser parser   = LookAheadLangParser.CreateCppParser(TestUtil.GetTextStream(code));
            BlockAnalyzer       analyzer = new BlockAnalyzer(parser, null, null, ParserSwitchBehavior.IgnoreCases);

            Assert.AreEqual(1, analyzer.ConsumeBlockCalculateAdditionalComplexity());
        }
                public static void Analyze(OperationBlockStartAnalysisContext context, SymbolStartAnalyzer symbolStartAnalyzer)
                {
                    if (HasSyntaxErrors() || context.OperationBlocks.IsEmpty)
                    {
                        return;
                    }

                    // All operation blocks for a symbol belong to the same tree.
                    var firstBlock = context.OperationBlocks[0];

                    if (!symbolStartAnalyzer._compilationAnalyzer.TryGetOptions(firstBlock.Syntax.SyntaxTree,
                                                                                firstBlock.Language,
                                                                                context.Options,
                                                                                context.CancellationToken,
                                                                                out var options))
                    {
                        return;
                    }

                    var blockAnalyzer = new BlockAnalyzer(symbolStartAnalyzer, options);

                    context.RegisterOperationAction(blockAnalyzer.AnalyzeExpressionStatement, OperationKind.ExpressionStatement);
                    context.RegisterOperationAction(blockAnalyzer.AnalyzeDelegateCreationOrAnonymousFunction, OperationKind.DelegateCreation, OperationKind.AnonymousFunction);
                    context.RegisterOperationAction(blockAnalyzer.AnalyzeArgument, OperationKind.Argument);
                    context.RegisterOperationAction(blockAnalyzer.AnalyzeConversion, OperationKind.Conversion);
                    context.RegisterOperationAction(blockAnalyzer.AnalyzeFieldOrPropertyReference, OperationKind.FieldReference, OperationKind.PropertyReference);
                    context.RegisterOperationAction(blockAnalyzer.AnalyzeParameterReference, OperationKind.ParameterReference);
                    context.RegisterOperationBlockEndAction(blockAnalyzer.AnalyzeOperationBlockEnd);

                    return;

                    // Local Functions.
                    bool HasSyntaxErrors()
                    {
                        foreach (var operationBlock in context.OperationBlocks)
                        {
                            if (operationBlock.Syntax.GetDiagnostics().ToImmutableArrayOrEmpty().HasAnyErrors())
                            {
                                return(true);
                            }
                        }

                        return(false);
                    }
                }
Beispiel #21
0
        public void SwitchEmbeddedIntoWhile()
        {
            string code = "{             " +
                          " while (true) {   " +
                          "  switch(x)) {   " +
                          "     case 3: break; " +
                          "     case 4: break; " +
                          "     default: break; " +
                          "  } " +
                          " }" +
                          "}";

            LookAheadLangParser parser = LookAheadLangParser.CreateCppParser(TestUtil.GetTextStream(code));

            BlockAnalyzer analyzer = new BlockAnalyzer(parser);

            Assert.AreEqual(3, analyzer.ConsumeBlockCalculateAdditionalComplexity());
        }
Beispiel #22
0
        public void CodeInCatchCounted()
        {
            string code = "{             " +
                          "  try {       " +
                          "    int* p = 0 " +
                          "    *p = 2; " +
                          "  } " +
                          "  catch (const ex&) " +
                          "  {  " +
                          "     if (x > y) x++ " +
                          "  } " +
                          "}";

            LookAheadLangParser parser = LookAheadLangParser.CreateCppParser(TestUtil.GetTextStream(code));

            BlockAnalyzer analyzer = new BlockAnalyzer(parser);

            Assert.AreEqual(2, analyzer.ConsumeBlockCalculateAdditionalComplexity());
        }
 private void OnOperationBlock(OperationBlockStartAnalysisContext context)
 {
     context.RegisterOperationAction(OnMethodReference, OperationKind.MethodReference);
     BlockAnalyzer.Analyze(context, this);
 }
                public static void Analyze(OperationBlockStartAnalysisContext context, SymbolStartAnalyzer symbolStartAnalyzer)
                {
                    if (HasSyntaxErrors() || context.OperationBlocks.IsEmpty)
                    {
                        return;
                    }

                    // Bail out in presence of conditional directives
                    // This is a workaround for https://github.com/dotnet/roslyn/issues/31820
                    // Issue https://github.com/dotnet/roslyn/issues/31821 tracks
                    // reverting this workaround.
                    if (HasConditionalDirectives())
                    {
                        return;
                    }

                    // All operation blocks for a symbol belong to the same tree.
                    var firstBlock = context.OperationBlocks[0];

                    if (!symbolStartAnalyzer._compilationAnalyzer.TryGetOptions(firstBlock.Syntax.SyntaxTree,
                                                                                firstBlock.Language,
                                                                                context.Options,
                                                                                context.CancellationToken,
                                                                                out var options))
                    {
                        return;
                    }

                    var blockAnalyzer = new BlockAnalyzer(symbolStartAnalyzer, options);

                    context.RegisterOperationAction(blockAnalyzer.AnalyzeExpressionStatement, OperationKind.ExpressionStatement);
                    context.RegisterOperationAction(blockAnalyzer.AnalyzeDelegateCreationOrAnonymousFunction, OperationKind.DelegateCreation, OperationKind.AnonymousFunction);
                    context.RegisterOperationAction(blockAnalyzer.AnalyzeLocalOrParameterReference, OperationKind.LocalReference, OperationKind.ParameterReference);
                    context.RegisterOperationAction(_ => blockAnalyzer._hasInvalidOperation = true, OperationKind.Invalid);
                    context.RegisterOperationBlockEndAction(blockAnalyzer.AnalyzeOperationBlockEnd);

                    return;

                    // Local Functions.
                    bool HasSyntaxErrors()
                    {
                        foreach (var operationBlock in context.OperationBlocks)
                        {
                            if (operationBlock.Syntax.GetDiagnostics().ToImmutableArrayOrEmpty().HasAnyErrors())
                            {
                                return(true);
                            }
                        }

                        return(false);
                    }

                    bool HasConditionalDirectives()
                    {
                        foreach (var operationBlock in context.OperationBlocks)
                        {
                            if (operationBlock.Syntax.DescendantNodes(descendIntoTrivia: true)
                                .Any(n => symbolStartAnalyzer._compilationAnalyzer.IsIfConditionalDirective(n)))
                            {
                                return(true);
                            }
                        }

                        return(false);
                    }
                }
                public static void Analyze(OperationBlockStartAnalysisContext context, SymbolStartAnalyzer symbolStartAnalyzer)
                {
                    if (HasSyntaxErrors() || context.OperationBlocks.IsEmpty)
                    {
                        return;
                    }

                    // Bail out in presence of conditional directives
                    // This is a workaround for https://github.com/dotnet/roslyn/issues/31820
                    // Issue https://github.com/dotnet/roslyn/issues/31821 tracks
                    // reverting this workaround.
                    if (HasConditionalDirectives())
                    {
                        return;
                    }

                    // All operation blocks for a symbol belong to the same tree.
                    var firstBlock = context.OperationBlocks[0];

                    if (!symbolStartAnalyzer._compilationAnalyzer.TryGetOptions(firstBlock.Syntax.SyntaxTree,
                                                                                context.Options,
                                                                                out var options))
                    {
                        return;
                    }

                    // Ignore methods that are just a single-throw method.  These are often
                    // in-progress pieces of work and we don't want to force the user to fixup other
                    // issues before they've even gotten around to writing their code.
                    if (IsSingleThrowNotImplementedOperation(firstBlock))
                    {
                        return;
                    }

                    var blockAnalyzer = new BlockAnalyzer(symbolStartAnalyzer, options);

                    context.RegisterOperationAction(blockAnalyzer.AnalyzeExpressionStatement, OperationKind.ExpressionStatement);
                    context.RegisterOperationAction(blockAnalyzer.AnalyzeDelegateCreationOrAnonymousFunction, OperationKind.DelegateCreation, OperationKind.AnonymousFunction);
                    context.RegisterOperationAction(blockAnalyzer.AnalyzeLocalOrParameterReference, OperationKind.LocalReference, OperationKind.ParameterReference);
                    context.RegisterOperationAction(_ => blockAnalyzer._hasInvalidOperation = true, OperationKind.Invalid);
                    context.RegisterOperationBlockEndAction(blockAnalyzer.AnalyzeOperationBlockEnd);

                    return;

                    // Local Functions.
                    bool HasSyntaxErrors()
                    {
                        foreach (var operationBlock in context.OperationBlocks)
                        {
                            if (operationBlock.Syntax.GetDiagnostics().ToImmutableArrayOrEmpty().HasAnyErrors())
                            {
                                return(true);
                            }
                        }

                        return(false);
                    }

                    bool HasConditionalDirectives()
                    {
                        foreach (var operationBlock in context.OperationBlocks)
                        {
                            if (operationBlock.Syntax.DescendantNodes(descendIntoTrivia: true)
                                .Any(n => symbolStartAnalyzer._compilationAnalyzer.IsIfConditionalDirective(n)))
                            {
                                return(true);
                            }
                        }

                        return(false);
                    }