From 4638609e26cdd75ef45644c439e55c6757e083e0 Mon Sep 17 00:00:00 2001 From: Jay Arthanareeswaran Date: Tue, 12 Dec 2023 18:24:16 +0530 Subject: [PATCH] [21] Processed string templates falsely contain backslash characters (#1730) #1719 --- .../jdt/internal/compiler/parser/Parser.java | 1 - .../jdt/internal/compiler/parser/Scanner.java | 3 +- .../regression/StringTemplateTest.java | 148 ++++++++++++++++++ 3 files changed, 150 insertions(+), 2 deletions(-) diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/Parser.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/Parser.java index 35da56c4f0e..4f59cafdacf 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/Parser.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/Parser.java @@ -10031,7 +10031,6 @@ protected void consumeTemplate(int token) { } // get rid of all the cached values this.scanner.withoutUnicodePtr = 0; - this.scanner.textBlockOffset = -1; StringTemplate template = new StringTemplate(fragments, expressions, fragments[0].sourceStart, fragments[expressions.length].sourceEnd, isMultiline); pushOnExpressionStack(template); } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/Scanner.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/Scanner.java index 98eea9ea139..9319081f7d6 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/Scanner.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/Scanner.java @@ -1888,7 +1888,8 @@ protected int scanForStringLiteral() throws InvalidInputException { this.startPosition = startBkup; return token; } else { - int textFragmentStart = this.currentPosition - 1; + int textFragmentStart = this.currentPosition; + this.textBlockOffset = -1; // Make sure that the previous values set by any preceding text block is reset. int lastCharPos = this.currentPosition; try { // consume next character diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StringTemplateTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StringTemplateTest.java index c1996601943..c1104c109cf 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StringTemplateTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StringTemplateTest.java @@ -1756,4 +1756,152 @@ interface Intf { "Syntax error on token \")\", delete this token\n" + "----------\n"); } + public void testIssue1719() { + runConformTest( + new String[] { + "X.java", + """ + public class X { + public static void main(String[] args) { + String name = "Bill"; + System.out.println(STR."\\{name}"); + String html = STR.\""" + \\{name} + \"""; + } + }""" + }, + "Bill"); + } + public void testIssue1722() { + runConformTest( + new String[] { + "X.java", + """ + public class X { + public static void main(String[] args) { + String firstName = "Bill", lastName = "Duck"; + System.out.println(STR."\\{firstName} \\{lastName}"); + + String title = "My Web Page"; + + String html = STR.\""" + + \"""; + System.out.println(html); + } + }""" + }, + "Bill Duck\n" + + " "); + } + public void testJEP430Examples() { + runConformTest( + new String[] { + "X.java", + """ + import java.io.File; + import java.time.LocalTime; + import java.time.format.DateTimeFormatter; + import java.util.Date; + import java.util.List; + public class X { + @SuppressWarnings("preview") + public static void main(String[] args) { + String firstName = "Bill"; + String lastName = "Duck"; + String fullName = STR."\\{firstName} \\{lastName}"; + System.out.println(fullName); // "Bill Duck" + String sortName = STR."\\{lastName}, \\{firstName}"; + System.out.println(sortName); // "Duck, Bill" + int x = 10, y = 20; + String s = STR."\\{x} + \\{y} = \\{x + y}"; + System.out.println(s); // "10 + 20 = 30" + s = STR."You have a \\{getOfferType()} waiting for you!"; + System.out.println(s); // "You have a gift waiting for you!" + Request req = new Request(); + String t = STR."Access at \\{req.date} \\{req.time} from \\{req.ipAddress}"; + + String filePath = "tmp.dat"; + File file = new File(filePath); + String old = "The file " + filePath + " " + (file.exists() ? "does" : "does not") + " exist"; + String msg = STR."The file \\{filePath} \\{file.exists() ? "does" : "does not"} exist"; + System.out.println(msg); // "The file tmp.dat does exist" or "The file tmp.dat does not exist" + String time = STR."The time is \\{ + // The java.time.format package is very useful + DateTimeFormatter + .ofPattern("HH:mm:ss") + .format(LocalTime.NOON) + } right now"; + System.out.println(time); // "The time is 12:34:56 right now" + int index = 0; + String data = STR."\\{index++}, \\{index++}, \\{index++}, \\{index++}"; + System.out.println(data); //"0, 1, 2, 3" + String[] fruit = { "apples", "oranges", "peaches" }; + s = STR."\\{fruit[0]}, \\{STR."\\{fruit[1]}, \\{fruit[2]}"}"; + System.out.println(s); //"apples, oranges, peaches" + s = STR."\\{fruit[0]}, \\{ + STR."\\{fruit[1]}, \\{fruit[2]}" + }"; + System.out.println(s); + String tmp = STR."\\{fruit[1]}, \\{fruit[2]}"; + s = STR."\\{fruit[0]}, \\{tmp}"; + System.out.println(s); + Rectangle[] zone = new Rectangle[] { + new Rectangle("Alfa", 17.8, 31.4), + new Rectangle("Bravo", 9.6, 12.4), + new Rectangle("Charlie", 7.1, 11.23), + }; + String table = STR.\""" + Description Width height() Area + \\{zone[0].name()} \\{zone[0].width()} \\{zone[0].height()} \\{zone[0].area()} + \\{zone[1].name()} \\{zone[1].width()} \\{zone[1].height()} \\{zone[1].area()} + \\{zone[2].name()} \\{zone[2].width()} \\{zone[2].height()} \\{zone[2].area()} + Total \\{zone[0].area() + zone[1].area() + zone[2].area()} + \"""; + System.out.println(table); + x = 10; + y = 20; + StringTemplate st = StringTemplate.RAW."\\{x} plus \\{y} equals \\{x + y}"; + List fragments = st.fragments(); + String result = String.join("\\\\{}", fragments); + System.out.println(result); //"\\{} plus \\{} equals \\{}" + List values = st.values(); + System.out.println(values);//[10, 20, 30] + } + static String getOfferType() { + return "gift"; + } + } + record Rectangle(String name, double width, double height) { + double area() { + return width * height; + } + } + class Request { + Date date = new Date(3, 5, 2022); + String time = "15:34"; + String ipAddress = "0.0.0.0"; + }""" + }, + """ + Bill Duck + Duck, Bill + 10 + 20 = 30 + You have a gift waiting for you! + The file tmp.dat does not exist + The time is 12:00:00 right now + 0, 1, 2, 3 + apples, oranges, peaches + apples, oranges, peaches + apples, oranges, peaches + Description Width height() Area + Alfa 17.8 31.4 558.92 + Bravo 9.6 12.4 119.03999999999999 + Charlie 7.1 11.23 79.733 + Total 757.693 + + \\{} plus \\{} equals \\{} + [10, 20, 30]"""); + } }