Search in sources :

Example 11 with NameOccurrence

use of net.sourceforge.pmd.lang.symboltable.NameOccurrence in project pmd by pmd.

the class ForLoopCanBeForeachRule method isReplaceableIteratorLoop.

private boolean isReplaceableIteratorLoop(Entry<VariableNameDeclaration, List<NameOccurrence>> indexInfo, ASTExpression guardCondition, Entry<VariableNameDeclaration, List<NameOccurrence>> iterableInfo, ASTForStatement stmt) {
    if (isIterableModifiedInsideLoop(iterableInfo, stmt)) {
        return false;
    }
    String indexName = indexInfo.getKey().getName();
    if (indexName == null) {
        return false;
    }
    if (!guardCondition.hasDescendantMatchingXPath("./PrimaryExpression/PrimaryPrefix/Name[@Image='" + indexName + ".hasNext']")) {
        return false;
    }
    List<NameOccurrence> occurrences = indexInfo.getValue();
    if (occurrences.size() > 2) {
        return false;
    }
    for (NameOccurrence occ : indexInfo.getValue()) {
        ScopedNode location = occ.getLocation();
        boolean isCallingNext = location instanceof ASTName && (location.hasImageEqualTo(indexName + ".hasNext") || location.hasImageEqualTo(indexName + ".next"));
        if (!isCallingNext) {
            return false;
        }
    }
    return true;
}
Also used : ScopedNode(net.sourceforge.pmd.lang.symboltable.ScopedNode) ASTName(net.sourceforge.pmd.lang.java.ast.ASTName) NameOccurrence(net.sourceforge.pmd.lang.symboltable.NameOccurrence)

Example 12 with NameOccurrence

use of net.sourceforge.pmd.lang.symboltable.NameOccurrence in project pmd by pmd.

the class UnusedPrivateMethodRule method calledFromOutsideItself.

private boolean calledFromOutsideItself(List<NameOccurrence> occs, NameDeclaration mnd) {
    int callsFromOutsideMethod = 0;
    for (NameOccurrence occ : occs) {
        Node occNode = occ.getLocation();
        ASTConstructorDeclaration enclosingConstructor = occNode.getFirstParentOfType(ASTConstructorDeclaration.class);
        if (enclosingConstructor != null) {
            callsFromOutsideMethod++;
            // Do we miss unused private constructors here?
            break;
        }
        ASTInitializer enclosingInitializer = occNode.getFirstParentOfType(ASTInitializer.class);
        if (enclosingInitializer != null) {
            callsFromOutsideMethod++;
            break;
        }
        ASTMethodDeclaration enclosingMethod = occNode.getFirstParentOfType(ASTMethodDeclaration.class);
        if (enclosingMethod == null || !mnd.getNode().jjtGetParent().equals(enclosingMethod)) {
            callsFromOutsideMethod++;
        }
    }
    return callsFromOutsideMethod == 0;
}
Also used : ASTConstructorDeclaration(net.sourceforge.pmd.lang.java.ast.ASTConstructorDeclaration) ASTMethodDeclaration(net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration) Node(net.sourceforge.pmd.lang.ast.Node) AccessNode(net.sourceforge.pmd.lang.java.ast.AccessNode) ASTInitializer(net.sourceforge.pmd.lang.java.ast.ASTInitializer) NameOccurrence(net.sourceforge.pmd.lang.symboltable.NameOccurrence)

Example 13 with NameOccurrence

use of net.sourceforge.pmd.lang.symboltable.NameOccurrence in project pmd by pmd.

the class UnnecessaryLocalBeforeReturnRule method visit.

@Override
public Object visit(ASTReturnStatement rtn, Object data) {
    // skip returns of literals
    ASTName name = rtn.getFirstDescendantOfType(ASTName.class);
    if (name == null) {
        return data;
    }
    // skip 'complicated' expressions
    if (rtn.findDescendantsOfType(ASTExpression.class).size() > 1 || rtn.findDescendantsOfType(ASTPrimaryExpression.class).size() > 1 || isMethodCall(rtn)) {
        return data;
    }
    Map<VariableNameDeclaration, List<NameOccurrence>> vars = name.getScope().getDeclarations(VariableNameDeclaration.class);
    for (Map.Entry<VariableNameDeclaration, List<NameOccurrence>> entry : vars.entrySet()) {
        VariableNameDeclaration variableDeclaration = entry.getKey();
        List<NameOccurrence> usages = entry.getValue();
        if (usages.size() == 1) {
            // If there is more than 1 usage, then it's not only returned
            NameOccurrence occ = usages.get(0);
            if (occ.getLocation().equals(name) && isNotAnnotated(variableDeclaration)) {
                String var = name.getImage();
                if (var.indexOf('.') != -1) {
                    var = var.substring(0, var.indexOf('.'));
                }
                // Is the variable initialized with another member that is later used?
                if (!isInitDataModifiedAfterInit(variableDeclaration, rtn) && !statementsBeforeReturn(variableDeclaration, rtn)) {
                    addViolation(data, rtn, var);
                }
            }
        }
    }
    return data;
}
Also used : VariableNameDeclaration(net.sourceforge.pmd.lang.java.symboltable.VariableNameDeclaration) ASTName(net.sourceforge.pmd.lang.java.ast.ASTName) List(java.util.List) Map(java.util.Map) NameOccurrence(net.sourceforge.pmd.lang.symboltable.NameOccurrence)

