@Test public void try_return_catch_finally() { ControlFlowGraph actualCfg = cfgForBlock("" + "try {" + " tryBody(succ = [_empty], syntSucc = _empty);" + " return;" + "} catch (Exception $e) {" + " catchBody1(succ=[finallyBody], pred = [_empty]);" + "} catch (Exception $e) {" + " catchBody2(succ=[finallyBody], pred = [_empty]);" + "} finally {" + " finallyBody(succ=[after,END], pred = [catchBody1,catchBody2,_empty]);" + "}" + "after(succ = [END], pred = [finallyBody]);"); ExpectedCfgStructure expectedCfgStructure = ExpectedCfgStructure.parse(actualCfg.blocks(), expected -> { expected.createEmptyBlockExpectation() .withPredecessorIds("tryBody") .withSuccessorsIds("catchBody1", "catchBody2", "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; }