Handle c-style array parameter declarations
MOE_MIGRATED_REVID=137780263
diff --git a/java/com/google/turbine/parse/Parser.java b/java/com/google/turbine/parse/Parser.java
index 1762282..ab05511 100644
--- a/java/com/google/turbine/parse/Parser.java
+++ b/java/com/google/turbine/parse/Parser.java
@@ -37,6 +37,7 @@
import com.google.turbine.tree.Tree.CompUnit;
import com.google.turbine.tree.Tree.Expression;
import com.google.turbine.tree.Tree.ImportDecl;
+import com.google.turbine.tree.Tree.Kind;
import com.google.turbine.tree.Tree.MethDecl;
import com.google.turbine.tree.Tree.PkgDecl;
import com.google.turbine.tree.Tree.PrimTy;
@@ -654,9 +655,9 @@
Type ty = baseTy;
if (it.hasNext()) {
SavedToken next = it.next();
+ int extra = 0;
while (next.token == Token.LBRACK) {
- // TODO(cushon): type annotations on c-style array dims
- ty = new ArrTy(position, ImmutableList.of(), ty);
+ extra++;
next = it.next();
if (next.token != Token.RBRACK) {
throw error("%s", next);
@@ -665,6 +666,7 @@
next = it.next();
}
}
+ ty = extraDims(ty, extra);
}
// TODO(cushon): skip more fields that are definitely non-const
IteratorLexer lexer = new IteratorLexer(this.lexer.source(), it);
@@ -690,11 +692,12 @@
eat(Token.RPAREN);
if (token == Token.LBRACK) {
- // TODO(cushon): support type annotations here. or not.
+ int extra = 0;
while (maybe(Token.LBRACK)) {
eat(Token.RBRACK);
- result = new ArrTy(position, ImmutableList.of(), result);
+ extra++;
}
+ result = extraDims(result, extra);
}
ImmutableList.Builder<ClassTy> exceptions = ImmutableList.builder();
@@ -744,6 +747,25 @@
Optional.fromNullable(defaultValue));
}
+ /**
+ * Given a base {@code type} and some number of {@code extra} c-style array dimension specifiers,
+ * construct a new array type.
+ *
+ * <p>For reasons that are unclear from the spec, {@code int @A [] x []} is equivalent to {@code
+ * int [] @A [] x}, not {@code int @A [] [] x}.
+ */
+ // TODO(cushon): support type annotations here. or not.
+ private Type extraDims(Type type, int extra) {
+ if (extra == 0) {
+ return type;
+ }
+ if (type.kind() == Kind.ARR_TY) {
+ ArrTy arrTy = (ArrTy) type;
+ return new ArrTy(arrTy.position(), arrTy.annos(), extraDims(arrTy.elem(), extra));
+ }
+ return new ArrTy(type.position(), ImmutableList.of(), extraDims(type, extra - 1));
+ }
+
private ImmutableList<ClassTy> exceptions() {
ImmutableList.Builder<ClassTy> result = ImmutableList.builder();
result.add(classty());
@@ -791,6 +813,12 @@
// Overwrite everything up to the terminal 'this' for inner classes; we don't need it
name = identOrThis();
}
+ int extra = 0;
+ while (maybe(Token.LBRACK)) {
+ eat(Token.RBRACK);
+ extra++;
+ }
+ ty = extraDims(ty, extra);
return new VarDecl(position, access, annos.build(), ty, name, Optional.<Expression>absent());
}
diff --git a/javatests/com/google/turbine/lower/LowerIntegrationTest.java b/javatests/com/google/turbine/lower/LowerIntegrationTest.java
index 6d943c4..368d5ce 100644
--- a/javatests/com/google/turbine/lower/LowerIntegrationTest.java
+++ b/javatests/com/google/turbine/lower/LowerIntegrationTest.java
@@ -256,6 +256,7 @@
"type_anno_qual.test",
"array_class_literal.test",
"underscore_literal.test",
+ "c_array.test",
};
List<Object[]> tests =
ImmutableList.copyOf(testCases).stream().map(x -> new Object[] {x}).collect(toList());
diff --git a/javatests/com/google/turbine/lower/testdata/c_array.test b/javatests/com/google/turbine/lower/testdata/c_array.test
new file mode 100644
index 0000000..fd2bb3a
--- /dev/null
+++ b/javatests/com/google/turbine/lower/testdata/c_array.test
@@ -0,0 +1,20 @@
+=== Test.java ===
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+@Target({ElementType.TYPE_USE, ElementType.PARAMETER})
+@interface A {}
+@Target(ElementType.TYPE_USE)
+@interface B {}
+@Target(ElementType.TYPE_USE)
+@interface C {}
+
+class Test {
+ public static void main(@A String args[]) {}
+ void f(@A String @B [] args []) {}
+ void g(@A String args [] []) {}
+ void h(@A String @B [] @C [] args) {}
+ void i(@A String @B [] args [] []) {}
+ void j(@A String @B [] @C [] args []) {}
+}
+