Search in sources :

Example 1 with GenericsTypeName

use of org.codehaus.groovy.ast.GenericsType.GenericsTypeName in project groovy by apache.

the class ResolveVisitor method resolve.

protected boolean resolve(final ClassNode type, final boolean testModuleImports, final boolean testDefaultImports, final boolean testStaticInnerClasses) {
    resolveGenericsTypes(type.getGenericsTypes());
    if (type.isResolved() || type.isPrimaryClassNode())
        return true;
    if (type.isArray()) {
        ClassNode element = type.getComponentType();
        boolean resolved = resolve(element, testModuleImports, testDefaultImports, testStaticInnerClasses);
        if (resolved) {
            ClassNode cn = element.makeArray();
            type.setRedirect(cn);
        }
        return resolved;
    }
    // test if vanilla name is current class name
    if (currentClass == type)
        return true;
    String typeName = type.getName();
    GenericsType genericsType = genericParameterNames.get(new GenericsTypeName(typeName));
    if (genericsType != null) {
        type.setRedirect(genericsType.getType());
        type.setGenericsTypes(new GenericsType[] { genericsType });
        type.setGenericsPlaceHolder(true);
        return true;
    }
    if (currentClass.getNameWithoutPackage().equals(typeName)) {
        type.setRedirect(currentClass);
        return true;
    }
    return (!type.hasPackageName() && resolveNestedClass(type)) || resolveFromModule(type, testModuleImports) || resolveFromCompileUnit(type) || (testDefaultImports && !type.hasPackageName() && resolveFromDefaultImports(type)) || resolveToOuter(type) || (testStaticInnerClasses && type.hasPackageName() && resolveFromStaticInnerClasses(type));
}
Also used : InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) GenericsType(org.codehaus.groovy.ast.GenericsType) GenericsTypeName(org.codehaus.groovy.ast.GenericsType.GenericsTypeName)

Example 2 with GenericsTypeName

use of org.codehaus.groovy.ast.GenericsType.GenericsTypeName in project groovy by apache.

the class StaticTypeCheckingVisitor method extractPlaceHolders.

private static Map<GenericsTypeName, GenericsType> extractPlaceHolders(final ClassNode receiver, final ClassNode declaringClass) {
    Map<GenericsTypeName, GenericsType> result = null;
    ClassNode[] todo;
    if (receiver instanceof UnionTypeClassNode) {
        todo = ((UnionTypeClassNode) receiver).getDelegates();
    } else {
        todo = new ClassNode[] { !isPrimitiveType(declaringClass) ? wrapTypeIfNecessary(receiver) : receiver };
    }
    for (ClassNode type : todo) {
        ClassNode current = type;
        while (current != null) {
            Map<GenericsTypeName, GenericsType> placeHolders = new HashMap<>();
            // GROOVY-10055: handle diamond or raw
            if (current.getGenericsTypes() != null ? current.getGenericsTypes().length == 0 : current.redirect().getGenericsTypes() != null) {
                for (GenericsType gt : current.redirect().getGenericsTypes()) {
                    ClassNode cn = gt.getUpperBounds() != null ? gt.getUpperBounds()[0] : gt.getType().redirect();
                    placeHolders.put(new GenericsTypeName(gt.getName()), cn.getPlainNodeReference().asGenericsType());
                }
            }
            boolean currentIsDeclaring = current.equals(declaringClass) || isGenericsPlaceHolderOrArrayOf(declaringClass);
            if (currentIsDeclaring) {
                extractGenericsConnections(placeHolders, current, declaringClass);
            } else {
                GenericsUtils.extractPlaceholders(current, placeHolders);
            }
            if (result != null) {
                // merge maps
                for (Map.Entry<GenericsTypeName, GenericsType> entry : placeHolders.entrySet()) {
                    GenericsType gt = entry.getValue();
                    if (!gt.isPlaceholder())
                        continue;
                    GenericsType referenced = result.get(new GenericsTypeName(gt.getName()));
                    if (referenced == null)
                        continue;
                    entry.setValue(referenced);
                }
            }
            result = placeHolders;
            // we are done if we are now in the declaring class
            if (currentIsDeclaring)
                break;
            current = getNextSuperClass(current, declaringClass);
            if (current == null && isClassType(declaringClass)) {
                // this can happen if the receiver is Class<Foo>, then
                // the actual receiver is Foo and declaringClass is Class
                current = declaringClass;
            } else {
                current = applyGenericsContext(placeHolders, current);
            }
        }
    }
    if (result == null) {
        throw new GroovyBugError("Declaring class " + prettyPrintTypeName(declaringClass) + " was not matched with receiver " + prettyPrintTypeName(receiver) + ". This should not have happened!");
    }
    return result;
}
Also used : StaticTypeCheckingSupport.findDGMMethodsForClassNode(org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.findDGMMethodsForClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) LinkedHashMap(java.util.LinkedHashMap) HashMap(java.util.HashMap) GenericsType(org.codehaus.groovy.ast.GenericsType) StaticTypeCheckingSupport.getCombinedGenericsType(org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.getCombinedGenericsType) GroovyBugError(org.codehaus.groovy.GroovyBugError) GenericsTypeName(org.codehaus.groovy.ast.GenericsType.GenericsTypeName) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) Collectors.toMap(java.util.stream.Collectors.toMap) EnumMap(java.util.EnumMap) HashMap(java.util.HashMap)

Example 3 with GenericsTypeName

use of org.codehaus.groovy.ast.GenericsType.GenericsTypeName in project groovy by apache.

