From a38a23e85f549268974891a896e8ace85665c427 Mon Sep 17 00:00:00 2001 From: Nick Mancuso Date: Tue, 31 Oct 2023 09:00:29 -0400 Subject: [PATCH] PT-13830: Support Java 21 string template syntax --- .../checkstyle/AstTreeStringPrinter.java | 2 +- .../tools/checkstyle/JavaAstVisitor.java | 158 +++++++ .../tools/checkstyle/api/TokenTypes.java | 15 + .../grammar/java/JavaLanguageLexer.g4 | 34 +- .../grammar/java/JavaLanguageParser.g4 | 19 + .../java21/Java21AstRegressionTest.java | 41 ++ .../java21/ExpectedStringTemplateBasic.txt | 421 ++++++++++++++++++ .../java21/InputStringTemplateBasic.java | 52 +++ 8 files changed, 738 insertions(+), 4 deletions(-) create mode 100644 src/test/java/com/puppycrawl/tools/checkstyle/grammar/java21/Java21AstRegressionTest.java create mode 100644 src/test/resources-noncompilable/com/puppycrawl/tools/checkstyle/grammar/java21/ExpectedStringTemplateBasic.txt create mode 100644 src/test/resources-noncompilable/com/puppycrawl/tools/checkstyle/grammar/java21/InputStringTemplateBasic.java diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/AstTreeStringPrinter.java b/src/main/java/com/puppycrawl/tools/checkstyle/AstTreeStringPrinter.java index 87758b356e27..dbf9e26aa24e 100644 --- a/src/main/java/com/puppycrawl/tools/checkstyle/AstTreeStringPrinter.java +++ b/src/main/java/com/puppycrawl/tools/checkstyle/AstTreeStringPrinter.java @@ -162,7 +162,7 @@ public static String printBranch(DetailAST node) { * @param ast the root AST node. * @return string AST. */ - private static String printTree(DetailAST ast) { + public static String printTree(DetailAST ast) { final StringBuilder messageBuilder = new StringBuilder(1024); DetailAST node = ast; while (node != null) { diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/JavaAstVisitor.java b/src/main/java/com/puppycrawl/tools/checkstyle/JavaAstVisitor.java index 7e39fd4caeef..5ab8945088e0 100644 --- a/src/main/java/com/puppycrawl/tools/checkstyle/JavaAstVisitor.java +++ b/src/main/java/com/puppycrawl/tools/checkstyle/JavaAstVisitor.java @@ -103,6 +103,12 @@ public final class JavaAstVisitor extends JavaLanguageParserBaseVisitor 0 && _modeStack.peek() == TextBlock; + } } // Keywords and restricted identifiers @@ -242,7 +250,14 @@ LITERAL_FALSE: 'false'; CHAR_LITERAL: '\'' (EscapeSequence | ~['\\\r\n]) '\''; -STRING_LITERAL: '"' (EscapeSequence | ~["\\\r\n])* '"'; +fragment StringFragment: (EscapeSequence | ~["\\\r\n])*; + +STRING_LITERAL: '"' StringFragment '"'; + +// explore if we can gather StringFragment and emit a token +STRING_TEMPLATE_BEGIN: '"' StringFragment '\\' '{'; +STRING_TEMPLATE_MID: '}' StringFragment '\\' '{'; +STRING_TEMPLATE_END: '}' StringFragment '"'; TEXT_BLOCK_LITERAL_BEGIN: '"' '"' '"' -> pushMode(TextBlock); @@ -403,7 +418,20 @@ fragment Letter // Text block lexical mode mode TextBlock; TEXT_BLOCK_CONTENT - : ( TwoDoubleQuotes + : TextBlockFragment + ; + + TEXT_BLOCK_TEMPLATE_BEGIN + : TextBlockFragment '\\' '{' -> pushMode(DEFAULT_MODE); + + TEXT_BLOCK_TEMPLATE_MID + : '}' TextBlockFragment '\\' '{'; + + TEXT_BLOCK_TEMPLATE_END + : '}' TextBlockFragment TEXT_BLOCK_LITERAL_END -> popMode; + + fragment TextBlockFragment + : ( TwoDoubleQuotes | OneDoubleQuote | Newline | ~'"' diff --git a/src/main/resources/com/puppycrawl/tools/checkstyle/grammar/java/JavaLanguageParser.g4 b/src/main/resources/com/puppycrawl/tools/checkstyle/grammar/java/JavaLanguageParser.g4 index 13452fb5e8aa..d84168cc216b 100644 --- a/src/main/resources/com/puppycrawl/tools/checkstyle/grammar/java/JavaLanguageParser.g4 +++ b/src/main/resources/com/puppycrawl/tools/checkstyle/grammar/java/JavaLanguageParser.g4 @@ -688,6 +688,7 @@ expression expr : primary #primaryExp + | expr DOT templateArgument #templateExp | expr bop=DOT id #refOp | expr bop=DOT id LPAREN expressionList? RPAREN #methodCall | expr bop=DOT LITERAL_THIS #thisExp @@ -757,6 +758,24 @@ primary DOT LITERAL_CLASS #primitivePrimary ; +templateArgument + : template + | STRING_LITERAL + | TEXT_BLOCK_LITERAL_BEGIN TEXT_BLOCK_CONTENT TEXT_BLOCK_LITERAL_END + ; + +template + : stringTemplate + ; + +stringTemplate + : STRING_TEMPLATE_BEGIN expr? stringTemplateMiddle* STRING_TEMPLATE_END + ; + +stringTemplateMiddle + : STRING_TEMPLATE_MID expr? + ; + classType : (classOrInterfaceType[false] DOT)? annotations[false] id typeArguments? ; diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/grammar/java21/Java21AstRegressionTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/grammar/java21/Java21AstRegressionTest.java new file mode 100644 index 000000000000..92502ea00d03 --- /dev/null +++ b/src/test/java/com/puppycrawl/tools/checkstyle/grammar/java21/Java21AstRegressionTest.java @@ -0,0 +1,41 @@ +/////////////////////////////////////////////////////////////////////////////////////////////// +// checkstyle: Checks Java source code and other text files for adherence to a set of rules. +// Copyright (C) 2001-2023 the original author or authors. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +/////////////////////////////////////////////////////////////////////////////////////////////// + +package com.puppycrawl.tools.checkstyle.grammar.java21; + +import org.junit.jupiter.api.Test; + +import com.puppycrawl.tools.checkstyle.AbstractTreeTestSupport; + +public class Java21AstRegressionTest extends AbstractTreeTestSupport { + + @Override + protected String getPackageLocation() { + return "com/puppycrawl/tools/checkstyle/grammar/java21"; + } + + @Test + public void testBasicStringTemplate() throws Exception { + verifyAst( + getNonCompilablePath( + "ExpectedStringTemplateBasic.txt"), + getNonCompilablePath( + "InputStringTemplateBasic.java")); + } +} diff --git a/src/test/resources-noncompilable/com/puppycrawl/tools/checkstyle/grammar/java21/ExpectedStringTemplateBasic.txt b/src/test/resources-noncompilable/com/puppycrawl/tools/checkstyle/grammar/java21/ExpectedStringTemplateBasic.txt new file mode 100644 index 000000000000..139020aff3be --- /dev/null +++ b/src/test/resources-noncompilable/com/puppycrawl/tools/checkstyle/grammar/java21/ExpectedStringTemplateBasic.txt @@ -0,0 +1,421 @@ +COMPILATION_UNIT -> COMPILATION_UNIT [2:0] +|--PACKAGE_DEF -> package [2:0] +| |--ANNOTATIONS -> ANNOTATIONS [2:47] +| |--DOT -> . [2:47] +| | |--DOT -> . [2:39] +| | | |--DOT -> . [2:28] +| | | | |--DOT -> . [2:22] +| | | | | |--DOT -> . [2:11] +| | | | | | |--IDENT -> com [2:8] +| | | | | | `--IDENT -> puppycrawl [2:12] +| | | | | `--IDENT -> tools [2:23] +| | | | `--IDENT -> checkstyle [2:29] +| | | `--IDENT -> grammar [2:40] +| | `--IDENT -> java21 [2:48] +| `--SEMI -> ; [2:54] +`--CLASS_DEF -> CLASS_DEF [4:0] + |--MODIFIERS -> MODIFIERS [4:0] + | `--LITERAL_PUBLIC -> public [4:0] + |--LITERAL_CLASS -> class [4:7] + |--IDENT -> InputStringTemplateBasic [4:13] + `--OBJBLOCK -> OBJBLOCK [4:38] + |--LCURLY -> { [4:38] + |--VARIABLE_DEF -> VARIABLE_DEF [5:4] + | |--MODIFIERS -> MODIFIERS [5:4] + | |--TYPE -> TYPE [5:4] + | | `--LITERAL_INT -> int [5:4] + | |--IDENT -> x [5:8] + | |--ASSIGN -> = [5:10] + | | `--EXPR -> EXPR [5:12] + | | `--NUM_INT -> 10 [5:12] + | `--SEMI -> ; [5:14] + |--VARIABLE_DEF -> VARIABLE_DEF [6:4] + | |--MODIFIERS -> MODIFIERS [6:4] + | |--TYPE -> TYPE [6:4] + | | `--LITERAL_INT -> int [6:4] + | |--IDENT -> y [6:8] + | |--ASSIGN -> = [6:10] + | | `--EXPR -> EXPR [6:12] + | | `--NUM_INT -> 20 [6:12] + | `--SEMI -> ; [6:14] + |--VARIABLE_DEF -> VARIABLE_DEF [9:4] + | |--MODIFIERS -> MODIFIERS [9:4] + | |--TYPE -> TYPE [9:4] + | | `--IDENT -> String [9:4] + | |--IDENT -> result1 [9:11] + | |--ASSIGN -> = [9:19] + | | `--EXPR -> EXPR [9:24] + | | `--DOT -> . [9:24] + | | |--IDENT -> STR [9:21] + | | `--STRING_LITERAL -> "" [9:25] + | `--SEMI -> ; [9:27] + |--VARIABLE_DEF -> VARIABLE_DEF [12:4] + | |--MODIFIERS -> MODIFIERS [12:4] + | |--TYPE -> TYPE [12:4] + | | `--IDENT -> String [12:4] + | |--IDENT -> x [12:11] + | |--ASSIGN -> = [12:13] + | | `--EXPR -> EXPR [12:18] + | | `--DOT -> . [12:18] + | | |--IDENT -> STR [12:15] + | | `--STRING_TEMPLATE_BEGIN -> " [12:19] + | | |--STRING_TEMPLATE_CONTENT -> [12:20] + | | |--EMBEDDED_EXPRESSION_BEGIN -> \{ [12:20] + | | |--EMBEDDED_EXPRESSION -> EMBEDDED_EXPRESSION [12:24] + | | |--EMBEDDED_EXPRESSION_END -> } [12:24] + | | |--STRING_TEMPLATE_CONTENT -> [12:25] + | | `--STRING_TEMPLATE_END -> " [12:25] + | `--SEMI -> ; [12:26] + |--VARIABLE_DEF -> VARIABLE_DEF [15:4] + | |--MODIFIERS -> MODIFIERS [15:4] + | |--TYPE -> TYPE [15:4] + | | `--IDENT -> String [15:4] + | |--IDENT -> result2 [15:11] + | |--ASSIGN -> = [15:19] + | | `--EXPR -> EXPR [15:24] + | | `--DOT -> . [15:24] + | | |--IDENT -> STR [15:21] + | | `--STRING_TEMPLATE_BEGIN -> " [15:26] + | | |--STRING_TEMPLATE_CONTENT -> x [15:27] + | | |--EMBEDDED_EXPRESSION_BEGIN -> \{ [15:28] + | | |--EMBEDDED_EXPRESSION -> EMBEDDED_EXPRESSION [15:31] + | | | `--IDENT -> x [15:31] + | | |--EMBEDDED_EXPRESSION_END -> } [15:33] + | | |--STRING_TEMPLATE_CONTENT -> x [15:34] + | | `--STRING_TEMPLATE_END -> " [15:35] + | `--SEMI -> ; [15:36] + |--VARIABLE_DEF -> VARIABLE_DEF [18:4] + | |--MODIFIERS -> MODIFIERS [18:4] + | |--TYPE -> TYPE [18:4] + | | `--IDENT -> String [18:4] + | |--IDENT -> result3 [18:11] + | |--ASSIGN -> = [18:19] + | | `--EXPR -> EXPR [18:24] + | | `--DOT -> . [18:24] + | | |--IDENT -> STR [18:21] + | | `--STRING_TEMPLATE_BEGIN -> " [18:26] + | | |--STRING_TEMPLATE_CONTENT -> [18:27] + | | |--EMBEDDED_EXPRESSION_BEGIN -> \{ [18:27] + | | |--EMBEDDED_EXPRESSION -> EMBEDDED_EXPRESSION [18:31] + | | | `--METHOD_CALL -> ( [18:31] + | | | |--IDENT -> y [18:30] + | | | |--ELIST -> ELIST [18:33] + | | | | `--EXPR -> EXPR [18:33] + | | | | `--METHOD_CALL -> ( [18:33] + | | | | |--IDENT -> y [18:32] + | | | | |--ELIST -> ELIST [18:34] + | | | | | `--EXPR -> EXPR [18:34] + | | | | | `--STRING_LITERAL -> "y" [18:34] + | | | | `--RPAREN -> ) [18:37] + | | | `--RPAREN -> ) [18:38] + | | |--EMBEDDED_EXPRESSION_END -> } [18:40] + | | |--STRING_TEMPLATE_CONTENT -> [18:41] + | | `--STRING_TEMPLATE_END -> " [18:41] + | `--SEMI -> ; [18:42] + |--VARIABLE_DEF -> VARIABLE_DEF [21:4] + | |--MODIFIERS -> MODIFIERS [21:4] + | |--TYPE -> TYPE [21:4] + | | `--IDENT -> String [21:4] + | |--IDENT -> result4 [21:11] + | |--ASSIGN -> = [21:19] + | | `--EXPR -> EXPR [21:36] + | | `--PLUS -> + [21:36] + | | |--DOT -> . [21:24] + | | | |--IDENT -> STR [21:21] + | | | `--STRING_TEMPLATE_BEGIN -> " [21:26] + | | | |--STRING_TEMPLATE_CONTENT -> [21:27] + | | | |--EMBEDDED_EXPRESSION_BEGIN -> \{ [21:27] + | | | |--EMBEDDED_EXPRESSION -> EMBEDDED_EXPRESSION [21:30] + | | | | `--IDENT -> x [21:30] + | | | |--EMBEDDED_EXPRESSION_END -> } [21:32] + | | | |--STRING_TEMPLATE_CONTENT -> [21:33] + | | | `--STRING_TEMPLATE_END -> " [21:33] + | | `--DOT -> . [21:41] + | | |--IDENT -> STR [21:38] + | | `--STRING_TEMPLATE_BEGIN -> " [21:43] + | | |--STRING_TEMPLATE_CONTENT -> [21:44] + | | |--EMBEDDED_EXPRESSION_BEGIN -> \{ [21:44] + | | |--EMBEDDED_EXPRESSION -> EMBEDDED_EXPRESSION [21:47] + | | | `--IDENT -> y [21:47] + | | |--EMBEDDED_EXPRESSION_END -> } [21:49] + | | |--STRING_TEMPLATE_CONTENT -> [21:50] + | | `--STRING_TEMPLATE_END -> " [21:50] + | `--SEMI -> ; [21:51] + |--VARIABLE_DEF -> VARIABLE_DEF [24:4] + | |--MODIFIERS -> MODIFIERS [24:4] + | |--TYPE -> TYPE [24:4] + | | `--IDENT -> String [24:4] + | |--IDENT -> result5 [24:11] + | |--ASSIGN -> = [24:19] + | | `--EXPR -> EXPR [24:44] + | | `--PLUS -> + [24:44] + | | |--DOT -> . [24:24] + | | | |--IDENT -> STR [24:21] + | | | `--STRING_TEMPLATE_BEGIN -> " [24:26] + | | | |--STRING_TEMPLATE_CONTENT -> [24:27] + | | | |--EMBEDDED_EXPRESSION_BEGIN -> \{ [24:27] + | | | |--EMBEDDED_EXPRESSION -> EMBEDDED_EXPRESSION [24:31] + | | | | `--METHOD_CALL -> ( [24:31] + | | | | |--IDENT -> y [24:30] + | | | | |--ELIST -> ELIST [24:33] + | | | | | `--EXPR -> EXPR [24:33] + | | | | | `--METHOD_CALL -> ( [24:33] + | | | | | |--IDENT -> y [24:32] + | | | | | |--ELIST -> ELIST [24:34] + | | | | | | `--EXPR -> EXPR [24:34] + | | | | | | `--STRING_LITERAL -> "y" [24:34] + | | | | | `--RPAREN -> ) [24:37] + | | | | `--RPAREN -> ) [24:38] + | | | |--EMBEDDED_EXPRESSION_END -> } [24:40] + | | | |--STRING_TEMPLATE_CONTENT -> [24:41] + | | | `--STRING_TEMPLATE_END -> " [24:41] + | | `--DOT -> . [24:49] + | | |--IDENT -> STR [24:46] + | | `--STRING_TEMPLATE_BEGIN -> " [24:51] + | | |--STRING_TEMPLATE_CONTENT -> [24:52] + | | |--EMBEDDED_EXPRESSION_BEGIN -> \{ [24:52] + | | |--EMBEDDED_EXPRESSION -> EMBEDDED_EXPRESSION [24:56] + | | | `--METHOD_CALL -> ( [24:56] + | | | |--IDENT -> y [24:55] + | | | |--ELIST -> ELIST [24:58] + | | | | `--EXPR -> EXPR [24:58] + | | | | `--METHOD_CALL -> ( [24:58] + | | | | |--IDENT -> y [24:57] + | | | | |--ELIST -> ELIST [24:59] + | | | | | `--EXPR -> EXPR [24:59] + | | | | | `--STRING_LITERAL -> "y" [24:59] + | | | | `--RPAREN -> ) [24:62] + | | | `--RPAREN -> ) [24:63] + | | |--EMBEDDED_EXPRESSION_END -> } [24:65] + | | |--STRING_TEMPLATE_CONTENT -> [24:66] + | | `--STRING_TEMPLATE_END -> " [24:66] + | `--SEMI -> ; [24:67] + |--VARIABLE_DEF -> VARIABLE_DEF [27:4] + | |--MODIFIERS -> MODIFIERS [27:4] + | |--TYPE -> TYPE [27:4] + | | `--IDENT -> String [27:4] + | |--IDENT -> result6 [27:11] + | |--ASSIGN -> = [27:19] + | | `--EXPR -> EXPR [27:36] + | | `--PLUS -> + [27:36] + | | |--DOT -> . [27:24] + | | | |--IDENT -> STR [27:21] + | | | `--STRING_TEMPLATE_BEGIN -> " [27:26] + | | | |--STRING_TEMPLATE_CONTENT -> [27:27] + | | | |--EMBEDDED_EXPRESSION_BEGIN -> \{ [27:27] + | | | |--EMBEDDED_EXPRESSION -> EMBEDDED_EXPRESSION [27:30] + | | | | `--IDENT -> x [27:30] + | | | |--EMBEDDED_EXPRESSION_END -> } [27:32] + | | | |--STRING_TEMPLATE_CONTENT -> [27:33] + | | | `--STRING_TEMPLATE_END -> " [27:33] + | | `--DOT -> . [27:41] + | | |--IDENT -> STR [27:38] + | | `--STRING_TEMPLATE_BEGIN -> " [27:43] + | | |--STRING_TEMPLATE_CONTENT -> [27:44] + | | |--EMBEDDED_EXPRESSION_BEGIN -> \{ [27:44] + | | |--EMBEDDED_EXPRESSION -> EMBEDDED_EXPRESSION [27:47] + | | | `--IDENT -> y [27:47] + | | |--EMBEDDED_EXPRESSION_END -> } [27:49] + | | |--STRING_TEMPLATE_CONTENT -> [27:50] + | | `--STRING_TEMPLATE_END -> " [27:50] + | `--SEMI -> ; [27:51] + |--VARIABLE_DEF -> VARIABLE_DEF [30:4] + | |--MODIFIERS -> MODIFIERS [30:4] + | |--TYPE -> TYPE [30:4] + | | `--IDENT -> String [30:4] + | |--IDENT -> result7 [30:11] + | |--ASSIGN -> = [30:19] + | | `--EXPR -> EXPR [30:24] + | | `--DOT -> . [30:24] + | | |--IDENT -> STR [30:21] + | | `--STRING_TEMPLATE_BEGIN -> " [30:26] + | | |--STRING_TEMPLATE_CONTENT -> [30:27] + | | |--EMBEDDED_EXPRESSION_BEGIN -> \{ [30:27] + | | |--EMBEDDED_EXPRESSION -> EMBEDDED_EXPRESSION [30:32] + | | | `--PLUS -> + [30:32] + | | | |--IDENT -> x [30:30] + | | | `--IDENT -> y [30:34] + | | |--EMBEDDED_EXPRESSION_END -> } [30:36] + | | |--STRING_TEMPLATE_CONTENT -> [30:37] + | | `--STRING_TEMPLATE_END -> " [30:37] + | `--SEMI -> ; [30:38] + |--VARIABLE_DEF -> VARIABLE_DEF [33:4] + | |--MODIFIERS -> MODIFIERS [33:4] + | |--TYPE -> TYPE [33:4] + | | `--IDENT -> String [33:4] + | |--IDENT -> result8 [33:11] + | |--ASSIGN -> = [33:19] + | | `--EXPR -> EXPR [33:24] + | | `--DOT -> . [33:24] + | | |--IDENT -> STR [33:21] + | | `--STRING_TEMPLATE_BEGIN -> " [33:26] + | | |--STRING_TEMPLATE_CONTENT -> hey [33:27] + | | |--EMBEDDED_EXPRESSION_BEGIN -> \{ [33:31] + | | |--EMBEDDED_EXPRESSION -> EMBEDDED_EXPRESSION [33:44] + | | | `--PLUS -> + [33:44] + | | | |--METHOD_CALL -> ( [33:35] + | | | | |--IDENT -> y [33:34] + | | | | |--ELIST -> ELIST [33:37] + | | | | | `--EXPR -> EXPR [33:37] + | | | | | `--METHOD_CALL -> ( [33:37] + | | | | | |--IDENT -> y [33:36] + | | | | | |--ELIST -> ELIST [33:38] + | | | | | | `--EXPR -> EXPR [33:38] + | | | | | | `--STRING_LITERAL -> "y" [33:38] + | | | | | `--RPAREN -> ) [33:41] + | | | | `--RPAREN -> ) [33:42] + | | | `--METHOD_CALL -> ( [33:47] + | | | |--IDENT -> y [33:46] + | | | |--ELIST -> ELIST [33:49] + | | | | `--EXPR -> EXPR [33:49] + | | | | `--METHOD_CALL -> ( [33:49] + | | | | |--IDENT -> y [33:48] + | | | | |--ELIST -> ELIST [33:50] + | | | | | `--EXPR -> EXPR [33:50] + | | | | | `--STRING_LITERAL -> "y" [33:50] + | | | | `--RPAREN -> ) [33:53] + | | | `--RPAREN -> ) [33:54] + | | |--EMBEDDED_EXPRESSION_END -> } [33:56] + | | |--STRING_TEMPLATE_CONTENT -> there [33:57] + | | `--STRING_TEMPLATE_END -> " [33:63] + | `--SEMI -> ; [33:64] + |--VARIABLE_DEF -> VARIABLE_DEF [36:4] + | |--MODIFIERS -> MODIFIERS [36:4] + | |--TYPE -> TYPE [36:4] + | | `--IDENT -> String [36:4] + | |--IDENT -> result9 [36:11] + | |--ASSIGN -> = [36:19] + | | `--EXPR -> EXPR [36:24] + | | `--DOT -> . [36:24] + | | |--IDENT -> STR [36:21] + | | `--STRING_TEMPLATE_BEGIN -> " [36:26] + | | |--STRING_TEMPLATE_CONTENT -> hey [36:27] + | | |--EMBEDDED_EXPRESSION_BEGIN -> \{ [36:31] + | | |--EMBEDDED_EXPRESSION -> EMBEDDED_EXPRESSION [37:22] + | | | `--PLUS -> + [37:22] + | | | |--METHOD_CALL -> ( [37:13] + | | | | |--IDENT -> y [37:12] + | | | | |--ELIST -> ELIST [37:15] + | | | | | `--EXPR -> EXPR [37:15] + | | | | | `--METHOD_CALL -> ( [37:15] + | | | | | |--IDENT -> y [37:14] + | | | | | |--ELIST -> ELIST [37:16] + | | | | | | `--EXPR -> EXPR [37:16] + | | | | | | `--STRING_LITERAL -> "y" [37:16] + | | | | | `--RPAREN -> ) [37:19] + | | | | `--RPAREN -> ) [37:20] + | | | `--METHOD_CALL -> ( [37:25] + | | | |--IDENT -> y [37:24] + | | | |--ELIST -> ELIST [37:27] + | | | | `--EXPR -> EXPR [37:27] + | | | | `--METHOD_CALL -> ( [37:27] + | | | | |--IDENT -> y [37:26] + | | | | |--ELIST -> ELIST [37:28] + | | | | | `--EXPR -> EXPR [37:28] + | | | | | `--STRING_LITERAL -> "y" [37:28] + | | | | `--RPAREN -> ) [37:31] + | | | `--RPAREN -> ) [37:32] + | | |--EMBEDDED_EXPRESSION_END -> } [38:12] + | | |--STRING_TEMPLATE_CONTENT -> there [38:13] + | | `--STRING_TEMPLATE_END -> " [38:19] + | `--SEMI -> ; [38:20] + |--VARIABLE_DEF -> VARIABLE_DEF [41:4] + | |--MODIFIERS -> MODIFIERS [41:4] + | |--TYPE -> TYPE [41:4] + | | `--IDENT -> String [41:4] + | |--IDENT -> result10 [41:11] + | |--ASSIGN -> = [41:20] + | | `--EXPR -> EXPR [41:25] + | | `--DOT -> . [41:25] + | | |--IDENT -> STR [41:22] + | | `--STRING_TEMPLATE_BEGIN -> " [41:27] + | | |--STRING_TEMPLATE_CONTENT -> hey [41:28] + | | |--EMBEDDED_EXPRESSION_BEGIN -> \{ [41:32] + | | |--EMBEDDED_EXPRESSION -> EMBEDDED_EXPRESSION [42:22] + | | | `--PLUS -> + [42:22] + | | | |--METHOD_CALL -> ( [42:13] + | | | | |--IDENT -> y [42:12] + | | | | |--ELIST -> ELIST [42:15] + | | | | | `--EXPR -> EXPR [42:15] + | | | | | `--METHOD_CALL -> ( [42:15] + | | | | | |--IDENT -> y [42:14] + | | | | | |--ELIST -> ELIST [42:16] + | | | | | | `--EXPR -> EXPR [42:16] + | | | | | | `--STRING_LITERAL -> "y" [42:16] + | | | | | `--RPAREN -> ) [42:19] + | | | | `--RPAREN -> ) [42:20] + | | | `--METHOD_CALL -> ( [42:25] + | | | |--IDENT -> y [42:24] + | | | |--ELIST -> ELIST [42:27] + | | | | `--EXPR -> EXPR [42:27] + | | | | `--METHOD_CALL -> ( [42:27] + | | | | |--IDENT -> y [42:26] + | | | | |--ELIST -> ELIST [42:28] + | | | | | `--EXPR -> EXPR [42:28] + | | | | | `--STRING_LITERAL -> "y" [42:28] + | | | | `--RPAREN -> ) [42:31] + | | | `--RPAREN -> ) [42:32] + | | |--EMBEDDED_EXPRESSION_END -> } [43:12] + | | |--STRING_TEMPLATE_CONTENT -> there [44:13] + | | |--EMBEDDED_EXPRESSION_BEGIN -> \{ [43:20] + | | |--EMBEDDED_EXPRESSION -> EMBEDDED_EXPRESSION [45:12] + | | | `--PLUS -> + [45:12] + | | | |--PLUS -> + [44:22] + | | | | |--METHOD_CALL -> ( [44:13] + | | | | | |--IDENT -> y [44:12] + | | | | | |--ELIST -> ELIST [44:15] + | | | | | | `--EXPR -> EXPR [44:15] + | | | | | | `--METHOD_CALL -> ( [44:15] + | | | | | | |--IDENT -> y [44:14] + | | | | | | |--ELIST -> ELIST [44:16] + | | | | | | | `--EXPR -> EXPR [44:16] + | | | | | | | `--STRING_LITERAL -> "y" [44:16] + | | | | | | `--RPAREN -> ) [44:19] + | | | | | `--RPAREN -> ) [44:20] + | | | | `--METHOD_CALL -> ( [44:25] + | | | | |--IDENT -> y [44:24] + | | | | |--ELIST -> ELIST [44:27] + | | | | | `--EXPR -> EXPR [44:27] + | | | | | `--METHOD_CALL -> ( [44:27] + | | | | | |--IDENT -> y [44:26] + | | | | | |--ELIST -> ELIST [44:28] + | | | | | | `--EXPR -> EXPR [44:28] + | | | | | | `--STRING_LITERAL -> "y" [44:28] + | | | | | `--RPAREN -> ) [44:31] + | | | | `--RPAREN -> ) [44:32] + | | | `--DOT -> . [45:17] + | | | |--IDENT -> STR [45:14] + | | | `--STRING_TEMPLATE_BEGIN -> " [45:18] + | | | |--STRING_TEMPLATE_CONTENT -> x [45:19] + | | | |--EMBEDDED_EXPRESSION_BEGIN -> \{ [45:20] + | | | |--EMBEDDED_EXPRESSION -> EMBEDDED_EXPRESSION [45:23] + | | | | `--IDENT -> x [45:23] + | | | |--EMBEDDED_EXPRESSION_END -> } [45:25] + | | | |--STRING_TEMPLATE_CONTENT -> x [45:26] + | | | `--STRING_TEMPLATE_END -> " [45:27] + | | |--EMBEDDED_EXPRESSION_END -> } [46:12] + | | |--STRING_TEMPLATE_CONTENT -> [46:13] + | | `--STRING_TEMPLATE_END -> " [46:13] + | `--SEMI -> ; [46:14] + |--METHOD_DEF -> METHOD_DEF [49:4] + | |--MODIFIERS -> MODIFIERS [49:4] + | | |--LITERAL_PRIVATE -> private [49:4] + | | `--LITERAL_STATIC -> static [49:12] + | |--TYPE -> TYPE [49:19] + | | `--IDENT -> String [49:19] + | |--IDENT -> y [49:26] + | |--LPAREN -> ( [49:27] + | |--PARAMETERS -> PARAMETERS [49:28] + | | `--PARAMETER_DEF -> PARAMETER_DEF [49:28] + | | |--MODIFIERS -> MODIFIERS [49:28] + | | |--TYPE -> TYPE [49:28] + | | | `--IDENT -> String [49:28] + | | `--IDENT -> y [49:35] + | |--RPAREN -> ) [49:36] + | `--SLIST -> { [49:38] + | |--LITERAL_RETURN -> return [50:8] + | | |--EXPR -> EXPR [50:15] + | | | `--STRING_LITERAL -> "y" [50:15] + | | `--SEMI -> ; [50:18] + | `--RCURLY -> } [51:4] + `--RCURLY -> } [52:0] diff --git a/src/test/resources-noncompilable/com/puppycrawl/tools/checkstyle/grammar/java21/InputStringTemplateBasic.java b/src/test/resources-noncompilable/com/puppycrawl/tools/checkstyle/grammar/java21/InputStringTemplateBasic.java new file mode 100644 index 000000000000..2e92ac0bccc4 --- /dev/null +++ b/src/test/resources-noncompilable/com/puppycrawl/tools/checkstyle/grammar/java21/InputStringTemplateBasic.java @@ -0,0 +1,52 @@ +//non-compiled with javac: Compilable with Java21 +package com.puppycrawl.tools.checkstyle.grammar.java21; + +public class InputStringTemplateBasic { + int x = 10; + int y = 20; + + // most basic example, empty string template expression + String result1 = STR.""; + + // no content, no expression + String x = STR."\{ }"; + + // simple single value interpolation + String result2 = STR. "x\{ x }x"; + + // simple single value interpolation with a method call + String result3 = STR. "\{ y(y("y")) }"; + + // bit more complex example, multiple interpolations + String result4 = STR. "\{ x }" + STR. "\{ y }"; + + // bit more complex example, multiple interpolations with method calls + String result5 = STR. "\{ y(y("y")) }" + STR. "\{ y(y("y")) }"; + + // string template concatenation + String result6 = STR. "\{ x }" + STR. "\{ y }"; + + // concatentation in embedded expression + String result7 = STR. "\{ x + y }"; + + // concatentation in embedded expression with method calls + String result8 = STR. "hey \{ y(y("y")) + y(y("y")) } there"; + + // multiple lines + String result9 = STR. "hey \{ + y(y("y")) + y(y("y")) + } there"; + + // multiple lines with many expressions + String result10 = STR. "hey \{ + y(y("y")) + y(y("y")) + } there \{ + y(y("y")) + y(y("y")) + + STR."x\{ x }x" + }"; + + + private static String y(String y) { + return "y"; + } +}