CfgUtils { public static Set<CfgBlock> unreachableBlocks(ControlFlowGraph cfg) { Set<CfgBlock> reachableBlocks = new HashSet<>(); Deque<CfgBlock> workList = new ArrayDeque<>(); workList.push(cfg.start()); while (!workList.isEmpty()) { CfgBlock currentBlock = workList.pop(); if (reachableBlocks.add(currentBlock)) { currentBlock.successors().forEach(workList::push); } } return difference(cfg.blocks(), reachableBlocks); } private  CfgUtils(); static Set<CfgBlock> unreachableBlocks(ControlFlowGraph cfg);  }
@Test public void unreachableBlocks_empty() { ControlFlowGraph cfg = cfg( "x = 10" ); assertThat(CfgUtils.unreachableBlocks(cfg)).isEmpty(); }
@Test public void unreachableBlocks_one() { ControlFlowGraph cfg = cfg( "x = 10", "return", "y = 42" ); assertThat(CfgUtils.unreachableBlocks(cfg)).containsExactlyInAnyOrder(cfg.start().syntacticSuccessor()); }
@Test public void unreachableBlocks_conditional() { ControlFlowGraph cfg = cfg( "x = 10", "return", "if x > 9:", " print(x)", "y = 42" ); Set<CfgBlock> unreachableBlocks = new HashSet<>(); CfgBlock syntacticSuccessor = cfg.start().syntacticSuccessor(); unreachableBlocks.add(syntacticSuccessor); unreachableBlocks.addAll(syntacticSuccessor.successors()); assertThat(CfgUtils.unreachableBlocks(cfg)).isEqualTo(unreachableBlocks); }