the class StaticTypeCheckingSupport method extractResolvedPlaceHolders.

private static Set<GenericsTypeName> extractResolvedPlaceHolders(final Map<GenericsTypeName, GenericsType> resolvedMethodGenerics) {
    if (resolvedMethodGenerics.isEmpty())
        return Collections.emptySet();
    Set<GenericsTypeName> result = new HashSet<>();
    for (Map.Entry<GenericsTypeName, GenericsType> entry : resolvedMethodGenerics.entrySet()) {
        GenericsType value = entry.getValue();
        if (value.isPlaceholder())
            continue;
        result.add(entry.getKey());
    }
    return result;
}
Also used : GenericsType(org.codehaus.groovy.ast.GenericsType) GenericsTypeName(org.codehaus.groovy.ast.GenericsType.GenericsTypeName) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) HashMap(java.util.HashMap) LinkedHashSet(java.util.LinkedHashSet) HashSet(java.util.HashSet)

Example 4 with GenericsTypeName

use of org.codehaus.groovy.ast.GenericsType.GenericsTypeName in project groovy by apache.

the class StaticTypeCheckingSupport method fullyResolve.

/**
 * Given a generics type representing SomeClass&lt;T,V&gt; and a resolved placeholder map, returns a new generics type
 * for which placeholders are resolved recursively.
 */
protected static GenericsType fullyResolve(GenericsType gt, final Map<GenericsTypeName, GenericsType> placeholders) {
    GenericsType fromMap = placeholders.get(new GenericsTypeName(gt.getName()));
    if (gt.isPlaceholder() && fromMap != null) {
        gt = fromMap;
    }
    ClassNode type = fullyResolveType(gt.getType(), placeholders);
    ClassNode lowerBound = gt.getLowerBound();
    if (lowerBound != null)
        lowerBound = fullyResolveType(lowerBound, placeholders);
    ClassNode[] upperBounds = gt.getUpperBounds();
    if (upperBounds != null) {
        ClassNode[] copy = new ClassNode[upperBounds.length];
        for (int i = 0, upperBoundsLength = upperBounds.length; i < upperBoundsLength; i++) {
            final ClassNode upperBound = upperBounds[i];
            copy[i] = fullyResolveType(upperBound, placeholders);
        }
        upperBounds = copy;
    }
    GenericsType genericsType = new GenericsType(type, upperBounds, lowerBound);
    genericsType.setWildcard(gt.isWildcard());
    return genericsType;
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) GenericsType(org.codehaus.groovy.ast.GenericsType) GenericsTypeName(org.codehaus.groovy.ast.GenericsType.GenericsTypeName)

Example 5 with GenericsTypeName

use of org.codehaus.groovy.ast.GenericsType.GenericsTypeName in project groovy by apache.

the class StaticTypeCheckingSupport method fullyResolveType.

protected static ClassNode fullyResolveType(final ClassNode type, final Map<GenericsTypeName, GenericsType> placeholders) {
    if (type.isArray()) {
        return fullyResolveType(type.getComponentType(), placeholders).makeArray();
    }
    if (type.isUsingGenerics()) {
        if (type.isGenericsPlaceHolder()) {
            GenericsType gt = placeholders.get(new GenericsTypeName(type.getUnresolvedName()));
            if (gt != null) {
                return gt.getType();
            }
            ClassNode cn = type.redirect();
            return cn != type ? cn : OBJECT_TYPE;
        } else {
            GenericsType[] gts = type.getGenericsTypes();
            if (gts != null) {
                gts = Arrays.stream(gts).map(gt -> {
                    if (gt.isPlaceholder()) {
                        GenericsTypeName gtn = new GenericsTypeName(gt.getName());
                        return placeholders.getOrDefault(gtn, extractType(gt).asGenericsType());
                    }
                    return fullyResolve(gt, placeholders);
                }).toArray(GenericsType[]::new);
            }
            ClassNode cn = type.getPlainNodeReference();
            cn.setGenericsTypes(gts);
            return cn;
        }
    }
    return type;
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) GenericsType(org.codehaus.groovy.ast.GenericsType) GenericsTypeName(org.codehaus.groovy.ast.GenericsType.GenericsTypeName)

Aggregations

GenericsType (org.codehaus.groovy.ast.GenericsType)27 GenericsTypeName (org.codehaus.groovy.ast.GenericsType.GenericsTypeName)27 ClassNode (org.codehaus.groovy.ast.ClassNode)25 InnerClassNode (org.codehaus.groovy.ast.InnerClassNode)25 HashMap (java.util.HashMap)16 LinkedHashMap (java.util.LinkedHashMap)15 Parameter (org.codehaus.groovy.ast.Parameter)14 Map (java.util.Map)12 MethodNode (org.codehaus.groovy.ast.MethodNode)12 StaticTypeCheckingSupport.findDGMMethodsForClassNode (org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.findDGMMethodsForClassNode)12 StaticTypeCheckingSupport.getCombinedGenericsType (org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.getCombinedGenericsType)12 ClosureSignatureHint (groovy.transform.stc.ClosureSignatureHint)10 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)10 ArrayExpression (org.codehaus.groovy.ast.expr.ArrayExpression)10 BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)10 CastExpression (org.codehaus.groovy.ast.expr.CastExpression)10 ClosureExpression (org.codehaus.groovy.ast.expr.ClosureExpression)10 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)10 Expression (org.codehaus.groovy.ast.expr.Expression)10 ListExpression (org.codehaus.groovy.ast.expr.ListExpression)10