Search in sources :

Example 1 with ASTForInit

use of net.sourceforge.pmd.lang.java.ast.ASTForInit in project pmd by pmd.

the class ForLoopCanBeForeachRule method visit.

@Override
public Object visit(ASTForStatement node, Object data) {
    final ASTForInit init = node.getFirstChildOfType(ASTForInit.class);
    final ASTForUpdate update = node.getFirstChildOfType(ASTForUpdate.class);
    final ASTExpression guardCondition = node.getFirstChildOfType(ASTExpression.class);
    if (init == null && update == null || guardCondition == null) {
        return data;
    }
    Entry<VariableNameDeclaration, List<NameOccurrence>> indexDecl = getIndexVarDeclaration(init, update);
    if (indexDecl == null) {
        return data;
    }
    List<NameOccurrence> occurrences = indexDecl.getValue();
    VariableNameDeclaration index = indexDecl.getKey();
    if (TypeHelper.isA(index, Iterator.class)) {
        Entry<VariableNameDeclaration, List<NameOccurrence>> iterableInfo = getIterableDeclOfIteratorLoop(index, node.getScope());
        if (iterableInfo != null && isReplaceableIteratorLoop(indexDecl, guardCondition, iterableInfo, node)) {
            addViolation(data, node);
        }
        return data;
    }
    if (occurrences == null || !"int".equals(index.getTypeImage()) || !indexStartsAtZero(index)) {
        return data;
    }
    String itName = index.getName();
    String iterableName = getIterableNameOrNullToAbort(guardCondition, itName);
    if (!isForUpdateSimpleEnough(update, itName) || iterableName == null) {
        return data;
    }
    Entry<VariableNameDeclaration, List<NameOccurrence>> iterableInfo = findDeclaration(iterableName, node.getScope());
    VariableNameDeclaration iterableDeclaration = iterableInfo == null ? null : iterableInfo.getKey();
    if (iterableDeclaration == null) {
        return data;
    }
    if (iterableDeclaration.isArray() && isReplaceableArrayLoop(node, occurrences, iterableDeclaration)) {
        addViolation(data, node);
    } else if (iterableDeclaration.getTypeImage() != null && iterableDeclaration.getTypeImage().matches("List|ArrayList|LinkedList") && isReplaceableListLoop(node, occurrences, iterableDeclaration)) {
        addViolation(data, node);
    }
    return data;
}
Also used : VariableNameDeclaration(net.sourceforge.pmd.lang.java.symboltable.VariableNameDeclaration) ASTForInit(net.sourceforge.pmd.lang.java.ast.ASTForInit) List(java.util.List) ASTForUpdate(net.sourceforge.pmd.lang.java.ast.ASTForUpdate) ASTExpression(net.sourceforge.pmd.lang.java.ast.ASTExpression) NameOccurrence(net.sourceforge.pmd.lang.symboltable.NameOccurrence)

Example 2 with ASTForInit

use of net.sourceforge.pmd.lang.java.ast.ASTForInit in project pmd by pmd.

the class ForLoopCanBeForeachRule method getIndexVarDeclaration.

/* Finds the declaration of the index variable and its occurrences, null to abort */
private Entry<VariableNameDeclaration, List<NameOccurrence>> getIndexVarDeclaration(ASTForInit init, ASTForUpdate update) {
    if (init == null) {
        return guessIndexVarFromUpdate(update);
    }
    ASTLocalVariableDeclaration decl = init.getFirstChildOfType(ASTLocalVariableDeclaration.class);
    if (decl == null) {
        return null;
    }
    int numDeclaredVars = decl.findChildrenOfType(ASTVariableDeclarator.class).size();
    if (numDeclaredVars > 1) {
        // will abort in the calling function
        return null;
    }
    Map<VariableNameDeclaration, List<NameOccurrence>> decls = init.getScope().getDeclarations(VariableNameDeclaration.class);
    Entry<VariableNameDeclaration, List<NameOccurrence>> indexVarAndOccurrences = null;
    for (Entry<VariableNameDeclaration, List<NameOccurrence>> e : decls.entrySet()) {
        ASTForInit declInit = e.getKey().getNode().getFirstParentOfType(ASTForInit.class);
        if (Objects.equals(declInit, init)) {
            indexVarAndOccurrences = e;
            break;
        }
    }
    return indexVarAndOccurrences;
}
Also used : VariableNameDeclaration(net.sourceforge.pmd.lang.java.symboltable.VariableNameDeclaration) ASTLocalVariableDeclaration(net.sourceforge.pmd.lang.java.ast.ASTLocalVariableDeclaration) ASTVariableDeclarator(net.sourceforge.pmd.lang.java.ast.ASTVariableDeclarator) ASTForInit(net.sourceforge.pmd.lang.java.ast.ASTForInit) List(java.util.List)

Example 3 with ASTForInit

use of net.sourceforge.pmd.lang.java.ast.ASTForInit in project pmd by pmd.

