8228647: Broken enum produce inconvenient errors and AST

Improving error recovery for misplace members in enums.

Reviewed-by: vromero
This commit is contained in:
Jan Lahoda 2019-08-13 10:27:33 +02:00
parent 6e86f5b47b
commit 36ae680f2a
8 changed files with 316 additions and 20 deletions

View file

@ -1291,6 +1291,179 @@ public class JavacParserTest extends TestCase {
assertTrue("testAnalyzeParensWithComma2", found[0]);
}
@Test
void testBrokenEnum1() throws IOException {
assert tool != null;
String code = "package test; class Test { enum E { A, B, C. D, E, F; } }";
StringWriter output = new StringWriter();
JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(output, fm, null, List.of("-XDrawDiagnostics"),
null, Arrays.asList(new MyFileObject(code)));
CompilationUnitTree cut = ct.parse().iterator().next();
List<String> actual = List.of(output.toString().split("\r?\n"));
List<String> expected = List.of("Test.java:1:44: compiler.err.expected3: ',', '}', ';'");
assertEquals("The expected and actual errors do not match, actual errors: " + actual,
actual,
expected);
String actualAST = cut.toString().replaceAll("\r*\n", "\n");
String expectedAST = "package test;\n" +
"\n" +
"class Test {\n" +
" \n" +
" enum E {\n" +
" /*public static final*/ A /* = new E() */ /*enum*/ ,\n" +
" /*public static final*/ B /* = new E() */ /*enum*/ ,\n" +
" /*public static final*/ C /* = new E() */ /*enum*/ ,\n" +
" /*public static final*/ D /* = new E() */ /*enum*/ ,\n" +
" /*public static final*/ E /* = new E() */ /*enum*/ ,\n" +
" /*public static final*/ F /* = new E() */ /*enum*/ ;\n" +
" (ERROR) <error>;\n" +
" }\n" +
"}";
assertEquals("The expected and actual AST do not match, actual AST: " + actualAST,
actualAST,
expectedAST);
}
@Test
void testBrokenEnum2() throws IOException {
assert tool != null;
String code = "package test; class Test { enum E { A, B, C void t() {} } }";
StringWriter output = new StringWriter();
JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(output, fm, null, List.of("-XDrawDiagnostics"),
null, Arrays.asList(new MyFileObject(code)));
CompilationUnitTree cut = ct.parse().iterator().next();
List<String> actual = List.of(output.toString().split("\r?\n"));
List<String> expected = List.of("Test.java:1:44: compiler.err.expected3: ',', '}', ';'");
assertEquals("The expected and actual errors do not match, actual errors: " + actual,
actual,
expected);
String actualAST = cut.toString().replaceAll("\r*\n", "\n");
String expectedAST = "package test;\n" +
"\n" +
"class Test {\n" +
" \n" +
" enum E {\n" +
" /*public static final*/ A /* = new E() */ /*enum*/ ,\n" +
" /*public static final*/ B /* = new E() */ /*enum*/ ,\n" +
" /*public static final*/ C /* = new E() */ /*enum*/ ;\n" +
" \n" +
" void t() {\n" +
" }\n" +
" }\n" +
"}";
assertEquals("The expected and actual AST do not match, actual AST: " + actualAST,
actualAST,
expectedAST);
}
@Test
void testBrokenEnum3() throws IOException {
assert tool != null;
String code = "package test; class Test { enum E { , void t() {} } }";
StringWriter output = new StringWriter();
JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(output, fm, null, List.of("-XDrawDiagnostics"),
null, Arrays.asList(new MyFileObject(code)));
CompilationUnitTree cut = ct.parse().iterator().next();
List<String> actual = List.of(output.toString().split("\r?\n"));
List<String> expected = List.of("Test.java:1:38: compiler.err.expected2: '}', ';'");
assertEquals("The expected and actual errors do not match, actual errors: " + actual,
actual,
expected);
String actualAST = cut.toString().replaceAll("\r*\n", "\n");
String expectedAST = "package test;\n" +
"\n" +
"class Test {\n" +
" \n" +
" enum E {\n" +
";\n" +
" \n" +
" void t() {\n" +
" }\n" +
" }\n" +
"}";
assertEquals("The expected and actual AST do not match, actual AST: " + actualAST,
actualAST,
expectedAST);
}
@Test
void testBrokenEnum4() throws IOException {
assert tool != null;
String code = "package test; class Test { enum E { A, B, C, void t() {} } }";
StringWriter output = new StringWriter();
JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(output, fm, null, List.of("-XDrawDiagnostics"),
null, Arrays.asList(new MyFileObject(code)));
CompilationUnitTree cut = ct.parse().iterator().next();
List<String> actual = List.of(output.toString().split("\r?\n"));
List<String> expected = List.of("Test.java:1:46: compiler.err.enum.constant.expected");
assertEquals("The expected and actual errors do not match, actual errors: " + actual,
actual,
expected);
String actualAST = cut.toString().replaceAll("\r*\n", "\n");
String expectedAST = "package test;\n" +
"\n" +
"class Test {\n" +
" \n" +
" enum E {\n" +
" /*public static final*/ A /* = new E() */ /*enum*/ ,\n" +
" /*public static final*/ B /* = new E() */ /*enum*/ ,\n" +
" /*public static final*/ C /* = new E() */ /*enum*/ ;\n" +
" \n" +
" void t() {\n" +
" }\n" +
" }\n" +
"}";
assertEquals("The expected and actual AST do not match, actual AST: " + actualAST,
actualAST,
expectedAST);
}
@Test
void testBrokenEnum5() throws IOException {
assert tool != null;
String code = "package test; class Test { enum E { A; void t() {} B; } }";
StringWriter output = new StringWriter();
JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(output, fm, null, List.of("-XDrawDiagnostics"),
null, Arrays.asList(new MyFileObject(code)));
CompilationUnitTree cut = ct.parse().iterator().next();
List<String> actual = List.of(output.toString().split("\r?\n"));
List<String> expected = List.of("Test.java:1:52: compiler.err.enum.constant.not.expected");
assertEquals("The expected and actual errors do not match, actual errors: " + actual,
actual,
expected);
String actualAST = cut.toString().replaceAll("\r*\n", "\n");
String expectedAST = "package test;\n" +
"\n" +
"class Test {\n" +
" \n" +
" enum E {\n" +
" /*public static final*/ A /* = new E() */ /*enum*/ ,\n" +
" /*public static final*/ B /* = new E() */ /*enum*/ ;\n" +
" \n" +
" void t() {\n" +
" }\n" +
" }\n" +
"}";
assertEquals("The expected and actual AST do not match, actual AST: " + actualAST,
actualAST,
expectedAST);
}
void run(String[] args) throws Exception {
int passed = 0, failed = 0;
final Pattern p = (args != null && args.length > 0)