@Test public void while_try_break_catch_finally() { ControlFlowGraph actualCfg = cfgForBlock("" + "while (cond(succ=[tryBody, after])) {" + " try {" + " tryBody(succ=[_empty], syntSucc=_empty);" + " break;" + " } catch (Exception $e) {" + " catchBody(succ = [finallyBody]);" + " } finally {" + " finallyBody(succ = [cond, END]);" + " }" + "}" + "after(succ=[END]);"); ExpectedCfgStructure expectedCfgStructure = ExpectedCfgStructure.parse(actualCfg.blocks(), expected -> { expected.createEmptyBlockExpectation() .withPredecessorIds("tryBody") .withSuccessorsIds("catchBody", "finallyBody"); return expected; }); new Validator(expectedCfgStructure).assertCfg(actualCfg); }
public Set<CfgBlock> blocks() { return blocks; }
ControlFlowGraph { public Set<CfgBlock> blocks() { return blocks; } }
ControlFlowGraph { public Set<CfgBlock> blocks() { return blocks; } ControlFlowGraph(ImmutableSet<CfgBlock> blocks, CfgBlock start, PhpCfgEndBlock end); }
ControlFlowGraph { public Set<CfgBlock> blocks() { return blocks; } ControlFlowGraph(ImmutableSet<CfgBlock> blocks, CfgBlock start, PhpCfgEndBlock end); @VisibleForTesting static ControlFlowGraph build(BlockTree body); @CheckForNull static ControlFlowGraph build(Tree tree, CheckContext context); CfgBlock start(); CfgBlock end(); Set<CfgBlock> blocks(); }
ControlFlowGraph { public Set<CfgBlock> blocks() { return blocks; } ControlFlowGraph(ImmutableSet<CfgBlock> blocks, CfgBlock start, PhpCfgEndBlock end); @VisibleForTesting static ControlFlowGraph build(BlockTree body); @CheckForNull static ControlFlowGraph build(Tree tree, CheckContext context); CfgBlock start(); CfgBlock end(); Set<CfgBlock> blocks(); static final Set<Tree.Kind> KINDS_WITH_CONTROL_FLOW; }