8241741: Implement Text Blocks as a standard feature in javac

Reviewed-by: jlahoda
This commit is contained in:
Jim Laskey 2020-04-09 10:55:01 -03:00
parent d9bf934831
commit ef8537ec1a
11 changed files with 69 additions and 44 deletions

View File

@ -55,7 +55,7 @@ public @interface PreviewFeature {
public enum Feature {
PATTERN_MATCHING_IN_INSTANCEOF,
TEXT_BLOCKS,
TEXT_BLOCKS, // 8242284: needs to be removed after JDK 15
RECORDS,
;
}

View File

@ -167,7 +167,6 @@ public class Preview {
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).

View File

@ -233,8 +233,8 @@ public class JavaTokenizer {
if (!multiline) {
lexError(reader.bp, Errors.IllegalEscChar);
} else {
int start = reader.bp;
checkSourceLevel(reader.bp, Feature.TEXT_BLOCKS);
int start = reader.bp;
if (reader.ch == '\r' && reader.peekChar() == '\n') {
reader.nextChar(translateEscapesNow);
}
@ -402,6 +402,17 @@ public class JavaTokenizer {
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 @@ public class JavaTokenizer {
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 @@ public class JavaTokenizer {
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;

View File

@ -58,7 +58,7 @@ public class TextBlockAPI {
*/
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 @@ public class TextBlockAPI {
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 @@ public class TextBlockAPI {
new JavacTask(TOOLBOX)
.sources(code)
.classpath(".")
.options("--enable-preview", "-source", JDK_VERSION, "-encoding", "utf8", "-Xlint")
.options("-encoding", "utf8", "-Xlint")
.run();
}
@ -221,7 +220,7 @@ public class TextBlockAPI {
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 @@ public class TextBlockAPI {
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);

View File

@ -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 {

View File

@ -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

View File

@ -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 {

View File

@ -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() {

View File

@ -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() {

View File

@ -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
""";
}
}

View File

@ -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() {