Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correct finding type variables of enclosing classes. #4931

Merged
merged 11 commits into from Oct 21, 2021
Expand Up @@ -216,28 +216,50 @@ public List<AnnotatedDeclaredType> visitDeclared(AnnotatedDeclaredType type, Voi
*/
smillst marked this conversation as resolved.
Show resolved Hide resolved
private Map<TypeVariable, AnnotatedTypeMirror> getTypeVarToTypeArg(AnnotatedDeclaredType type) {
Map<TypeVariable, AnnotatedTypeMirror> mapping = new HashMap<>();
AnnotatedDeclaredType enclosing = type;
while (enclosing != null) {
TypeElement enclosingTypeElement = (TypeElement) enclosing.getUnderlyingType().asElement();
List<? extends TypeParameterElement> typeParams = enclosingTypeElement.getTypeParameters();
List<AnnotatedTypeMirror> typeArgs = enclosing.getTypeArguments();
for (int i = 0; i < enclosing.getTypeArguments().size(); ++i) {
AnnotatedTypeMirror typArg = typeArgs.get(i);
TypeParameterElement ele = typeParams.get(i);
mapping.put((TypeVariable) ele.asType(), typArg);
}
// addTypeVarsFromEnclosingTypes can't be called with `type` because it calls
// `directSupertypes(types)`, which then calls this method. Add the type variables from `type`
// and then recur on the enclosing type and super types.
smillst marked this conversation as resolved.
Show resolved Hide resolved
addTypeVariablesToMapping(mapping, type);
addTypeVarsFromEnclosingTypes(type.getEnclosingType(), mapping);
return mapping;
}

@SuppressWarnings("interning:not.interned") // First time through type == enclosing.
boolean notType = enclosing != type;
if (notType) {
for (AnnotatedDeclaredType enclSuper : directSupertypes(enclosing)) {
mapping.putAll(getTypeVarToTypeArg(enclSuper));
}
}
/**
* Adds a mapping from a type parameter to its corresponding annotated type argument for all
* type parameters of {@code type}.
*
* @param mapping type variable to type argument map; side-effected by this method
* @param type a type
*/
private void addTypeVariablesToMapping(
Map<TypeVariable, AnnotatedTypeMirror> mapping, AnnotatedDeclaredType type) {
TypeElement enclosingTypeElement = (TypeElement) type.getUnderlyingType().asElement();
List<? extends TypeParameterElement> typeParams = enclosingTypeElement.getTypeParameters();
List<AnnotatedTypeMirror> typeArgs = type.getTypeArguments();
for (int i = 0; i < type.getTypeArguments().size(); ++i) {
AnnotatedTypeMirror typArg = typeArgs.get(i);
TypeParameterElement ele = typeParams.get(i);
mapping.put((TypeVariable) ele.asType(), typArg);
}
}

/**
* Creates a mapping from a type parameter to its corresponding annotated type argument for all
smillst marked this conversation as resolved.
Show resolved Hide resolved
* type parameters of {@code enclosing}, its enclosing types, and all super types of all {@code
smillst marked this conversation as resolved.
Show resolved Hide resolved
* type}'s enclosing types.
*
* @param mapping type variable to type argument map; side-effected by this method
* @param enclosing a type
*/
private void addTypeVarsFromEnclosingTypes(
AnnotatedDeclaredType enclosing, Map<TypeVariable, AnnotatedTypeMirror> mapping) {
smillst marked this conversation as resolved.
Show resolved Hide resolved
while (enclosing != null) {
addTypeVariablesToMapping(mapping, enclosing);
for (AnnotatedDeclaredType enclSuper : directSupertypes(enclosing)) {
addTypeVarsFromEnclosingTypes(enclSuper, mapping);
}
enclosing = enclosing.getEnclosingType();
}
return mapping;
}

private List<AnnotatedDeclaredType> supertypesFromElement(
Expand Down
15 changes: 15 additions & 0 deletions framework/tests/all-systems/Issue4924.java
@@ -0,0 +1,15 @@
public class Issue4924 {
interface Callback<A> {}

static class Template<B> {
class Adapter implements Callback<B> {}
}

static class Super<C> extends Template<C> {}

static class Issue extends Super<String> {
void foo() {
Callback<String> f = new Adapter();
}
}
}