Search in sources :

Example 1 with VariableNameDeclaration

use of net.sourceforge.pmd.lang.java.symboltable.VariableNameDeclaration in project pmd by pmd.

the class VariableAccessVisitor method markUsages.

private List<VariableAccess> markUsages(DataFlowNode inode) {
    // undefinitions was once a field... seems like it works fine as a local
    List<VariableAccess> undefinitions = new ArrayList<>();
    Set<Map<VariableNameDeclaration, List<NameOccurrence>>> variableDeclarations = collectDeclarations(inode);
    for (Map<VariableNameDeclaration, List<NameOccurrence>> declarations : variableDeclarations) {
        for (Map.Entry<VariableNameDeclaration, List<NameOccurrence>> entry : declarations.entrySet()) {
            VariableNameDeclaration vnd = entry.getKey();
            if (vnd.getAccessNodeParent() instanceof ASTFormalParameter) {
                // no definition/undefinition/references for parameters
                continue;
            } else if (vnd.getAccessNodeParent().getFirstDescendantOfType(ASTVariableInitializer.class) != null) {
                // add definition for initialized variables
                addVariableAccess(vnd.getNode(), new VariableAccess(VariableAccess.DEFINITION, vnd.getImage()), inode.getFlow());
            }
            undefinitions.add(new VariableAccess(VariableAccess.UNDEFINITION, vnd.getImage()));
            for (NameOccurrence occurrence : entry.getValue()) {
                addAccess((JavaNameOccurrence) occurrence, inode);
            }
        }
    }
    return undefinitions;
}
Also used : VariableNameDeclaration(net.sourceforge.pmd.lang.java.symboltable.VariableNameDeclaration) VariableAccess(net.sourceforge.pmd.lang.dfa.VariableAccess) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) ASTFormalParameter(net.sourceforge.pmd.lang.java.ast.ASTFormalParameter) Map(java.util.Map) JavaNameOccurrence(net.sourceforge.pmd.lang.java.symboltable.JavaNameOccurrence) NameOccurrence(net.sourceforge.pmd.lang.symboltable.NameOccurrence)

Example 2 with VariableNameDeclaration

use of net.sourceforge.pmd.lang.java.symboltable.VariableNameDeclaration in project pmd by pmd.

the class CompareObjectsWithEqualsRule method visit.

public Object visit(ASTEqualityExpression node, Object data) {
    Node c0 = node.jjtGetChild(0).jjtGetChild(0);
    Node c1 = node.jjtGetChild(1).jjtGetChild(0);
    // equals expression is correct
    if (isAllocation(c0) || isAllocation(c1)) {
        addViolation(data, node);
        return data;
    }
    // skip if either child is not a simple name
    if (!hasName(c0) || !hasName(c1)) {
        return data;
    }
    // skip if either is a qualified name
    if (isQualifiedName(c0.jjtGetChild(0)) || isQualifiedName(c1.jjtGetChild(0))) {
        return data;
    }
    // skip if either is part of a qualified name
    if (isPartOfQualifiedName(node.jjtGetChild(0)) || isPartOfQualifiedName(node.jjtGetChild(1))) {
        return data;
    }
    // skip static initializers... missing some cases here
    if (!node.getParentsOfType(ASTInitializer.class).isEmpty()) {
        return data;
    }
    ASTName n0 = (ASTName) c0.jjtGetChild(0);
    ASTName n1 = (ASTName) c1.jjtGetChild(0);
    if (n0.getNameDeclaration() instanceof VariableNameDeclaration && n1.getNameDeclaration() instanceof VariableNameDeclaration) {
        VariableNameDeclaration nd0 = (VariableNameDeclaration) n0.getNameDeclaration();
        VariableNameDeclaration nd1 = (VariableNameDeclaration) n1.getNameDeclaration();
        // FIXME catch comparisons btwn array elements of reference types
        if (nd0.isArray() || nd1.isArray()) {
            return data;
        }
        if (nd0.isReferenceType() && nd1.isReferenceType()) {
            ASTReferenceType type0 = ((Node) nd0.getAccessNodeParent()).getFirstDescendantOfType(ASTReferenceType.class);
            ASTReferenceType type1 = ((Node) nd1.getAccessNodeParent()).getFirstDescendantOfType(ASTReferenceType.class);
            // skip, if it is an enum
            if (type0.getType() != null && type0.getType().equals(type1.getType()) && // It may be a custom enum class or an explicit Enum class usage
            (type0.getType().isEnum() || type0.getType() == java.lang.Enum.class)) {
                return data;
            }
            addViolation(data, node);
        }
    }
    return data;
}
Also used : VariableNameDeclaration(net.sourceforge.pmd.lang.java.symboltable.VariableNameDeclaration) ASTName(net.sourceforge.pmd.lang.java.ast.ASTName) Node(net.sourceforge.pmd.lang.ast.Node) ASTReferenceType(net.sourceforge.pmd.lang.java.ast.ASTReferenceType)

