Search in sources :

Example 11 with ASTClassOrInterfaceDeclaration

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

the class ClassTypeResolver method visit.

@Override
public Object visit(ASTPrimaryExpression primaryNode, Object data) {
    // visit method arguments in reverse
    for (int i = primaryNode.jjtGetNumChildren() - 1; i >= 0; --i) {
        ((JavaNode) primaryNode.jjtGetChild(i)).jjtAccept(this, data);
    }
    JavaTypeDefinition primaryNodeType = null;
    AbstractJavaTypeNode previousChild = null;
    AbstractJavaTypeNode nextChild;
    Class<?> accessingClass = getEnclosingTypeDeclarationClass(primaryNode);
    for (int childIndex = 0; childIndex < primaryNode.jjtGetNumChildren(); ++childIndex) {
        AbstractJavaTypeNode currentChild = (AbstractJavaTypeNode) primaryNode.jjtGetChild(childIndex);
        nextChild = childIndex + 1 < primaryNode.jjtGetNumChildren() ? (AbstractJavaTypeNode) primaryNode.jjtGetChild(childIndex + 1) : null;
        // skip children which already have their type assigned
        if (currentChild.getType() == null) {
            // Last token, because if 'this' is a Suffix, it'll have tokens '.' and 'this'
            if (currentChild.jjtGetLastToken().toString().equals("this")) {
                if (previousChild != null) {
                    // Qualified 'this' expression
                    currentChild.setTypeDefinition(previousChild.getTypeDefinition());
                } else {
                    // simple 'this' expression
                    ASTClassOrInterfaceDeclaration typeDeclaration = currentChild.getFirstParentOfType(ASTClassOrInterfaceDeclaration.class);
                    if (typeDeclaration != null) {
                        currentChild.setTypeDefinition(typeDeclaration.getTypeDefinition());
                    }
                }
            // Last token, because if 'super' is a Suffix, it'll have tokens '.' and 'super'
            } else if (currentChild.jjtGetLastToken().toString().equals("super")) {
                if (previousChild != null) {
                    // Qualified 'super' expression
                    // anonymous classes can't have qualified super expression, thus
                    // getSuperClassTypeDefinition's second argumet isn't null, but we are not
                    // looking for enclosing super types
                    currentChild.setTypeDefinition(getSuperClassTypeDefinition(currentChild, previousChild.getType()));
                } else {
                    // simple 'super' expression
                    currentChild.setTypeDefinition(getSuperClassTypeDefinition(currentChild, null));
                }
            } else if (currentChild.getFirstChildOfType(ASTArguments.class) != null) {
                currentChild.setTypeDefinition(previousChild.getTypeDefinition());
            } else if (previousChild != null && previousChild.getType() != null) {
                String currentChildImage = currentChild.getImage();
                if (currentChildImage == null) {
                    // this.<Something>foo(); <Something>foo would be in a Suffix and would have a null image
                    currentChildImage = currentChild.jjtGetLastToken().toString();
                }
                ASTArguments astArguments = nextChild != null ? nextChild.getFirstChildOfType(ASTArguments.class) : null;
                if (astArguments != null) {
                    // method
                    ASTArgumentList astArgumentList = getArgumentList(astArguments);
                    int methodArgsArity = getArgumentListArity(astArgumentList);
                    List<JavaTypeDefinition> typeArguments = getMethodExplicitTypeArugments(currentChild);
                    List<MethodType> methods = getApplicableMethods(previousChild.getTypeDefinition(), currentChildImage, typeArguments, methodArgsArity, accessingClass);
                    currentChild.setTypeDefinition(getBestMethodReturnType(previousChild.getTypeDefinition(), methods, astArgumentList));
                } else {
                    // field
                    currentChild.setTypeDefinition(getFieldType(previousChild.getTypeDefinition(), currentChildImage, accessingClass));
                }
            }
        }
        if (currentChild.getType() != null) {
            primaryNodeType = currentChild.getTypeDefinition();
        } else {
            // avoid falsely passing tests
            primaryNodeType = null;
            break;
        }
        previousChild = currentChild;
    }
    primaryNode.setTypeDefinition(primaryNodeType);
    return data;
}
Also used : ASTClassOrInterfaceDeclaration(net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration) 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) ASTArguments(net.sourceforge.pmd.lang.java.ast.ASTArguments) ASTArgumentList(net.sourceforge.pmd.lang.java.ast.ASTArgumentList) JavaNode(net.sourceforge.pmd.lang.java.ast.JavaNode) AbstractJavaTypeNode(net.sourceforge.pmd.lang.java.ast.AbstractJavaTypeNode)

