Search in sources :

Example 6 with JavaTypeDefinition

use of net.sourceforge.pmd.lang.java.typeresolution.typedefinition.JavaTypeDefinition in project pmd by pmd.

the class MethodTypeResolution method getTypeDefOfMethod.

public static MethodType getTypeDefOfMethod(JavaTypeDefinition context, Method method, List<JavaTypeDefinition> typeArguments) {
    if (typeArguments.isEmpty() && isGeneric(method)) {
        return MethodType.build(method);
    }
    JavaTypeDefinition returnType = context.resolveTypeDefinition(method.getGenericReturnType(), method, typeArguments);
    List<JavaTypeDefinition> argTypes = new ArrayList<>();
    for (Type argType : method.getGenericParameterTypes()) {
        argTypes.add(context.resolveTypeDefinition(argType, method, typeArguments));
    }
    return MethodType.build(returnType, argTypes, method);
}
Also used : Type(java.lang.reflect.Type) JavaTypeDefinition(net.sourceforge.pmd.lang.java.typeresolution.typedefinition.JavaTypeDefinition) ArrayList(java.util.ArrayList)

Example 7 with JavaTypeDefinition

use of net.sourceforge.pmd.lang.java.typeresolution.typedefinition.JavaTypeDefinition in project pmd by pmd.

the class TypeInferenceResolver method lub.

public static JavaTypeDefinition lub(List<JavaTypeDefinition> types) {
    for (JavaTypeDefinition type : types) {
        if (type.isArrayType()) {
            // TODO: add support for array types
            return JavaTypeDefinition.forClass(Object.class);
        }
    }
    // step 1 - EC
    Set<Class<?>> erasedCandidateSet = getErasedCandidateSet(types);
    // step 2 - MEC
    Set<Class<?>> minimalSet = getMinimalErasedCandidateSet(erasedCandidateSet);
    List<JavaTypeDefinition> candidates = new ArrayList<>();
    // for each element G n MEC
    for (Class<?> erasedSupertype : minimalSet) {
        JavaTypeDefinition lci = types.get(0).getAsSuper(erasedSupertype);
        for (JavaTypeDefinition type : types) {
            if (lci == null) {
                throw new ResolutionFailedException();
            }
            lci = intersect(lci, type.getAsSuper(erasedSupertype));
        }
        candidates.add(lci);
    }
    if (candidates.isEmpty()) {
        throw new ResolutionFailedException();
    }
    JavaTypeDefinition result = candidates.get(0);
    for (JavaTypeDefinition candidate : candidates) {
        if (MethodTypeResolution.isSubtypeable(candidate, result)) {
            result = candidate;
        } else if (!MethodTypeResolution.isSubtypeable(result, candidate)) {
            // TODO: add support for compound types
            throw new ResolutionFailedException();
        }
    // else: result contains candidate, nothing else to do
    }
    return result;
}
Also used : JavaTypeDefinition(net.sourceforge.pmd.lang.java.typeresolution.typedefinition.JavaTypeDefinition) ArrayList(java.util.ArrayList)

Example 8 with JavaTypeDefinition

use of net.sourceforge.pmd.lang.java.typeresolution.typedefinition.JavaTypeDefinition in project pmd by pmd.

the class ClassTypeResolver method visit.

