Search in sources :

Example 6 with ASTMethodDeclarator

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

the class UselessOverridingMethodRule method visit.

@Override
public Object visit(ASTMethodDeclaration node, Object data) {
    // them.
    if (node.isAbstract() || node.isFinal() || node.isNative() || node.isSynchronized()) {
        return super.visit(node, data);
    }
    // implement them anyway ( see bug 1522517)
    if (CLONE.equals(node.getMethodName()) && node.isPublic() && !this.hasArguments(node) && this.isMethodType(node, OBJECT) && this.isMethodThrowingType(node, exceptions)) {
        return super.visit(node, data);
    }
    ASTBlock block = node.getBlock();
    if (block == null) {
        return super.visit(node, data);
    }
    // Only process functions with one BlockStatement
    if (block.jjtGetNumChildren() != 1 || block.findDescendantsOfType(ASTStatement.class).size() != 1) {
        return super.visit(node, data);
    }
    Node statement = block.jjtGetChild(0).jjtGetChild(0);
    if (statement.jjtGetChild(0).jjtGetNumChildren() == 0) {
        // skips empty return statements
        return data;
    }
    Node statementGrandChild = statement.jjtGetChild(0).jjtGetChild(0);
    ASTPrimaryExpression primaryExpression;
    if (statementGrandChild instanceof ASTPrimaryExpression) {
        primaryExpression = (ASTPrimaryExpression) statementGrandChild;
    } else {
        List<ASTPrimaryExpression> primaryExpressions = findFirstDegreeChildrenOfType(statementGrandChild, ASTPrimaryExpression.class);
        if (primaryExpressions.size() != 1) {
            return super.visit(node, data);
        }
        primaryExpression = primaryExpressions.get(0);
    }
    ASTPrimaryPrefix primaryPrefix = findFirstDegreeChildrenOfType(primaryExpression, ASTPrimaryPrefix.class).get(0);
    if (!primaryPrefix.usesSuperModifier()) {
        return super.visit(node, data);
    }
    List<ASTPrimarySuffix> primarySuffixList = findFirstDegreeChildrenOfType(primaryExpression, ASTPrimarySuffix.class);
    if (primarySuffixList.size() != 2) {
        // extra method call on result of super method
        return super.visit(node, data);
    }
    ASTMethodDeclarator methodDeclarator = findFirstDegreeChildrenOfType(node, ASTMethodDeclarator.class).get(0);
    ASTPrimarySuffix primarySuffix = primarySuffixList.get(0);
    if (!primarySuffix.hasImageEqualTo(methodDeclarator.getImage())) {
        return super.visit(node, data);
    }
    // Process arguments
    primarySuffix = primarySuffixList.get(1);
    ASTArguments arguments = (ASTArguments) primarySuffix.jjtGetChild(0);
    ASTFormalParameters formalParameters = (ASTFormalParameters) methodDeclarator.jjtGetChild(0);
    if (formalParameters.jjtGetNumChildren() != arguments.jjtGetNumChildren()) {
        return super.visit(node, data);
    }
    if (!ignoreAnnotations) {
        ASTClassOrInterfaceBodyDeclaration parent = (ASTClassOrInterfaceBodyDeclaration) node.jjtGetParent();
        for (int i = 0; i < parent.jjtGetNumChildren(); i++) {
            Node n = parent.jjtGetChild(i);
            if (n instanceof ASTAnnotation) {
                if (n.jjtGetChild(0) instanceof ASTMarkerAnnotation) {
                    // @Override is ignored
                    if ("Override".equals(((ASTName) n.jjtGetChild(0).jjtGetChild(0)).getImage())) {
                        continue;
                    }
                }
                return super.visit(node, data);
            }
        }
    }
    if (arguments.jjtGetNumChildren() == 0) {
        addViolation(data, node, getMessage());
    } else {
        ASTArgumentList argumentList = (ASTArgumentList) arguments.jjtGetChild(0);
        for (int i = 0; i < argumentList.jjtGetNumChildren(); i++) {
            Node expressionChild = argumentList.jjtGetChild(i).jjtGetChild(0);
            if (!(expressionChild instanceof ASTPrimaryExpression) || expressionChild.jjtGetNumChildren() != 1) {
                // The arguments are not simply passed through
                return super.visit(node, data);
            }
            ASTPrimaryExpression argumentPrimaryExpression = (ASTPrimaryExpression) expressionChild;
            ASTPrimaryPrefix argumentPrimaryPrefix = (ASTPrimaryPrefix) argumentPrimaryExpression.jjtGetChild(0);
            if (argumentPrimaryPrefix.jjtGetNumChildren() == 0) {
                // The arguments are not simply passed through (using "this" for instance)
                return super.visit(node, data);
            }
            Node argumentPrimaryPrefixChild = argumentPrimaryPrefix.jjtGetChild(0);
            if (!(argumentPrimaryPrefixChild instanceof ASTName)) {
                // The arguments are not simply passed through
                return super.visit(node, data);
            }
            if (formalParameters.jjtGetNumChildren() < i + 1) {
                // different number of args
                return super.visit(node, data);
            }
            ASTName argumentName = (ASTName) argumentPrimaryPrefixChild;
            ASTFormalParameter formalParameter = (ASTFormalParameter) formalParameters.jjtGetChild(i);
            ASTVariableDeclaratorId variableId = findFirstDegreeChildrenOfType(formalParameter, ASTVariableDeclaratorId.class).get(0);
            if (!argumentName.hasImageEqualTo(variableId.getImage())) {
                // The arguments are not simply passed through
                return super.visit(node, data);
            }
        }
        // All arguments are passed through directly
        addViolation(data, node, getMessage());
    }
    return super.visit(node, data);
}
Also used : ASTPrimaryPrefix(net.sourceforge.pmd.lang.java.ast.ASTPrimaryPrefix) Node(net.sourceforge.pmd.lang.ast.Node) ASTFormalParameters(net.sourceforge.pmd.lang.java.ast.ASTFormalParameters) ASTPrimaryExpression(net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression) ASTArguments(net.sourceforge.pmd.lang.java.ast.ASTArguments) ASTClassOrInterfaceBodyDeclaration(net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceBodyDeclaration) ASTFormalParameter(net.sourceforge.pmd.lang.java.ast.ASTFormalParameter) ASTPrimarySuffix(net.sourceforge.pmd.lang.java.ast.ASTPrimarySuffix) ASTMarkerAnnotation(net.sourceforge.pmd.lang.java.ast.ASTMarkerAnnotation) ASTStatement(net.sourceforge.pmd.lang.java.ast.ASTStatement) ASTArgumentList(net.sourceforge.pmd.lang.java.ast.ASTArgumentList) ASTMethodDeclarator(net.sourceforge.pmd.lang.java.ast.ASTMethodDeclarator) ASTVariableDeclaratorId(net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId) ASTBlock(net.sourceforge.pmd.lang.java.ast.ASTBlock) ASTName(net.sourceforge.pmd.lang.java.ast.ASTName) ASTAnnotation(net.sourceforge.pmd.lang.java.ast.ASTAnnotation)

