@Test void switch_expression_with_fallthrough() { final CFG cfg = buildCFG("int fun(int foo) throws Exception {\n" + " int a = switch (foo) {\n" + " case 1:\n" + " fun(bar);\n" + " case 2:\n" + " case 3:\n" + " case 4:\n" + " yield fun(bar1) + fun(bar2);\n" + " case 5:\n" + " throw new Exception(\"boom\");\n" + " case 6:\n" + " yield foo;\n" + " default:\n" + " yield fun(def);\n" + " };\n" + " return a;\n" + " }"); final CFGChecker cfgChecker = checker( block( element(Tree.Kind.CASE_GROUP), element(IDENTIFIER, "fun"), element(IDENTIFIER, "bar"), element(METHOD_INVOCATION)).hasCaseGroup().successors(6), block( element(Tree.Kind.CASE_GROUP), element(IDENTIFIER, "fun"), element(IDENTIFIER, "bar1"), element(METHOD_INVOCATION), element(IDENTIFIER, "fun"), element(IDENTIFIER, "bar2"), element(METHOD_INVOCATION), element(PLUS)).hasCaseGroup().terminator(YIELD_STATEMENT).successors(1), block( element(Tree.Kind.CASE_GROUP), element(STRING_LITERAL, "boom"), element(NEW_CLASS)).hasCaseGroup().terminator(THROW_STATEMENT).successors(0), block( element(Tree.Kind.CASE_GROUP), element(IDENTIFIER, "foo")).hasCaseGroup().successors(1), block( element(Tree.Kind.CASE_GROUP), element(IDENTIFIER, "fun"), element(IDENTIFIER, "def"), element(METHOD_INVOCATION)).hasCaseGroup().successors(1), block( element(IDENTIFIER, "foo"), element(Tree.Kind.INT_LITERAL, 1), element(Tree.Kind.INT_LITERAL, 2), element(Tree.Kind.INT_LITERAL, 3), element(Tree.Kind.INT_LITERAL, 4), element(Tree.Kind.INT_LITERAL, 5), element(Tree.Kind.INT_LITERAL, 6)).terminator(SWITCH_EXPRESSION).successors(3, 4, 5, 6, 7), block( element(VARIABLE, "a"), element(IDENTIFIER, "a")).terminator(RETURN_STATEMENT).successors(0)); cfgChecker.check(cfg); }
public static CFG buildCFG(List<? extends Tree> trees, boolean ignoreBreak) { return new CFG(trees, null, ignoreBreak); }
CFG implements ControlFlowGraph { public static CFG buildCFG(List<? extends Tree> trees, boolean ignoreBreak) { return new CFG(trees, null, ignoreBreak); } }
CFG implements ControlFlowGraph { public static CFG buildCFG(List<? extends Tree> trees, boolean ignoreBreak) { return new CFG(trees, null, ignoreBreak); } private  CFG(List<? extends Tree> trees, @Nullable Symbol.MethodSymbol symbol, boolean ignoreBreakAndContinue); }
CFG implements ControlFlowGraph { public static CFG buildCFG(List<? extends Tree> trees, boolean ignoreBreak) { return new CFG(trees, null, ignoreBreak); } private  CFG(List<? extends Tree> trees, @Nullable Symbol.MethodSymbol symbol, boolean ignoreBreakAndContinue); @Override Block exitBlock(); @Nullable Symbol.MethodSymbol methodSymbol(); @Override Block entryBlock(); @Override List<Block> blocks(); List<Block> reversedBlocks(); static CFG buildCFG(List<? extends Tree> trees, boolean ignoreBreak); static CFG buildCFG(List<? extends Tree> trees); static CFG build(MethodTree tree); void setMethodSymbol(Symbol.MethodSymbol methodSymbol); }
CFG implements ControlFlowGraph { public static CFG buildCFG(List<? extends Tree> trees, boolean ignoreBreak) { return new CFG(trees, null, ignoreBreak); } private  CFG(List<? extends Tree> trees, @Nullable Symbol.MethodSymbol symbol, boolean ignoreBreakAndContinue); @Override Block exitBlock(); @Nullable Symbol.MethodSymbol methodSymbol(); @Override Block entryBlock(); @Override List<Block> blocks(); List<Block> reversedBlocks(); static CFG buildCFG(List<? extends Tree> trees, boolean ignoreBreak); static CFG buildCFG(List<? extends Tree> trees); static CFG build(MethodTree tree); void setMethodSymbol(Symbol.MethodSymbol methodSymbol);  }