diff options
author | cushon <cushon@google.com> | 2016-11-21 08:59:52 -0800 |
---|---|---|
committer | Liam Miller-Cushon <cushon@google.com> | 2016-11-22 23:34:43 -0800 |
commit | 4f0d47545d6c6eb6c7fbdcb19c09fe90088e3f81 (patch) | |
tree | 572c0ce9ac520fe9324c338673d1e54220e546b9 | |
parent | 0ddf140d2a04f5bab18638c3ac1d1ce58f85c368 (diff) | |
download | turbine-4f0d47545d6c6eb6c7fbdcb19c09fe90088e3f81.tar.gz |
Fix a type resolution and canonicalization bug
Interface and superclass type arguments cannot refer to members of the
current type, so any simple name references to member types are not
implicitly qualified by the current class.
MOE_MIGRATED_REVID=139791656
4 files changed, 33 insertions, 18 deletions
diff --git a/java/com/google/turbine/binder/CanonicalTypeBinder.java b/java/com/google/turbine/binder/CanonicalTypeBinder.java index 31dc444..cbfdf0f 100644 --- a/java/com/google/turbine/binder/CanonicalTypeBinder.java +++ b/java/com/google/turbine/binder/CanonicalTypeBinder.java @@ -41,11 +41,11 @@ public class CanonicalTypeBinder { ClassSymbol sym, SourceTypeBoundClass base, Env<ClassSymbol, TypeBoundClass> env) { ClassTy superClassType = null; if (base.superClassType() != null) { - superClassType = Canonicalize.canonicalizeClassTy(env, sym, base.superClassType()); + superClassType = Canonicalize.canonicalizeClassTy(env, base.owner(), base.superClassType()); } ImmutableList.Builder<ClassTy> interfaceTypes = ImmutableList.builder(); for (ClassTy i : base.interfaceTypes()) { - interfaceTypes.add(Canonicalize.canonicalizeClassTy(env, sym, i)); + interfaceTypes.add(Canonicalize.canonicalizeClassTy(env, base.owner(), i)); } ImmutableMap<TyVarSymbol, TyVarInfo> typParamTypes = typeParameters(env, sym, base.typeParameterTypes()); diff --git a/java/com/google/turbine/binder/TypeBinder.java b/java/com/google/turbine/binder/TypeBinder.java index 8397325..071ab39 100644 --- a/java/com/google/turbine/binder/TypeBinder.java +++ b/java/com/google/turbine/binder/TypeBinder.java @@ -195,22 +195,6 @@ public class TypeBinder { case INTERFACE: if (base.decl().xtnds().isPresent()) { superClassType = (Type.ClassTy) bindClassTy(bindingScope, base.decl().xtnds().get()); - // Members inherited from the superclass are visible to interface types. - // (The same is not true for interface types declared before other interface - // types, at least according to javac.) - bindingScope = - bindingScope.append( - new Scope() { - @Override - public LookupResult lookup(LookupKey lookup) { - ClassSymbol result = - Resolve.resolve(env, owner, base.superclass(), lookup.first()); - if (result != null) { - return new LookupResult(result, lookup); - } - return null; - } - }); } else { superClassType = Type.ClassTy.OBJECT; } diff --git a/javatests/com/google/turbine/lower/LowerIntegrationTest.java b/javatests/com/google/turbine/lower/LowerIntegrationTest.java index 91c7d86..a7b4e86 100644 --- a/javatests/com/google/turbine/lower/LowerIntegrationTest.java +++ b/javatests/com/google/turbine/lower/LowerIntegrationTest.java @@ -280,6 +280,7 @@ public class LowerIntegrationTest { "type_anno_array_bound.test", "type_anno_return.test", "type_anno_order.test", + "canon_class_header.test", }; List<Object[]> tests = ImmutableList.copyOf(testCases).stream().map(x -> new Object[] {x}).collect(toList()); diff --git a/javatests/com/google/turbine/lower/testdata/canon_class_header.test b/javatests/com/google/turbine/lower/testdata/canon_class_header.test new file mode 100644 index 0000000..a8012d4 --- /dev/null +++ b/javatests/com/google/turbine/lower/testdata/canon_class_header.test @@ -0,0 +1,30 @@ +=== test/Test.java === +package test; +import test.A.Inner; +import java.util.TreeMap; +import java.util.Map; + +// in Map<K, Inner>, Inner is resolved using the single type import, and is raw +class A<K extends Comparable> extends TreeMap<K, Inner> { + public class Inner {} +} + +class S<T> { + public class Inner {} +} + +// Inner is resolved using the single type import, and is raw +abstract class B<K extends Comparable> extends S implements Map<K, Inner> { +} + +class C extends S<String> { + // Inner is resolved as a member of the enclosing instance, and is implicitly + // qualified by `S<String>` + abstract class One<K> extends TreeMap<K, Inner> { + } + + // Inner is resolved as a member of the enclosing instance (not as a member + // of the superclass!), and is qualified by `S<String>` (not S<Number>) + abstract class Two<K> extends S<Number> implements Map<K, Inner> { + } +} |