private void checkElements(CFG.Block block, Set<Symbol> blockOut, Symbol.MethodSymbol methodSymbol) { Set<Symbol> out = new HashSet<>(blockOut); Set<Tree> assignmentLHS = new HashSet<>(); Lists.reverse(block.elements()).forEach(element -> checkElement(methodSymbol, out, assignmentLHS, element)); }
private void checkElements(CFG.Block block, Set<Symbol> blockOut, Symbol.MethodSymbol methodSymbol) { Set<Symbol> out = new HashSet<>(blockOut); Set<Tree> assignmentLHS = new HashSet<>(); Lists.reverse(block.elements()).forEach(element -> checkElement(methodSymbol, out, assignmentLHS, element)); }
private static Block nonEmptySuccessor(Block initialBlock) { Block result = initialBlock; while (result.elements().isEmpty() && result.successors().size() == 1) { result = result.successors().iterator().next(); } return result; } }
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 static boolean hasPredecessorInBlock(CFG.Block block, Tree loop) { for (CFG.Block predecessor : block.predecessors()) { List<Tree> predecessorElements = predecessor.elements(); if (predecessorElements.isEmpty()) { return hasPredecessorInBlock(predecessor, loop); } else { Tree predecessorFirstElement = predecessorElements.get(0); if (isForStatementInitializer(predecessorFirstElement, loop)) { // skip 'for' loops initializers continue; } if (isForStatementUpdate(predecessorFirstElement, loop)) { // there is no way to reach the 'for' loop update return !predecessor.predecessors().isEmpty(); } if (isDescendant(predecessorFirstElement, loop)) { return true; } } } return false; }
private static boolean hasPredecessorInBlock(CFG.Block block, Tree loop) { for (CFG.Block predecessor : block.predecessors()) { List<Tree> predecessorElements = predecessor.elements(); if (predecessorElements.isEmpty()) { return hasPredecessorInBlock(predecessor, loop); } else { Tree predecessorFirstElement = predecessorElements.get(0); if (isForStatementInitializer(predecessorFirstElement, loop)) { // skip 'for' loops initializers continue; } if (isForStatementUpdate(predecessorFirstElement, loop)) { // there is no way to reach the 'for' loop update return !predecessor.predecessors().isEmpty(); } if (isDescendant(predecessorFirstElement, loop)) { return true; } } } return false; }
private void executePost() { this.transition = false; if (currentCheckerIndex < checks.size()) { explodedGraphWalker.programState = checks.get(currentCheckerIndex).checkPostStatement(this, syntaxNode); } else { CFG.Block block = (CFG.Block) explodedGraphWalker.programPosition.block; if (explodedGraphWalker.programPosition.i< block.elements().size()) { explodedGraphWalker.clearStack(block.elements().get(explodedGraphWalker.programPosition.i)); } explodedGraphWalker.enqueue( explodedGraphWalker.programPosition.next(), explodedGraphWalker.programState, explodedGraphWalker.node.exitPath, methodYield); return; } if (!transition) { addTransition(explodedGraphWalker.programState); } }
private void executePost() { this.transition = false; if (currentCheckerIndex < checks.size()) { explodedGraphWalker.programState = checks.get(currentCheckerIndex).checkPostStatement(this, syntaxNode); } else { if (explodedGraphWalker.programPosition.i< explodedGraphWalker.programPosition.block.elements().size()) { explodedGraphWalker.clearStack(explodedGraphWalker.programPosition.block.elements().get(explodedGraphWalker.programPosition.i)); } explodedGraphWalker.enqueue( new ExplodedGraph.ProgramPoint(explodedGraphWalker.programPosition.block, explodedGraphWalker.programPosition.i + 1), explodedGraphWalker.programState, explodedGraphWalker.node.exitPath); return; } if (!transition) { addTransition(explodedGraphWalker.programState); } }
private void executePost() { this.transition = false; if (currentCheckerIndex < checks.size()) { explodedGraphWalker.programState = checks.get(currentCheckerIndex).checkPostStatement(this, syntaxNode); } else { CFG.Block block = (CFG.Block) explodedGraphWalker.programPosition.block; if (explodedGraphWalker.programPosition.i< block.elements().size()) { explodedGraphWalker.clearStack(block.elements().get(explodedGraphWalker.programPosition.i)); } explodedGraphWalker.enqueue( explodedGraphWalker.programPosition.next(), explodedGraphWalker.programState, explodedGraphWalker.node.exitPath, methodYield); return; } if (!transition) { addTransition(explodedGraphWalker.programState); } }
private static boolean isCatchingUncheckedException(CFG.Block catchBlock) { Type caughtType = ((VariableTree) catchBlock.elements().get(0)).symbol().type(); return ExceptionUtils.isUncheckedException(caughtType); }
private boolean isMethodInvocationNode(ExplodedGraph.Node node) { // ProgramPoint#syntaxTree will not always return the correct tree, so we need to go to ProgramPoint#block directly ProgramPoint pp = node.programPoint; if (pp.i < pp.block.elements().size()) { Tree tree = ((CFG.Block) pp.block).elements().get(pp.i); return tree.is(Tree.Kind.METHOD_INVOCATION); } return false; }
private static boolean isCatchingUncheckedException(CFG.Block catchBlock) { Type caughtType = ((VariableTree) catchBlock.elements().get(0)).symbol().type(); return ExceptionUtils.isUncheckedException(caughtType); }
private static Block nonEmptySuccessor(Block initialBlock) { Block result = initialBlock; while (result.elements().isEmpty() && result.successors().size() == 1) { result = result.successors().iterator().next(); } return result; } }
@Override public String toString() { String tree = ""; if (block instanceof CFG.Block) { List<Tree> elements = ((CFG.Block) block).elements(); if (i < elements.size()) { tree = "" + elements.get(i).kind() + elements.get(i).firstToken().line(); } } return "B" + block.id() + "." + i + " " + tree; }
private static boolean isCaughtByBlock(@Nullable Type thrownType, CFG.Block catchBlock) { if (thrownType != null) { Type caughtType = ((VariableTree) catchBlock.elements().get(0)).symbol().type(); return thrownType.isSubtypeOf(caughtType) || caughtType.isSubtypeOf(thrownType); } return false; }
private static boolean isCaughtByBlock(@Nullable Type thrownType, CFG.Block catchBlock) { if (thrownType != null) { Type caughtType = ((VariableTree) catchBlock.elements().get(0)).symbol().type(); return thrownType.isSubtypeOf(caughtType) || caughtType.isSubtypeOf(thrownType); } return false; }
private boolean isMethodInvocationNode(ExplodedGraph.Node node) { // ProgramPoint#syntaxTree will not always return the correct tree, so we need to go to ProgramPoint#block directly ProgramPoint pp = node.programPoint; if (pp.i < pp.block.elements().size()) { Tree tree = ((CFG.Block) pp.block).elements().get(pp.i); return tree.is(Tree.Kind.METHOD_INVOCATION); } return false; }
@Override public String toString() { String tree = ""; if (block instanceof CFG.Block) { List<Tree> elements = ((CFG.Block) block).elements(); if (i < elements.size()) { tree = "" + elements.get(i).kind() + elements.get(i).firstToken().line(); } } return "B" + block.id() + "." + i + " " + tree; }