Example 3 with VariableNameDeclaration

use of net.sourceforge.pmd.lang.java.symboltable.VariableNameDeclaration in project pmd by pmd.

the class ImmutableFieldRule method visit.

@Override
public Object visit(ASTClassOrInterfaceDeclaration node, Object data) {
    Object result = super.visit(node, data);
    Map<VariableNameDeclaration, List<NameOccurrence>> vars = node.getScope().getDeclarations(VariableNameDeclaration.class);
    List<ASTConstructorDeclaration> constructors = findAllConstructors(node);
    for (Map.Entry<VariableNameDeclaration, List<NameOccurrence>> entry : vars.entrySet()) {
        VariableNameDeclaration field = entry.getKey();
        AccessNode accessNodeParent = field.getAccessNodeParent();
        if (accessNodeParent.isStatic() || !accessNodeParent.isPrivate() || accessNodeParent.isFinal() || accessNodeParent.isVolatile() || hasClassLombokAnnotation()) {
            continue;
        }
        FieldImmutabilityType type = initializedInConstructor(entry.getValue(), new HashSet<>(constructors));
        if (type == FieldImmutabilityType.MUTABLE) {
            continue;
        }
        if (type == FieldImmutabilityType.IMMUTABLE || type == FieldImmutabilityType.CHECKDECL && initializedWhenDeclared(field)) {
            addViolation(data, field.getNode(), field.getImage());
        }
    }
    return result;
}
Also used : ASTConstructorDeclaration(net.sourceforge.pmd.lang.java.ast.ASTConstructorDeclaration) VariableNameDeclaration(net.sourceforge.pmd.lang.java.symboltable.VariableNameDeclaration) List(java.util.List) AccessNode(net.sourceforge.pmd.lang.java.ast.AccessNode) Map(java.util.Map)

Example 4 with VariableNameDeclaration

use of net.sourceforge.pmd.lang.java.symboltable.VariableNameDeclaration in project pmd by pmd.

the class ClassTypeResolver method getTypeDefinitionOfVariableFromScope.

/**
 * Search for a field by it's image stating from a scope and taking into account if it's visible from the
 * accessingClass Class. The method takes into account that Nested inherited fields shadow outer scope fields.
 *
 * @param scope          The scope to start the search from.
 * @param image          The name of the field, local variable or method parameter.
 * @param accessingClass The Class (which is defined in the current ACU) that is trying to access the field.
 * @return Type def. of the field, or null if it could not be resolved.
 */
private JavaTypeDefinition getTypeDefinitionOfVariableFromScope(Scope scope, String image, Class<?> accessingClass) {
    if (accessingClass == null) {
        return null;
    }
    for (; /* empty */
    scope != null; scope = scope.getParent()) {
        // search each enclosing scope one by one
        for (Map.Entry<VariableNameDeclaration, List<NameOccurrence>> entry : scope.getDeclarations(VariableNameDeclaration.class).entrySet()) {
            if (entry.getKey().getImage().equals(image)) {
                ASTType typeNode = entry.getKey().getDeclaratorId().getTypeNode();
                if (typeNode == null) {
                    // TODO : Type is infered, ie, this is a lambda such as (var) -> var.equals(other)
                    return null;
                }
                if (typeNode.jjtGetChild(0) instanceof ASTReferenceType) {
                    return ((TypeNode) typeNode.jjtGetChild(0)).getTypeDefinition();
                } else {
                    // primitive type
                    return JavaTypeDefinition.forClass(typeNode.getType());
                }
            }
        }
        // Nested class' inherited fields shadow enclosing variables
        if (scope instanceof ClassScope) {
            try {
                // get the superclass type def. ot the Class the ClassScope belongs to
                JavaTypeDefinition superClass = getSuperClassTypeDefinition(((ClassScope) scope).getClassDeclaration().getNode(), null);
                // TODO: check if anonymous classes are class scope
                // try searching this type def.
                JavaTypeDefinition foundTypeDef = getFieldType(superClass, image, accessingClass);
                if (foundTypeDef != null) {
                    // if null, then it's not an inherited field
                    return foundTypeDef;
                }
            } catch (ClassCastException ignored) {
            // if there is an anonymous class, getClassDeclaration().getType() will throw
            // TODO: maybe there is a better way to handle this, maybe this hides bugs
            }
        }
    }
    // will return null if not found
    return searchImportedStaticFields(image);
}
Also used : ASTType(net.sourceforge.pmd.lang.java.ast.ASTType) VariableNameDeclaration(net.sourceforge.pmd.lang.java.symboltable.VariableNameDeclaration) JavaTypeDefinition(net.sourceforge.pmd.lang.java.typeresolution.typedefinition.JavaTypeDefinition) ASTExtendsList(net.sourceforge.pmd.lang.java.ast.ASTExtendsList) ASTArgumentList(net.sourceforge.pmd.lang.java.ast.ASTArgumentList) List(java.util.List) ArrayList(java.util.ArrayList) TypeNode(net.sourceforge.pmd.lang.java.ast.TypeNode) AbstractJavaTypeNode(net.sourceforge.pmd.lang.java.ast.AbstractJavaTypeNode) Map(java.util.Map) HashMap(java.util.HashMap) ASTReferenceType(net.sourceforge.pmd.lang.java.ast.ASTReferenceType) ClassScope(net.sourceforge.pmd.lang.java.symboltable.ClassScope)