Example 7 with ASTMethodDeclarator

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

the class BeanMembersShouldSerializeRule method visit.

@Override
public Object visit(ASTClassOrInterfaceDeclaration node, Object data) {
    if (node.isInterface()) {
        return data;
    }
    Map<MethodNameDeclaration, List<NameOccurrence>> methods = node.getScope().getEnclosingScope(ClassScope.class).getMethodDeclarations();
    List<ASTMethodDeclarator> getSetMethList = new ArrayList<>(methods.size());
    for (MethodNameDeclaration d : methods.keySet()) {
        ASTMethodDeclarator mnd = d.getMethodNameDeclaratorNode();
        if (isBeanAccessor(mnd)) {
            getSetMethList.add(mnd);
        }
    }
    String[] methNameArray = imagesOf(getSetMethList);
    Arrays.sort(methNameArray);
    Map<VariableNameDeclaration, List<NameOccurrence>> vars = node.getScope().getDeclarations(VariableNameDeclaration.class);
    for (Map.Entry<VariableNameDeclaration, List<NameOccurrence>> entry : vars.entrySet()) {
        VariableNameDeclaration decl = entry.getKey();
        AccessNode accessNodeParent = decl.getAccessNodeParent();
        if (entry.getValue().isEmpty() || accessNodeParent.isTransient() || accessNodeParent.isStatic()) {
            continue;
        }
        String varName = trimIfPrefix(decl.getImage());
        varName = varName.substring(0, 1).toUpperCase(Locale.ROOT) + varName.substring(1, varName.length());
        boolean hasGetMethod = Arrays.binarySearch(methNameArray, "get" + varName) >= 0 || Arrays.binarySearch(methNameArray, "is" + varName) >= 0;
        boolean hasSetMethod = Arrays.binarySearch(methNameArray, "set" + varName) >= 0;
        // variable...
        if (!hasGetMethod || !accessNodeParent.isFinal() && !hasSetMethod) {
            addViolation(data, decl.getNode(), decl.getImage());
        }
    }
    return super.visit(node, data);
}
Also used : VariableNameDeclaration(net.sourceforge.pmd.lang.java.symboltable.VariableNameDeclaration) ArrayList(java.util.ArrayList) ClassScope(net.sourceforge.pmd.lang.java.symboltable.ClassScope) ASTMethodDeclarator(net.sourceforge.pmd.lang.java.ast.ASTMethodDeclarator) MethodNameDeclaration(net.sourceforge.pmd.lang.java.symboltable.MethodNameDeclaration) ArrayList(java.util.ArrayList) List(java.util.List) AccessNode(net.sourceforge.pmd.lang.java.ast.AccessNode) Map(java.util.Map)

