private static CFG.Block getLoopBlock(CFG cfg, Tree loopTree) { return cfg.blocks().stream() .filter(block -> loopTree.equals(block.terminator())) .findFirst() .orElseThrow(() -> new IllegalStateException("CFG necessarily contains the loop block.")); }
private static CFG.Block getLoopBlock(CFG cfg, Tree loopTree) { return cfg.blocks().stream() .filter(block -> loopTree.equals(block.terminator())) .findFirst() .orElseThrow(() -> new IllegalStateException("CFG necessarily contains the loop block.")); }
@Override public void visitNode(Tree tree) { MethodTree methodTree = (MethodTree) tree; if (methodTree.block() != null) { CFG cfg = CFG.build(methodTree); cfg.blocks().forEach(this::checkBlock); } }
@Override public void visitNode(Tree tree) { MethodTree methodTree = (MethodTree) tree; if (methodTree.block() != null) { CFG cfg = CFG.build(methodTree); cfg.blocks().forEach(this::checkBlock); } }
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; }
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 computeExecutableLines(List<? extends Tree> trees) { if(trees.isEmpty()) { return; } // rely on cfg to get every instructions and get most of the token. CFG cfg = CFG.buildCFG(trees); cfg.blocks() .stream() .flatMap(b->b.elements().stream()) .forEach( t -> { if (t.is(NEW_CLASS)) { NewClassTree newClassTree = (NewClassTree) t; new ExecutableLinesTokenVisitor().scanTree(newClassTree.identifier()); executableLines.add(newClassTree.newKeyword().line()); } else if (t.is(TRY_STATEMENT)) { // add last token of try statements executableLines.add(t.lastToken().line()); } else { executableLines.add(t.firstToken().line()); } } ); }
private void computeExecutableLines(List<? extends Tree> trees) { if(trees.isEmpty()) { return; } // rely on cfg to get every instructions and get most of the token. CFG cfg = CFG.buildCFG(trees); cfg.blocks() .stream() .flatMap(b->b.elements().stream()) .forEach( t -> { if (t.is(NEW_CLASS)) { NewClassTree newClassTree = (NewClassTree) t; new ExecutableLinesTokenVisitor().scanTree(newClassTree.identifier()); executableLines.add(newClassTree.newKeyword().line()); } else if (t.is(TRY_STATEMENT)) { // add last token of try statements executableLines.add(t.lastToken().line()); } else { executableLines.add(t.firstToken().line()); } } ); }
@Override public void visitNode(Tree tree) { if (!hasSemantic()) { return; } MethodTree methodTree = (MethodTree) tree; if (methodTree.block() == null) { return; } // TODO(npe) Exclude try statements with finally as CFG is incorrect for those and lead to false positive if (hasTryFinallyWithLocalVar(methodTree.block(), methodTree.symbol())) { return; } Symbol.MethodSymbol methodSymbol = methodTree.symbol(); CFG cfg = CFG.build(methodTree); LiveVariables liveVariables = LiveVariables.analyze(cfg); // Liveness analysis provides information only for block boundaries, so we should do analysis between elements within blocks for (CFG.Block block : cfg.blocks()) { checkElements(block, liveVariables.getOut(block), methodSymbol); } }
@Override public void visitNode(Tree tree) { if (!hasSemantic()) { return; } MethodTree methodTree = (MethodTree) tree; if (methodTree.block() == null) { return; } // TODO(npe) Exclude try statements with finally as CFG is incorrect for those and lead to false positive if (hasTryFinallyWithLocalVar(methodTree.block(), methodTree.symbol())) { return; } Symbol.MethodSymbol methodSymbol = methodTree.symbol(); CFG cfg = CFG.build(methodTree); LiveVariables liveVariables = LiveVariables.analyze(cfg); // Liveness analysis provides information only for block boundaries, so we should do analysis between elements within blocks for (CFG.Block block : cfg.blocks()) { checkElements(block, liveVariables.getOut(block), methodSymbol); } }