Example 12 with ASTClassOrInterfaceDeclaration

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

the class ClassTypeResolver method visit.

@Override
public Object visit(ASTTypeParameters node, Object data) {
    super.visit(node, data);
    if (node.jjtGetParent() instanceof ASTClassOrInterfaceDeclaration) {
        TypeNode parent = (TypeNode) node.jjtGetParent();
        final JavaTypeDefinition[] boundGenerics = new JavaTypeDefinition[node.jjtGetNumChildren()];
        for (int i = 0; i < node.jjtGetNumChildren(); ++i) {
            boundGenerics[i] = ((TypeNode) node.jjtGetChild(i)).getTypeDefinition();
        }
        parent.setTypeDefinition(JavaTypeDefinition.forClass(parent.getType(), boundGenerics));
    }
    return data;
}
Also used : ASTClassOrInterfaceDeclaration(net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration) JavaTypeDefinition(net.sourceforge.pmd.lang.java.typeresolution.typedefinition.JavaTypeDefinition) TypeNode(net.sourceforge.pmd.lang.java.ast.TypeNode) AbstractJavaTypeNode(net.sourceforge.pmd.lang.java.ast.AbstractJavaTypeNode)

Example 13 with ASTClassOrInterfaceDeclaration

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

the class ClassScope method determineSuper.

private SimpleTypedNameDeclaration determineSuper(Node declaringNode) {
    SimpleTypedNameDeclaration result = null;
    if (declaringNode instanceof ASTClassOrInterfaceDeclaration) {
        ASTClassOrInterfaceDeclaration classDeclaration = (ASTClassOrInterfaceDeclaration) declaringNode;
        ASTImplementsList implementsList = classDeclaration.getFirstChildOfType(ASTImplementsList.class);
        if (implementsList != null) {
            List<ASTClassOrInterfaceType> types = implementsList.findChildrenOfType(ASTClassOrInterfaceType.class);
            SimpleTypedNameDeclaration type = convertToSimpleType(types);
            result = type;
        }
        ASTExtendsList extendsList = classDeclaration.getFirstChildOfType(ASTExtendsList.class);
        if (extendsList != null) {
            List<ASTClassOrInterfaceType> types = extendsList.findChildrenOfType(ASTClassOrInterfaceType.class);
            SimpleTypedNameDeclaration type = convertToSimpleType(types);
            if (result == null) {
                result = type;
            } else {
                result.addNext(type);
            }
        }
    }
    return result;
}
Also used : ASTImplementsList(net.sourceforge.pmd.lang.java.ast.ASTImplementsList) ASTClassOrInterfaceDeclaration(net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration) ASTClassOrInterfaceType(net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceType) ASTExtendsList(net.sourceforge.pmd.lang.java.ast.ASTExtendsList)

Example 14 with ASTClassOrInterfaceDeclaration

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

the class SingularFieldRule method visit.

