aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLiam Miller-Cushon <cushon@google.com>2023-01-23 14:13:40 -0800
committerJavac Team <javac-team+copybara@google.com>2023-01-23 14:14:45 -0800
commit7a40bb4dfb0f2fc9dc4f1b95434abe268752ec6c (patch)
tree5ce99b3ecf5e8c87b5762b8654a0fa16149a7434
parent52699ff1ba8f358a02842b894dc10337def0e7fc (diff)
downloadturbine-7a40bb4dfb0f2fc9dc4f1b95434abe268752ec6c.tar.gz
Check interface and non-interface types in `extends` and `implements` lists
PiperOrigin-RevId: 504078954
-rw-r--r--java/com/google/turbine/binder/TypeBinder.java29
-rw-r--r--java/com/google/turbine/diag/TurbineError.java2
-rw-r--r--javatests/com/google/turbine/binder/BinderErrorTest.java40
-rw-r--r--javatests/com/google/turbine/binder/BinderTest.java2
-rw-r--r--javatests/com/google/turbine/lower/LowerTest.java2
-rw-r--r--javatests/com/google/turbine/processing/TurbineElementsGetAllMembersTest.java10
6 files changed, 74 insertions, 11 deletions
diff --git a/java/com/google/turbine/binder/TypeBinder.java b/java/com/google/turbine/binder/TypeBinder.java
index edfacba..ec579e7 100644
--- a/java/com/google/turbine/binder/TypeBinder.java
+++ b/java/com/google/turbine/binder/TypeBinder.java
@@ -206,7 +206,8 @@ public class TypeBinder {
break;
case CLASS:
if (base.decl().xtnds().isPresent()) {
- superClassType = bindClassTy(bindingScope, base.decl().xtnds().get());
+ superClassType =
+ checkClassType(bindingScope, base.decl().xtnds().get(), /* expectInterface= */ false);
} else if (owner.equals(ClassSymbol.OBJECT)) {
// java.lang.Object doesn't have a superclass
superClassType = null;
@@ -228,7 +229,7 @@ public class TypeBinder {
}
for (Tree.ClassTy i : base.decl().impls()) {
- interfaceTypes.add(bindClassTy(bindingScope, i));
+ interfaceTypes.add(checkClassType(bindingScope, i, /* expectInterface= */ true));
}
ImmutableList.Builder<ClassSymbol> permits = ImmutableList.builder();
@@ -449,6 +450,30 @@ public class TypeBinder {
throw new AssertionError(a.tyKind());
}
+ private Type checkClassType(CompoundScope scope, ClassTy tree, boolean expectInterface) {
+ Type type = bindClassTy(scope, tree);
+ if (type.tyKind().equals(Type.TyKind.ERROR_TY)) {
+ return type;
+ }
+ HeaderBoundClass info = env.getNonNull(((Type.ClassTy) type).sym());
+ boolean isInterface;
+ switch (info.kind()) {
+ case INTERFACE:
+ case ANNOTATION:
+ isInterface = true;
+ break;
+ default:
+ isInterface = false;
+ break;
+ }
+ if (expectInterface != isInterface) {
+ log.error(
+ tree.position(),
+ expectInterface ? ErrorKind.EXPECTED_INTERFACE : ErrorKind.UNEXPECTED_INTERFACE);
+ }
+ return type;
+ }
+
/**
* A generated for synthetic {@link MethodSymbol}s.
*
diff --git a/java/com/google/turbine/diag/TurbineError.java b/java/com/google/turbine/diag/TurbineError.java
index f839345..8031fa5 100644
--- a/java/com/google/turbine/diag/TurbineError.java
+++ b/java/com/google/turbine/diag/TurbineError.java
@@ -57,6 +57,8 @@ public class TurbineError extends Error {
BAD_MODULE_INFO("unexpected declaration found in module-info"),
UNCLOSED_COMMENT("unclosed comment"),
UNEXPECTED_TYPE("unexpected type %s"),
+ EXPECTED_INTERFACE("expected interface type"),
+ UNEXPECTED_INTERFACE("unexpected interface type"),
UNEXPECTED_MODIFIER("unexpected modifier: %s"),
PROC("%s");
diff --git a/javatests/com/google/turbine/binder/BinderErrorTest.java b/javatests/com/google/turbine/binder/BinderErrorTest.java
index 1a83f0d..a1bea05 100644
--- a/javatests/com/google/turbine/binder/BinderErrorTest.java
+++ b/javatests/com/google/turbine/binder/BinderErrorTest.java
@@ -681,7 +681,9 @@ public class BinderErrorTest {
"class T extends T {}",
},
{
- "<>:1: error: cycle in class hierarchy: T", "class T extends T {}", " ^",
+ "<>:1: error: cycle in class hierarchy: T", //
+ "class T extends T {}",
+ " ^",
},
},
{
@@ -692,6 +694,19 @@ public class BinderErrorTest {
"<>:1: error: cycle in class hierarchy: T",
"class T implements T {}",
" ^",
+ "<>:1: error: expected interface type",
+ "class T implements T {}",
+ " ^",
+ },
+ },
+ {
+ {
+ "interface T extends T {}",
+ },
+ {
+ "<>:1: error: cycle in class hierarchy: T",
+ "interface T extends T {}",
+ " ^",
},
},
{
@@ -768,7 +783,9 @@ public class BinderErrorTest {
"@interface Test {}",
},
{
- "<>:3: error: missing required annotation argument: value", "@Retention", "^",
+ "<>:3: error: missing required annotation argument: value", //
+ "@Retention",
+ "^",
},
},
{
@@ -958,6 +975,25 @@ public class BinderErrorTest {
},
{
{
+ "class C {}", //
+ "interface I {}",
+ "class A extends I implements C {}",
+ "interface B extends C {}",
+ },
+ {
+ "<>:3: error: unexpected interface type",
+ "class A extends I implements C {}",
+ " ^",
+ "<>:3: error: expected interface type",
+ "class A extends I implements C {}",
+ " ^",
+ "<>:4: error: expected interface type",
+ "interface B extends C {}",
+ " ^",
+ },
+ },
+ {
+ {
"class T<X, X> {", //
" <Y, Y> void f() {}",
"}",
diff --git a/javatests/com/google/turbine/binder/BinderTest.java b/javatests/com/google/turbine/binder/BinderTest.java
index 40387ac..52b769b 100644
--- a/javatests/com/google/turbine/binder/BinderTest.java
+++ b/javatests/com/google/turbine/binder/BinderTest.java
@@ -265,7 +265,7 @@ public class BinderTest {
parseLines(
"import java.lang.annotation.Target;",
"import java.lang.annotation.ElementType;",
- "public class C implements B {",
+ "public class C extends B {",
" @Target(ElementType.TYPE_USE)",
" @interface A {};",
"}"));
diff --git a/javatests/com/google/turbine/lower/LowerTest.java b/javatests/com/google/turbine/lower/LowerTest.java
index fdcfbb3..f04ef27 100644
--- a/javatests/com/google/turbine/lower/LowerTest.java
+++ b/javatests/com/google/turbine/lower/LowerTest.java
@@ -545,7 +545,7 @@ public class LowerTest {
.put(
"Test.java",
lines(
- "public class Test extends B.BM {", //
+ "public class Test implements B.BM {", //
" I i;",
"}"))
.build();
diff --git a/javatests/com/google/turbine/processing/TurbineElementsGetAllMembersTest.java b/javatests/com/google/turbine/processing/TurbineElementsGetAllMembersTest.java
index 11dedbf..bc6d9e6 100644
--- a/javatests/com/google/turbine/processing/TurbineElementsGetAllMembersTest.java
+++ b/javatests/com/google/turbine/processing/TurbineElementsGetAllMembersTest.java
@@ -77,17 +77,17 @@ public class TurbineElementsGetAllMembersTest {
},
{
"=== I.java ===",
- "abstract class I {",
- " abstract Integer f();",
+ "interface I {",
+ " default Integer f() {}",
"}",
"=== J.java ===",
- "interface J extends I {",
- " default Integer f() {",
+ "class J implements I {",
+ " Integer f() {",
" return 42;",
" }",
"}",
"=== Test.java ===", //
- "class Test extends I implements J {",
+ "class Test extends J implements I {",
"}",
},
{