Fix underscore handling in octal literals
The octal radix check needs to accept e.g. `0_10`, while still excluding
`0` and `0L`.
MOE_MIGRATED_REVID=139086201
diff --git a/java/com/google/turbine/parse/ConstExpressionParser.java b/java/com/google/turbine/parse/ConstExpressionParser.java
index 3c89ffe..4a3b297 100644
--- a/java/com/google/turbine/parse/ConstExpressionParser.java
+++ b/java/com/google/turbine/parse/ConstExpressionParser.java
@@ -286,9 +286,7 @@
if (text.startsWith("0x") || text.startsWith("0X")) {
text = text.substring(2);
radix = 0x10;
- } else if (text.startsWith("0")
- && text.length() > 1
- && Character.isDigit(text.charAt(1))) {
+ } else if (isOctal(text)) {
radix = 010;
} else if (text.startsWith("0b") || text.startsWith("0B")) {
text = text.substring(2);
@@ -316,9 +314,7 @@
if (text.startsWith("0x") || text.startsWith("0X")) {
text = text.substring(2);
radix = 0x10;
- } else if (text.startsWith("0")
- && text.length() > 1
- && Character.isDigit(text.charAt(1))) {
+ } else if (isOctal(text)) {
radix = 010;
} else if (text.startsWith("0b") || text.startsWith("0B")) {
text = text.substring(2);
@@ -360,6 +356,17 @@
return new Tree.Literal(position, kind, value);
}
+ static boolean isOctal(String text) {
+ if (!text.startsWith("0")) {
+ return false;
+ }
+ if (text.length() <= 1) {
+ return false;
+ }
+ char next = text.charAt(1);
+ return Character.isDigit(next) || next == '_';
+ }
+
/**
* Parse the string as a signed long.
*
diff --git a/javatests/com/google/turbine/lower/LowerIntegrationTest.java b/javatests/com/google/turbine/lower/LowerIntegrationTest.java
index fd332b3..c1859e5 100644
--- a/javatests/com/google/turbine/lower/LowerIntegrationTest.java
+++ b/javatests/com/google/turbine/lower/LowerIntegrationTest.java
@@ -266,6 +266,7 @@
"deficient_types_classfile.test",
"ctor_anno.test",
"anno_const_coerce.test",
+ "const_octal_underscore.test",
};
List<Object[]> tests =
ImmutableList.copyOf(testCases).stream().map(x -> new Object[] {x}).collect(toList());
diff --git a/javatests/com/google/turbine/lower/testdata/const_octal_underscore.test b/javatests/com/google/turbine/lower/testdata/const_octal_underscore.test
new file mode 100644
index 0000000..142edd7
--- /dev/null
+++ b/javatests/com/google/turbine/lower/testdata/const_octal_underscore.test
@@ -0,0 +1,6 @@
+=== Test.java ===
+class Test {
+ static final int A = 0_10;
+ static final long B = 0_10;
+ static final long C = 0_10L;
+}
\ No newline at end of file