@SuppressWarnings("PMD.CompareObjectsWithEquals")
@Override
public Object visit(ASTFieldDeclaration node, Object data) {
    boolean checkInnerClasses = getProperty(CHECK_INNER_CLASSES);
    boolean disallowNotAssignment = getProperty(DISALLOW_NOT_ASSIGNMENT);
    if (node.isPrivate() && !node.isStatic() && !hasClassLombokAnnotation() && !hasLombokAnnotation(node)) {
        for (ASTVariableDeclarator declarator : node.findChildrenOfType(ASTVariableDeclarator.class)) {
            ASTVariableDeclaratorId declaration = (ASTVariableDeclaratorId) declarator.jjtGetChild(0);
            List<NameOccurrence> usages = declaration.getUsages();
            Node decl = null;
            boolean violation = true;
            for (int ix = 0; ix < usages.size(); ix++) {
                NameOccurrence no = usages.get(ix);
                Node location = no.getLocation();
                ASTPrimaryExpression primaryExpressionParent = location.getFirstParentOfType(ASTPrimaryExpression.class);
                if (ix == 0 && !disallowNotAssignment) {
                    if (primaryExpressionParent.getFirstParentOfType(ASTIfStatement.class) != null) {
                        // the first usage is in an if, so it may be skipped
                        // on
                        // later calls to the method. So this might be legit
                        // code
                        // that simply stores an object for later use.
                        violation = false;
                        // Optimization
                        break;
                    }
                    // Is the first usage in an assignment?
                    Node potentialStatement = primaryExpressionParent.jjtGetParent();
                    // Check that the assignment is not to a field inside
                    // the field object
                    boolean assignmentToField = no.getImage().equals(location.getImage());
                    if (!assignmentToField || !isInAssignment(potentialStatement)) {
                        violation = false;
                        // Optimization
                        break;
                    } else {
                        if (usages.size() > ix + 1) {
                            Node secondUsageLocation = usages.get(ix + 1).getLocation();
                            List<ASTStatementExpression> parentStatements = secondUsageLocation.getParentsOfType(ASTStatementExpression.class);
                            for (ASTStatementExpression statementExpression : parentStatements) {
                                if (statementExpression != null && statementExpression.equals(potentialStatement)) {
                                    // The second usage is in the assignment
                                    // of the first usage, which is allowed
                                    violation = false;
                                    // Optimization
                                    break;
                                }
                            }
                        }
                    }
                }
                if (!checkInnerClasses) {
                    // Skip inner classes because the field can be used in
                    // the outer class and checking this is too difficult
                    ASTClassOrInterfaceDeclaration clazz = location.getFirstParentOfType(ASTClassOrInterfaceDeclaration.class);
                    if (clazz != null && clazz.getFirstParentOfType(ASTClassOrInterfaceDeclaration.class) != null) {
                        violation = false;
                        // Optimization
                        break;
                    }
                }
                if (primaryExpressionParent.jjtGetParent() instanceof ASTSynchronizedStatement) {
                    // This usage is directly in an expression of a
                    // synchronized block
                    violation = false;
                    // Optimization
                    break;
                }
                if (location.getFirstParentOfType(ASTLambdaExpression.class) != null) {
                    // This usage is inside a lambda expression
                    violation = false;
                    // Optimization
                    break;
                }
                Node method = location.getFirstParentOfType(ASTMethodDeclaration.class);
                if (method == null) {
                    method = location.getFirstParentOfType(ASTConstructorDeclaration.class);
                    if (method == null) {
                        method = location.getFirstParentOfType(ASTInitializer.class);
                        if (method == null) {
                            continue;
                        }
                    }
                }
                if (decl == null) {
                    decl = method;
                    continue;
                } else if (decl != method && // handle inner classes
                decl.getFirstParentOfType(ASTClassOrInterfaceDeclaration.class) == method.getFirstParentOfType(ASTClassOrInterfaceDeclaration.class)) {
                    violation = false;
                    // Optimization
                    break;
                }
            }
            if (violation && !usages.isEmpty()) {
                addViolation(data, node, new Object[] { declaration.getImage() });
            }
        }
    }
    return data;
}
Also used : ASTConstructorDeclaration(net.sourceforge.pmd.lang.java.ast.ASTConstructorDeclaration) Node(net.sourceforge.pmd.lang.ast.Node) ASTIfStatement(net.sourceforge.pmd.lang.java.ast.ASTIfStatement) ASTPrimaryExpression(net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression) ASTSynchronizedStatement(net.sourceforge.pmd.lang.java.ast.ASTSynchronizedStatement) ASTInitializer(net.sourceforge.pmd.lang.java.ast.ASTInitializer) ASTStatementExpression(net.sourceforge.pmd.lang.java.ast.ASTStatementExpression) ASTLambdaExpression(net.sourceforge.pmd.lang.java.ast.ASTLambdaExpression) ASTClassOrInterfaceDeclaration(net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration) ASTVariableDeclaratorId(net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId) ASTVariableDeclarator(net.sourceforge.pmd.lang.java.ast.ASTVariableDeclarator) NameOccurrence(net.sourceforge.pmd.lang.symboltable.NameOccurrence)

