Search in sources :

Example 56 with TypeVariable

use of javax.lang.model.type.TypeVariable in project checker-framework by typetools.

the class AnnotatedTypes method substituteTypeVariables.

/**
 * Substitute type variables.
 *
 * @param types type utilities
 * @param atypeFactory the type factory
 * @param receiverType the type of the class that contains member (or a subtype of it)
 * @param member a type member, such as a method or field
 * @param memberType the type of {@code member}
 * @return {@code memberType}, substituted
 */
private static AnnotatedTypeMirror substituteTypeVariables(Types types, AnnotatedTypeFactory atypeFactory, AnnotatedTypeMirror receiverType, Element member, AnnotatedTypeMirror memberType) {
    // Basic Algorithm:
    // 1. Find the enclosingClassOfMember of the element
    // 2. Find the base type of enclosingClassOfMember (e.g. type of enclosingClassOfMember as
    // supertype of passed type)
    // 3. Substitute for type variables if any exist
    TypeElement enclosingClassOfMember = ElementUtils.enclosingTypeElement(member);
    final Map<TypeVariable, AnnotatedTypeMirror> mappings = new HashMap<>();
    // and collect type to be substituted for those type variables
    while (enclosingClassOfMember != null) {
        addTypeVarMappings(types, atypeFactory, receiverType, enclosingClassOfMember, mappings);
        enclosingClassOfMember = ElementUtils.enclosingTypeElement(enclosingClassOfMember.getEnclosingElement());
    }
    if (!mappings.isEmpty()) {
        memberType = atypeFactory.getTypeVarSubstitutor().substitute(mappings, memberType);
    }
    return memberType;
}
Also used : TypeVariable(javax.lang.model.type.TypeVariable) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) TypeElement(javax.lang.model.element.TypeElement) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 57 with TypeVariable

use of javax.lang.model.type.TypeVariable in project checker-framework by typetools.

the class TypeFromTypeTreeVisitor method getTypeVariableFromDeclaration.

/**
 * If a tree is can be found for the declaration of the type variable {@code type}, then a {@link
 * AnnotatedTypeVariable} is returned with explicit annotations from the type variables declared
 * bounds. If a tree cannot be found, then {@code type}, converted to a use, is returned.
 *
 * @param type type variable used to find declaration tree
 * @param f annotated type factory
 * @return the AnnotatedTypeVariable from the declaration of {@code type} or {@code type} if no
 *     tree is found.
 */
private AnnotatedTypeVariable getTypeVariableFromDeclaration(AnnotatedTypeVariable type, AnnotatedTypeFactory f) {
    TypeVariable typeVar = type.getUnderlyingType();
    TypeParameterElement tpe = (TypeParameterElement) typeVar.asElement();
    Element elt = tpe.getGenericElement();
    if (elt instanceof TypeElement) {
        TypeElement typeElt = (TypeElement) elt;
        int idx = typeElt.getTypeParameters().indexOf(tpe);
        ClassTree cls = (ClassTree) f.declarationFromElement(typeElt);
        if (cls == null || cls.getTypeParameters().isEmpty()) {
            // contains all necessary information and we can return that.
            return type.asUse();
        }
        // will return a declaration ATV.  So change it to a use.
        return visitTypeParameter(cls.getTypeParameters().get(idx), f).asUse();
    } else if (elt instanceof ExecutableElement) {
        ExecutableElement exElt = (ExecutableElement) elt;
        int idx = exElt.getTypeParameters().indexOf(tpe);
        MethodTree meth = (MethodTree) f.declarationFromElement(exElt);
        if (meth == null) {
            // + elt);
            return type.asUse();
        }
        // This works the same as the case above.  Even though `meth` itself is not a
        // type declaration tree, the elements of `meth.getTypeParameters()` still are.
        AnnotatedTypeVariable result = visitTypeParameter(meth.getTypeParameters().get(idx), f).shallowCopy();
        result.setDeclaration(false);
        return result;
    } else if (TypesUtils.isCapturedTypeVariable(typeVar)) {
        // not an element at all, namely Symtab.noSymbol.
        return type.asUse();
    } else {
        throw new BugInCF("TypeFromTree.forTypeVariable: not a supported element: " + elt);
    }
}
Also used : AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) TypeVariable(javax.lang.model.type.TypeVariable) MethodTree(com.sun.source.tree.MethodTree) TypeElement(javax.lang.model.element.TypeElement) TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) Element(javax.lang.model.element.Element) TypeParameterElement(javax.lang.model.element.TypeParameterElement) ExecutableElement(javax.lang.model.element.ExecutableElement) ClassTree(com.sun.source.tree.ClassTree) BugInCF(org.checkerframework.javacutil.BugInCF) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) TypeParameterElement(javax.lang.model.element.TypeParameterElement)