Example 5 with VariableNameDeclaration

use of net.sourceforge.pmd.lang.java.symboltable.VariableNameDeclaration in project pmd by pmd.

the class AvoidReassigningParametersRule method lookForViolation.

private void lookForViolation(Map<VariableNameDeclaration, List<NameOccurrence>> params, Object data) {
    for (Map.Entry<VariableNameDeclaration, List<NameOccurrence>> entry : params.entrySet()) {
        VariableNameDeclaration decl = entry.getKey();
        List<NameOccurrence> usages = entry.getValue();
        for (NameOccurrence occ : usages) {
            JavaNameOccurrence jocc = (JavaNameOccurrence) occ;
            if ((jocc.isOnLeftHandSide() || jocc.isSelfAssignment()) && jocc.getNameForWhichThisIsAQualifier() == null && !jocc.useThisOrSuper() && !decl.isVarargs() && (!decl.isArray() || jocc.getLocation().jjtGetParent().jjtGetParent().jjtGetNumChildren() == 1)) {
                // not an array or no primary suffix to access the array
                // values
                addViolation(data, decl.getNode(), decl.getImage());
            }
        }
    }
}
Also used : VariableNameDeclaration(net.sourceforge.pmd.lang.java.symboltable.VariableNameDeclaration) JavaNameOccurrence(net.sourceforge.pmd.lang.java.symboltable.JavaNameOccurrence) List(java.util.List) Map(java.util.Map) JavaNameOccurrence(net.sourceforge.pmd.lang.java.symboltable.JavaNameOccurrence) NameOccurrence(net.sourceforge.pmd.lang.symboltable.NameOccurrence)

Aggregations

VariableNameDeclaration (net.sourceforge.pmd.lang.java.symboltable.VariableNameDeclaration)23 List (java.util.List)18 Map (java.util.Map)15 NameOccurrence (net.sourceforge.pmd.lang.symboltable.NameOccurrence)8 ASTName (net.sourceforge.pmd.lang.java.ast.ASTName)7 ArrayList (java.util.ArrayList)6 AccessNode (net.sourceforge.pmd.lang.java.ast.AccessNode)6 Node (net.sourceforge.pmd.lang.ast.Node)5 ASTArgumentList (net.sourceforge.pmd.lang.java.ast.ASTArgumentList)4 ASTPrimaryExpression (net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression)4 JavaNameOccurrence (net.sourceforge.pmd.lang.java.symboltable.JavaNameOccurrence)4 ASTPrimaryPrefix (net.sourceforge.pmd.lang.java.ast.ASTPrimaryPrefix)3 ClassScope (net.sourceforge.pmd.lang.java.symboltable.ClassScope)3 ASTExpression (net.sourceforge.pmd.lang.java.ast.ASTExpression)2 ASTForInit (net.sourceforge.pmd.lang.java.ast.ASTForInit)2 ASTFormalParameter (net.sourceforge.pmd.lang.java.ast.ASTFormalParameter)2 ASTLiteral (net.sourceforge.pmd.lang.java.ast.ASTLiteral)2 ASTMethodDeclaration (net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration)2 ASTReferenceType (net.sourceforge.pmd.lang.java.ast.ASTReferenceType)2 ASTVariableInitializer (net.sourceforge.pmd.lang.java.ast.ASTVariableInitializer)2