From 387fa417a56fdbd5634f3f29af924f9490afcdbb Mon Sep 17 00:00:00 2001 From: Suzanne Millstein Date: Fri, 15 Oct 2021 15:10:42 -0700 Subject: [PATCH 1/8] Fix issue 4924. --- .../framework/type/SupertypeFinder.java | 40 ++++++++++--------- framework/tests/all-systems/Issue4924.java | 15 +++++++ 2 files changed, 37 insertions(+), 18 deletions(-) create mode 100644 framework/tests/all-systems/Issue4924.java 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 b5c73e76dd2..cfbac0b01b4 100644 --- a/framework/src/main/java/org/checkerframework/framework/type/SupertypeFinder.java +++ b/framework/src/main/java/org/checkerframework/framework/type/SupertypeFinder.java @@ -216,28 +216,32 @@ public List visitDeclared(AnnotatedDeclaredType type, Voi */ private Map getTypeVarToTypeArg(AnnotatedDeclaredType type) { Map mapping = new HashMap<>(); - AnnotatedDeclaredType enclosing = type; - while (enclosing != null) { - TypeElement enclosingTypeElement = (TypeElement) enclosing.getUnderlyingType().asElement(); - 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); - } + addTypeVariablesToMapping(mapping, type); + getTypeVarToTypeArg(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)); - } - } + private void addTypeVariablesToMapping( + Map mapping, AnnotatedDeclaredType type) { + TypeElement enclosingTypeElement = (TypeElement) type.getUnderlyingType().asElement(); + List typeParams = enclosingTypeElement.getTypeParameters(); + List 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); + } + } + private void getTypeVarToTypeArg( + AnnotatedDeclaredType enclosing, Map mapping) { + while (enclosing != null) { + addTypeVariablesToMapping(mapping, enclosing); + for (AnnotatedDeclaredType enclSuper : directSupertypes(enclosing)) { + getTypeVarToTypeArg(enclSuper, mapping); + } enclosing = enclosing.getEnclosingType(); } - return mapping; } private List supertypesFromElement( diff --git a/framework/tests/all-systems/Issue4924.java b/framework/tests/all-systems/Issue4924.java new file mode 100644 index 00000000000..d6391c30dd8 --- /dev/null +++ b/framework/tests/all-systems/Issue4924.java @@ -0,0 +1,15 @@ +public class Issue4924 { + interface Callback {} + + static class Template { + class Adapter implements Callback {} + } + + static class Super extends Template {} + + static class Issue extends Super { + void foo() { + Callback f = new Adapter(); + } + } +} From 5c7ef107dbe00af3453d87f4e2c4bd597e46775c Mon Sep 17 00:00:00 2001 From: Suzanne Millstein Date: Fri, 15 Oct 2021 15:47:24 -0700 Subject: [PATCH 2/8] Add Javadocs. --- .../framework/type/SupertypeFinder.java | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 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 cfbac0b01b4..5e42a8c3ed2 100644 --- a/framework/src/main/java/org/checkerframework/framework/type/SupertypeFinder.java +++ b/framework/src/main/java/org/checkerframework/framework/type/SupertypeFinder.java @@ -216,11 +216,23 @@ public List visitDeclared(AnnotatedDeclaredType type, Voi */ private Map getTypeVarToTypeArg(AnnotatedDeclaredType type) { Map mapping = new HashMap<>(); + // 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. addTypeVariablesToMapping(mapping, type); - getTypeVarToTypeArg(type.getEnclosingType(), mapping); + addTypeVarsFromEnclosingTypes(type.getEnclosingType(), mapping); return mapping; } + /** + * 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 + * @param type a type + */ private void addTypeVariablesToMapping( Map mapping, AnnotatedDeclaredType type) { TypeElement enclosingTypeElement = (TypeElement) type.getUnderlyingType().asElement(); @@ -233,12 +245,20 @@ private void addTypeVariablesToMapping( } } - private void getTypeVarToTypeArg( + /** + * Creates a mapping from a type parameter to its corresponding annotated type argument for all + * type parameters of {@code enclosing}, its enclosing types, and all super types of all {@code + * type}'s enclosing types. + * + * @param mapping type variable to type argument map + * @param enclosing a type + */ + private void addTypeVarsFromEnclosingTypes( AnnotatedDeclaredType enclosing, Map mapping) { while (enclosing != null) { addTypeVariablesToMapping(mapping, enclosing); for (AnnotatedDeclaredType enclSuper : directSupertypes(enclosing)) { - getTypeVarToTypeArg(enclSuper, mapping); + addTypeVarsFromEnclosingTypes(enclSuper, mapping); } enclosing = enclosing.getEnclosingType(); } From 633cbbf4b63ec238a770fcff44ca4193dfceae9d Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Tue, 19 Oct 2021 19:11:30 -0700 Subject: [PATCH 3/8] Formatting --- .../checkerframework/framework/type/SupertypeFinder.java | 6 ++---- 1 file changed, 2 insertions(+), 4 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 5e42a8c3ed2..bc0200eeb01 100644 --- a/framework/src/main/java/org/checkerframework/framework/type/SupertypeFinder.java +++ b/framework/src/main/java/org/checkerframework/framework/type/SupertypeFinder.java @@ -217,10 +217,8 @@ public List visitDeclared(AnnotatedDeclaredType type, Voi private Map getTypeVarToTypeArg(AnnotatedDeclaredType type) { Map mapping = new HashMap<>(); // 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. + // `directSupertypes(types)`, which then calls this method. Add the type variables from `type` + // and then recur on the enclosing type and super types. addTypeVariablesToMapping(mapping, type); addTypeVarsFromEnclosingTypes(type.getEnclosingType(), mapping); return mapping; From 0b557a48a1a8612e08f6162200f046272dfaa172 Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Tue, 19 Oct 2021 19:15:04 -0700 Subject: [PATCH 4/8] Add note about side effects --- .../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 bc0200eeb01..e9cfc364222 100644 --- a/framework/src/main/java/org/checkerframework/framework/type/SupertypeFinder.java +++ b/framework/src/main/java/org/checkerframework/framework/type/SupertypeFinder.java @@ -228,7 +228,7 @@ private Map getTypeVarToTypeArg(AnnotatedDecl * 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 + * @param mapping type variable to type argument map; side-effected by this method * @param type a type */ private void addTypeVariablesToMapping( @@ -248,7 +248,7 @@ private void addTypeVariablesToMapping( * type parameters of {@code enclosing}, its enclosing types, and all super types of all {@code * type}'s enclosing types. * - * @param mapping type variable to type argument map + * @param mapping type variable to type argument map; side-effected by this method * @param enclosing a type */ private void addTypeVarsFromEnclosingTypes( From 2f425ceb33caf344023763443c33b6f1192a9b2a Mon Sep 17 00:00:00 2001 From: Suzanne Millstein Date: Wed, 20 Oct 2021 12:49:35 -0700 Subject: [PATCH 5/8] Address code review. --- .../framework/type/SupertypeFinder.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 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 e9cfc364222..f1ec3bb0194 100644 --- a/framework/src/main/java/org/checkerframework/framework/type/SupertypeFinder.java +++ b/framework/src/main/java/org/checkerframework/framework/type/SupertypeFinder.java @@ -218,8 +218,8 @@ private Map getTypeVarToTypeArg(AnnotatedDecl Map mapping = new HashMap<>(); // 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. - addTypeVariablesToMapping(mapping, type); + // and then call addTypeVarsFromEnclosingTypes on the enclosing type. + addTypeVariablesToMapping(type, mapping); addTypeVarsFromEnclosingTypes(type.getEnclosingType(), mapping); return mapping; } @@ -228,11 +228,11 @@ private Map getTypeVarToTypeArg(AnnotatedDecl * 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 + * @param mapping type variable to type argument map; side-effected by this method */ private void addTypeVariablesToMapping( - Map mapping, AnnotatedDeclaredType type) { + AnnotatedDeclaredType type, Map mapping) { TypeElement enclosingTypeElement = (TypeElement) type.getUnderlyingType().asElement(); List typeParams = enclosingTypeElement.getTypeParameters(); List typeArgs = type.getTypeArguments(); @@ -244,7 +244,7 @@ private void addTypeVariablesToMapping( } /** - * Creates a mapping from a type parameter to its corresponding annotated type argument for all + * Adds a mapping from a type parameter to its corresponding annotated type argument for all * type parameters of {@code enclosing}, its enclosing types, and all super types of all {@code * type}'s enclosing types. * @@ -254,7 +254,7 @@ private void addTypeVariablesToMapping( private void addTypeVarsFromEnclosingTypes( AnnotatedDeclaredType enclosing, Map mapping) { while (enclosing != null) { - addTypeVariablesToMapping(mapping, enclosing); + addTypeVariablesToMapping(enclosing, mapping); for (AnnotatedDeclaredType enclSuper : directSupertypes(enclosing)) { addTypeVarsFromEnclosingTypes(enclSuper, mapping); } From 0bac969bef6601ce87cc2605634f5b1baa0ffd31 Mon Sep 17 00:00:00 2001 From: Suzanne Millstein Date: Wed, 20 Oct 2021 13:42:37 -0700 Subject: [PATCH 6/8] Correct documentation. --- .../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 f1ec3bb0194..b28ed461148 100644 --- a/framework/src/main/java/org/checkerframework/framework/type/SupertypeFinder.java +++ b/framework/src/main/java/org/checkerframework/framework/type/SupertypeFinder.java @@ -245,8 +245,8 @@ private void addTypeVariablesToMapping( /** * Adds a mapping from a type parameter to its corresponding annotated type argument for all - * type parameters of {@code enclosing}, its enclosing types, and all super types of all {@code - * type}'s enclosing types. + * type parameters of {@code enclosing} and its enclosing types. This method recurs on all the + * super type of {@code enclosing}. * * @param mapping type variable to type argument map; side-effected by this method * @param enclosing a type From 9e969d0a4eb3496f124f73ed6b100cf0b0bcff05 Mon Sep 17 00:00:00 2001 From: Suzanne Millstein Date: Thu, 21 Oct 2021 10:22:34 -0700 Subject: [PATCH 7/8] Add javadoc. --- .../org/checkerframework/framework/type/SupertypeFinder.java | 3 +++ 1 file changed, 3 insertions(+) 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 b28ed461148..a36d8562293 100644 --- a/framework/src/main/java/org/checkerframework/framework/type/SupertypeFinder.java +++ b/framework/src/main/java/org/checkerframework/framework/type/SupertypeFinder.java @@ -211,6 +211,9 @@ public List visitDeclared(AnnotatedDeclaredType type, Voi * type parameters of {@code type}, its enclosing types, and all super types of all {@code * type}'s enclosing types. * + *

It does not get the type parameters of the supertypes of {@code type} because the result + * of this method is used to substitute the type arguments of the supertypes of {@code type}. + * * @param type a type * @return a mapping from each type parameter to its corresponding annotated type argument */ From 80e6e3a103004776b5867aa6cf3576c57714e28e Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Thu, 21 Oct 2021 12:24:05 -0700 Subject: [PATCH 8/8] Fix typo --- .../org/checkerframework/framework/type/SupertypeFinder.java | 2 +- 1 file changed, 1 insertion(+), 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 a36d8562293..2fe2af1542b 100644 --- a/framework/src/main/java/org/checkerframework/framework/type/SupertypeFinder.java +++ b/framework/src/main/java/org/checkerframework/framework/type/SupertypeFinder.java @@ -249,7 +249,7 @@ private void addTypeVariablesToMapping( /** * Adds a mapping from a type parameter to its corresponding annotated type argument for all * type parameters of {@code enclosing} and its enclosing types. This method recurs on all the - * super type of {@code enclosing}. + * super types of {@code enclosing}. * * @param mapping type variable to type argument map; side-effected by this method * @param enclosing a type