Example 58 with TypeVariable

use of javax.lang.model.type.TypeVariable in project checker-framework by typetools.

the class TypesUtils method simpleTypeName.

/**
 * Returns the simple type name, without annotations.
 *
 * @param type a type
 * @return the simple type name, without annotations
 */
public static String simpleTypeName(TypeMirror type) {
    switch(type.getKind()) {
        case ARRAY:
            return simpleTypeName(((ArrayType) type).getComponentType()) + "[]";
        case TYPEVAR:
            return ((TypeVariable) type).asElement().getSimpleName().toString();
        case DECLARED:
            return ((DeclaredType) type).asElement().getSimpleName().toString();
        case NULL:
            return "<nulltype>";
        case VOID:
            return "void";
        case WILDCARD:
            WildcardType wildcard = (WildcardType) type;
            TypeMirror extendsBound = wildcard.getExtendsBound();
            TypeMirror superBound = wildcard.getSuperBound();
            return "?" + (extendsBound != null ? " extends " + simpleTypeName(extendsBound) : "") + (superBound != null ? " super " + simpleTypeName(superBound) : "");
        case UNION:
            StringJoiner sj = new StringJoiner(" | ");
            for (TypeMirror alternative : ((UnionType) type).getAlternatives()) {
                sj.add(simpleTypeName(alternative));
            }
            return sj.toString();
        default:
            if (type.getKind().isPrimitive()) {
                return TypeAnnotationUtils.unannotatedType(type).toString();
            } else {
                throw new BugInCF("simpleTypeName: unhandled type kind: %s, type: %s", type.getKind(), type);
            }
    }
}
Also used : ArrayType(javax.lang.model.type.ArrayType) UnionType(javax.lang.model.type.UnionType) WildcardType(javax.lang.model.type.WildcardType) TypeVariable(javax.lang.model.type.TypeVariable) TypeMirror(javax.lang.model.type.TypeMirror) StringJoiner(java.util.StringJoiner) DeclaredType(javax.lang.model.type.DeclaredType)

Example 59 with TypeVariable

use of javax.lang.model.type.TypeVariable in project checker-framework by typetools.

the class DefaultTypeArgumentInference method createAssignmentConstraints.

/**
 * The first half of Step 6.
 *
 * <p>This method creates constraints:
 *
 * <ul>
 *   <li>between the bounds of types that are already inferred and their inferred arguments
 *   <li>between the assignment context and the return type of the method (with the previously
 *       inferred arguments substituted into these constraints)
 * </ul>
 */
public ConstraintMap createAssignmentConstraints(final AnnotatedTypeMirror assignedTo, final AnnotatedTypeMirror boxedReturnType, final AnnotatedExecutableType methodType, final Set<AFConstraint> afArgumentConstraints, final Map<TypeVariable, AnnotatedTypeMirror> inferredArgs, final Set<TypeVariable> targets, final AnnotatedTypeFactory typeFactory) {
    final ArrayDeque<AFConstraint> assignmentAfs = new ArrayDeque<>(2 * methodType.getTypeVariables().size() + afArgumentConstraints.size());
    for (AnnotatedTypeVariable typeParam : methodType.getTypeVariables()) {
        final TypeVariable target = typeParam.getUnderlyingType();
        final AnnotatedTypeMirror inferredType = inferredArgs.get(target);
        // the lower bound for all uninferred types Tu: Tu >> Bi and Lu >> Tu
        if (inferredType != null) {
            assignmentAfs.add(new A2F(inferredType, typeParam.getUpperBound()));
            assignmentAfs.add(new F2A(typeParam.getLowerBound(), inferredType));
        } else {
            assignmentAfs.add(new F2A(typeParam, typeParam.getUpperBound()));
            assignmentAfs.add(new A2F(typeParam.getLowerBound(), typeParam));
        }
    }
    for (AFConstraint argConstraint : afArgumentConstraints) {
        if (argConstraint instanceof F2A) {
            assignmentAfs.add(argConstraint);
        }
    }
    ArrayDeque<AFConstraint> substitutedAssignmentConstraints = new ArrayDeque<>(assignmentAfs.size() + 1);
    for (AFConstraint afConstraint : assignmentAfs) {
        substitutedAssignmentConstraints.add(afConstraint.substitute(inferredArgs));
    }
    final AnnotatedTypeMirror substitutedReturnType = TypeArgInferenceUtil.substitute(inferredArgs, boxedReturnType);
    substitutedAssignmentConstraints.add(new F2A(substitutedReturnType, assignedTo));
    final Set<AFConstraint> reducedConstraints = new LinkedHashSet<>();
    reduceAfConstraints(typeFactory, reducedConstraints, substitutedAssignmentConstraints, targets);
    final Set<TUConstraint> tuAssignmentConstraints = afToTuConstraints(reducedConstraints, targets);
    addConstraintsBetweenTargets(tuAssignmentConstraints, targets, true, typeFactory);
    return constraintMapBuilder.build(targets, tuAssignmentConstraints, typeFactory);
}
Also used : LinkedHashSet(java.util.LinkedHashSet) F2A(org.checkerframework.framework.util.typeinference.constraint.F2A) TypeVariable(javax.lang.model.type.TypeVariable) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) A2F(org.checkerframework.framework.util.typeinference.constraint.A2F) TUConstraint(org.checkerframework.framework.util.typeinference.constraint.TUConstraint) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) AFConstraint(org.checkerframework.framework.util.typeinference.constraint.AFConstraint) ArrayDeque(java.util.ArrayDeque)

