private static void ReadCodeBlock(JavaCodeBlockParser blockParser, JavaGlobalInfo info) { string keyword; while((keyword = blockParser.ReadNextKeywordSkip()).Length > 0){ switch(keyword){ case "do": ReadCodeBlock((JavaCodeBlockParser)blockParser.ReadBlock('{', '}'), info); if (blockParser.ReadNextKeywordSkip() != "while"){ blockParser.RevertKeywordSkip(); // should not happen } ++info.Statements[FlowStatement.DoWhile]; break; case "while": ++info.Statements[FlowStatement.While]; break; case "for": JavaCodeBlockParser cycleDeclBlock = (JavaCodeBlockParser)blockParser.ReadBlock('(', ')'); ReadCodeBlock(cycleDeclBlock, info); JavaCodeParser cycleDeclParser = new JavaCodeParser(cycleDeclBlock.Contents); cycleDeclParser.ReadTypeOf(false); cycleDeclParser.SkipSpaces().ReadIdentifier(); ++info.Statements[cycleDeclParser.SkipSpaces().Char == ':' ? FlowStatement.EnhancedFor : FlowStatement.For]; break; case "switch": JavaCodeBlockParser switchBlock = (JavaCodeBlockParser)blockParser.ReadBlock('{', '}'); ReadCodeBlock(switchBlock, info); switchBlock.Reset(); string switchKeyword; int cases = 0; while((switchKeyword = switchBlock.ReadNextKeywordSkip()).Length > 0){ if (switchKeyword == "switch"){ switchBlock.SkipBlock('{', '}'); } else if (switchKeyword == "case"){ ++info.Statements[FlowStatement.SwitchCase]; ++cases; } else if (switchKeyword == "default"){ ++info.Statements[FlowStatement.SwitchDefault]; // TODO count as a case? } } if (cases < info.MinSwitchCases)info.MinSwitchCases = cases; if (cases > info.MaxSwitchCases)info.MaxSwitchCases = cases; ++info.Statements[FlowStatement.Switch]; break; case "try": bool isTryWithResources = blockParser.SkipSpaces().Char == '('; ReadCodeBlock((JavaCodeBlockParser)blockParser.ReadBlock('{', '}'), info); string tryKeyword; int catches = 0; while((tryKeyword = blockParser.ReadNextKeywordSkip()).Length > 0){ if (tryKeyword == "catch"){ ++info.Statements[FlowStatement.Catch]; ++catches; } else if (tryKeyword == "finally"){ ++info.Statements[FlowStatement.Finally]; if (isTryWithResources)++info.TryWithResourcesWithFinally; else ++info.TryCatchWithFinally; } else if (tryKeyword != "try"){ blockParser.RevertKeywordSkip(); break; } ReadCodeBlock((JavaCodeBlockParser)blockParser.ReadBlock('{', '}'), info); } if (catches < info.MinCatchBlocks)info.MinCatchBlocks = catches; if (catches > info.MaxCatchBlocks)info.MaxCatchBlocks = catches; ++info.Statements[isTryWithResources ? FlowStatement.TryWithResources : FlowStatement.TryCatch]; ++info.Statements[FlowStatement.Try]; break; case "if": ++info.Statements[FlowStatement.If]; break; case "else": ++info.Statements[FlowStatement.Else]; if (blockParser.ReadNextKeywordSkip() != "if"){ blockParser.RevertKeywordSkip(); } break; case "return": ++info.Statements[FlowStatement.Return]; break; case "continue": ++info.Statements[FlowStatement.Continue]; break; case "break": ++info.Statements[FlowStatement.Break]; break; } } }
private static void ReadCodeBlock(JavaCodeBlockParser blockParser, JavaGlobalInfo info) { string keyword; while ((keyword = blockParser.ReadNextKeywordSkip()).Length > 0) { switch (keyword) { case "do": ReadCodeBlock((JavaCodeBlockParser)blockParser.ReadBlock('{', '}'), info); if (blockParser.ReadNextKeywordSkip() != "while") { blockParser.RevertKeywordSkip(); // should not happen } ++info.Statements[FlowStatement.DoWhile]; break; case "while": ++info.Statements[FlowStatement.While]; break; case "for": JavaCodeBlockParser cycleDeclBlock = (JavaCodeBlockParser)blockParser.ReadBlock('(', ')'); ReadCodeBlock(cycleDeclBlock, info); JavaCodeParser cycleDeclParser = new JavaCodeParser(cycleDeclBlock.Contents); cycleDeclParser.ReadTypeOf(false); cycleDeclParser.SkipSpaces().ReadIdentifier(); ++info.Statements[cycleDeclParser.SkipSpaces().Char == ':' ? FlowStatement.EnhancedFor : FlowStatement.For]; break; case "switch": JavaCodeBlockParser switchBlock = (JavaCodeBlockParser)blockParser.ReadBlock('{', '}'); ReadCodeBlock(switchBlock, info); switchBlock.Reset(); string switchKeyword; int cases = 0; while ((switchKeyword = switchBlock.ReadNextKeywordSkip()).Length > 0) { if (switchKeyword == "switch") { switchBlock.SkipBlock('{', '}'); } else if (switchKeyword == "case") { ++info.Statements[FlowStatement.SwitchCase]; ++cases; } else if (switchKeyword == "default") { ++info.Statements[FlowStatement.SwitchDefault]; // TODO count as a case? } } if (cases < info.MinSwitchCases) { info.MinSwitchCases = cases; } if (cases > info.MaxSwitchCases) { info.MaxSwitchCases = cases; } ++info.Statements[FlowStatement.Switch]; break; case "try": bool isTryWithResources = blockParser.SkipSpaces().Char == '('; ReadCodeBlock((JavaCodeBlockParser)blockParser.ReadBlock('{', '}'), info); string tryKeyword; int catches = 0; while ((tryKeyword = blockParser.ReadNextKeywordSkip()).Length > 0) { if (tryKeyword == "catch") { ++info.Statements[FlowStatement.Catch]; ++catches; } else if (tryKeyword == "finally") { ++info.Statements[FlowStatement.Finally]; if (isTryWithResources) { ++info.TryWithResourcesWithFinally; } else { ++info.TryCatchWithFinally; } } else if (tryKeyword != "try") { blockParser.RevertKeywordSkip(); break; } ReadCodeBlock((JavaCodeBlockParser)blockParser.ReadBlock('{', '}'), info); } if (catches < info.MinCatchBlocks) { info.MinCatchBlocks = catches; } if (catches > info.MaxCatchBlocks) { info.MaxCatchBlocks = catches; } ++info.Statements[isTryWithResources ? FlowStatement.TryWithResources : FlowStatement.TryCatch]; ++info.Statements[FlowStatement.Try]; break; case "if": ++info.Statements[FlowStatement.If]; break; case "else": ++info.Statements[FlowStatement.Else]; if (blockParser.ReadNextKeywordSkip() != "if") { blockParser.RevertKeywordSkip(); } break; case "return": ++info.Statements[FlowStatement.Return]; break; case "continue": ++info.Statements[FlowStatement.Continue]; break; case "break": ++info.Statements[FlowStatement.Break]; break; } } }