8189796: Incorrect end position for missing statement
authorjlahoda
Tue, 24 Oct 2017 12:07:27 +0200
changeset 47439 94943e6674be
parent 47438 286cb51fd280
child 47440 963f70aa578d
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
src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java
test/langtools/tools/javac/parser/JavacParserTest.java
--- 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() { " +