Example 60 with TypeVariable

use of javax.lang.model.type.TypeVariable in project checker-framework by typetools.

the class TypeArgInferenceUtil method correctResults.

/**
 * If the type arguments computed by DefaultTypeArgumentInference don't match the return type
 * mirror of {@code invocation}, then replace those type arguments with an uninferred wildcard.
 */
protected static Map<TypeVariable, AnnotatedTypeMirror> correctResults(Map<TypeVariable, AnnotatedTypeMirror> result, ExpressionTree invocation, ExecutableType methodType, AnnotatedTypeFactory factory) {
    ProcessingEnvironment env = factory.getProcessingEnv();
    Types types = env.getTypeUtils();
    Map<TypeVariable, TypeMirror> fromReturn = getMappingFromReturnType(invocation, methodType, env);
    for (Map.Entry<TypeVariable, AnnotatedTypeMirror> entry : // result is side-effected by this loop, so iterate over a copy
    new ArrayList<>(result.entrySet())) {
        TypeVariable typeVariable = entry.getKey();
        if (!fromReturn.containsKey(typeVariable)) {
            continue;
        }
        TypeMirror correctType = fromReturn.get(typeVariable);
        TypeMirror inferredType = entry.getValue().getUnderlyingType();
        if (types.isSameType(types.erasure(correctType), types.erasure(inferredType))) {
            if (areSameCapture(correctType, inferredType)) {
                continue;
            }
        }
        if (!types.isSameType(correctType, inferredType)) {
            AnnotatedWildcardType wt = factory.getUninferredWildcardType((AnnotatedTypeVariable) AnnotatedTypeMirror.createType(typeVariable, factory, false));
            wt.replaceAnnotations(entry.getValue().getAnnotations());
            result.put(typeVariable, wt);
        }
    }
    return result;
}
Also used : Types(javax.lang.model.util.Types) AnnotatedTypes(org.checkerframework.framework.util.AnnotatedTypes) TypeVariable(javax.lang.model.type.TypeVariable) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror) ArrayList(java.util.ArrayList) AnnotatedWildcardType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedWildcardType) ProcessingEnvironment(javax.annotation.processing.ProcessingEnvironment) Map(java.util.Map) HashMap(java.util.HashMap) AnnotationMirrorMap(org.checkerframework.framework.util.AnnotationMirrorMap) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Aggregations

TypeVariable (javax.lang.model.type.TypeVariable)80 AnnotatedTypeVariable (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable)38 TypeMirror (javax.lang.model.type.TypeMirror)30 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)22 TypeElement (javax.lang.model.element.TypeElement)21 ArrayList (java.util.ArrayList)16 DeclaredType (javax.lang.model.type.DeclaredType)15 HashMap (java.util.HashMap)14 LinkedHashMap (java.util.LinkedHashMap)13 Map (java.util.Map)13 ExecutableElement (javax.lang.model.element.ExecutableElement)12 TypeParameterElement (javax.lang.model.element.TypeParameterElement)12 Test (org.junit.Test)10 ArrayType (javax.lang.model.type.ArrayType)9 WildcardType (javax.lang.model.type.WildcardType)9 AnnotationMirror (javax.lang.model.element.AnnotationMirror)8 Element (javax.lang.model.element.Element)8 AnnotationMirrorMap (org.checkerframework.framework.util.AnnotationMirrorMap)8 AnnotationMirrorSet (org.checkerframework.framework.util.AnnotationMirrorSet)8 VariableElement (javax.lang.model.element.VariableElement)7