Search in sources :

Example 51 with TypeParameterElement

use of javax.lang.model.element.TypeParameterElement in project checker-framework by typetools.

the class SceneToStubWriter method printTypeParameters.

/**
 * Prints the given type parameters.
 *
 * @param typeParameters the type element to print
 * @param printWriter where to print the type parameters
 */
private static void printTypeParameters(List<? extends TypeParameterElement> typeParameters, PrintWriter printWriter) {
    if (typeParameters.isEmpty()) {
        return;
    }
    StringJoiner sj = new StringJoiner(", ", "<", ">");
    for (TypeParameterElement t : typeParameters) {
        sj.add(t.getSimpleName().toString());
    }
    printWriter.print(sj.toString());
}
Also used : StringJoiner(java.util.StringJoiner) TypeParameterElement(javax.lang.model.element.TypeParameterElement)

Example 52 with TypeParameterElement

use of javax.lang.model.element.TypeParameterElement in project checker-framework by typetools.

the class AnnotatedTypes method areCorrespondingTypeVariables.

/**
 * When overriding a method, you must include the same number of type parameters as the base
 * method. By index, these parameters are considered equivalent to the type parameters of the
 * overridden method.
 *
 * <p>Necessary conditions:
 *
 * <ul>
 *   <li>Both type variables are defined in methods.
 *   <li>One of the two methods overrides the other.
 *   <li>Within their method declaration, both types have the same type parameter index.
 * </ul>
 *
 * @return true if type1 and type2 are corresponding type variables (that is, either one
 *     "overrides" the other)
 */
public static boolean areCorrespondingTypeVariables(Elements elements, AnnotatedTypeVariable type1, AnnotatedTypeVariable type2) {
    final TypeParameterElement type1ParamElem = (TypeParameterElement) type1.getUnderlyingType().asElement();
    final TypeParameterElement type2ParamElem = (TypeParameterElement) type2.getUnderlyingType().asElement();
    if (type1ParamElem.getGenericElement() instanceof ExecutableElement && type2ParamElem.getGenericElement() instanceof ExecutableElement) {
        final ExecutableElement type1Executable = (ExecutableElement) type1ParamElem.getGenericElement();
        final ExecutableElement type2Executable = (ExecutableElement) type2ParamElem.getGenericElement();
        final TypeElement type1Class = (TypeElement) type1Executable.getEnclosingElement();
        final TypeElement type2Class = (TypeElement) type2Executable.getEnclosingElement();
        boolean methodIsOverriden = elements.overrides(type1Executable, type2Executable, type1Class) || elements.overrides(type2Executable, type1Executable, type2Class);
        if (methodIsOverriden) {
            boolean haveSameIndex = type1Executable.getTypeParameters().indexOf(type1ParamElem) == type2Executable.getTypeParameters().indexOf(type2ParamElem);
            return haveSameIndex;
        }
    }
    return false;
}
Also used : TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) TypeParameterElement(javax.lang.model.element.TypeParameterElement)

Example 53 with TypeParameterElement

use of javax.lang.model.element.TypeParameterElement 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 54 with TypeParameterElement

use of javax.lang.model.element.TypeParameterElement in project checker-framework by typetools.

the class TypeArgumentMapper method mapTypeArguments.

/**
 * Returns a mapping from the type parameters of subtype to a list of the type parameters in
 * supertype that must be the same type as subtype.
 *
 * <p>e.g.,
 *
 * <pre>{@code
 * class A<A1,A2,A3>
 * class B<B1,B2,B3,B4> extends A<B1,B1,B3> {}
 * }</pre>
 *
 * results in a {@code Map(B1 => [A1,A2], B2 => [], B3 => [A3], B4 => [])}
 *
 * @return a mapping from the type parameters of subtype to the supertype type parameter's that to
 *     which they are a type argument
 */
