changeset 60853:be95ba8d08c4

8241741: Implement Text Blocks as a standard feature in javac Reviewed-by: jlahoda
author jlaskey
date Thu, 09 Apr 2020 10:55:01 -0300
parents 60ec850952da
children 49baadd53e06
files src/java.base/share/classes/jdk/internal/PreviewFeature.java src/jdk.compiler/share/classes/com/sun/tools/javac/code/Preview.java src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java test/langtools/tools/javac/TextBlockAPI.java test/langtools/tools/javac/TextBlockIllegalEscape.java test/langtools/tools/javac/TextBlockIllegalEscape.out test/langtools/tools/javac/TextBlockLang.java test/langtools/tools/javac/diags/examples/TextBlockCloseDelimiter.java test/langtools/tools/javac/diags/examples/TextBlockOpenDelimiter.java test/langtools/tools/javac/diags/examples/TextBlockSource.java test/langtools/tools/javac/diags/examples/TextBlockWhitespace.java
diffstat 11 files changed, 69 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/classes/jdk/internal/PreviewFeature.java	Thu Apr 09 10:55:01 2020 -0300
+++ b/src/java.base/share/classes/jdk/internal/PreviewFeature.java	Thu Apr 09 10:55:01 2020 -0300
@@ -55,7 +55,7 @@
 
     public enum Feature {
         PATTERN_MATCHING_IN_INSTANCEOF,
-        TEXT_BLOCKS,
+        TEXT_BLOCKS, // 8242284: needs to be removed after JDK 15
         RECORDS,
         ;
     }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Preview.java	Thu Apr 09 10:55:01 2020 -0300
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Preview.java	Thu Apr 09 10:55:01 2020 -0300
@@ -167,7 +167,6 @@
     public boolean isPreview(Feature feature) {
         if (feature == Feature.PATTERN_MATCHING_IN_INSTANCEOF ||
             feature == Feature.REIFIABLE_TYPES_INSTANCEOF ||
-            feature == Feature.TEXT_BLOCKS ||
             feature == Feature.RECORDS)
             return true;
         //Note: this is a backdoor which allows to optionally treat all features as 'preview' (for testing).
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java	Thu Apr 09 10:55:01 2020 -0300
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java	Thu Apr 09 10:55:01 2020 -0300
@@ -233,8 +233,8 @@
                     if (!multiline) {
                         lexError(reader.bp, Errors.IllegalEscChar);
                     } else {
+                        checkSourceLevel(reader.bp, Feature.TEXT_BLOCKS);
                         int start = reader.bp;
-                        checkSourceLevel(reader.bp, Feature.TEXT_BLOCKS);
                         if (reader.ch == '\r' && reader.peekChar() == '\n') {
                            reader.nextChar(translateEscapesNow);
                         }
@@ -402,6 +402,17 @@
         return count;
     }
 
+    /** Skip and process a line terminator.
+     */
+    private void skipLineTerminator() {
+        int start = reader.bp;
+        if (isCRLF()) {
+            reader.scanChar();
+        }
+        reader.scanChar();
+        processLineTerminator(start, reader.bp);
+    }
+
     /** Scan a string literal or text block.
      */
     private void scanString(int pos) {
@@ -425,26 +436,21 @@
             checkSourceLevel(pos, Feature.TEXT_BLOCKS);
             isTextBlock = true;
             // Verify the open delimiter sequence.
-            boolean hasOpenEOLN = false;
-            while (reader.bp < reader.buflen && Character.isWhitespace(reader.ch)) {
-                hasOpenEOLN = isEOLN();
-                if (hasOpenEOLN) {
+            while (reader.bp < reader.buflen) {
+                char ch = reader.ch;
+                if (ch != ' ' && ch != '\t' && ch != FF) {
                     break;
                 }
                 reader.scanChar();
             }
-            // Error if the open delimiter sequence not is """<Whitespace>*<LineTerminator>.
-            if (!hasOpenEOLN) {
+            if (isEOLN()) {
+                skipLineTerminator();
+            } else {
+                // Error if the open delimiter sequence is not
+                //     """<white space>*<LineTerminator>.
                 lexError(reader.bp, Errors.IllegalTextBlockOpen);
                 return;
             }
-            // Skip line terminator.
-            int start = reader.bp;
-            if (isCRLF()) {
-                reader.scanChar();
-            }
-            reader.scanChar();
-            processLineTerminator(start, reader.bp);
             break;
         }
         // While characters are available.
@@ -466,13 +472,9 @@
                 if (openCount == 1) {
                     break;
                 }
-                 // Add line terminator to string buffer.
-                int start = reader.bp;
-                if (isCRLF()) {
-                    reader.scanChar();
-                }
-                reader.putChar('\n', true);
-                processLineTerminator(start, reader.bp);
+                skipLineTerminator();
+                // Add line terminator to string buffer.
+                reader.putChar('\n', false);
                 // Record first line terminator for error recovery.
                 if (firstEOLN == -1) {
                     firstEOLN = reader.bp;
--- a/test/langtools/tools/javac/TextBlockAPI.java	Thu Apr 09 10:55:01 2020 -0300
+++ b/test/langtools/tools/javac/TextBlockAPI.java	Thu Apr 09 10:55:01 2020 -0300
@@ -58,7 +58,7 @@
      */
     static void test1() {
         for (String lineterminators : new String[] { "\n", "\r", "\r\n" })
-        for (String whitespace : new String[] { "", "   ", "\t", "\u2002" })
+        for (String whitespace : new String[] { "", "   ", "\t", "\f" })
         for (String content : new String[] { "a", "ab", "abc", "\u2022", "*".repeat(1000), "*".repeat(10000) })  {
             String code =
                     "public class CorrectTest {\n" +
@@ -126,10 +126,9 @@
             new JavacTask(TOOLBOX)
                     .sources(code)
                     .classpath(".")
-                    .options("--enable-preview", "-source", JDK_VERSION, "-encoding", "utf8")
+                    .options("-encoding", "utf8")
                     .run();
             String output = new JavaTask(TOOLBOX)
-                    .vmOptions("--enable-preview")
                     .classpath(".")
                     .classArgs("LineTerminatorTest")
                     .run()
@@ -210,7 +209,7 @@
         new JavacTask(TOOLBOX)
             .sources(code)
             .classpath(".")
-            .options("--enable-preview", "-source", JDK_VERSION, "-encoding", "utf8", "-Xlint")
+            .options("-encoding", "utf8", "-Xlint")
             .run();
      }
 
@@ -221,7 +220,7 @@
         String output = new JavacTask(TOOLBOX)
                 .sources(source)
                 .classpath(".")
-                .options("--enable-preview", "-source", JDK_VERSION, "-encoding", "utf8")
+                .options("-encoding", "utf8")
                 .run()
                 .writeAll()
                 .getOutput(Task.OutputKind.DIRECT);
@@ -242,7 +241,7 @@
         String errors = new JavacTask(TOOLBOX)
                 .sources(source)
                 .classpath(".")
-                .options("-XDrawDiagnostics", "--enable-preview", "-source", JDK_VERSION, "-encoding", "utf8")
+                .options("-XDrawDiagnostics", "-encoding", "utf8")
                 .run(Task.Expect.FAIL)
                 .writeAll()
                 .getOutput(Task.OutputKind.DIRECT);
--- a/test/langtools/tools/javac/TextBlockIllegalEscape.java	Thu Apr 09 10:55:01 2020 -0300
+++ b/test/langtools/tools/javac/TextBlockIllegalEscape.java	Thu Apr 09 10:55:01 2020 -0300
@@ -2,7 +2,7 @@
  * @test /nodynamiccopyright/
  * @bug 8227640
  * @summary Verify that illegal escapes in text blocks do not crash the javac.
- * @compile/fail/ref=TextBlockIllegalEscape.out --enable-preview -source ${jdk.version} -XDrawDiagnostics TextBlockIllegalEscape.java
+ * @compile/fail/ref=TextBlockIllegalEscape.out -XDrawDiagnostics TextBlockIllegalEscape.java
  */
 
 public class TextBlockIllegalEscape {
--- a/test/langtools/tools/javac/TextBlockIllegalEscape.out	Thu Apr 09 10:55:01 2020 -0300
+++ b/test/langtools/tools/javac/TextBlockIllegalEscape.out	Thu Apr 09 10:55:01 2020 -0300
@@ -1,4 +1,2 @@
 TextBlockIllegalEscape.java:11:13: compiler.err.illegal.esc.char
-- compiler.note.preview.filename: TextBlockIllegalEscape.java
-- compiler.note.preview.recompile
 1 error
--- a/test/langtools/tools/javac/TextBlockLang.java	Thu Apr 09 10:55:01 2020 -0300
+++ b/test/langtools/tools/javac/TextBlockLang.java	Thu Apr 09 10:55:01 2020 -0300
@@ -25,8 +25,8 @@
  * @test
  * @bug 8223967
  * @summary Unit tests for Text Block language changes
- * @compile --enable-preview -source ${jdk.version} -encoding utf8 TextBlockLang.java
- * @run main/othervm --enable-preview TextBlockLang
+ * @compile -encoding utf8 TextBlockLang.java
+ * @run main TextBlockLang
  */
 
 public class TextBlockLang {
--- a/test/langtools/tools/javac/diags/examples/TextBlockCloseDelimiter.java	Thu Apr 09 10:55:01 2020 -0300
+++ b/test/langtools/tools/javac/diags/examples/TextBlockCloseDelimiter.java	Thu Apr 09 10:55:01 2020 -0300
@@ -21,10 +21,7 @@
  * questions.
  */
 
- // key: compiler.warn.preview.feature.use.plural
- // key: compiler.misc.feature.text.blocks
  // key: compiler.err.unclosed.text.block
- // options: --enable-preview -source ${jdk.version} -Xlint:preview
 
 class TextBlockCloseDelimiter {
     String m() {
--- a/test/langtools/tools/javac/diags/examples/TextBlockOpenDelimiter.java	Thu Apr 09 10:55:01 2020 -0300
+++ b/test/langtools/tools/javac/diags/examples/TextBlockOpenDelimiter.java	Thu Apr 09 10:55:01 2020 -0300
@@ -21,10 +21,7 @@
  * questions.
  */
 
- // key: compiler.warn.preview.feature.use.plural
- // key: compiler.misc.feature.text.blocks
- // key: compiler.err.illegal.text.block.open
- // options: --enable-preview -source ${jdk.version} -Xlint:preview
+  // key: compiler.err.illegal.text.block.open
 
 class TextBlockOpenDelimiter {
     String m() {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/diags/examples/TextBlockSource.java	Thu Apr 09 10:55:01 2020 -0300
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ // key: compiler.misc.feature.text.blocks
+ // key: compiler.err.feature.not.supported.in.source.plural
+ // key: compiler.warn.source.no.system.modules.path
+ // options: -source 14
+
+class TextBlockSource {
+    String m() {
+        return """
+               abc
+               """;
+    }
+}
--- a/test/langtools/tools/javac/diags/examples/TextBlockWhitespace.java	Thu Apr 09 10:55:01 2020 -0300
+++ b/test/langtools/tools/javac/diags/examples/TextBlockWhitespace.java	Thu Apr 09 10:55:01 2020 -0300
@@ -21,11 +21,9 @@
  * questions.
  */
 
- // key: compiler.warn.preview.feature.use.plural
- // key: compiler.misc.feature.text.blocks
  // key: compiler.warn.inconsistent.white.space.indentation
  // key: compiler.warn.trailing.white.space.will.be.removed
- // options: --enable-preview -source ${jdk.version} -Xlint:preview,text-blocks
+ // options: -Xlint:text-blocks
 
 class TextBlockWhitespace {
     String m() {