Example 8 with ASTMethodDeclarator

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

the class CloneMethodMustImplementCloneableRule method visit.

@Override
public Object visit(final ASTMethodDeclaration node, final Object data) {
    // Is this a clone method?
    final ASTMethodDeclarator methodDeclarator = node.getFirstChildOfType(ASTMethodDeclarator.class);
    if (!isCloneMethod(methodDeclarator)) {
        return data;
    }
    // Is the clone method just throwing CloneNotSupportedException?
    final ASTClassOrInterfaceDeclaration classOrInterface = node.getFirstParentOfType(ASTClassOrInterfaceDeclaration.class);
    if (// Don't analyze enums, which cannot subclass clone()
    classOrInterface != null && (node.isFinal() || classOrInterface.isFinal())) {
        if (node.findDescendantsOfType(ASTBlock.class).size() == 1) {
            final List<ASTBlockStatement> blocks = node.findDescendantsOfType(ASTBlockStatement.class);
            if (blocks.size() == 1) {
                final ASTBlockStatement block = blocks.get(0);
                final ASTClassOrInterfaceType type = block.getFirstDescendantOfType(ASTClassOrInterfaceType.class);
                if (type != null && type.getType() != null && type.getNthParent(9).equals(node) && type.getType().equals(CloneNotSupportedException.class)) {
                    return data;
                } else if (type != null && type.getType() == null && "CloneNotSupportedException".equals(type.getImage())) {
                    return data;
                }
            }
        }
    }
    // TODO : Should we really care about this? It can only happen with an incomplete auxclasspath
    if (classOrInterface != null && classOrInterface.getType() == null) {
        // Now check other whether implemented or extended classes are defined inside the same file
        final Set<String> classesNames = determineTopLevelCloneableClasses(classOrInterface);
        final ASTImplementsList implementsList = classOrInterface.getFirstChildOfType(ASTImplementsList.class);
        if (implementsList != null) {
            final List<ASTClassOrInterfaceType> types = implementsList.findChildrenOfType(ASTClassOrInterfaceType.class);
            for (final ASTClassOrInterfaceType t : types) {
                if (classesNames.contains(t.getImage())) {
                    return data;
                }
            }
        }
        final ASTExtendsList extendsList = classOrInterface.getFirstChildOfType(ASTExtendsList.class);
        if (extendsList != null) {
            final ASTClassOrInterfaceType type = extendsList.getFirstChildOfType(ASTClassOrInterfaceType.class);
            if (classesNames.contains(type.getImage())) {
                return data;
            }
        }
    }
    // Nothing can save us now
    addViolation(data, node);
    return data;
}
Also used : ASTMethodDeclarator(net.sourceforge.pmd.lang.java.ast.ASTMethodDeclarator) ASTImplementsList(net.sourceforge.pmd.lang.java.ast.ASTImplementsList) ASTClassOrInterfaceDeclaration(net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration) ASTBlockStatement(net.sourceforge.pmd.lang.java.ast.ASTBlockStatement) ASTClassOrInterfaceType(net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceType) ASTExtendsList(net.sourceforge.pmd.lang.java.ast.ASTExtendsList)