Example 15 with ASTClassOrInterfaceDeclaration

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

the class UseUtilityClassRule method visit.

@Override
public Object visit(ASTClassOrInterfaceBody decl, Object data) {
    if (decl.jjtGetParent() instanceof ASTClassOrInterfaceDeclaration) {
        ASTClassOrInterfaceDeclaration parent = (ASTClassOrInterfaceDeclaration) decl.jjtGetParent();
        if (parent.isAbstract() || parent.isInterface() || isExceptionType(parent)) {
            return super.visit(decl, data);
        }
        if (isOkUsingLombok(parent)) {
            return super.visit(decl, data);
        }
        int i = decl.jjtGetNumChildren();
        int methodCount = 0;
        boolean isOK = false;
        while (i > 0) {
            Node p = decl.jjtGetChild(--i);
            if (p.jjtGetNumChildren() == 0) {
                continue;
            }
            Node n = skipAnnotations(p);
            if (n instanceof ASTFieldDeclaration) {
                if (!((ASTFieldDeclaration) n).isStatic()) {
                    isOK = true;
                    break;
                }
            } else if (n instanceof ASTConstructorDeclaration) {
                if (((ASTConstructorDeclaration) n).isPrivate()) {
                    isOK = true;
                    break;
                }
            } else if (n instanceof ASTMethodDeclaration) {
                ASTMethodDeclaration m = (ASTMethodDeclaration) n;
                if (!m.isPrivate()) {
                    methodCount++;
                }
                if (!m.isStatic()) {
                    isOK = true;
                    break;
                }
                // TODO use symbol table
                if (m.getMethodName().equals("suite")) {
                    ASTResultType res = m.getResultType();
                    ASTClassOrInterfaceType c = res.getFirstDescendantOfType(ASTClassOrInterfaceType.class);
                    if (c != null && c.hasImageEqualTo("Test")) {
                        isOK = true;
                        break;
                    }
                }
            }
        }
        if (!isOK && methodCount > 0) {
            addViolation(data, decl);
        }
    }
    return super.visit(decl, data);
}
Also used : ASTConstructorDeclaration(net.sourceforge.pmd.lang.java.ast.ASTConstructorDeclaration) ASTClassOrInterfaceDeclaration(net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration) ASTMethodDeclaration(net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration) Node(net.sourceforge.pmd.lang.ast.Node) ASTFieldDeclaration(net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration) ASTResultType(net.sourceforge.pmd.lang.java.ast.ASTResultType) ASTClassOrInterfaceType(net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceType)

Aggregations

ASTClassOrInterfaceDeclaration (net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration)31 Test (org.junit.Test)18 EnumTest (net.sourceforge.pmd.lang.java.symboltable.testdata.InnerClass.TheInnerClass.EnumTest)15 List (java.util.List)14 NameDeclaration (net.sourceforge.pmd.lang.symboltable.NameDeclaration)12 Node (net.sourceforge.pmd.lang.ast.Node)7 Map (java.util.Map)4 ASTAnnotationTypeDeclaration (net.sourceforge.pmd.lang.java.ast.ASTAnnotationTypeDeclaration)3 ASTClassOrInterfaceType (net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceType)3 ASTCompilationUnit (net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit)3 ASTExtendsList (net.sourceforge.pmd.lang.java.ast.ASTExtendsList)3 ASTMethodDeclaration (net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration)3 AbstractJavaTypeNode (net.sourceforge.pmd.lang.java.ast.AbstractJavaTypeNode)3 JavaNode (net.sourceforge.pmd.lang.java.ast.JavaNode)3 NameOccurrence (net.sourceforge.pmd.lang.symboltable.NameOccurrence)3 ArrayList (java.util.ArrayList)2 ASTArguments (net.sourceforge.pmd.lang.java.ast.ASTArguments)2 ASTConstructorDeclaration (net.sourceforge.pmd.lang.java.ast.ASTConstructorDeclaration)2 ASTImplementsList (net.sourceforge.pmd.lang.java.ast.ASTImplementsList)2 ASTTypeDeclaration (net.sourceforge.pmd.lang.java.ast.ASTTypeDeclaration)2