@Override public void visitForEachStatement(ForEachStatement tree) { CFG cfg = CFG.buildCFG(Collections.singletonList(tree), true); Symbol var = tree.variable().symbol(); boolean liveVar = true; if(var.owner().isMethodSymbol()) { cfg.setMethodSymbol((Symbol.MethodSymbol) var.owner()); LiveVariables analyze = LiveVariables.analyze(cfg); Set<Symbol> live = analyze.getOut(cfg.reversedBlocks().get(1)); liveVar = live.contains(var); } if(!liveVar) { variables.add(var); } super.visitForEachStatement(tree); if(!liveVar) { variables.remove(var); } }
@Override public void visitForEachStatement(ForEachStatement tree) { CFG cfg = CFG.buildCFG(Collections.singletonList(tree), true); Symbol var = tree.variable().symbol(); boolean liveVar = true; if(var.owner().isMethodSymbol()) { cfg.setMethodSymbol((Symbol.MethodSymbol) var.owner()); LiveVariables analyze = LiveVariables.analyze(cfg); Set<Symbol> live = analyze.getOut(cfg.reversedBlocks().get(1)); liveVar = live.contains(var); } if(!liveVar) { variables.add(var); } super.visitForEachStatement(tree); if(!liveVar) { variables.remove(var); } }
@Override public void visitForEachStatement(ForEachStatement tree) { scan(tree.variable()); scan(tree.expression()); visitStatement(tree.statement()); }
@Override public void visitForEachStatement(ForEachStatement tree) { scan(tree.variable()); scan(tree.expression()); scan(tree.statement()); }
@Override public void visitForEachStatement(ForEachStatement tree) { scan(tree.variable()); scan(tree.expression()); scan(tree.statement()); }
@Override public void visitNode(Tree tree) { if (!hasSemantic()) { return; } ForEachStatement actualStatement = (ForEachStatement) tree; Type variableType = actualStatement.variable().type().symbolType(); Type collectionItemType = getCollectionItemType(actualStatement.expression()); if (collectionItemType != null && !isMostPreciseType(variableType, collectionItemType)) { // Second pass: check if the variable is down-cast in the statement block DownCastVisitor downCastVisitor = new DownCastVisitor(actualStatement.variable().symbol()); actualStatement.statement().accept(downCastVisitor); if (downCastVisitor.hasDownCastOfLoopVariable) { List<JavaFileScannerContext.Location> locations = Collections.singletonList( new JavaFileScannerContext.Location(String.format(SECONDARY_MESSAGE, collectionItemType.name()), actualStatement.expression())); reportIssue(actualStatement.variable().type(), String.format(PRIMARY_MESSAGE, variableType.name()), locations, 0); } } }
@Override public void visitForEachStatement(ForEachStatement tree) { scan(tree.variable()); scan(tree.expression()); scan(tree.statement()); }
@Override public void visitForEachStatement(ForEachStatement tree) { scan(tree.variable()); scan(tree.expression()); scan(tree.statement()); }
@Override public void visitNode(Tree tree) { if (!hasSemantic()) { return; } ForEachStatement actualStatement = (ForEachStatement) tree; Type variableType = actualStatement.variable().type().symbolType(); Type collectionItemType = getCollectionItemType(actualStatement.expression()); if (collectionItemType != null && !isMostPreciseType(variableType, collectionItemType)) { // Second pass: check if the variable is down-cast in the statement block DownCastVisitor downCastVisitor = new DownCastVisitor(actualStatement.variable().symbol()); actualStatement.statement().accept(downCastVisitor); if (downCastVisitor.hasDownCastOfLoopVariable) { List<JavaFileScannerContext.Location> locations = Collections.singletonList( new JavaFileScannerContext.Location(String.format(SECONDARY_MESSAGE, collectionItemType.name()), actualStatement.expression())); reportIssue(actualStatement.variable().type(), String.format(PRIMARY_MESSAGE, variableType.name()), locations, 0); } } }
@Override public void visitForEachStatement(ForEachStatement tree) { scan(tree.variable()); scan(tree.expression()); TypeTree typeTree = tree.variable().type(); if (typeTree.is(Tree.Kind.VAR_TYPE)) { JavaType iteratedObjectType = getIteratedObjectType((JavaType) tree.expression().symbolType()); setInferedType(upwardProjection(iteratedObjectType), (DeferredType) typeTree.symbolType()); } // scan the body only after handling type of variable scan(tree.statement()); }
private void buildForEachStatement(ForEachStatement tree) { // TODO(npe) One solution is to create a forstatement node depending on type of expression (iterable or array) and build CFG from it. Block afterLoop = currentBlock; Block statementBlock = createBlock(); Block loopback = createBranch(tree, statementBlock, afterLoop); currentBlock = createBlock(loopback); addContinueTarget(loopback); breakTargets.addLast(afterLoop); build(tree.statement()); breakTargets.removeLast(); continueTargets.removeLast(); statementBlock.addSuccessor(currentBlock); currentBlock = loopback; build(tree.variable()); currentBlock = createBlock(currentBlock); build(tree.expression()); currentBlock = createBlock(currentBlock); }
@Override public void visitForEachStatement(ForEachStatement tree) { scan(tree.variable()); scan(tree.expression()); TypeTree typeTree = tree.variable().type(); if (typeTree.is(Tree.Kind.VAR_TYPE)) { JavaType iteratedObjectType = getIteratedObjectType((JavaType) tree.expression().symbolType()); setInferedType(upwardProjection(iteratedObjectType), (DeferredType) typeTree.symbolType()); } // scan the body only after handling type of variable scan(tree.statement()); }
private void buildForEachStatement(ForEachStatement tree) { // TODO(npe) One solution is to create a forstatement node depending on type of expression (iterable or array) and build CFG from it. Block afterLoop = currentBlock; Block statementBlock = createBlock(); Block loopback = createBranch(tree, statementBlock, afterLoop); currentBlock = createBlock(loopback); addContinueTarget(loopback); breakTargets.addLast(afterLoop); build(tree.statement()); breakTargets.removeLast(); continueTargets.removeLast(); statementBlock.addSuccessor(currentBlock); currentBlock = loopback; build(tree.variable()); currentBlock = createBlock(currentBlock); build(tree.expression()); currentBlock = createBlock(currentBlock); }
private void buildForEachStatement(ForEachStatement tree) { // TODO(npe) One solution is to create a forstatement node depending on type of expression (iterable or array) and build CFG from it. Block afterLoop = currentBlock; Block statementBlock = createBlock(); Block loopback = createBranch(tree, statementBlock, afterLoop); currentBlock = createBlock(loopback); addContinueTarget(loopback); breakTargets.addLast(afterLoop); build(tree.statement()); breakTargets.removeLast(); continueTargets.removeLast(); statementBlock.addSuccessor(currentBlock); currentBlock = loopback; build(tree.variable()); currentBlock = createBlock(currentBlock); build(tree.expression()); currentBlock = createBlock(currentBlock); }
@Override public void visitNode(Tree tree) { if (hasSemantic()) { ForEachStatement forEachTree = (ForEachStatement) tree; ExpressionTree expressionTree = forEachTree.expression(); if (expressionTree.is(Tree.Kind.METHOD_INVOCATION)) { MethodInvocationTree methodTree = (MethodInvocationTree) expressionTree; Symbol ownerSymbol = getOwnerSymbol(methodTree); if (ownerSymbol != null && MAP_KEYSET_METHOD.matches(methodTree)) { new GetUsageVisitor().isCallingGetWithSymbol(forEachTree, forEachTree.variable().symbol(), ownerSymbol); } } } }
@Override public void visitNode(Tree tree) { if (hasSemantic()) { ForEachStatement forEachTree = (ForEachStatement) tree; ExpressionTree expressionTree = forEachTree.expression(); if (expressionTree.is(Tree.Kind.METHOD_INVOCATION)) { MethodInvocationTree methodTree = (MethodInvocationTree) expressionTree; Symbol ownerSymbol = getOwnerSymbol(methodTree); if (ownerSymbol != null && MAP_KEYSET_METHOD.matches(methodTree)) { new GetUsageVisitor().isCallingGetWithSymbol(forEachTree, forEachTree.variable().symbol(), ownerSymbol); } } } }
@Override public void leaveNode(Tree tree) { if (hasSemantic()) { if (tree.is(Tree.Kind.BLOCK, Tree.Kind.STATIC_INITIALIZER)) { BlockTree blockTree = (BlockTree) tree; addVariables(blockTree.body()); } else if (tree.is(Tree.Kind.FOR_STATEMENT)) { ForStatementTree forStatementTree = (ForStatementTree) tree; addVariables(forStatementTree.initializer()); } else if (tree.is(Tree.Kind.FOR_EACH_STATEMENT)) { ForEachStatement forEachStatement = (ForEachStatement) tree; addVariable(forEachStatement.variable()); } else if (tree.is(Tree.Kind.EXPRESSION_STATEMENT)) { leaveExpressionStatement((ExpressionStatementTree) tree); } else { checkVariableUsages(); variables.clear(); assignments.clear(); } } }
@Override public void leaveNode(Tree tree) { if (hasSemantic()) { if (tree.is(Tree.Kind.BLOCK, Tree.Kind.STATIC_INITIALIZER)) { BlockTree blockTree = (BlockTree) tree; addVariables(blockTree.body()); } else if (tree.is(Tree.Kind.FOR_STATEMENT)) { ForStatementTree forStatementTree = (ForStatementTree) tree; addVariables(forStatementTree.initializer()); } else if (tree.is(Tree.Kind.FOR_EACH_STATEMENT)) { ForEachStatement forEachStatement = (ForEachStatement) tree; addVariable(forEachStatement.variable()); } else if (tree.is(Tree.Kind.EXPRESSION_STATEMENT)) { leaveExpressionStatement((ExpressionStatementTree) tree); } else { checkVariableUsages(); variables.clear(); assignments.clear(); } } }
@Override public void leaveNode(Tree tree) { if (hasSemantic()) { if (tree.is(Tree.Kind.BLOCK, Tree.Kind.STATIC_INITIALIZER)) { BlockTree blockTree = (BlockTree) tree; addVariables(blockTree.body()); } else if (tree.is(Tree.Kind.FOR_STATEMENT)) { ForStatementTree forStatementTree = (ForStatementTree) tree; addVariables(forStatementTree.initializer()); } else if (tree.is(Tree.Kind.FOR_EACH_STATEMENT)) { ForEachStatement forEachStatement = (ForEachStatement) tree; addVariable(forEachStatement.variable()); } else if (tree.is(Tree.Kind.TRY_STATEMENT)) { TryStatementTree tryStatementTree = (TryStatementTree) tree; for (VariableTree resource : tryStatementTree.resources()) { addVariable(resource); } } else if (tree.is(Tree.Kind.EXPRESSION_STATEMENT)) { leaveExpressionStatement((ExpressionStatementTree) tree); } else if (tree.is(Tree.Kind.COMPILATION_UNIT)) { checkVariableUsages(); variables.clear(); assignments.clear(); } } }