< prev index next >

test/langtools/tools/javac/parser/JavacParserTest.java

Print this page
rev 60625 : 8237041: AssertionError in parsing
Summary: Avoid parser crash for deeply nested classes without closing braces, improve error recovery for classes without an opening brace.
Reviewed-by: TBD


   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @bug 7073631 7159445 7156633 8028235 8065753 8205418 8205913 8228451
  27  * @summary tests error and diagnostics positions
  28  * @author  Jan Lahoda
  29  * @modules jdk.compiler/com.sun.tools.javac.api
  30  *          jdk.compiler/com.sun.tools.javac.main
  31  *          jdk.compiler/com.sun.tools.javac.tree
  32  */
  33 
  34 import com.sun.source.tree.BinaryTree;
  35 import com.sun.source.tree.BlockTree;
  36 import com.sun.source.tree.ClassTree;
  37 import com.sun.source.tree.CompilationUnitTree;
  38 import com.sun.source.tree.ErroneousTree;
  39 import com.sun.source.tree.ExpressionStatementTree;
  40 import com.sun.source.tree.ExpressionTree;
  41 import com.sun.source.tree.IfTree;
  42 import com.sun.source.tree.LambdaExpressionTree;
  43 import com.sun.source.tree.MethodInvocationTree;
  44 import com.sun.source.tree.MethodTree;
  45 import com.sun.source.tree.ModifiersTree;
  46 import com.sun.source.tree.PrimitiveTypeTree;


1493     }
1494 
1495     @Test
1496     void testStartAndEndPositionForClassesInPermitsClause() throws IOException {
1497         String code = "package t; sealed class Test permits Sub1, Sub2 {} final class Sub1 extends Test {} final class Sub2 extends Test {}";
1498         JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, fm, null,
1499                 List.of("--enable-preview", "-source", Integer.toString(Runtime.version().feature())),
1500                 null, Arrays.asList(new MyFileObject(code)));
1501         CompilationUnitTree cut = ct.parse().iterator().next();
1502         ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0);
1503         List<? extends Tree> permitsList = clazz.getPermitsClause();
1504         assertEquals("testStartAndEndPositionForClassesInPermitsClause", 2, permitsList.size());
1505         Trees t = Trees.instance(ct);
1506         List<String> expected = List.of("Sub1", "Sub2");
1507         int i = 0;
1508         for (Tree permitted: permitsList) {
1509             int start = (int) t.getSourcePositions().getStartPosition(cut, permitted);
1510             int end = (int) t.getSourcePositions().getEndPosition(cut, permitted);
1511             assertEquals("testStartAndEndPositionForClassesInPermitsClause", expected.get(i++), code.substring(start, end));
1512         }




















































