8114842: JShell: SourceCodeAnalysis splits code with array initialiazer incorrectly
Reviewed-by: jlahoda
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/CompletenessAnalyzer.java Mon Nov 21 07:13:21 2016 -0800
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/CompletenessAnalyzer.java Mon Nov 21 12:28:56 2016 -0800
@@ -233,7 +233,7 @@
// Declarations and type parameters (thus expressions)
EXTENDS(TokenKind.EXTENDS, XEXPR|XDECL), // extends
- COMMA(TokenKind.COMMA, XEXPR|XDECL|XTERM), // ,
+ COMMA(TokenKind.COMMA, XEXPR|XDECL), // ,
AMP(TokenKind.AMP, XEXPR|XDECL), // &
GT(TokenKind.GT, XEXPR|XDECL), // >
LT(TokenKind.LT, XEXPR|XDECL1), // <
@@ -541,7 +541,10 @@
ct = new CT(TK.tokenKindToTK(prevTK, current.kind), advance());
break;
}
- if (ct.kind.isStart() && !prevTK.isOkToTerminate()) {
+ // Detect an error if we are at starting position and the last
+ // token wasn't a terminating one. Special case: within braces,
+ // comma can proceed semicolon, e.g. the values list in enum
+ if (ct.kind.isStart() && !prevTK.isOkToTerminate() && prevTK != COMMA) {
return new CT(ERROR, current, "No '" + prevTK + "' before '" + ct.kind + "'");
}
if (stack.isEmpty() || ct.kind.isError()) {
@@ -653,12 +656,7 @@
}
switch (token.kind) {
case EQ:
- // Check for array initializer
nextToken();
- if (token.kind == BRACES) {
- nextToken();
- return lastly(SEMI);
- }
return parseExpressionStatement();
case BRACES:
case SEMI:
--- a/langtools/test/jdk/jshell/CompletenessTest.java Mon Nov 21 07:13:21 2016 -0800
+++ b/langtools/test/jdk/jshell/CompletenessTest.java Mon Nov 21 12:28:56 2016 -0800
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8149524 8131024 8165211 8080071 8130454 8167343 8129559
+ * @bug 8149524 8131024 8165211 8080071 8130454 8167343 8129559 8114842
* @summary Test SourceCodeAnalysis
* @build KullaTesting TestingInputStream
* @run testng CompletenessTest
@@ -118,6 +118,10 @@
"baz: while (true) if (t()) printf('-'); else break baz",
"java.util.function.IntFunction<int[]> ggg = int[]::new",
"List<? extends Object> l",
+ "int[] m = {1, 2}",
+ "int[] m = {1, 2}, n = null",
+ "int[] m = {1, 2}, n",
+ "int[] m = {1, 2}, n = {3, 4}",
};
static final String[] considered_incomplete = new String[] {
@@ -177,6 +181,11 @@
"void f()",
"void f() throws E",
"@A(",
+ "int n = 4,",
+ "int n,",
+ "int[] m = {1, 2},",
+ "int[] m = {1, 2}, n = {3, 4},",
+ "Map<String,"
};
static final String[] unknown = new String[] {
@@ -315,5 +324,7 @@
assertStatus("if (t) if ", DEFINITELY_INCOMPLETE, "if (t) if"); //Bug
assertStatus("int m() {} dfd", COMPLETE, "int m() {}");
assertStatus("int p = ", DEFINITELY_INCOMPLETE, "int p ="); //Bug
+ assertStatus("int[] m = {1, 2}, n = new int[0]; int i;", COMPLETE,
+ "int[] m = {1, 2}, n = new int[0];");
}
}