[java] Text Blocks are now a permanent language feature with JDK 15

This commit is contained in:
Andreas Dangel
2020-08-13 19:58:21 +02:00
parent 2a2fa20883
commit 40f0eedf88
3 changed files with 195 additions and 5 deletions

View File

@ -1,5 +1,6 @@
/**
* Remove support for Java 13 preview language features
* Remove support for Java 13 preview language features.
* Promote text blocks as a permanent language features with Java 15.
* Andreas Dangel 08/2020
*====================================================================
* Add support for record types introduced as a preview language
@ -453,14 +454,14 @@ public class JavaParser {
}
private void checkForTextBlockLiteral() {
if (jdkVersion != 14 || !preview) {
throwParseException("Text block literals are only supported with Java 14 Preview");
if (jdkVersion < 15 && !preview) {
throwParseException("Text block literals are only supported with Java 14 Preview and Java >= 15");
}
}
private void checkForNewStringSpaceEscape(String s) {
if ((jdkVersion != 14 || !preview) && s.contains("\\s") && !s.contains("\\\\s")) {
throwParseException("The escape sequence \"\\s\" is only supported with Java 14 Preview");
if ((jdkVersion < 15 && !preview) && s.contains("\\s") && !s.contains("\\\\s")) {
throwParseException("The escape sequence \"\\s\" is only supported with Java 14 Preview and Java >= 15");
}
}

View File

@ -0,0 +1,74 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.java.ast;
import java.util.ArrayList;
import java.util.List;
import org.junit.Assert;
import org.junit.Test;
import net.sourceforge.pmd.lang.ast.ParseException;
import net.sourceforge.pmd.lang.java.JavaParsingHelper;
public class Java15Test {
private final JavaParsingHelper java15 =
JavaParsingHelper.WITH_PROCESSING.withDefaultVersion("15")
.withResourceContext(Java15Test.class, "jdkversiontests/java15/");
private final JavaParsingHelper java15p = java15.withDefaultVersion("15-preview");
private final JavaParsingHelper java14 = java15.withDefaultVersion("14");
@Test
public void textBlocks() {
textBlocks(java15);
textBlocks(java15p);
}
private void textBlocks(JavaParsingHelper parser) {
ASTCompilationUnit compilationUnit = parser.parseResource("TextBlocks.java");
List<ASTLiteral> literals = compilationUnit.findDescendantsOfType(ASTLiteral.class);
Assert.assertEquals(22, literals.size());
Assert.assertFalse(literals.get(2).isTextBlock());
Assert.assertFalse(literals.get(12).isTextBlock());
Assert.assertFalse(literals.get(17).isTextBlock());
Assert.assertFalse(literals.get(18).isTextBlock());
Assert.assertFalse(literals.get(20).isTextBlock());
Assert.assertFalse(literals.get(21).isTextBlock());
List<ASTLiteral> textBlocks = new ArrayList<>();
for (ASTLiteral literal : literals) {
if (literal.isTextBlock()) {
textBlocks.add(literal);
}
}
Assert.assertEquals(16, textBlocks.size());
Assert.assertEquals("\"\"\"\n"
+ " <html> \n"
+ " <body>\n"
+ " <p>Hello, world</p> \n"
+ " </body> \n"
+ " </html> \n"
+ " \"\"\"",
textBlocks.get(0).getImage());
Assert.assertEquals("<html>\n"
+ " <body>\n"
+ " <p>Hello, world</p>\n"
+ " </body>\n"
+ "</html>\n", textBlocks.get(0).getTextBlockContent());
// Note: More tests are in ASTLiteralTest.
}
@Test(expected = ParseException.class)
public void textBlocksBeforeJava15ShouldFail() {
java14.parseResource("TextBlocks.java");
}
@Test(expected = ParseException.class)
public void stringEscapeSequenceShouldFail() {
java14.parse("class Foo { String s =\"a\\sb\"; }");
}
}

View File

@ -0,0 +1,115 @@
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
/**
* Text Blocks are a permanent language feature with JDK 15.
*
* @see <a href="https://openjdk.java.net/jeps/378>JEP 378: Text Blocks</a>
*/
public class TextBlocks {
public static void main(String[] args) throws Exception {
// note: there is trailing whitespace!!
String html = """
<html>
<body>
<p>Hello, world</p>
</body>
</html>
""";
System.out.println(html);
String query = """
SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`
WHERE `CITY` = 'INDIANAPOLIS'
ORDER BY `EMP_ID`, `LAST_NAME`;
""";
System.out.println(query);
ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
Object obj = engine.eval("""
function hello() {
print('"Hello, world"');
}
hello();
""");
// Escape sequences
String htmlWithEscapes = """
<html>\r
<body>\r
<p>Hello, world</p>\r
</body>\r
</html>\r
""";
System.out.println(htmlWithEscapes);
String season = """
winter"""; // the six characters w i n t e r
String period = """
winter
"""; // the seven characters w i n t e r LF
String greeting =
"""
Hi, "Bob"
"""; // the ten characters H i , SP " B o b " LF
String salutation =
"""
Hi,
"Bob"
"""; // the eleven characters H i , LF SP " B o b " LF
String empty = """
"""; // the empty string (zero length)
String quote = """
"
"""; // the two characters " LF
String backslash = """
\\
"""; // the two characters \ LF
String normalStringLiteral = "test";
String code =
"""
String text = \"""
A text block inside a text block
\""";
""";
// new escape sequences
String text = """
Lorem ipsum dolor sit amet, consectetur adipiscing \
elit, sed do eiusmod tempor incididunt ut labore \
et dolore magna aliqua.\
""";
System.out.println(text);
String colors = """
red \s
green\s
blue \s
""";
System.out.println(colors);
// empty new line as first content
String emptyLine = """
test
""";
System.out.println(emptyLine.replaceAll("\n", "<LF>"));
// backslash escapes
String bs = """
\\test
""";
System.out.println(bs.replaceAll("\n", "<LF>"));
}
}