private static CFGLoop create(CFG.Block block, Map<Tree, CFGLoop> container) { CFGLoop loop = new CFGLoop(block); container.put(block.terminator(), loop); loop.initialize(block, container); return loop; } }
private void collectBlocks(CFG.Block block, Map<Tree, CFGLoop> container) { collectBlocks(block, container, new HashSet<CFG.Block>()); }
public static Map<Tree, CFGLoop> getCFGLoops(CFG cfg) { Map<Tree, CFGLoop> cfgLoops = new HashMap<>(); for (CFG.Block block : cfg.blocks()) { if (CFGLoop.isStarting(block)) { Tree terminator = block.terminator(); if (!cfgLoops.containsKey(terminator)) { create(block, cfgLoops); } } } return cfgLoops; }
private void collectWaysOut(Map<Tree, CFGLoop> container) { for (CFG.Block block : blocks) { if (isStarting(block)) { CFGLoop innerLoop = container.get(block.terminator()); successors.addAll(innerLoop.successors()); } else { successors.addAll(block.successors()); } } successors.removeAll(blocks); successors.remove(startingBlock); }
private void initialize(CFG.Block block, Map<Tree, CFGLoop> container) { Block loopFirstBlock = block.trueBlock(); if (loopFirstBlock == null) { // Special case where no condition is given in FOR loop: only one successor specified loopFirstBlock = block.successors().iterator().next(); } collectBlocks(loopFirstBlock, container); successors.addAll(block.successors()); successors.remove(block.falseBlock()); collectWaysOut(container); }
private boolean collectBlocks(CFG.Block block, Map<Tree, CFGLoop> container, Set<CFG.Block> visitedBlocks) { if (blocks.contains(block)) { return true; } if (block.id() == startingBlock.id() || !visitedBlocks.add(block)) { return false; } boolean answer = returnsToStart(block, container, visitedBlocks); if (answer || isBreak(block)) { blocks.add(block); } return answer; }
private boolean returnsToStart(CFG.Block block, Map<Tree, CFGLoop> container, Set<CFG.Block> visitedBlocks) { Set<Block> localSuccessors = localSuccessors(block, container); if (localSuccessors == null) { return true; } boolean answer = false; for (CFG.Block successor : localSuccessors) { if (startingBlock.id() == successor.id()) { answer = true; } else { answer |= collectBlocks(successor, container, visitedBlocks); } } return answer; }
private void checkLoopWithAlwaysTrueCondition(CheckerContext context, Tree statementParent) { CFGLoop loopBlocks = contexts.peek().getLoop(statementParent); if (loopBlocks != null && loopBlocks.hasNoWayOut()) { context.reportIssue(statementParent, NoWayOutLoopCheck.this, "Add an end condition to this loop."); } }
MethodContext(MethodTree tree, CFG cfg) { loopStarts = CFGLoop.getCFGLoops(cfg); threadRunMethod = THREAD_RUN_MATCHER.matches(tree); }
private void initialize(CFG.Block block, Map<Tree, CFGLoop> container) { Block loopFirstBlock = block.trueBlock(); if (loopFirstBlock == null) { // Special case where no condition is given in FOR loop: only one successor specified loopFirstBlock = block.successors().iterator().next(); } collectBlocks(loopFirstBlock, container); successors.addAll(block.successors()); successors.remove(block.falseBlock()); collectWaysOut(container); }
private void collectWaysOut(Map<Tree, CFGLoop> container) { for (CFG.Block block : blocks) { if (isStarting(block)) { CFGLoop innerLoop = container.get(block.terminator()); successors.addAll(innerLoop.successors()); } else { successors.addAll(block.successors()); } } successors.removeAll(blocks); successors.remove(startingBlock); }
private boolean collectBlocks(CFG.Block block, Map<Tree, CFGLoop> container, Set<CFG.Block> visitedBlocks) { if (blocks.contains(block)) { return true; } if (block.id() == startingBlock.id() || !visitedBlocks.add(block)) { return false; } boolean answer = returnsToStart(block, container, visitedBlocks); if (answer || isBreak(block)) { blocks.add(block); } return answer; }
private boolean returnsToStart(CFG.Block block, Map<Tree, CFGLoop> container, Set<CFG.Block> visitedBlocks) { Set<Block> localSuccessors = localSuccessors(block, container); if (localSuccessors == null) { return true; } boolean answer = false; for (CFG.Block successor : localSuccessors) { if (startingBlock.id() == successor.id()) { answer = true; } else { answer |= collectBlocks(successor, container, visitedBlocks); } } return answer; }
private void checkLoopWithAlwaysTrueCondition(CheckerContext context, Tree statementParent) { CFGLoop loopBlocks = contexts.peek().getLoop(statementParent); if (loopBlocks != null && loopBlocks.hasNoWayOut()) { context.reportIssue(statementParent, NoWayOutLoopCheck.this, "Add an end condition to this loop."); } }
MethodContext(MethodTree tree, CFG cfg) { loopStarts = CFGLoop.getCFGLoops(cfg); threadRunMethod = THREAD_RUN_MATCHER.matches(tree); }
public static Map<Tree, CFGLoop> getCFGLoops(CFG cfg) { Map<Tree, CFGLoop> cfgLoops = new HashMap<>(); for (CFG.Block block : cfg.blocks()) { if (CFGLoop.isStarting(block)) { Tree terminator = block.terminator(); if (!cfgLoops.containsKey(terminator)) { create(block, cfgLoops); } } } return cfgLoops; }
private static CFGLoop create(CFG.Block block, Map<Tree, CFGLoop> container) { CFGLoop loop = new CFGLoop(block); container.put(block.terminator(), loop); loop.initialize(block, container); return loop; } }
private void collectBlocks(CFG.Block block, Map<Tree, CFGLoop> container) { collectBlocks(block, container, new HashSet<CFG.Block>()); }
@CheckForNull private static Set<Block> localSuccessors(CFG.Block block, Map<Tree, CFGLoop> container) { if (isStarting(block)) { CFGLoop loop = container.get(block.terminator()); if (loop == null) { loop = create(block, container); } Set<Block> loopSuccessors = new HashSet<>(loop.successors); if (block.trueBlock() == null) { // Special case where no condition is given in FOR loop: only one successor specified return null; } else { loopSuccessors.add(block.falseBlock()); } return loopSuccessors; } return block.successors(); }
@CheckForNull private static Set<Block> localSuccessors(CFG.Block block, Map<Tree, CFGLoop> container) { if (isStarting(block)) { CFGLoop loop = container.get(block.terminator()); if (loop == null) { loop = create(block, container); } Set<Block> loopSuccessors = new HashSet<>(loop.successors); if (block.trueBlock() == null) { // Special case where no condition is given in FOR loop: only one successor specified return null; } else { loopSuccessors.add(block.falseBlock()); } return loopSuccessors; } return block.successors(); }