Search in sources :

Example 1 with ASTTypeParameter

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

the class ClassScope method resolveGenericType.

/**
 * Tries to resolve a given typeImage as a generic Type. If the Generic Type
 * is found, any defined ClassOrInterfaceType below this type declaration is
 * used (this is typically a type bound, e.g. {@code <T extends List>}.
 *
 * @param argument
 *            the node, from where to start searching.
 * @param typeImage
 *            the type as string
 * @return the resolved class or <code>null</code> if nothing was found.
 */
private Class<?> resolveGenericType(Node argument, String typeImage) {
    List<ASTTypeParameter> types = new ArrayList<>();
    // first search only within the same method
    ASTClassOrInterfaceBodyDeclaration firstParentOfType = argument.getFirstParentOfType(ASTClassOrInterfaceBodyDeclaration.class);
    if (firstParentOfType != null) {
        types.addAll(firstParentOfType.findDescendantsOfType(ASTTypeParameter.class));
    }
    // then search class level types, from inner-most to outer-most
    List<ASTClassOrInterfaceDeclaration> enclosingClasses = argument.getParentsOfType(ASTClassOrInterfaceDeclaration.class);
    for (ASTClassOrInterfaceDeclaration enclosing : enclosingClasses) {
        ASTTypeParameters classLevelTypeParameters = enclosing.getFirstChildOfType(ASTTypeParameters.class);
        if (classLevelTypeParameters != null) {
            types.addAll(classLevelTypeParameters.findDescendantsOfType(ASTTypeParameter.class));
        }
    }
    return resolveGenericType(typeImage, types);
}
Also used : ASTClassOrInterfaceDeclaration(net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration) ArrayList(java.util.ArrayList) ASTClassOrInterfaceBodyDeclaration(net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceBodyDeclaration) ASTTypeParameter(net.sourceforge.pmd.lang.java.ast.ASTTypeParameter) ASTTypeParameters(net.sourceforge.pmd.lang.java.ast.ASTTypeParameters)

Example 2 with ASTTypeParameter

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

the class ClassTypeResolver method populateType.

private void populateType(TypeNode node, String className, int arrayDimens) {
    String qualifiedName = className;
    Class<?> myType = PRIMITIVE_TYPES.get(className);
    if (myType == null && importedClasses != null) {
        if (importedClasses.containsKey(className)) {
            qualifiedName = importedClasses.get(className);
        } else if (importedClasses.containsValue(className)) {
            qualifiedName = className;
        }
        if (qualifiedName != null) {
            try {
                /*
                     * TODO - the map right now contains just class names. if we
                     * use a map of classname/class then we don't have to hit
                     * the class loader for every type - much faster
                     */
                myType = pmdClassLoader.loadClass(qualifiedName);
            } catch (ClassNotFoundException e) {
                myType = processOnDemand(qualifiedName);
            } catch (LinkageError e) {
                myType = processOnDemand(qualifiedName);
            }
        }
    }
    if (myType == null && qualifiedName != null && qualifiedName.contains(".")) {
        // try if the last part defines a inner class
        String qualifiedNameInner = qualifiedName.substring(0, qualifiedName.lastIndexOf('.')) + "$" + qualifiedName.substring(qualifiedName.lastIndexOf('.') + 1);
        try {
            myType = pmdClassLoader.loadClass(qualifiedNameInner);
        } catch (Exception ignored) {
        // ignored, we'll try again with a different package name/fqcn
        }
    }
    if (myType == null && qualifiedName != null && !qualifiedName.contains(".")) {
        // try again with java.lang....
        try {
            myType = pmdClassLoader.loadClass("java.lang." + qualifiedName);
        } catch (Exception ignored) {
        // ignored, we'll try again with generics
        }
    }
    // TODO: generic declarations can shadow type declarations ... :(
    if (myType == null) {
        ASTTypeParameter parameter = getTypeParameterDeclaration(node, className);
        if (parameter != null) {
            node.setTypeDefinition(parameter.getTypeDefinition());
        }
    } else {
        if (arrayDimens > 0) {
            myType = Array.newInstance(myType, (int[]) Array.newInstance(int.class, arrayDimens)).getClass();
        }
        node.setType(myType);
    }
}
Also used : ASTTypeParameter(net.sourceforge.pmd.lang.java.ast.ASTTypeParameter)

Aggregations

ASTTypeParameter (net.sourceforge.pmd.lang.java.ast.ASTTypeParameter)2 ArrayList (java.util.ArrayList)1 ASTClassOrInterfaceBodyDeclaration (net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceBodyDeclaration)1 ASTClassOrInterfaceDeclaration (net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration)1 ASTTypeParameters (net.sourceforge.pmd.lang.java.ast.ASTTypeParameters)1