From 000f8a1e937cebfcf1ed9ab63870ea2a6dd1e60c Mon Sep 17 00:00:00 2001 From: Suzanne Millstein Date: Thu, 5 Aug 2021 09:50:47 -0700 Subject: [PATCH 1/3] Type parameters from enclosing super types. --- checker/tests/nullness/Issue4853Nullness.java | 18 +++++++++ .../framework/type/SupertypeFinder.java | 40 ++++++++++++++----- framework/tests/all-systems/Issue4853.java | 16 ++++++++ 3 files changed, 64 insertions(+), 10 deletions(-) create mode 100644 checker/tests/nullness/Issue4853Nullness.java create mode 100644 framework/tests/all-systems/Issue4853.java diff --git a/checker/tests/nullness/Issue4853Nullness.java b/checker/tests/nullness/Issue4853Nullness.java new file mode 100644 index 00000000000..2800a9b9411 --- /dev/null +++ b/checker/tests/nullness/Issue4853Nullness.java @@ -0,0 +1,18 @@ +import org.checkerframework.checker.nullness.qual.Nullable; + +public class Issue4853Nullness { + interface Interface {} + + static class MyClass { + class InnerMyClass implements Interface {} + } + + abstract static class SubMyClass extends MyClass<@Nullable String> { + protected void f() { + // :: error: (argument) + method(new InnerMyClass()); + } + + abstract void method(Interface callback); + } +} diff --git a/framework/src/main/java/org/checkerframework/framework/type/SupertypeFinder.java b/framework/src/main/java/org/checkerframework/framework/type/SupertypeFinder.java index 5c2e3e7ade7..82b8822b5d2 100644 --- a/framework/src/main/java/org/checkerframework/framework/type/SupertypeFinder.java +++ b/framework/src/main/java/org/checkerframework/framework/type/SupertypeFinder.java @@ -193,29 +193,49 @@ public List visitDeclared(AnnotatedDeclaredType type, Voi supertypes.add(jlaAnnotation); } + Map typeVarToTypeArg = getTypeVarToTypeArg(type); + + List superTypesNew = new ArrayList<>(); + for (AnnotatedDeclaredType dt : supertypes) { + type.atypeFactory.initializeAtm(dt); + superTypesNew.add( + (AnnotatedDeclaredType) + atypeFactory.getTypeVarSubstitutor().substitute(typeVarToTypeArg, dt)); + } + + return superTypesNew; + } + + /** + * Creates a mapping from a type parameter to its corresponding annotated type argument for all + * type parameters of {@code type}, it's enclosing types, and all super types of all {@code + * type}'s enclosing types. + * + * @param type a type + * @return a mapping from a type parameter to its corresponding annotated type argument + */ + private Map getTypeVarToTypeArg(AnnotatedDeclaredType type) { Map mapping = new HashMap<>(); AnnotatedDeclaredType enclosing = type; while (enclosing != null) { TypeElement enclosingTypeElement = (TypeElement) enclosing.getUnderlyingType().asElement(); - List typeArgs = enclosing.getTypeArguments(); List typeParams = enclosingTypeElement.getTypeParameters(); + List 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); } - enclosing = enclosing.getEnclosingType(); - } + if (enclosing != type) { + for (AnnotatedDeclaredType enclSuper : directSupertypes(enclosing)) { + mapping.putAll(getTypeVarToTypeArg(enclSuper)); + } + } - List superTypesNew = new ArrayList<>(); - for (AnnotatedDeclaredType dt : supertypes) { - type.atypeFactory.initializeAtm(dt); - superTypesNew.add( - (AnnotatedDeclaredType) atypeFactory.getTypeVarSubstitutor().substitute(mapping, dt)); + enclosing = enclosing.getEnclosingType(); } - - return superTypesNew; + return mapping; } private List supertypesFromElement( diff --git a/framework/tests/all-systems/Issue4853.java b/framework/tests/all-systems/Issue4853.java new file mode 100644 index 00000000000..7445725eeb1 --- /dev/null +++ b/framework/tests/all-systems/Issue4853.java @@ -0,0 +1,16 @@ +@SuppressWarnings("all") // Just check for crashes. +public class Issue4853 { + interface Interface {} + + static class MyClass { + class InnerMyClass implements Interface {} + } + + abstract static class SubMyClass extends MyClass { + protected void f() { + method(new InnerMyClass()); + } + + abstract void method(Interface callback); + } +} From 646da0843462a7ce8bd43af57758a4a561e0081f Mon Sep 17 00:00:00 2001 From: Suzanne Millstein Date: Thu, 5 Aug 2021 10:49:13 -0700 Subject: [PATCH 2/3] Suppress warning. --- .../org/checkerframework/framework/type/SupertypeFinder.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/framework/src/main/java/org/checkerframework/framework/type/SupertypeFinder.java b/framework/src/main/java/org/checkerframework/framework/type/SupertypeFinder.java index 82b8822b5d2..7d36191cbd3 100644 --- a/framework/src/main/java/org/checkerframework/framework/type/SupertypeFinder.java +++ b/framework/src/main/java/org/checkerframework/framework/type/SupertypeFinder.java @@ -227,7 +227,9 @@ private Map getTypeVarToTypeArg(AnnotatedDecl mapping.put((TypeVariable) ele.asType(), typArg); } - if (enclosing != type) { + @SuppressWarnings("interning:not.interned") // First time through type == enclosing. + boolean notType = enclosing != type; + if (notType) { for (AnnotatedDeclaredType enclSuper : directSupertypes(enclosing)) { mapping.putAll(getTypeVarToTypeArg(enclSuper)); } From 9fca96017cc9c75f5298ff45d14fb3040ce513b1 Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Thu, 12 Aug 2021 09:26:05 -0700 Subject: [PATCH 3/3] Fix typo --- .../org/checkerframework/framework/type/SupertypeFinder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/framework/src/main/java/org/checkerframework/framework/type/SupertypeFinder.java b/framework/src/main/java/org/checkerframework/framework/type/SupertypeFinder.java index 7d36191cbd3..b5c73e76dd2 100644 --- a/framework/src/main/java/org/checkerframework/framework/type/SupertypeFinder.java +++ b/framework/src/main/java/org/checkerframework/framework/type/SupertypeFinder.java @@ -208,11 +208,11 @@ public List visitDeclared(AnnotatedDeclaredType type, Voi /** * Creates a mapping from a type parameter to its corresponding annotated type argument for all - * type parameters of {@code type}, it's enclosing types, and all super types of all {@code + * type parameters of {@code type}, its enclosing types, and all super types of all {@code * type}'s enclosing types. * * @param type a type - * @return a mapping from a type parameter to its corresponding annotated type argument + * @return a mapping from each type parameter to its corresponding annotated type argument */ private Map getTypeVarToTypeArg(AnnotatedDeclaredType type) { Map mapping = new HashMap<>();