Search in sources :

Example 71 with Types

use of javax.lang.model.util.Types in project checker-framework by typetools.

the class TypeArgInferenceUtil method getMappingFromReturnType.

/**
 * Returns a mapping of type variable to type argument computed using the type of {@code
 * methodInvocationTree} and the return type of {@code methodType}.
 */
private static Map<TypeVariable, TypeMirror> getMappingFromReturnType(ExpressionTree methodInvocationTree, ExecutableType methodType, ProcessingEnvironment env) {
    TypeMirror methodCallType = TreeUtils.typeOf(methodInvocationTree);
    Types types = env.getTypeUtils();
    GetMapping mapping = new GetMapping(methodType.getTypeVariables(), types);
    mapping.visit(methodType.getReturnType(), methodCallType);
    return mapping.subs;
}
Also used : Types(javax.lang.model.util.Types) AnnotatedTypes(org.checkerframework.framework.util.AnnotatedTypes) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror)

Example 72 with Types

use of javax.lang.model.util.Types 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)

Example 73 with Types

use of javax.lang.model.util.Types in project checker-framework by typetools.

the class SupertypesSolver method targetToTypeLubs.

/**
 * For each target, lub all of the types/annotations in its supertypes constraints and return the
 * lubs.
 *
 * @param remainingTargets targets that do not already have an inferred type argument
 * @param constraintMap the set of constraints for all targets
 * @return the lub determined for each target that has at least 1 supertype constraint
 */
private Lubs targetToTypeLubs(Set<TypeVariable> remainingTargets, ConstraintMap constraintMap, AnnotatedTypeFactory typeFactory) {
    final QualifierHierarchy qualifierHierarchy = typeFactory.getQualifierHierarchy();
    final AnnotationMirrorSet tops = new AnnotationMirrorSet(qualifierHierarchy.getTopAnnotations());
    Lubs solution = new Lubs();
    AnnotationMirrorMap<AnnotationMirror> lubOfPrimaries = new AnnotationMirrorMap<>();
    List<TypeVariable> targetsSupertypesLast = new ArrayList<>(remainingTargets);
    final Types types = typeFactory.getProcessingEnv().getTypeUtils();
    // If we have two type variables <A, A extends B> order them B then A
    // this is required because we will use the fact that A must be above B
    // when determining the LUB of A
    Collections.sort(targetsSupertypesLast, new Comparator<TypeVariable>() {

        @Override
        public int compare(TypeVariable o1, TypeVariable o2) {
            if (types.isSubtype(o1, o2)) {
                return -1;
            } else if (types.isSubtype(o2, o1)) {
                return 1;
            }
            return 0;
        }
    });
    for (final TypeVariable target : targetsSupertypesLast) {
        TargetConstraints targetRecord = constraintMap.getConstraints(target);
        final AnnotationMirrorMap<AnnotationMirrorSet> subtypeAnnos = targetRecord.supertypes.primaries;
        final Map<AnnotatedTypeMirror, AnnotationMirrorSet> subtypesOfTarget = targetRecord.supertypes.types;
        // If this target is a supertype of other targets and those targets have already been lubbed
        // add that LUB to the list of lubs for this target (as it must be above this target).
        propagatePreviousLubs(targetRecord, solution, subtypesOfTarget);
        // lub all the primary annotations and put them in lubOfPrimaries
        lubPrimaries(lubOfPrimaries, subtypeAnnos, tops, qualifierHierarchy);
        solution.addPrimaries(target, lubOfPrimaries);
        if (!subtypesOfTarget.isEmpty()) {
            final AnnotatedTypeMirror lub = leastUpperBound(target, typeFactory, subtypesOfTarget);
            final AnnotationMirrorSet effectiveLubAnnos = new AnnotationMirrorSet(lub.getEffectiveAnnotations());
            for (AnnotationMirror lubAnno : effectiveLubAnnos) {
                final AnnotationMirror hierarchy = qualifierHierarchy.getTopAnnotation(lubAnno);
                final AnnotationMirror primaryLub = lubOfPrimaries.get(hierarchy);
                if (primaryLub != null) {
                    if (qualifierHierarchy.isSubtype(lubAnno, primaryLub) && !AnnotationUtils.areSame(lubAnno, primaryLub)) {
                        lub.replaceAnnotation(primaryLub);
                    }
                }
            }
            solution.addType(target, lub);
        }
    }
    return solution;
}
Also used : Types(javax.lang.model.util.Types) AnnotatedTypes(org.checkerframework.framework.util.AnnotatedTypes) AnnotationMirrorMap(org.checkerframework.framework.util.AnnotationMirrorMap) ArrayList(java.util.ArrayList) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) AnnotationMirror(javax.lang.model.element.AnnotationMirror) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) TypeVariable(javax.lang.model.type.TypeVariable) QualifierHierarchy(org.checkerframework.framework.type.QualifierHierarchy) AnnotationMirrorSet(org.checkerframework.framework.util.AnnotationMirrorSet)

Example 74 with Types

use of javax.lang.model.util.Types in project checker-framework by typetools.

the class GlbUtil method sortForGlb.

/**
 * Sort the list of type mirrors, placing supertypes first and subtypes last.
 *
 * <p>E.g. the list: {@code ArrayList<String>, List<String>, AbstractList<String>} becomes: {@code
 * List<String>, AbstractList<String>, ArrayList<String>}
 */
