aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcushon <cushon@google.com>2017-08-25 15:41:25 -0700
committerLiam Miller-Cushon <cushon@google.com>2017-08-28 15:16:12 -0700
commit7e739192557087e402693d4e0c1f342459ad04f6 (patch)
tree462e137acac7add5668e78c7b07e78cb21d9e384
parentb44b5f69708f02440bb278402d8155963391d832 (diff)
downloadturbine-7e739192557087e402693d4e0c1f342459ad04f6.tar.gz
Short-circuit import based name resolution for the enclosing type
This should usually be a no-op, but it avoids import completion in some situations when resolving a type inside its own declaration. This fix allows such compilations to succeed with unresolvable unused imports. It's also a minor performance improvement. MOE_MIGRATED_REVID=166535423
-rw-r--r--java/com/google/turbine/binder/TypeBinder.java5
-rw-r--r--javatests/com/google/turbine/lower/LowerTest.java63
2 files changed, 66 insertions, 2 deletions
diff --git a/java/com/google/turbine/binder/TypeBinder.java b/java/com/google/turbine/binder/TypeBinder.java
index 402de98..5bee45d 100644
--- a/java/com/google/turbine/binder/TypeBinder.java
+++ b/java/com/google/turbine/binder/TypeBinder.java
@@ -151,12 +151,12 @@ public class TypeBinder {
CompoundScope enclosingScope =
base.scope()
.toScope(Resolve.resolveFunction(env, owner))
+ .append(new SingletonScope(base.decl().name(), owner))
.append(new ClassMemberScope(base.owner(), env));
ImmutableList<AnnoInfo> annotations = bindAnnotations(enclosingScope, base.decl().annos());
- CompoundScope bindingScope =
- enclosingScope.append(new SingletonScope(base.decl().name(), owner));
+ CompoundScope bindingScope = enclosingScope;
// type parameters can refer to each other in f-bounds, so update the scope first
bindingScope = bindingScope.append(new MapScope(base.typeParameters()));
@@ -206,6 +206,7 @@ public class TypeBinder {
CompoundScope scope =
base.scope()
.toScope(Resolve.resolveFunction(env, owner))
+ .append(new SingletonScope(base.decl().name(), owner))
.append(new ClassMemberScope(owner, env));
List<MethodInfo> methods =
diff --git a/javatests/com/google/turbine/lower/LowerTest.java b/javatests/com/google/turbine/lower/LowerTest.java
index 8fe8214..7d916fd 100644
--- a/javatests/com/google/turbine/lower/LowerTest.java
+++ b/javatests/com/google/turbine/lower/LowerTest.java
@@ -423,4 +423,67 @@ public class LowerTest {
0);
assertThat((acc[0] & Opcodes.ACC_DEPRECATED) == Opcodes.ACC_DEPRECATED).isTrue();
}
+
+ @Test
+ public void lazyImports() throws Exception {
+ ImmutableMap<String, String> sources =
+ ImmutableMap.<String, String>builder()
+ .put(
+ "b/B.java",
+ lines(
+ "package b;", //
+ "public class B {",
+ " public static class A {",
+ " public static final int X = 0;",
+ " }",
+ " public static class C {}",
+ "}"))
+ .put(
+ "anno/Anno.java",
+ lines(
+ "package anno;", //
+ "public @interface Anno {",
+ " int value() default 0;",
+ "}"))
+ .put(
+ "a/A.java",
+ lines(
+ "package a;", //
+ "import b.B;",
+ "import anno.Anno;",
+ "import static b.B.nosuch.A;",
+ "@Anno(A.X)",
+ "public class A extends B {",
+ " public A a;",
+ " public static final int X = 1;",
+ "}"))
+ .put(
+ "a/C.java",
+ lines(
+ "package c;", //
+ "import static b.B.nosuch.C;",
+ "class C {",
+ " C c;",
+ "}"))
+ .build();
+
+ ImmutableMap<String, String> noImports;
+ {
+ ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
+ sources.forEach(
+ (k, v) -> builder.put(k, v.replaceAll("import static b\\.B\\.nosuch\\..*;", "")));
+ noImports = builder.build();
+ }
+
+ Map<String, byte[]> expected =
+ IntegrationTestSupport.runJavac(noImports, ImmutableList.of(), BOOTCLASSPATH);
+ Map<String, byte[]> actual =
+ IntegrationTestSupport.runTurbine(sources, ImmutableList.of(), BOOTCLASSPATH);
+ assertThat(IntegrationTestSupport.dump(IntegrationTestSupport.sortMembers(actual)))
+ .isEqualTo(IntegrationTestSupport.dump(IntegrationTestSupport.canonicalize(expected)));
+ }
+
+ static String lines(String... lines) {
+ return Joiner.on("\n").join(lines);
+ }
}