8189796: Incorrect end position for missing statement
Summary: Recording end positions for error trees representing missing statements.
Reviewed-by: mcimadamore
Contributed-by: dusan.balek@oracle.com, jan.lahoda@oracle.com
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Mon Oct 23 14:11:04 2017 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Tue Oct 24 12:07:27 2017 +0200
@@ -2396,9 +2396,8 @@
int pos = token.pos;
List<JCStatement> stats = blockStatement();
if (stats.isEmpty()) {
- JCErroneous e = F.at(pos).Erroneous();
- error(e, "illegal.start.of.stmt");
- return F.at(pos).Exec(e);
+ JCErroneous e = syntaxError(pos, "illegal.start.of.stmt");
+ return toP(F.at(pos).Exec(e));
} else {
JCStatement first = stats.head;
String error = null;
--- a/test/langtools/tools/javac/parser/JavacParserTest.java Mon Oct 23 14:11:04 2017 +0200
+++ b/test/langtools/tools/javac/parser/JavacParserTest.java Tue Oct 24 12:07:27 2017 +0200
@@ -38,6 +38,7 @@
import com.sun.source.tree.ErroneousTree;
import com.sun.source.tree.ExpressionStatementTree;
import com.sun.source.tree.ExpressionTree;
+import com.sun.source.tree.IfTree;
import com.sun.source.tree.LambdaExpressionTree;
import com.sun.source.tree.MethodInvocationTree;
import com.sun.source.tree.MethodTree;
@@ -285,6 +286,48 @@
}
@Test
+ void testPositionMissingStatement() throws IOException {
+ String code = "class C { void t() { if (true) } }";
+ DiagnosticCollector<JavaFileObject> dc = new DiagnosticCollector<>();
+
+ JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, fm, dc, null,
+ null, Arrays.asList(new MyFileObject(code)));
+
+ CompilationUnitTree cut = ct.parse().iterator().next();
+ Trees trees = Trees.instance(ct);
+ SourcePositions positions = trees.getSourcePositions();
+
+ new TreeScanner<Void, Void>() {
+ @Override
+ public Void visitIf(IfTree it, Void v) {
+ StatementTree st = it.getThenStatement();
+ int startpos = (int) positions.getStartPosition(cut, st);
+ int endpos = (int) positions.getEndPosition(cut, st);
+ assertEquals("testPositionMissingStatement.execpos", startpos, endpos);
+ assertEquals("testPositionMissingStatement.execkind",
+ Kind.EXPRESSION_STATEMENT,
+ st.getKind());
+ Tree err = ((ExpressionStatementTree) st).getExpression();
+ startpos = (int) positions.getStartPosition(cut, err);
+ endpos = (int) positions.getEndPosition(cut, err);
+ assertEquals("testPositionMissingStatement.errpos", startpos, endpos);
+ assertEquals("testPositionMissingStatement.errkind",
+ Kind.ERRONEOUS,
+ err.getKind());
+ return super.visitIf(it, v);
+ }
+ }.scan(cut, null);
+
+ assertEquals("testPositionMissingStatement.diags", 1, dc.getDiagnostics().size());
+ Diagnostic<? extends JavaFileObject> d = dc.getDiagnostics().get(0);
+ int startpos = (int) d.getStartPosition();
+ int pos = (int) d.getPosition();
+ int endpos = (int) d.getEndPosition();
+ assertEquals("testPositionMissingStatement.diagspan", startpos, endpos);
+ assertEquals("testPositionMissingStatement.diagpref", startpos, pos);
+ }
+
+ @Test
void testPositionsSane1() throws IOException {
performPositionsSanityTest("package test; class Test { " +
"private void method() { " +