Skip to content
Permalink
Browse files

8241741: Implement Text Blocks as a standard feature in javac

Reviewed-by: jlahoda
  • Loading branch information
JimLaskey committed Apr 9, 2020
1 parent d9bf934 commit ef8537ec1a4e956d1a15d8eb4090446483e53bb3
@@ -55,7 +55,7 @@

public enum Feature {
PATTERN_MATCHING_IN_INSTANCEOF,
TEXT_BLOCKS,
TEXT_BLOCKS, // 8242284: needs to be removed after JDK 15
RECORDS,
;
}
@@ -167,7 +167,6 @@ public boolean isEnabled() {
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).
@@ -233,8 +233,8 @@ private void scanLitChar(int pos, boolean translateEscapesNow, boolean multiline
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 @@ private int countChar(char ch, int max) {
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 @@ private void scanString(int pos) {
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 @@ private void scanString(int pos) {
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;
@@ -58,7 +58,7 @@ public static void main(String... args) {
*/
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 @@ static void test4() {
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 @@ static void test8() {
new JavacTask(TOOLBOX)
.sources(code)
.classpath(".")
.options("--enable-preview", "-source", JDK_VERSION, "-encoding", "utf8", "-Xlint")
.options("-encoding", "utf8", "-Xlint")
.run();
}

@@ -221,7 +220,7 @@ static void compPass(String source) {
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 @@ static void compFail(String source) {
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);
@@ -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 {
@@ -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
@@ -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 {
@@ -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() {
@@ -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() {
@@ -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
""";
}
}
@@ -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() {

0 comments on commit ef8537e

Please sign in to comment.