@Override
public Object visit(ASTName node, Object data) {
    Class<?> accessingClass = getEnclosingTypeDeclarationClass(node);
    String[] dotSplitImage = node.getImage().split("\\.");
    int startIndex = searchNodeNameForClass(node);
    ASTArguments astArguments = getSuffixMethodArgs(node);
    ASTArgumentList astArgumentList = getArgumentList(astArguments);
    int methodArgsArity = getArgumentListArity(astArgumentList);
    JavaTypeDefinition previousType;
    if (node.getType() != null) {
        // static field or method
        // node.getType() has been set by the call to searchNodeNameForClass above
        // node.getType() will have the value equal to the Class found by that method
        previousType = node.getTypeDefinition();
    } else {
        // non-static field or method
        if (dotSplitImage.length == 1 && astArguments != null) {
            // method
            List<MethodType> methods = getLocalApplicableMethods(node, dotSplitImage[0], Collections.<JavaTypeDefinition>emptyList(), methodArgsArity, accessingClass);
            TypeNode enclosingType = getEnclosingTypeDeclaration(node);
            if (enclosingType == null) {
                // we can't proceed, probably uncompiled sources
                return data;
            }
            previousType = getBestMethodReturnType(enclosingType.getTypeDefinition(), methods, astArgumentList);
        } else {
            // field
            previousType = getTypeDefinitionOfVariableFromScope(node.getScope(), dotSplitImage[0], accessingClass);
        }
        // first element's type in dotSplitImage has already been resolved
        startIndex = 1;
    }
    // as the code is not compiled there and symbol table works on uncompiled code
    if (node.getNameDeclaration() != null && // if it's not null, then let other code handle things
    previousType == null && node.getNameDeclaration().getNode() instanceof TypeNode) {
        // Carry over the type from the declaration
        Class<?> nodeType = ((TypeNode) node.getNameDeclaration().getNode()).getType();
        // FIXME : generic classes and class with generic super types could have the wrong type assigned here
        if (nodeType != null) {
            node.setType(nodeType);
            return super.visit(node, data);
        }
    }
    for (int i = startIndex; i < dotSplitImage.length; ++i) {
        if (previousType == null) {
            break;
        }
        if (i == dotSplitImage.length - 1 && astArguments != null) {
            // method
            List<MethodType> methods = getApplicableMethods(previousType, dotSplitImage[i], Collections.<JavaTypeDefinition>emptyList(), methodArgsArity, accessingClass);
            previousType = getBestMethodReturnType(previousType, methods, astArgumentList);
        } else {
            // field
            previousType = getFieldType(previousType, dotSplitImage[i], accessingClass);
        }
    }
    if (previousType != null) {
        node.setTypeDefinition(previousType);
    }
    return super.visit(node, data);
}
Also used : 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) ASTArguments(net.sourceforge.pmd.lang.java.ast.ASTArguments) ASTArgumentList(net.sourceforge.pmd.lang.java.ast.ASTArgumentList)

Example 9 with JavaTypeDefinition

use of net.sourceforge.pmd.lang.java.typeresolution.typedefinition.JavaTypeDefinition 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 10 with JavaTypeDefinition

use of net.sourceforge.pmd.lang.java.typeresolution.typedefinition.JavaTypeDefinition in project pmd by pmd.

the class ClassTypeResolver method searchImportedStaticMethods.

private List<MethodType> searchImportedStaticMethods(String methodName, List<JavaTypeDefinition> typeArguments, int argArity, Class<?> accessingClass) {
    List<MethodType> foundMethods = new ArrayList<>();
    // TODO: member methods must not be looked at in the code below
    // TODO: add support for properly dealing with shadowing
    List<JavaTypeDefinition> explicitImports = staticNamesToClasses.get(methodName);
    if (explicitImports != null) {
        for (JavaTypeDefinition anImport : explicitImports) {
            foundMethods.addAll(getApplicableMethods(anImport, methodName, typeArguments, argArity, accessingClass));
        }
    }
    if (!foundMethods.isEmpty()) {
        // explicit imports shadow them by name, regardless of method parameters
        return foundMethods;
    }
    for (JavaTypeDefinition anOnDemandImport : importOnDemandStaticClasses) {
        foundMethods.addAll(getApplicableMethods(anOnDemandImport, methodName, typeArguments, argArity, accessingClass));
    }
    return foundMethods;
}
Also used : JavaTypeDefinition(net.sourceforge.pmd.lang.java.typeresolution.typedefinition.JavaTypeDefinition) ArrayList(java.util.ArrayList)

Aggregations

JavaTypeDefinition (net.sourceforge.pmd.lang.java.typeresolution.typedefinition.JavaTypeDefinition)19 ArrayList (java.util.ArrayList)11 ASTArgumentList (net.sourceforge.pmd.lang.java.ast.ASTArgumentList)6 Test (org.junit.Test)6 AbstractJavaTypeNode (net.sourceforge.pmd.lang.java.ast.AbstractJavaTypeNode)5 List (java.util.List)4 TypeNode (net.sourceforge.pmd.lang.java.ast.TypeNode)4 Constraint (net.sourceforge.pmd.lang.java.typeresolution.typeinference.Constraint)3 Method (java.lang.reflect.Method)2 ASTArguments (net.sourceforge.pmd.lang.java.ast.ASTArguments)2 ASTClassOrInterfaceDeclaration (net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration)2 ASTExtendsList (net.sourceforge.pmd.lang.java.ast.ASTExtendsList)2 ASTTypeArguments (net.sourceforge.pmd.lang.java.ast.ASTTypeArguments)2 Bound (net.sourceforge.pmd.lang.java.typeresolution.typeinference.Bound)2 Variable (net.sourceforge.pmd.lang.java.typeresolution.typeinference.Variable)2 AnoymousExtendingObject (net.sourceforge.pmd.typeresolution.testdata.AnoymousExtendingObject)2 SuperClassA2 (net.sourceforge.pmd.typeresolution.testdata.dummytypes.SuperClassA2)2 Type (java.lang.reflect.Type)1 Collection (java.util.Collection)1 HashMap (java.util.HashMap)1