public static void sortForGlb(final List<? extends AnnotatedTypeMirror> typeMirrors, final AnnotatedTypeFactory typeFactory) {
    final QualifierHierarchy qualifierHierarchy = typeFactory.getQualifierHierarchy();
    final Types types = typeFactory.getProcessingEnv().getTypeUtils();
    Collections.sort(typeMirrors, new Comparator<AnnotatedTypeMirror>() {

        @Override
        public int compare(AnnotatedTypeMirror type1, AnnotatedTypeMirror type2) {
            final TypeMirror underlyingType1 = type1.getUnderlyingType();
            final TypeMirror underlyingType2 = type2.getUnderlyingType();
            if (types.isSameType(underlyingType1, underlyingType2)) {
                return compareAnnotations(qualifierHierarchy, type1, type2);
            }
            if (types.isSubtype(underlyingType1, underlyingType2)) {
                return 1;
            }
            // if they're incomparable or type2 is a subtype of type1
            return -1;
        }

        private int compareAnnotations(final QualifierHierarchy qualHierarchy, final AnnotatedTypeMirror type1, final AnnotatedTypeMirror type2) {
            if (AnnotationUtils.areSame(type1.getAnnotations(), type2.getAnnotations())) {
                return 0;
            }
            if (qualHierarchy.isSubtype(type1.getAnnotations(), type2.getAnnotations())) {
                return 1;
            } else {
                return -1;
            }
        }
    });
}
Also used : Types(javax.lang.model.util.Types) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror) QualifierHierarchy(org.checkerframework.framework.type.QualifierHierarchy) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 75 with Types

use of javax.lang.model.util.Types in project checker-framework by typetools.

the class AnnotatedTypes method castedAsSuper.

/**
 * Calls asSuper and casts the result to the same type as the input supertype.
 *
 * @param subtype subtype to be transformed to supertype
 * @param supertype supertype that subtype is transformed to
 * @param <T> the type of supertype and return type
 * @return subtype as an instance of supertype
 */
public static <T extends AnnotatedTypeMirror> T castedAsSuper(final AnnotatedTypeFactory atypeFactory, final AnnotatedTypeMirror subtype, final T supertype) {
    final Types types = atypeFactory.getProcessingEnv().getTypeUtils();
    final Elements elements = atypeFactory.getProcessingEnv().getElementUtils();
    if (subtype.getKind() == TypeKind.NULL) {
        // Make a copy of the supertype so that if supertype is a composite type, the
        // returned type will be fully annotated.  (For example, if sub is @C null and super is
        // @A List<@B String>, then the returned type is @C List<@B String>.)
        @SuppressWarnings("unchecked") T copy = (T) supertype.deepCopy();
        copy.replaceAnnotations(subtype.getAnnotations());
        return copy;
    }
    final T asSuperType = AnnotatedTypes.asSuper(atypeFactory, subtype, supertype);
    fixUpRawTypes(subtype, asSuperType, supertype, types);
    // @1 Enum<E extends @2 Enum<E>>
    if (asSuperType != null && AnnotatedTypes.isEnum(asSuperType) && AnnotatedTypes.isDeclarationOfJavaLangEnum(types, elements, supertype)) {
        final AnnotatedDeclaredType resultAtd = ((AnnotatedDeclaredType) supertype).deepCopy();
        resultAtd.clearPrimaryAnnotations();
        resultAtd.addAnnotations(asSuperType.getAnnotations());
        final AnnotatedDeclaredType asSuperAdt = (AnnotatedDeclaredType) asSuperType;
        if (!resultAtd.getTypeArguments().isEmpty() && !asSuperAdt.getTypeArguments().isEmpty()) {
            final AnnotatedTypeMirror sourceTypeArg = asSuperAdt.getTypeArguments().get(0);
            final AnnotatedTypeMirror resultTypeArg = resultAtd.getTypeArguments().get(0);
            resultTypeArg.clearPrimaryAnnotations();
            if (resultTypeArg.getKind() == TypeKind.TYPEVAR) {
                // Only change the upper bound of a type variable.
                AnnotatedTypeVariable resultTypeArgTV = (AnnotatedTypeVariable) resultTypeArg;
                resultTypeArgTV.getUpperBound().addAnnotations(sourceTypeArg.getAnnotations());
            } else {
                resultTypeArg.addAnnotations(sourceTypeArg.getEffectiveAnnotations());
            }
            @SuppressWarnings("unchecked") T result = (T) resultAtd;
            return result;
        }
    }
    return asSuperType;
}
Also used : Types(javax.lang.model.util.Types) AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) Elements(javax.lang.model.util.Elements) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable)

Aggregations

Types (javax.lang.model.util.Types)113 TypeMirror (javax.lang.model.type.TypeMirror)77 TypeElement (javax.lang.model.element.TypeElement)52 Elements (javax.lang.model.util.Elements)48 ExecutableElement (javax.lang.model.element.ExecutableElement)34 Element (javax.lang.model.element.Element)30 SupportedAnnotationTypes (javax.annotation.processing.SupportedAnnotationTypes)27 DeclaredType (javax.lang.model.type.DeclaredType)26 ArrayList (java.util.ArrayList)25 Map (java.util.Map)24 VariableElement (javax.lang.model.element.VariableElement)24 List (java.util.List)21 AnnotationMirror (javax.lang.model.element.AnnotationMirror)20 TypeKind (javax.lang.model.type.TypeKind)18 Set (java.util.Set)16 Collection (java.util.Collection)15 HashMap (java.util.HashMap)13 ElementKind (javax.lang.model.element.ElementKind)13 Modifier (javax.lang.model.element.Modifier)13 IOException (java.io.IOException)12