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());
}
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;
}
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);
}
}
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;
}
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;
}
Aggregations