jamesfredley commented on code in PR #16551:
URL: https://github.com/apache/grails-core/pull/16551#discussion_r4210587289


##########
grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/LogicLineTrimmer.java:
##########
@@ -0,0 +1,94 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    https://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.grails.gsp.compiler;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Removes the lines of a page that hold only template logic, for a page 
declaring
+ * {@code trimLogicLines="true"}: a line holding nothing but page directives, 
scriptlets and comments,
+ * besides spaces and tabs, writes neither its indentation nor its line break. 
A line holding text, an
+ * expression or a tag is left as it is.
+ *
+ * <p>The line break of a removed line is moved inside the line's last 
construct, just after its
+ * opening delimiter, rather than dropped, so that every line of the page 
keeps its number in the
+ * compiled page and in the errors reported against it.</p>
+ */
+final class LogicLineTrimmer {
+
+    private static final String CONSTRUCT = "(?:" +
+            "<%--(?:(?!--%>).)*--%>" +          // <%-- comment --%>
+            "|%\\{--(?:(?!--\\}%).)*--\\}%" +   // %{-- comment --}%
+            "|<%@(?:(?!%>).)*%>" +              // <%@ directive %>
+            "|<%(?![=@]|--)(?:(?!%>).)*%>" +    // <% scriptlet %>

Review Comment:
   This alternative matches `<%` unless it is followed by `=`, `@`, or `--`, so 
a declaration `<%! ... %>` is treated as a scriptlet. `openingDelimiterLength` 
then returns 2 and the trimmer writes `<%`, a newline, then `!...%>`. The 
scanner compiles that as a scriptlet, and a page that used to compile with 
`trimLogicLines="true"` fails.
   
   Do not match `<%!`, or preserve the whole `<%!` delimiter.



##########
grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/LogicLineTrimmer.java:
##########
@@ -0,0 +1,94 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    https://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.grails.gsp.compiler;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Removes the lines of a page that hold only template logic, for a page 
declaring
+ * {@code trimLogicLines="true"}: a line holding nothing but page directives, 
scriptlets and comments,
+ * besides spaces and tabs, writes neither its indentation nor its line break. 
A line holding text, an
+ * expression or a tag is left as it is.
+ *
+ * <p>The line break of a removed line is moved inside the line's last 
construct, just after its
+ * opening delimiter, rather than dropped, so that every line of the page 
keeps its number in the
+ * compiled page and in the errors reported against it.</p>
+ */
+final class LogicLineTrimmer {
+
+    private static final String CONSTRUCT = "(?:" +
+            "<%--(?:(?!--%>).)*--%>" +          // <%-- comment --%>
+            "|%\\{--(?:(?!--\\}%).)*--\\}%" +   // %{-- comment --}%
+            "|<%@(?:(?!%>).)*%>" +              // <%@ directive %>
+            "|<%(?![=@]|--)(?:(?!%>).)*%>" +    // <% scriptlet %>
+            "|%\\{(?!--)(?:(?!\\}%).)*\\}%" +   // %{ scriptlet }%
+            ")";
+
+    private static final Pattern CONSTRUCT_PATTERN = 
Pattern.compile(CONSTRUCT, Pattern.DOTALL);
+
+    private static final Pattern LOGIC_LINE_PATTERN = Pattern.compile(
+            "^[ \\t]*(" + CONSTRUCT + "(?:[ \\t]*" + CONSTRUCT + ")*)[ 
\\t]*(\\r?\\n|\\z)",
+            Pattern.MULTILINE | Pattern.DOTALL);
+
+    private LogicLineTrimmer() {
+    }
+
+    static String trim(String gspSource) {
+        Matcher line = LOGIC_LINE_PATTERN.matcher(gspSource);

Review Comment:
   `LOGIC_LINE_PATTERN` is applied to the entire page. A line that contains 
only a scriptlet inside a multiline `${...}` expression, or inside a string, is 
trimmed too. Its indentation is removed and the newline is moved into the `<%` 
delimiter, which changes the rendered text.
   
   Only trim constructs that are at template level, not text that merely looks 
like a scriptlet inside an expression or a literal.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to