Example 9 with ASTMethodDeclarator

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

the class UnusedFormalParameterRule method isSerializationMethod.

private boolean isSerializationMethod(ASTMethodDeclaration node) {
    ASTMethodDeclarator declarator = node.getFirstDescendantOfType(ASTMethodDeclarator.class);
    List<ASTFormalParameter> parameters = declarator.findDescendantsOfType(ASTFormalParameter.class);
    if (node.isPrivate() && "readObject".equals(node.getMethodName()) && parameters.size() == 1 && throwsOneException(node, InvalidObjectException.class)) {
        ASTType type = parameters.get(0).getTypeNode();
        if (type.getType() == ObjectInputStream.class || ObjectInputStream.class.getSimpleName().equals(type.getTypeImage()) || ObjectInputStream.class.getName().equals(type.getTypeImage())) {
            return true;
        }
    }
    return false;
}
Also used : ASTMethodDeclarator(net.sourceforge.pmd.lang.java.ast.ASTMethodDeclarator) ASTType(net.sourceforge.pmd.lang.java.ast.ASTType) InvalidObjectException(java.io.InvalidObjectException) ASTFormalParameter(net.sourceforge.pmd.lang.java.ast.ASTFormalParameter) ObjectInputStream(java.io.ObjectInputStream)

Example 10 with ASTMethodDeclarator

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

the class AcceptanceTest method check.

private boolean check(int[][] array, List<ASTMethodDeclarator> methodNodes) {
    for (int i = 0; i < methodNodes.size(); i++) {
        ASTMethodDeclarator decl = methodNodes.get(i);
        DataFlowNode inode = decl.getDataFlowNode();
        for (int j = 0; j < inode.getChildren().size(); j++) {
            DataFlowNode child = inode.getChildren().get(j);
            if (array[i][j] != child.getIndex() - 1) {
                return false;
            }
        }
    }
    return true;
}
Also used : ASTMethodDeclarator(net.sourceforge.pmd.lang.java.ast.ASTMethodDeclarator) DataFlowNode(net.sourceforge.pmd.lang.dfa.DataFlowNode)

Aggregations

ASTMethodDeclarator (net.sourceforge.pmd.lang.java.ast.ASTMethodDeclarator)12 Node (net.sourceforge.pmd.lang.ast.Node)4 ASTFormalParameter (net.sourceforge.pmd.lang.java.ast.ASTFormalParameter)4 ASTPrimitiveType (net.sourceforge.pmd.lang.java.ast.ASTPrimitiveType)3 DataFlowNode (net.sourceforge.pmd.lang.dfa.DataFlowNode)2 ASTClassOrInterfaceType (net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceType)2 ASTFormalParameters (net.sourceforge.pmd.lang.java.ast.ASTFormalParameters)2 ASTType (net.sourceforge.pmd.lang.java.ast.ASTType)2 ASTVariableDeclaratorId (net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId)2 Test (org.junit.Test)2 InvalidObjectException (java.io.InvalidObjectException)1 ObjectInputStream (java.io.ObjectInputStream)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 Map (java.util.Map)1 AbstractNode (net.sourceforge.pmd.lang.ast.AbstractNode)1 DAAPathFinder (net.sourceforge.pmd.lang.dfa.pathfinder.DAAPathFinder)1 ASTAnnotation (net.sourceforge.pmd.lang.java.ast.ASTAnnotation)1 ASTArgumentList (net.sourceforge.pmd.lang.java.ast.ASTArgumentList)1 ASTArguments (net.sourceforge.pmd.lang.java.ast.ASTArguments)1