Repository: incubator-freemarker
Updated Branches:
  refs/heads/2.3-gae eacd51689 -> f55f9d891


(Some more cleanup in FTL.jj... as far as BC allows us)


Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/f55f9d89
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/f55f9d89
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/f55f9d89

Branch: refs/heads/2.3-gae
Commit: f55f9d8919aa7fce3b88af37ac55ea04eb701033
Parents: eacd516
Author: ddekany <ddek...@apache.org>
Authored: Mon Mar 19 00:24:15 2018 +0100
Committer: ddekany <ddek...@apache.org>
Committed: Mon Mar 19 00:24:15 2018 +0100

----------------------------------------------------------------------
 src/main/javacc/FTL.jj                          | 64 +++++++++++---------
 .../core/InterpolationSyntaxTest.java           |  1 +
 2 files changed, 35 insertions(+), 30 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f55f9d89/src/main/javacc/FTL.jj
----------------------------------------------------------------------
diff --git a/src/main/javacc/FTL.jj b/src/main/javacc/FTL.jj
index d3be697..26f3368 100644
--- a/src/main/javacc/FTL.jj
+++ b/src/main/javacc/FTL.jj
@@ -116,29 +116,29 @@ public class FMParser {
      *            The template associated with this parser.
      * @param reader
      *            The character stream to use as input
-     * @param strictEscapeSyntax
+     * @param strictSyntaxMode
      *            Whether FreeMarker directives must start with a #
      *
      * @Deprecated This is an internal API of FreeMarker; will be removed in 
2.4.
      */
-    public FMParser(Template template, Reader reader, boolean 
strictEscapeSyntax, boolean stripWhitespace) {
-        this(template, reader, strictEscapeSyntax, stripWhitespace, 
Configuration.AUTO_DETECT_TAG_SYNTAX);
+    public FMParser(Template template, Reader reader, boolean 
strictSyntaxMode, boolean stripWhitespace) {
+        this(template, reader, strictSyntaxMode, stripWhitespace, 
Configuration.AUTO_DETECT_TAG_SYNTAX);
     }
 
     /**
      * @Deprecated This is an internal API of FreeMarker; will be changed in 
2.4.
      */
-    public FMParser(Template template, Reader reader, boolean 
strictEscapeSyntax, boolean stripWhitespace, int tagSyntax) {
-        this(template, reader, strictEscapeSyntax, stripWhitespace, tagSyntax,
+    public FMParser(Template template, Reader reader, boolean 
strictSyntaxMode, boolean stripWhitespace, int tagSyntax) {
+        this(template, reader, strictSyntaxMode, stripWhitespace, tagSyntax,
                 Configuration.PARSED_DEFAULT_INCOMPATIBLE_ENHANCEMENTS);
     }
 
     /**
      * @Deprecated This is an internal API of FreeMarker; will be changed in 
2.4.
      */
-    public FMParser(Template template, Reader reader, boolean 
strictEscapeSyntax, boolean stripWhitespace,
+    public FMParser(Template template, Reader reader, boolean 
strictSyntaxMode, boolean stripWhitespace,
             int tagSyntax, int incompatibleImprovements) {
-        this(template, reader, strictEscapeSyntax, stripWhitespace,
+        this(template, reader, strictSyntaxMode, stripWhitespace,
                 tagSyntax, Configuration.AUTO_DETECT_NAMING_CONVENTION, 
incompatibleImprovements);
     }
 
@@ -240,7 +240,7 @@ public class FMParser {
 
         token_source.setParser(this);
 
-        token_source.strictEscapeSyntax = pCfg.getStrictSyntaxMode();
+        token_source.strictSyntaxMode = pCfg.getStrictSyntaxMode();
 
         int tagSyntax = pCfg.getTagSyntax();
         switch (tagSyntax) {
@@ -287,7 +287,7 @@ public class FMParser {
         token_source.initialNamingConvention = 
parentTokenSource.initialNamingConvention;
         token_source.namingConvention = parentTokenSource.namingConvention;
         token_source.namingConventionEstabilisher = 
parentTokenSource.namingConventionEstabilisher;
-        token_source.SwitchTo(NODIRECTIVE);
+        token_source.SwitchTo(NO_DIRECTIVE);
         
         this.outputFormat = outputFormat;
         recalculateAutoEscapingField();                                
@@ -621,11 +621,11 @@ TOKEN_MGR_DECLS:
      * Keeps track of how deeply nested we have the hash literals. This is 
necessary since we need to be able to
      * distinguish the } used to close a hash literal and the one used to 
close a ${
      */
-    private int hashLiteralNesting;
+    private int curlyBracketNesting;
     private int parenthesisNesting;
     private int bracketNesting;
     private boolean inFTLHeader;
-    boolean strictEscapeSyntax,
+    boolean strictSyntaxMode,
             squBracTagSyntax,
             autodetectTagSyntax,
             directiveSyntaxEstablished,
@@ -649,7 +649,7 @@ TOKEN_MGR_DECLS:
         
         // Non-strict syntax (deprecated) only supports legacy naming 
convention.
         // We didn't push this on the tokenizer because it made it slow, so we 
filter here.
-        if (!strictEscapeSyntax
+        if (!strictSyntaxMode
                 && (tokenNamingConvention == 
Configuration.CAMEL_CASE_NAMING_CONVENTION)
                 && !isStrictTag(image)) {
             tok.kind = STATIC_TEXT_NON_WS;
@@ -665,7 +665,7 @@ TOKEN_MGR_DECLS:
             return;
         }
         
-        if (!strictEscapeSyntax) {
+        if (!strictSyntaxMode) {
             // Legacy feature (or bug?): Tag syntax never gets estabilished in 
non-strict mode.
             // We do establilish the naming convention though.
             checkNamingConvention(tok, tokenNamingConvention);
@@ -824,22 +824,21 @@ TOKEN_MGR_DECLS:
         SwitchTo(FM_EXPRESSION);
     }
 
-    /**
-     * @param tok
-     *         Assumed to be an '}', or something that is the closing pair of 
another "mirror image" character.
-     */
-    private void endInterpolation(Token tok) {
+    private void endInterpolation(Token closingTk) {
         if (postInterpolationLexState == -1) {
-            char c = tok.image.charAt(0);
-            throw new TokenMgrError(
-                    "You can't have an \"" + c + "\" here, as there's nothing 
open that it could close.",
-                    TokenMgrError.LEXICAL_ERROR,
-                    tok.beginLine, tok.beginColumn,
-                    tok.endLine, tok.endColumn);
+            throw newUnexpectedClosingTokenException(closingTk);
         }
         SwitchTo(postInterpolationLexState);
         postInterpolationLexState = -1;
     }
+    
+    private TokenMgrError newUnexpectedClosingTokenException(Token closingTk) {
+            return new TokenMgrError(
+                    "You can't have an \"" + closingTk.image + "\" here, as 
there's nothing open that it could close.",
+                    TokenMgrError.LEXICAL_ERROR,
+                    closingTk.beginLine, closingTk.beginColumn,
+                    closingTk.endLine, closingTk.endColumn);
+    }
 
     private void eatNewline() {
         int charsRead = 0;
@@ -1095,7 +1094,7 @@ TOKEN:
                 matchedToken.kind = STATIC_TEXT_NON_WS;
             } else if (firstChar == '[' && !squBracTagSyntax) {
                 matchedToken.kind = STATIC_TEXT_NON_WS;
-            } else if (strictEscapeSyntax) {
+            } else if (strictSyntaxMode) {
                 String dn = matchedToken.image;
                 int index = dn.indexOf('#');
                 dn = dn.substring(index + 1);
@@ -1149,7 +1148,7 @@ TOKEN:
     }
 }
 
-<DEFAULT, NODIRECTIVE> TOKEN :
+<DEFAULT, NO_DIRECTIVE> TOKEN :
 {
     <STATIC_TEXT_WS : ("\n" | "\r" | "\t" | " ")+>
     |
@@ -1330,13 +1329,18 @@ TOKEN:
     |
     <OPENING_CURLY_BRACKET : "{">
     {
-        ++hashLiteralNesting;
+        ++curlyBracketNesting;
     }
     |
     <CLOSING_CURLY_BRACKET : "}">
     {
-        if (hashLiteralNesting == 0) endInterpolation(matchedToken);
-        else --hashLiteralNesting;
+        if (curlyBracketNesting > 0) {
+            --curlyBracketNesting;
+        } else if (interpolationSyntax != SQUARE_BRACKET_INTERPOLATION_SYNTAX) 
{
+            endInterpolation(matchedToken);
+        } else {
+            throw newUnexpectedClosingTokenException(matchedToken);
+        }
     }
     |
     <IN : "in">
@@ -4341,7 +4345,7 @@ void HeaderElement() :
                         } else if (ks.equalsIgnoreCase("STRIP_TEXT") || 
ks.equals("stripText")) {
                             this.stripText = getBoolean(exp, true);
                         } else if (ks.equalsIgnoreCase("STRICT_SYNTAX") || 
ks.equals("strictSyntax")) {
-                            this.token_source.strictEscapeSyntax = 
getBoolean(exp, true);
+                            this.token_source.strictSyntaxMode = 
getBoolean(exp, true);
                         } else if (ks.equalsIgnoreCase("auto_esc") || 
ks.equals("autoEsc")) {
                             if (getBoolean(exp, false)) {
                                 autoEscRequester = key;

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f55f9d89/src/test/java/freemarker/core/InterpolationSyntaxTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/core/InterpolationSyntaxTest.java 
b/src/test/java/freemarker/core/InterpolationSyntaxTest.java
index 8c57d36..2322d99 100644
--- a/src/test/java/freemarker/core/InterpolationSyntaxTest.java
+++ b/src/test/java/freemarker/core/InterpolationSyntaxTest.java
@@ -78,6 +78,7 @@ public class InterpolationSyntaxTest extends TemplateTest {
         
         assertErrorContains("[=", "end of file");
         assertErrorContains("[=1", "unclosed \"[\"");
+        assertErrorContains("[=1}", "\"}\"", "open");
         
         assertOutput("[='[\\=1]']", "[=1]");
         assertOutput("[='[\\=1][=2]']", "12"); // Usual legacy interpolation 
escaping glitch...

Reply via email to