/// <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; }
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()); }
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 } }
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()); }
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()); }
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()); }
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()); }
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()); }
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()); }
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()); }
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()); }
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()); }
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); }
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()); }
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 } }
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()); }
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()); }
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()); }
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); } }
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()); }
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); }