1513     }
1514 
1515     void run(String[] args) throws Exception {
1516         int passed = 0, failed = 0;
1517         final Pattern p = (args != null && args.length > 0)
1518                 ? Pattern.compile(args[0])
1519                 : null;
1520         for (Method m : this.getClass().getDeclaredMethods()) {
1521             boolean selected = (p == null)
1522                     ? m.isAnnotationPresent(Test.class)
1523                     : p.matcher(m.getName()).matches();
1524             if (selected) {
1525                 try {
1526                     m.invoke(this, (Object[]) null);
1527                     System.out.println(m.getName() + ": OK");
1528                     passed++;
1529                 } catch (Throwable ex) {
1530                     System.out.printf("Test %s failed: %s %n", m, ex.getCause());
1531                     failed++;
1532                 }




   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @bug 7073631 7159445 7156633 8028235 8065753 8205418 8205913 8228451 8237041
  27  * @summary tests error and diagnostics positions
  28  * @author  Jan Lahoda
  29  * @modules jdk.compiler/com.sun.tools.javac.api
  30  *          jdk.compiler/com.sun.tools.javac.main
  31  *          jdk.compiler/com.sun.tools.javac.tree
  32  */
  33 
  34 import com.sun.source.tree.BinaryTree;
  35 import com.sun.source.tree.BlockTree;
  36 import com.sun.source.tree.ClassTree;
  37 import com.sun.source.tree.CompilationUnitTree;
  38 import com.sun.source.tree.ErroneousTree;
  39 import com.sun.source.tree.ExpressionStatementTree;
  40 import com.sun.source.tree.ExpressionTree;
  41 import com.sun.source.tree.IfTree;
  42 import com.sun.source.tree.LambdaExpressionTree;
  43 import com.sun.source.tree.MethodInvocationTree;
  44 import com.sun.source.tree.MethodTree;
  45 import com.sun.source.tree.ModifiersTree;
  46 import com.sun.source.tree.PrimitiveTypeTree;


1493     }
1494 
1495     @Test
1496     void testStartAndEndPositionForClassesInPermitsClause() throws IOException {
1497         String code = "package t; sealed class Test permits Sub1, Sub2 {} final class Sub1 extends Test {} final class Sub2 extends Test {}";
1498         JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, fm, null,
1499                 List.of("--enable-preview", "-source", Integer.toString(Runtime.version().feature())),
1500                 null, Arrays.asList(new MyFileObject(code)));
1501         CompilationUnitTree cut = ct.parse().iterator().next();
1502         ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0);
1503         List<? extends Tree> permitsList = clazz.getPermitsClause();
1504         assertEquals("testStartAndEndPositionForClassesInPermitsClause", 2, permitsList.size());
1505         Trees t = Trees.instance(ct);
1506         List<String> expected = List.of("Sub1", "Sub2");
1507         int i = 0;
1508         for (Tree permitted: permitsList) {
1509             int start = (int) t.getSourcePositions().getStartPosition(cut, permitted);
1510             int end = (int) t.getSourcePositions().getEndPosition(cut, permitted);
1511             assertEquals("testStartAndEndPositionForClassesInPermitsClause", expected.get(i++), code.substring(start, end));
1512         }
1513     }
1514 
1515     @Test //JDK-8237041
1516     void testDeepNestingNoClose() throws IOException {
1517         //verify that many nested unclosed classes do not crash javac
1518         //due to the safety fallback in JavacParser.reportSyntaxError:
1519         String code = "package t; class Test {\n";
1520         for (int i = 0; i < 100; i++) {
1521             code += "class C" + i + " {\n";
1522         }
1523         JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, fm, null, List.of("-XDdev"),
1524                 null, Arrays.asList(new MyFileObject(code)));
1525         Result result = ct.doCall();
1526         assertEquals("Expected a (plain) error, got: " + result, result, Result.ERROR);
1527     }
1528 
1529     @Test //JDK-8237041
1530     void testErrorRecoveryClassNotBrace() throws IOException {
1531         //verify the AST form produced for classes without opening brace
1532         //(classes without an opening brace do not nest the upcoming content):
1533         String code = """
1534                       package t;
1535                       class Test {
1536                           String.class,
1537                           String.class,
1538                           class A
1539                           public
1540                           class B
1541                       }
1542                       """;
1543         JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, fm, null, List.of("-XDdev"),
1544                 null, Arrays.asList(new MyFileObject(code)));
1545         String ast = ct.parse().iterator().next().toString();
1546         String expected = """
1547                           package t;
1548                           \n\
1549                           class Test {
1550                               String.<error> <error>;
1551                               \n\
1552                               class <error> {
1553                               }
1554                               \n\
1555                               class <error> {
1556                               }
1557                               \n\
1558                               class A {
1559                               }
1560                               \n\
1561                               public class B {
1562                               }
1563                           }""";
1564         assertEquals("Unexpected AST, got:\n" + ast, expected, ast);
1565     }
1566 
1567     void run(String[] args) throws Exception {
1568         int passed = 0, failed = 0;
1569         final Pattern p = (args != null && args.length > 0)
1570                 ? Pattern.compile(args[0])
1571                 : null;
1572         for (Method m : this.getClass().getDeclaredMethods()) {
1573             boolean selected = (p == null)
1574                     ? m.isAnnotationPresent(Test.class)
1575                     : p.matcher(m.getName()).matches();
1576             if (selected) {
1577                 try {
1578                     m.invoke(this, (Object[]) null);
1579                     System.out.println(m.getName() + ": OK");
1580                     passed++;
1581                 } catch (Throwable ex) {
1582                     System.out.printf("Test %s failed: %s %n", m, ex.getCause());
1583                     failed++;
1584                 }


< prev index next >