the class StatementAndBraceFinder method addForExpressionNode.

/*
     * The method handles the special "for" loop. It creates always an
     * expression node even if the loop looks like for(;;).
     */
private void addForExpressionNode(Node node, Structure dataFlow) {
    ASTForStatement parent = (ASTForStatement) node.jjtGetParent();
    boolean hasExpressionChild = false;
    boolean hasForInitNode = false;
    boolean hasForUpdateNode = false;
    for (int i = 0; i < parent.jjtGetNumChildren(); i++) {
        if (parent.jjtGetChild(i) instanceof ASTExpression) {
            hasExpressionChild = true;
        } else if (parent.jjtGetChild(i) instanceof ASTForUpdate) {
            hasForUpdateNode = true;
        } else if (parent.jjtGetChild(i) instanceof ASTForInit) {
            hasForInitNode = true;
        }
    }
    if (!hasExpressionChild) {
        if (node instanceof ASTForInit) {
            dataFlow.createNewNode(node);
            dataFlow.pushOnStack(NodeType.FOR_EXPR, dataFlow.getLast());
            tryToLog(NodeType.FOR_EXPR, node);
        } else if (node instanceof ASTForUpdate) {
            if (!hasForInitNode) {
                dataFlow.createNewNode(node);
                dataFlow.pushOnStack(NodeType.FOR_EXPR, dataFlow.getLast());
                tryToLog(NodeType.FOR_EXPR, node);
            }
        } else if (node instanceof ASTStatement) {
            if (!hasForInitNode && !hasForUpdateNode) {
                dataFlow.createNewNode(node);
                dataFlow.pushOnStack(NodeType.FOR_EXPR, dataFlow.getLast());
                tryToLog(NodeType.FOR_EXPR, node);
            }
        }
    }
}
Also used : ASTForInit(net.sourceforge.pmd.lang.java.ast.ASTForInit) ASTForStatement(net.sourceforge.pmd.lang.java.ast.ASTForStatement) ASTForUpdate(net.sourceforge.pmd.lang.java.ast.ASTForUpdate) ASTStatement(net.sourceforge.pmd.lang.java.ast.ASTStatement) ASTExpression(net.sourceforge.pmd.lang.java.ast.ASTExpression)

Example 4 with ASTForInit

use of net.sourceforge.pmd.lang.java.ast.ASTForInit in project pmd by pmd.

the class PrematureDeclarationRule method visit.

/**
 * @param node
 *            ASTLocalVariableDeclaration
 * @param data
 *            Object
 * @return Object
 * @see net.sourceforge.pmd.lang.java.ast.JavaParserVisitor#visit(ASTLocalVariableDeclaration,
 *      Object)
 */
public Object visit(ASTLocalVariableDeclaration node, Object data) {
    // is it part of a for-loop declaration?
    if (node.jjtGetParent() instanceof ASTForInit) {
        // yes, those don't count
        return visit((AbstractJavaNode) node, data);
    }
    String varName = varNameIn(node);
    AbstractJavaNode grandparent = (AbstractJavaNode) node.jjtGetParent().jjtGetParent();
    List<ASTBlockStatement> nextBlocks = blocksAfter(grandparent, node);
    for (ASTBlockStatement block : nextBlocks) {
        if (hasReferencesIn(block, varName) || isLambda(block)) {
            break;
        }
        if (hasExit(block)) {
            addViolation(data, node, varName);
            break;
        }
    }
    return visit((AbstractJavaNode) node, data);
}
Also used : AbstractJavaNode(net.sourceforge.pmd.lang.java.ast.AbstractJavaNode) ASTBlockStatement(net.sourceforge.pmd.lang.java.ast.ASTBlockStatement) ASTForInit(net.sourceforge.pmd.lang.java.ast.ASTForInit)

Aggregations

ASTForInit (net.sourceforge.pmd.lang.java.ast.ASTForInit)4 List (java.util.List)2 ASTExpression (net.sourceforge.pmd.lang.java.ast.ASTExpression)2 ASTForUpdate (net.sourceforge.pmd.lang.java.ast.ASTForUpdate)2 VariableNameDeclaration (net.sourceforge.pmd.lang.java.symboltable.VariableNameDeclaration)2 ASTBlockStatement (net.sourceforge.pmd.lang.java.ast.ASTBlockStatement)1 ASTForStatement (net.sourceforge.pmd.lang.java.ast.ASTForStatement)1 ASTLocalVariableDeclaration (net.sourceforge.pmd.lang.java.ast.ASTLocalVariableDeclaration)1 ASTStatement (net.sourceforge.pmd.lang.java.ast.ASTStatement)1 ASTVariableDeclarator (net.sourceforge.pmd.lang.java.ast.ASTVariableDeclarator)1 AbstractJavaNode (net.sourceforge.pmd.lang.java.ast.AbstractJavaNode)1 NameOccurrence (net.sourceforge.pmd.lang.symboltable.NameOccurrence)1