public static Map<TypeParameterElement, Set<TypeParameterElement>> mapTypeArguments(final TypeElement subtype, final TypeElement supertype, final Types types) {
    final List<TypeRecord> pathToSupertype = depthFirstSearchForSupertype(subtype, supertype, types);
    if (pathToSupertype == null || pathToSupertype.isEmpty()) {
        return new LinkedHashMap<>();
    }
    final Map<TypeParameterElement, Set<TypeParameterElement>> intermediate = new LinkedHashMap<>();
    final Set<TypeParameterElement> currentTypeParams = new HashSet<>();
    // takes a type records of the form:
    // TypeRecord(element = MyMap<Y1,Y2>, type = null)
    // TypeRecord(element = AbstractMap<A1,A2>, type = AbstractMap<Y1,Y2>)
    // TypeRecord(element = Map<M1,M2>, type = AbstractMap<A1,A2>)
    // And makes a map:
    // Map(Y1 -> [A1], Y2 -> [A2], A1 -> [M1], A2 -> M2]
    Iterator<TypeRecord> path = pathToSupertype.iterator();
    TypeRecord current = path.next();
    while (path.hasNext()) {
        TypeRecord next = path.next();
        final List<? extends TypeParameterElement> nextTypeParameter = next.element.getTypeParameters();
        final List<? extends TypeMirror> nextTypeArgs = next.type != null ? next.type.getTypeArguments() : Collections.emptyList();
        currentTypeParams.clear();
        currentTypeParams.addAll(current.element.getTypeParameters());
        for (int i = 0; i < nextTypeArgs.size(); i++) {
            final TypeParameterElement correspondingParameter = nextTypeParameter.get(i);
            final TypeMirror typeArg = nextTypeArgs.get(i);
            final Element typeArgEle = types.asElement(typeArg);
            if (currentTypeParams.contains(typeArgEle)) {
                addToSetMap(intermediate, (TypeParameterElement) typeArgEle, correspondingParameter);
            }
        }
    }
    List<? extends TypeParameterElement> supertypeParams = supertype.getTypeParameters();
    final Map<TypeParameterElement, Set<TypeParameterElement>> result = new LinkedHashMap<>(subtype.getTypeParameters().size());
    // You can think of the map above as a set of links from SubtypeParameter -> Supertype Parameter
    for (TypeParameterElement subtypeParam : subtype.getTypeParameters()) {
        Set<TypeParameterElement> subtypePath = flattenPath(intermediate.get(subtypeParam), intermediate);
        subtypePath.retainAll(supertypeParams);
        result.put(subtypeParam, subtypePath);
    }
    return result;
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) Element(javax.lang.model.element.Element) TypeElement(javax.lang.model.element.TypeElement) TypeParameterElement(javax.lang.model.element.TypeParameterElement) LinkedHashMap(java.util.LinkedHashMap) TypeParameterElement(javax.lang.model.element.TypeParameterElement) TypeMirror(javax.lang.model.type.TypeMirror) HashSet(java.util.HashSet)

Example 55 with TypeParameterElement

use of javax.lang.model.element.TypeParameterElement in project checker-framework by typetools.

the class TypeArgumentMapper method mapTypeArgumentIndices.

/**
 * Returns a mapping from subtype's type parameter indices to the indices of corresponding type
 * parameters in supertype.
 */
public static Set<Pair<Integer, Integer>> mapTypeArgumentIndices(final TypeElement subtype, final TypeElement supertype, final Types types) {
    Set<Pair<Integer, Integer>> result = new HashSet<>();
    if (subtype.equals(supertype)) {
        for (int i = 0; i < subtype.getTypeParameters().size(); i++) {
            result.add(Pair.of(Integer.valueOf(i), Integer.valueOf(i)));
        }
    } else {
        Map<TypeParameterElement, Set<TypeParameterElement>> subToSuperElements = mapTypeArguments(subtype, supertype, types);
        Map<TypeParameterElement, Integer> supertypeIndexes = getElementToIndex(supertype);
        final List<? extends TypeParameterElement> subtypeParams = subtype.getTypeParameters();
        for (int subtypeIndex = 0; subtypeIndex < subtypeParams.size(); subtypeIndex++) {
            final TypeParameterElement subtypeParam = subtypeParams.get(subtypeIndex);
            final Set<TypeParameterElement> correspondingSuperArgs = subToSuperElements.get(subtypeParam);
            if (correspondingSuperArgs != null) {
                for (TypeParameterElement supertypeParam : subToSuperElements.get(subtypeParam)) {
                    result.add(Pair.of(subtypeIndex, supertypeIndexes.get(supertypeParam)));
                }
            }
        }
    }
    return result;
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) Pair(org.checkerframework.javacutil.Pair) HashSet(java.util.HashSet) TypeParameterElement(javax.lang.model.element.TypeParameterElement)

Aggregations

TypeParameterElement (javax.lang.model.element.TypeParameterElement)66 TypeElement (javax.lang.model.element.TypeElement)30 TypeMirror (javax.lang.model.type.TypeMirror)26 Test (org.junit.Test)18 ExecutableElement (javax.lang.model.element.ExecutableElement)13 TypeVariable (javax.lang.model.type.TypeVariable)13 Element (javax.lang.model.element.Element)10 VariableElement (javax.lang.model.element.VariableElement)9 ArrayList (java.util.ArrayList)7 LinkedHashMap (java.util.LinkedHashMap)7 List (java.util.List)7 DeclaredType (javax.lang.model.type.DeclaredType)7 MethodSpec (com.squareup.javapoet.MethodSpec)6 Map (java.util.Map)6 FieldSpec (com.squareup.javapoet.FieldSpec)5 HashSet (java.util.HashSet)4 Modifier (javax.lang.model.element.Modifier)4 ArrayType (javax.lang.model.type.ArrayType)4 Types (javax.lang.model.util.Types)4 MoreElements (com.google.auto.common.MoreElements)3