Example 14 with NameOccurrence

use of net.sourceforge.pmd.lang.symboltable.NameOccurrence in project pmd by pmd.

the class UnnecessaryLocalBeforeReturnRule method isInitDataModifiedAfterInit.

private boolean isInitDataModifiedAfterInit(final VariableNameDeclaration variableDeclaration, final ASTReturnStatement rtn) {
    final ASTVariableInitializer initializer = variableDeclaration.getAccessNodeParent().getFirstDescendantOfType(ASTVariableInitializer.class);
    if (initializer != null) {
        final List<ASTName> referencedNames = initializer.findDescendantsOfType(ASTName.class);
        for (final ASTName refName : referencedNames) {
            // TODO : Shouldn't the scope allow us to search for a var name occurrences directly, moving up through parent scopes?
            Scope scope = refName.getScope();
            do {
                final Map<VariableNameDeclaration, List<NameOccurrence>> declarations = scope.getDeclarations(VariableNameDeclaration.class);
                for (final Map.Entry<VariableNameDeclaration, List<NameOccurrence>> entry : declarations.entrySet()) {
                    if (entry.getKey().getName().equals(refName.getImage())) {
                        // Variable found! Check usage locations
                        for (final NameOccurrence occ : entry.getValue()) {
                            final ScopedNode location = occ.getLocation();
                            // Is it used after initializing our "unnecessary" local but before the return statement?
                            if (isAfter(location, initializer) && isAfter(rtn, location)) {
                                return true;
                            }
                        }
                        return false;
                    }
                }
                scope = scope.getParent();
            } while (scope != null);
        }
    }
    return false;
}
Also used : ScopedNode(net.sourceforge.pmd.lang.symboltable.ScopedNode) Scope(net.sourceforge.pmd.lang.symboltable.Scope) ASTVariableInitializer(net.sourceforge.pmd.lang.java.ast.ASTVariableInitializer) VariableNameDeclaration(net.sourceforge.pmd.lang.java.symboltable.VariableNameDeclaration) ASTName(net.sourceforge.pmd.lang.java.ast.ASTName) List(java.util.List) Map(java.util.Map) NameOccurrence(net.sourceforge.pmd.lang.symboltable.NameOccurrence)

Example 15 with NameOccurrence

use of net.sourceforge.pmd.lang.symboltable.NameOccurrence in project pmd by pmd.

the class AbstractInefficientZeroCheck method visit.

@Override
public Object visit(ASTVariableDeclaratorId node, Object data) {
    Node nameNode = node.getTypeNameNode();
    if (nameNode == null || nameNode instanceof ASTPrimitiveType || !appliesToClassName(node.getNameDeclaration().getTypeImage())) {
        return data;
    }
    List<NameOccurrence> declars = node.getUsages();
    for (NameOccurrence occ : declars) {
        JavaNameOccurrence jocc = (JavaNameOccurrence) occ;
        if (!isTargetMethod(jocc)) {
            continue;
        }
        Node expr = jocc.getLocation().jjtGetParent().jjtGetParent().jjtGetParent();
        checkNodeAndReport(data, jocc.getLocation(), expr);
    }
    return data;
}
Also used : ASTPrimitiveType(net.sourceforge.pmd.lang.java.ast.ASTPrimitiveType) JavaNameOccurrence(net.sourceforge.pmd.lang.java.symboltable.JavaNameOccurrence) Node(net.sourceforge.pmd.lang.ast.Node) JavaNameOccurrence(net.sourceforge.pmd.lang.java.symboltable.JavaNameOccurrence) NameOccurrence(net.sourceforge.pmd.lang.symboltable.NameOccurrence)

Aggregations

NameOccurrence (net.sourceforge.pmd.lang.symboltable.NameOccurrence)40 Node (net.sourceforge.pmd.lang.ast.Node)20 List (java.util.List)19 Map (java.util.Map)15 NameDeclaration (net.sourceforge.pmd.lang.symboltable.NameDeclaration)13 JavaNameOccurrence (net.sourceforge.pmd.lang.java.symboltable.JavaNameOccurrence)10 Test (org.junit.Test)10 ASTVariableDeclaratorId (net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId)9 ASTName (net.sourceforge.pmd.lang.java.ast.ASTName)8 VariableNameDeclaration (net.sourceforge.pmd.lang.java.symboltable.VariableNameDeclaration)8 ArrayList (java.util.ArrayList)7 ASTMethodDeclaration (net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration)7 ASTPrimaryExpression (net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression)7 ASTArgumentList (net.sourceforge.pmd.lang.java.ast.ASTArgumentList)4 Scope (net.sourceforge.pmd.lang.symboltable.Scope)4 HashSet (java.util.HashSet)3 ASTClassOrInterfaceDeclaration (net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration)3 ASTClassOrInterfaceType (net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceType)3 ASTConstructorDeclaration (net.sourceforge.pmd.lang.java.ast.ASTConstructorDeclaration)3 ASTStatementExpression (net.sourceforge.pmd.lang.java.ast.ASTStatementExpression)3