You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@freemarker.apache.org by dd...@apache.org on 2018/03/24 14:31:54 UTC

[1/7] incubator-freemarker git commit: (Minor internal renaming in FTL.jj)

Repository: incubator-freemarker
Updated Branches:
  refs/heads/2.3 edefaa2f6 -> 17480993a


(Minor internal renaming in FTL.jj)


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

Branch: refs/heads/2.3
Commit: 355a09a21ee5daf514b1d90ef36751e0badf411a
Parents: 0129453
Author: ddekany <dd...@apache.org>
Authored: Mon Mar 19 23:37:45 2018 +0100
Committer: ddekany <dd...@apache.org>
Committed: Mon Mar 19 23:37:45 2018 +0100

----------------------------------------------------------------------
 src/main/javacc/FTL.jj | 164 ++++++++++++++++++++++----------------------
 1 file changed, 82 insertions(+), 82 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/355a09a2/src/main/javacc/FTL.jj
----------------------------------------------------------------------
diff --git a/src/main/javacc/FTL.jj b/src/main/javacc/FTL.jj
index 630ef39..d1ab33d 100644
--- a/src/main/javacc/FTL.jj
+++ b/src/main/javacc/FTL.jj
@@ -628,7 +628,7 @@ TOKEN_MGR_DECLS:
     boolean strictSyntaxMode,
             squBracTagSyntax,
             autodetectTagSyntax,
-            directiveSyntaxEstablished,
+            tagSyntaxEstablished,
             inInvocation;
     int interpolationSyntax;
     int initialNamingConvention;
@@ -644,7 +644,7 @@ TOKEN_MGR_DECLS:
     // FreeMarker directives must start with <#. It also handles
     // tag syntax detection. If you update this logic, take a look
     // at the UNKNOWN_DIRECTIVE token too.
-    private void strictSyntaxCheck(Token tok, int tokenNamingConvention, int newLexState) {
+    private void handleTagSyntaxAndSwitch(Token tok, int tokenNamingConvention, int newLexState) {
         final String image = tok.image;
         
         // Non-strict syntax (deprecated) only supports legacy naming convention.
@@ -657,7 +657,7 @@ TOKEN_MGR_DECLS:
         }
         
         char firstChar = image.charAt(0);
-        if (autodetectTagSyntax && !directiveSyntaxEstablished) {
+        if (autodetectTagSyntax && !tagSyntaxEstablished) {
             squBracTagSyntax = (firstChar == '[');
         }
         if ((firstChar == '[' && !squBracTagSyntax) || (firstChar == '<' && squBracTagSyntax)) {
@@ -682,7 +682,7 @@ TOKEN_MGR_DECLS:
         }
         
         // We only get here if this is a strict FTL tag.
-        directiveSyntaxEstablished = true;
+        tagSyntaxEstablished = true;
         
         if (incompatibleImprovements >= _TemplateAPI.VERSION_INT_2_3_28
                 || interpolationSyntax == SQUARE_BRACKET_INTERPOLATION_SYNTAX) {
@@ -751,8 +751,8 @@ TOKEN_MGR_DECLS:
     /**
      * Used for tags whose name isn't affected by naming convention.
      */
-    private void strictSyntaxCheck(Token tok, int newLexState) {
-        strictSyntaxCheck(tok, Configuration.AUTO_DETECT_NAMING_CONVENTION, newLexState);
+    private void handleTagSyntaxAndSwitch(Token tok, int newLexState) {
+        handleTagSyntaxAndSwitch(tok, Configuration.AUTO_DETECT_NAMING_CONVENTION, newLexState);
     }
     
     private boolean isStrictTag(String image) {
@@ -788,7 +788,7 @@ TOKEN_MGR_DECLS:
 
     private void unifiedCall(Token tok) {
         char firstChar = tok.image.charAt(0);
-        if (autodetectTagSyntax && !directiveSyntaxEstablished) {
+        if (autodetectTagSyntax && !tagSyntaxEstablished) {
             squBracTagSyntax = (firstChar == '[');
         }
         if (squBracTagSyntax && firstChar == '<') {
@@ -799,7 +799,7 @@ TOKEN_MGR_DECLS:
             tok.kind = STATIC_TEXT_NON_WS;
             return;
         }
-        directiveSyntaxEstablished = true;
+        tagSyntaxEstablished = true;
         SwitchTo(NO_SPACE_EXPRESSION);
     }
 
@@ -881,9 +881,9 @@ TOKEN_MGR_DECLS:
     }
 
     private void ftlHeader(Token matchedToken) {
-        if (!directiveSyntaxEstablished) {
+        if (!tagSyntaxEstablished) {
             squBracTagSyntax = matchedToken.image.charAt(0) == '[';
-            directiveSyntaxEstablished = true;
+            tagSyntaxEstablished = true;
             autodetectTagSyntax = false;
         }
         String img = matchedToken.image;
@@ -918,168 +918,168 @@ TOKEN:
     /*
      * ATTENTION: Update _CoreAPI.*_BUILT_IN_DIRECTIVE_NAMES if you add new directives!
      */
-    <ATTEMPT : <START_TAG> "attempt" <CLOSE_TAG1>> { strictSyntaxCheck(matchedToken, DEFAULT); }
+    <ATTEMPT : <START_TAG> "attempt" <CLOSE_TAG1>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
     |
-    <RECOVER : <START_TAG> "recover" <CLOSE_TAG1>> { strictSyntaxCheck(matchedToken, DEFAULT); } 
+    <RECOVER : <START_TAG> "recover" <CLOSE_TAG1>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); } 
     |
-    <IF : <START_TAG> "if" <BLANK>> { strictSyntaxCheck(matchedToken, FM_EXPRESSION); }
+    <IF : <START_TAG> "if" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
     |
     <ELSE_IF : <START_TAG> "else" ("i" | "I") "f" <BLANK>> {
-        strictSyntaxCheck(matchedToken, getTagNamingConvention(matchedToken, 4), FM_EXPRESSION);
+        handleTagSyntaxAndSwitch(matchedToken, getTagNamingConvention(matchedToken, 4), FM_EXPRESSION);
     }
     |
-    <LIST : <START_TAG> "list" <BLANK>> { strictSyntaxCheck(matchedToken, FM_EXPRESSION); }
+    <LIST : <START_TAG> "list" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
     |
-    <ITEMS : <START_TAG> "items" (<BLANK>)+ <AS> <BLANK>> { strictSyntaxCheck(matchedToken, FM_EXPRESSION); }
+    <ITEMS : <START_TAG> "items" (<BLANK>)+ <AS> <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
     |
     <SEP : <START_TAG> "sep" <CLOSE_TAG1>>
     |
     <FOREACH : <START_TAG> "for" ("e" | "E") "ach" <BLANK>> {
-        strictSyntaxCheck(matchedToken, getTagNamingConvention(matchedToken, 3), FM_EXPRESSION);
+        handleTagSyntaxAndSwitch(matchedToken, getTagNamingConvention(matchedToken, 3), FM_EXPRESSION);
     }
     |
-    <SWITCH : <START_TAG> "switch" <BLANK>> { strictSyntaxCheck(matchedToken, FM_EXPRESSION); }
+    <SWITCH : <START_TAG> "switch" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
     |
-    <CASE : <START_TAG> "case" <BLANK>> { strictSyntaxCheck(matchedToken, FM_EXPRESSION); }
+    <CASE : <START_TAG> "case" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
     |
-    <ASSIGN : <START_TAG> "assign" <BLANK>> { strictSyntaxCheck(matchedToken, FM_EXPRESSION); }
+    <ASSIGN : <START_TAG> "assign" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
     |
-    <GLOBALASSIGN : <START_TAG> "global" <BLANK>> { strictSyntaxCheck(matchedToken, FM_EXPRESSION); }
+    <GLOBALASSIGN : <START_TAG> "global" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
     |
-    <LOCALASSIGN : <START_TAG> "local" <BLANK>> { strictSyntaxCheck(matchedToken, FM_EXPRESSION); }
+    <LOCALASSIGN : <START_TAG> "local" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
     |
-    <_INCLUDE : <START_TAG> "include" <BLANK>> { strictSyntaxCheck(matchedToken, FM_EXPRESSION); }
+    <_INCLUDE : <START_TAG> "include" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
     |
-    <IMPORT : <START_TAG> "import" <BLANK>> { strictSyntaxCheck(matchedToken, FM_EXPRESSION); }
+    <IMPORT : <START_TAG> "import" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
     |
-    <FUNCTION : <START_TAG> "function" <BLANK>> { strictSyntaxCheck(matchedToken, FM_EXPRESSION); }
+    <FUNCTION : <START_TAG> "function" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
     |
-    <MACRO : <START_TAG> "macro" <BLANK>> { strictSyntaxCheck(matchedToken, FM_EXPRESSION); }
+    <MACRO : <START_TAG> "macro" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
     |
-    <TRANSFORM : <START_TAG> "transform" <BLANK>> { strictSyntaxCheck(matchedToken, FM_EXPRESSION); }
+    <TRANSFORM : <START_TAG> "transform" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
     |
-    <VISIT : <START_TAG> "visit" <BLANK>> { strictSyntaxCheck(matchedToken, FM_EXPRESSION); }
+    <VISIT : <START_TAG> "visit" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
     |
-    <STOP : <START_TAG> "stop" <BLANK>> { strictSyntaxCheck(matchedToken, FM_EXPRESSION); }
+    <STOP : <START_TAG> "stop" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
     |
-    <RETURN : <START_TAG> "return" <BLANK>> { strictSyntaxCheck(matchedToken, FM_EXPRESSION); }
+    <RETURN : <START_TAG> "return" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
     |
-    <CALL : <START_TAG> "call" <BLANK>> { strictSyntaxCheck(matchedToken, FM_EXPRESSION); }
+    <CALL : <START_TAG> "call" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
     |
-    <SETTING : <START_TAG> "setting" <BLANK>> { strictSyntaxCheck(matchedToken, FM_EXPRESSION); }
+    <SETTING : <START_TAG> "setting" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
     |
     <OUTPUTFORMAT : <START_TAG> "output" ("f"|"F") "ormat" <BLANK>> {
-        strictSyntaxCheck(matchedToken, getTagNamingConvention(matchedToken, 6), FM_EXPRESSION);
+        handleTagSyntaxAndSwitch(matchedToken, getTagNamingConvention(matchedToken, 6), FM_EXPRESSION);
     }
     |
     <AUTOESC : <START_TAG> "auto" ("e"|"E") "sc" <CLOSE_TAG1>> {
-        strictSyntaxCheck(matchedToken, getTagNamingConvention(matchedToken, 4), DEFAULT);
+        handleTagSyntaxAndSwitch(matchedToken, getTagNamingConvention(matchedToken, 4), DEFAULT);
     }
     |
     <NOAUTOESC : <START_TAG> "no" ("autoe"|"AutoE") "sc" <CLOSE_TAG1>> {
-        strictSyntaxCheck(matchedToken, getTagNamingConvention(matchedToken, 2), DEFAULT);
+        handleTagSyntaxAndSwitch(matchedToken, getTagNamingConvention(matchedToken, 2), DEFAULT);
     }
     |
-    <COMPRESS : <START_TAG> "compress" <CLOSE_TAG1>> { strictSyntaxCheck(matchedToken, DEFAULT); }
+    <COMPRESS : <START_TAG> "compress" <CLOSE_TAG1>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
     |
     <COMMENT : <START_TAG> "comment" <CLOSE_TAG1>> {
-        strictSyntaxCheck(matchedToken, NO_PARSE); noparseTag = "comment";
+        handleTagSyntaxAndSwitch(matchedToken, NO_PARSE); noparseTag = "comment";
     }
     |
-    <TERSE_COMMENT : ("<" | "[") "#--" > { noparseTag = "-->"; strictSyntaxCheck(matchedToken, NO_PARSE); }
+    <TERSE_COMMENT : ("<" | "[") "#--" > { noparseTag = "-->"; handleTagSyntaxAndSwitch(matchedToken, NO_PARSE); }
     |
     <NOPARSE: <START_TAG> "no" ("p" | "P") "arse" <CLOSE_TAG1>> {
         int tagNamingConvention = getTagNamingConvention(matchedToken, 2);
-        strictSyntaxCheck(matchedToken, tagNamingConvention, NO_PARSE);
+        handleTagSyntaxAndSwitch(matchedToken, tagNamingConvention, NO_PARSE);
         noparseTag = tagNamingConvention == Configuration.CAMEL_CASE_NAMING_CONVENTION ? "noParse" : "noparse";
     }
     |
-    <END_IF : <END_TAG> "if" <CLOSE_TAG1>> { strictSyntaxCheck(matchedToken, DEFAULT); }
+    <END_IF : <END_TAG> "if" <CLOSE_TAG1>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
     |
-    <END_LIST : <END_TAG> "list" <CLOSE_TAG1>> { strictSyntaxCheck(matchedToken, DEFAULT); }
+    <END_LIST : <END_TAG> "list" <CLOSE_TAG1>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
     |
-    <END_ITEMS : <END_TAG> "items" <CLOSE_TAG1>> { strictSyntaxCheck(matchedToken, DEFAULT); }
+    <END_ITEMS : <END_TAG> "items" <CLOSE_TAG1>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
     |
-    <END_SEP : <END_TAG> "sep" <CLOSE_TAG1>> { strictSyntaxCheck(matchedToken, DEFAULT); }
+    <END_SEP : <END_TAG> "sep" <CLOSE_TAG1>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
     |
-    <END_RECOVER : <END_TAG> "recover" <CLOSE_TAG1>> { strictSyntaxCheck(matchedToken, DEFAULT); }
+    <END_RECOVER : <END_TAG> "recover" <CLOSE_TAG1>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
     |
-    <END_ATTEMPT : <END_TAG> "attempt" <CLOSE_TAG1>> { strictSyntaxCheck(matchedToken, DEFAULT); }
+    <END_ATTEMPT : <END_TAG> "attempt" <CLOSE_TAG1>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
     |
     <END_FOREACH : <END_TAG> "for" ("e" | "E") "ach" <CLOSE_TAG1>> {
-        strictSyntaxCheck(matchedToken, getTagNamingConvention(matchedToken, 3), DEFAULT);
+        handleTagSyntaxAndSwitch(matchedToken, getTagNamingConvention(matchedToken, 3), DEFAULT);
     }
     |
-    <END_LOCAL : <END_TAG> "local" <CLOSE_TAG1>> { strictSyntaxCheck(matchedToken, DEFAULT); }
+    <END_LOCAL : <END_TAG> "local" <CLOSE_TAG1>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
     |
-    <END_GLOBAL : <END_TAG> "global" <CLOSE_TAG1>> { strictSyntaxCheck(matchedToken, DEFAULT); }
+    <END_GLOBAL : <END_TAG> "global" <CLOSE_TAG1>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
     |
-    <END_ASSIGN : <END_TAG> "assign" <CLOSE_TAG1>> { strictSyntaxCheck(matchedToken, DEFAULT); }
+    <END_ASSIGN : <END_TAG> "assign" <CLOSE_TAG1>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
     |
-    <END_FUNCTION : <END_TAG> "function" <CLOSE_TAG1>> { strictSyntaxCheck(matchedToken, DEFAULT); }
+    <END_FUNCTION : <END_TAG> "function" <CLOSE_TAG1>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
     |
-    <END_MACRO : <END_TAG> "macro" <CLOSE_TAG1>> { strictSyntaxCheck(matchedToken, DEFAULT); }
+    <END_MACRO : <END_TAG> "macro" <CLOSE_TAG1>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
     |
     <END_OUTPUTFORMAT : <END_TAG> "output" ("f" | "F") "ormat" <CLOSE_TAG1>> {
-        strictSyntaxCheck(matchedToken, getTagNamingConvention(matchedToken, 6), DEFAULT);
+        handleTagSyntaxAndSwitch(matchedToken, getTagNamingConvention(matchedToken, 6), DEFAULT);
     }
     |
     <END_AUTOESC : <END_TAG> "auto" ("e" | "E") "sc" <CLOSE_TAG1>> {
-        strictSyntaxCheck(matchedToken, getTagNamingConvention(matchedToken, 4), DEFAULT);
+        handleTagSyntaxAndSwitch(matchedToken, getTagNamingConvention(matchedToken, 4), DEFAULT);
     }
     |
     <END_NOAUTOESC : <END_TAG> "no" ("autoe"|"AutoE") "sc" <CLOSE_TAG1>> {
-        strictSyntaxCheck(matchedToken, getTagNamingConvention(matchedToken, 2), DEFAULT);
+        handleTagSyntaxAndSwitch(matchedToken, getTagNamingConvention(matchedToken, 2), DEFAULT);
     }
     |
-    <END_COMPRESS : <END_TAG> "compress" <CLOSE_TAG1>> { strictSyntaxCheck(matchedToken, DEFAULT); }
+    <END_COMPRESS : <END_TAG> "compress" <CLOSE_TAG1>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
     |
-    <END_TRANSFORM : <END_TAG> "transform" <CLOSE_TAG1>> { strictSyntaxCheck(matchedToken, DEFAULT); }
+    <END_TRANSFORM : <END_TAG> "transform" <CLOSE_TAG1>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
     |
-    <END_SWITCH : <END_TAG> "switch" <CLOSE_TAG1>> { strictSyntaxCheck(matchedToken, DEFAULT); }
+    <END_SWITCH : <END_TAG> "switch" <CLOSE_TAG1>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
     |
-    <ELSE : <START_TAG> "else" <CLOSE_TAG2>> { strictSyntaxCheck(matchedToken, DEFAULT); }
+    <ELSE : <START_TAG> "else" <CLOSE_TAG2>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
     |
-    <BREAK : <START_TAG> "break" <CLOSE_TAG2>> { strictSyntaxCheck(matchedToken, DEFAULT); }
+    <BREAK : <START_TAG> "break" <CLOSE_TAG2>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
     |
-    <CONTINUE : <START_TAG> "continue" <CLOSE_TAG2>> { strictSyntaxCheck(matchedToken, DEFAULT); }
+    <CONTINUE : <START_TAG> "continue" <CLOSE_TAG2>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
     |
-    <SIMPLE_RETURN : <START_TAG> "return" <CLOSE_TAG2>> { strictSyntaxCheck(matchedToken, DEFAULT); }
+    <SIMPLE_RETURN : <START_TAG> "return" <CLOSE_TAG2>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
     |
-    <HALT : <START_TAG> "stop" <CLOSE_TAG2>> { strictSyntaxCheck(matchedToken, DEFAULT); }
+    <HALT : <START_TAG> "stop" <CLOSE_TAG2>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
     |
-    <FLUSH : <START_TAG> "flush" <CLOSE_TAG2>> { strictSyntaxCheck(matchedToken, DEFAULT); }
+    <FLUSH : <START_TAG> "flush" <CLOSE_TAG2>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
     |
-    <TRIM : <START_TAG> "t" <CLOSE_TAG2>> { strictSyntaxCheck(matchedToken, DEFAULT); }
+    <TRIM : <START_TAG> "t" <CLOSE_TAG2>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
     |
-    <LTRIM : <START_TAG> "lt" <CLOSE_TAG2>> { strictSyntaxCheck(matchedToken, DEFAULT); }
+    <LTRIM : <START_TAG> "lt" <CLOSE_TAG2>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
     |
-    <RTRIM : <START_TAG> "rt" <CLOSE_TAG2>> { strictSyntaxCheck(matchedToken, DEFAULT); }
+    <RTRIM : <START_TAG> "rt" <CLOSE_TAG2>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
     |
-    <NOTRIM : <START_TAG> "nt" <CLOSE_TAG2>> { strictSyntaxCheck(matchedToken, DEFAULT); }
+    <NOTRIM : <START_TAG> "nt" <CLOSE_TAG2>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
     |
-    <DEFAUL : <START_TAG> "default" <CLOSE_TAG1>> { strictSyntaxCheck(matchedToken, DEFAULT); }
+    <DEFAUL : <START_TAG> "default" <CLOSE_TAG1>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
     |
-    <SIMPLE_NESTED : <START_TAG> "nested" <CLOSE_TAG2>> { strictSyntaxCheck(matchedToken, DEFAULT); }
+    <SIMPLE_NESTED : <START_TAG> "nested" <CLOSE_TAG2>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
     |
-    <NESTED : <START_TAG> "nested" <BLANK>> { strictSyntaxCheck(matchedToken, FM_EXPRESSION); }
+    <NESTED : <START_TAG> "nested" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
     |
-    <SIMPLE_RECURSE : <START_TAG> "recurse" <CLOSE_TAG2>> { strictSyntaxCheck(matchedToken, DEFAULT); }
+    <SIMPLE_RECURSE : <START_TAG> "recurse" <CLOSE_TAG2>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
     |
-    <RECURSE : <START_TAG> "recurse" <BLANK>> { strictSyntaxCheck(matchedToken, FM_EXPRESSION); }
+    <RECURSE : <START_TAG> "recurse" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
     |
-    <FALLBACK : <START_TAG> "fallback" <CLOSE_TAG2>> { strictSyntaxCheck(matchedToken, DEFAULT); }
+    <FALLBACK : <START_TAG> "fallback" <CLOSE_TAG2>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
     |
-    <ESCAPE : <START_TAG> "escape" <BLANK>> { strictSyntaxCheck(matchedToken, FM_EXPRESSION); }
+    <ESCAPE : <START_TAG> "escape" <BLANK>> { handleTagSyntaxAndSwitch(matchedToken, FM_EXPRESSION); }
     |
-    <END_ESCAPE : <END_TAG> "escape" <CLOSE_TAG1>> { strictSyntaxCheck(matchedToken, DEFAULT); }
+    <END_ESCAPE : <END_TAG> "escape" <CLOSE_TAG1>> { handleTagSyntaxAndSwitch(matchedToken, DEFAULT); }
     |
     <NOESCAPE : <START_TAG> "no" ("e" | "E") "scape" <CLOSE_TAG1>> {
-        strictSyntaxCheck(matchedToken, getTagNamingConvention(matchedToken, 2), DEFAULT);
+        handleTagSyntaxAndSwitch(matchedToken, getTagNamingConvention(matchedToken, 2), DEFAULT);
     }
     |
     <END_NOESCAPE : <END_TAG> "no" ("e" | "E") "scape" <CLOSE_TAG1>> {
-        strictSyntaxCheck(matchedToken, getTagNamingConvention(matchedToken, 2), DEFAULT);
+        handleTagSyntaxAndSwitch(matchedToken, getTagNamingConvention(matchedToken, 2), DEFAULT);
     }
     |
     <UNIFIED_CALL : "<@" | "[@" > { unifiedCall(matchedToken); }
@@ -1095,14 +1095,14 @@ TOKEN:
      */
     <UNKNOWN_DIRECTIVE : ("[#" | "[/#" | "<#" | "</#") (["a"-"z", "A"-"Z", "_"])+>
     {
-        if (!directiveSyntaxEstablished && incompatibleImprovements < _TemplateAPI.VERSION_INT_2_3_19) {
+        if (!tagSyntaxEstablished && incompatibleImprovements < _TemplateAPI.VERSION_INT_2_3_19) {
             matchedToken.kind = STATIC_TEXT_NON_WS;
         } else {
             char firstChar = matchedToken.image.charAt(0);
 
-            if (!directiveSyntaxEstablished && autodetectTagSyntax) {
+            if (!tagSyntaxEstablished && autodetectTagSyntax) {
                 squBracTagSyntax = (firstChar == '[');
-                directiveSyntaxEstablished = true;
+                tagSyntaxEstablished = true;
             }
 
             if (firstChar == '<' && squBracTagSyntax) {
@@ -1559,7 +1559,7 @@ TOKEN:
         if (squBracTagSyntax || postInterpolationLexState != -1 /* We are in an interpolation */) {
             matchedToken.kind = NATURAL_GT;
         } else {
-            if (directiveSyntaxEstablished && ( incompatibleImprovements >= _TemplateAPI.VERSION_INT_2_3_28
+            if (tagSyntaxEstablished && ( incompatibleImprovements >= _TemplateAPI.VERSION_INT_2_3_28
                     || interpolationSyntax == SQUARE_BRACKET_INTERPOLATION_SYNTAX)) {
                 if (squBracTagSyntax) {
                     throw new TokenMgrError(
@@ -1576,7 +1576,7 @@ TOKEN:
     |
     <EMPTY_DIRECTIVE_END : "/>" | "/]">
     {
-        if (directiveSyntaxEstablished && (incompatibleImprovements >= _TemplateAPI.VERSION_INT_2_3_28
+        if (tagSyntaxEstablished && (incompatibleImprovements >= _TemplateAPI.VERSION_INT_2_3_28
                 || interpolationSyntax == SQUARE_BRACKET_INTERPOLATION_SYNTAX)) {
             String image = matchedToken.image;
             char lastChar = image.charAt(image.length() - 1);


[7/7] incubator-freemarker git commit: Merge remote-tracking branch 'origin/2.3-gae' into 2.3

Posted by dd...@apache.org.
Merge remote-tracking branch 'origin/2.3-gae' into 2.3


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

Branch: refs/heads/2.3
Commit: 17480993a9cb625808478b2110b37deaf59865ed
Parents: edefaa2 67a2ebd
Author: ddekany <dd...@apache.org>
Authored: Tue Mar 20 22:48:11 2018 +0100
Committer: ddekany <dd...@apache.org>
Committed: Tue Mar 20 22:48:11 2018 +0100

----------------------------------------------------------------------
 src/main/java/freemarker/core/Assignment.java   |  13 +-
 .../core/BuiltInsForStringsBasic.java           |   2 +-
 .../core/InvalidReferenceException.java         |   6 +-
 .../java/freemarker/template/Configuration.java |  51 ++++--
 .../freemarker/template/utility/StringUtil.java |  55 ++++---
 src/main/javacc/FTL.jj                          | 164 +++++++++----------
 src/manual/en_US/book.xml                       |  63 ++++++-
 .../freemarker/core/MiscErrorMessagesTest.java  |   7 +
 .../freemarker/template/ConfigurationTest.java  |   5 +
 9 files changed, 234 insertions(+), 132 deletions(-)
----------------------------------------------------------------------



[6/7] incubator-freemarker git commit: Added a new Configuration.removeTemplateFromCache overload that has a Object customLookupCondition parameter. This is useful to manually evacuate a template from the cache that was get via a non-null custom lookup c

Posted by dd...@apache.org.
Added a new Configuration.removeTemplateFromCache overload that has a Object customLookupCondition parameter. This is useful to manually evacuate a template from the cache that was get via a non-null custom lookup condition.


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

Branch: refs/heads/2.3
Commit: 67a2ebd8a48a12185d15ba59bb2d5dd7bad73089
Parents: e3ed32a
Author: ddekany <dd...@apache.org>
Authored: Tue Mar 20 20:08:35 2018 +0100
Committer: ddekany <dd...@apache.org>
Committed: Tue Mar 20 20:08:35 2018 +0100

----------------------------------------------------------------------
 .../java/freemarker/template/Configuration.java | 44 ++++++++++++++------
 src/manual/en_US/book.xml                       |  9 ++++
 2 files changed, 41 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/67a2ebd8/src/main/java/freemarker/template/Configuration.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/template/Configuration.java b/src/main/java/freemarker/template/Configuration.java
index 8db9155..f0c6a0d 100644
--- a/src/main/java/freemarker/template/Configuration.java
+++ b/src/main/java/freemarker/template/Configuration.java
@@ -3056,55 +3056,75 @@ public class Configuration extends Configurable implements Cloneable, ParserConf
     }
     
     /**
-     * Equivalent to <tt>removeTemplateFromCache(name, thisCfg.getLocale(), thisCfg.getEncoding(thisCfg.getLocale()), true)</tt>.
+     * Equivalent to {@link
+     * #removeTemplateFromCache(String, Locale, Object, String, boolean)
+     * removeTemplateFromCache(name, thisCfg.getLocale(), null, thisCfg.getEncoding(thisCfg.getLocale()), true)}.
      * @since 2.3.19
      */
     public void removeTemplateFromCache(String name) throws IOException {
         Locale loc = getLocale();
-        removeTemplateFromCache(name, loc, getEncoding(loc), true);
+        removeTemplateFromCache(name, loc, null, getEncoding(loc), true);
     }
 
     /**
-     * Equivalent to <tt>removeTemplateFromCache(name, locale, thisCfg.getEncoding(locale), true)</tt>.
+     * Equivalent to {@link
+     * #removeTemplateFromCache(String, Locale, Object, String, boolean)
+     * removeTemplateFromCache(name, locale, null, thisCfg.getEncoding(locale), true)}.
      * @since 2.3.19
      */
     public void removeTemplateFromCache(String name, Locale locale) throws IOException {
-        removeTemplateFromCache(name, locale, getEncoding(locale), true);
+        removeTemplateFromCache(name, locale, null, getEncoding(locale), true);
     }
 
     /**
-     * Equivalent to <tt>removeTemplateFromCache(name, thisCfg.getLocale(), encoding, true)</tt>.
+     * Equivalent to {@link
+     * #removeTemplateFromCache(String, Locale, Object, String, boolean)
+     * removeTemplateFromCache(name, thisCfg.getLocale(), null, encoding, true)}.
      * @since 2.3.19
      */
     public void removeTemplateFromCache(String name, String encoding) throws IOException {
-        removeTemplateFromCache(name, getLocale(), encoding, true);
+        removeTemplateFromCache(name, getLocale(), null, encoding, true);
     }
 
     /**
-     * Equivalent to <tt>removeTemplateFromCache(name, locale, encoding, true)</tt>.
+     * Equivalent to {@link
+     * #removeTemplateFromCache(String, Locale, Object, String, boolean)
+     * removeTemplateFromCache(name, locale, null, encoding, true)}.
      * @since 2.3.19
      */
     public void removeTemplateFromCache(String name, Locale locale, String encoding) throws IOException {
-        removeTemplateFromCache(name, locale, encoding, true);
+        removeTemplateFromCache(name, locale, null, encoding, true);
     }
     
     /**
+     * Equivalent to {@link
+     * #removeTemplateFromCache(String, Locale, Object, String, boolean)
+     * removeTemplateFromCache(name, locale, null, encoding, parse)}.
+     * @since 2.3.19
+     */
+    public void removeTemplateFromCache(
+            String name, Locale locale, String encoding, boolean parse)
+    throws IOException {
+        removeTemplateFromCache(name, locale, null, encoding, parse);
+    }    
+
+    /**
      * Removes a template from the template cache, hence forcing the re-loading
      * of it when it's next time requested. This is to give the application
      * finer control over cache updating than {@link #setTemplateUpdateDelay(int)}
      * alone does.
      * 
      * <p>For the meaning of the parameters, see
-     * {@link #getTemplate(String, Locale, String, boolean)}.
+     * {@link #getTemplate(String, Locale, Object, String, boolean, boolean)}.
      * 
      * <p>This method is thread-safe and can be called while the engine processes templates.
      * 
-     * @since 2.3.19
+     * @since 2.3.28
      */
     public void removeTemplateFromCache(
-            String name, Locale locale, String encoding, boolean parse)
+            String name, Locale locale, Object customLookupCondition, String encoding, boolean parse)
     throws IOException {
-        cache.removeTemplate(name, locale, encoding, parse);
+        cache.removeTemplate(name, locale, customLookupCondition, encoding, parse);
     }    
     
     /**

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/67a2ebd8/src/manual/en_US/book.xml
----------------------------------------------------------------------
diff --git a/src/manual/en_US/book.xml b/src/manual/en_US/book.xml
index 0f49b3f..2a0ce2c 100644
--- a/src/manual/en_US/book.xml
+++ b/src/manual/en_US/book.xml
@@ -27710,6 +27710,15 @@ TemplateModel x = env.getVariable("x");  // get variable x</programlisting>
             </listitem>
 
             <listitem>
+              <para>Added a new
+              <literal>Configuration.removeTemplateFromCache</literal>
+              overload that has a <literal>Object
+              customLookupCondition</literal> parameter. This is useful to
+              manually evacuate a template from the cache that was get via a
+              non-<literal>null</literal> custom lookup condition.</para>
+            </listitem>
+
+            <listitem>
               <para>Added new property to
               <literal>BeansWrapper.MethodAppearanceDecision</literal>:
               <literal>replaceExistingProperty</literal>. This is useful when


[5/7] incubator-freemarker git commit: When specifying the output_format configuration settings with String-String key-value pairs (like with Configuration.setSetting(String, String) or in a .properties file), it's now possible to specify the standard ou

Posted by dd...@apache.org.
When specifying the output_format configuration settings with String-String key-value pairs (like with Configuration.setSetting(String, String) or in a .properties file), it's now possible to specify the standard output formats by name rather than by class name  (like output_format=HTML). (Custom formats still has to be referred by class name, as FreeMarker can't discover what their names are, since it's not aware of the custom classes.)


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

Branch: refs/heads/2.3
Commit: e3ed32a1f184bfb6f7f28a75e4f24a07a64cac21
Parents: cb5f327
Author: ddekany <dd...@apache.org>
Authored: Tue Mar 20 19:53:03 2018 +0100
Committer: ddekany <dd...@apache.org>
Committed: Tue Mar 20 19:53:03 2018 +0100

----------------------------------------------------------------------
 src/main/java/freemarker/template/Configuration.java  |  7 +++++--
 src/manual/en_US/book.xml                             | 14 ++++++++++++++
 .../java/freemarker/template/ConfigurationTest.java   |  5 +++++
 3 files changed, 24 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/e3ed32a1/src/main/java/freemarker/template/Configuration.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/template/Configuration.java b/src/main/java/freemarker/template/Configuration.java
index 5376dda..8db9155 100644
--- a/src/main/java/freemarker/template/Configuration.java
+++ b/src/main/java/freemarker/template/Configuration.java
@@ -3178,8 +3178,11 @@ public class Configuration extends Configurable implements Cloneable, ParserConf
                 if (value.equalsIgnoreCase(DEFAULT)) {
                     unsetOutputFormat();
                 } else {
-                    setOutputFormat((OutputFormat) _ObjectBuilderSettingEvaluator.eval(
-                            value, OutputFormat.class, true, _SettingEvaluationEnvironment.getCurrent()));
+                    OutputFormat stdOF = STANDARD_OUTPUT_FORMATS.get(value);
+                    setOutputFormat(
+                            stdOF != null ? stdOF
+                            : (OutputFormat) _ObjectBuilderSettingEvaluator.eval(
+                                    value, OutputFormat.class, true, _SettingEvaluationEnvironment.getCurrent()));
                 }
             } else if (REGISTERED_CUSTOM_OUTPUT_FORMATS_KEY_SNAKE_CASE.equals(name)
                     || REGISTERED_CUSTOM_OUTPUT_FORMATS_KEY_CAMEL_CASE.equals(name)) {

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/e3ed32a1/src/manual/en_US/book.xml
----------------------------------------------------------------------
diff --git a/src/manual/en_US/book.xml b/src/manual/en_US/book.xml
index eb4470f..0f49b3f 100644
--- a/src/manual/en_US/book.xml
+++ b/src/manual/en_US/book.xml
@@ -27696,6 +27696,20 @@ TemplateModel x = env.getVariable("x");  // get variable x</programlisting>
             </listitem>
 
             <listitem>
+              <para>When specifying the <literal>output_format</literal>
+              configuration settings with
+              <literal>String</literal>-<literal>String</literal> key-value
+              pairs (like with <literal>Configuration.setSetting(String,
+              String)</literal> or in a <literal>.properties</literal> file),
+              it's now possible to specify the standard output formats by name
+              rather than by class name (like
+              <literal>output_format=HTML</literal>). (Custom formats still
+              has to be referred by class name, as FreeMarker can't discover
+              what their names are, since it's not aware of the custom
+              classes.)</para>
+            </listitem>
+
+            <listitem>
               <para>Added new property to
               <literal>BeansWrapper.MethodAppearanceDecision</literal>:
               <literal>replaceExistingProperty</literal>. This is useful when

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/e3ed32a1/src/test/java/freemarker/template/ConfigurationTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/template/ConfigurationTest.java b/src/test/java/freemarker/template/ConfigurationTest.java
index 72c1291..f3e8be9 100644
--- a/src/test/java/freemarker/template/ConfigurationTest.java
+++ b/src/test/java/freemarker/template/ConfigurationTest.java
@@ -75,6 +75,7 @@ import freemarker.core.TemplateDateFormatFactory;
 import freemarker.core.TemplateNumberFormatFactory;
 import freemarker.core.UndefinedOutputFormat;
 import freemarker.core.UnregisteredOutputFormatException;
+import freemarker.core.XHTMLOutputFormat;
 import freemarker.core.XMLOutputFormat;
 import freemarker.core._CoreStringUtils;
 import freemarker.ext.beans.BeansWrapperBuilder;
@@ -942,6 +943,10 @@ public class ConfigurationTest extends TestCase {
        
        cfg.setSetting(Configuration.OUTPUT_FORMAT_KEY_SNAKE_CASE, HTMLOutputFormat.class.getSimpleName());
        assertEquals(HTMLOutputFormat.INSTANCE, cfg.getOutputFormat());
+
+       // Set standard format by name instead of class name:
+       cfg.setSetting(Configuration.OUTPUT_FORMAT_KEY_CAMEL_CASE, XHTMLOutputFormat.INSTANCE.getName());
+       assertEquals(XHTMLOutputFormat.INSTANCE, cfg.getOutputFormat());
        
        cfg.unsetOutputFormat();
        assertEquals(UndefinedOutputFormat.INSTANCE, cfg.getOutputFormat());


[2/7] incubator-freemarker git commit: Updated JSP-FreeMarker comparison in FAQ

Posted by dd...@apache.org.
Updated JSP-FreeMarker comparison in FAQ


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

Branch: refs/heads/2.3
Commit: afccb1040306ab7d8dd9d5355134ecd7f066c4eb
Parents: 355a09a
Author: ddekany <dd...@apache.org>
Authored: Tue Mar 20 08:11:58 2018 +0100
Committer: ddekany <dd...@apache.org>
Committed: Tue Mar 20 08:11:58 2018 +0100

----------------------------------------------------------------------
 src/manual/en_US/book.xml | 27 +++++++++++++++++++--------
 1 file changed, 19 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/afccb104/src/manual/en_US/book.xml
----------------------------------------------------------------------
diff --git a/src/manual/en_US/book.xml b/src/manual/en_US/book.xml
index f06b759..349319c 100644
--- a/src/manual/en_US/book.xml
+++ b/src/manual/en_US/book.xml
@@ -26165,6 +26165,25 @@ End book</programlisting>
               </listitem>
 
               <listitem>
+                <para><link linkend="dgui_misc_autoescaping">Auto-escaping
+                option</link> to escape HTML and XML special characters
+                printed with
+                <literal>${<replaceable>...</replaceable>}</literal>. So you
+                can just write <literal>${x}</literal> instead of
+                <literal>&lt;c:out value="${x}"/&gt;</literal>, and most
+                importantly, you can't accidentally forget to do
+                escaping.</para>
+              </listitem>
+
+              <listitem>
+                <para>Locale-sensitive number and date formatting by default.
+                When you output for a human audience, all you need to do is
+                just write <literal>${x}</literal> rather than
+                <literal>&lt;fmt:formatNumber value="${x}"
+                /&gt;</literal>.</para>
+              </listitem>
+
+              <listitem>
                 <para>No servlet specific scopes and other highly technical
                 things in templates (unless, of course, you expose them into
                 the data-model deliberately). It was made for MVC from the
@@ -26177,14 +26196,6 @@ End book</programlisting>
               </listitem>
 
               <listitem>
-                <para>Locale-sensitive number and date formatting by default.
-                When you output for a human audience, all you need to do is
-                just write <literal>${x}</literal> rather than
-                <literal>&lt;fmt:formatNumber value="${x}"
-                /&gt;</literal>.</para>
-              </listitem>
-
-              <listitem>
                 <para>Easier to define ad-hoc macros and functions.</para>
               </listitem>
 


[4/7] incubator-freemarker git commit: Bug fixed: When string?split(separator) is called with "" as the argument, the string will be split to characters now. Earlier it has thrown an IllegalArgumentException (unless the r flag was specified).

Posted by dd...@apache.org.
Bug fixed: When string?split(separator) is called with "" as the argument, the string will be split to characters now. Earlier it has thrown an IllegalArgumentException (unless the r flag was specified).


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

Branch: refs/heads/2.3
Commit: cb5f3276ca3a3c45cfd6938921297030a0aa4b5f
Parents: 470971a
Author: ddekany <dd...@apache.org>
Authored: Tue Mar 20 18:57:52 2018 +0100
Committer: ddekany <dd...@apache.org>
Committed: Tue Mar 20 18:57:52 2018 +0100

----------------------------------------------------------------------
 .../core/BuiltInsForStringsBasic.java           |  2 +-
 .../freemarker/template/utility/StringUtil.java | 55 ++++++++++++--------
 src/manual/en_US/book.xml                       | 13 +++++
 3 files changed, 47 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/cb5f3276/src/main/java/freemarker/core/BuiltInsForStringsBasic.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/BuiltInsForStringsBasic.java b/src/main/java/freemarker/core/BuiltInsForStringsBasic.java
index abb3530..27a6212 100644
--- a/src/main/java/freemarker/core/BuiltInsForStringsBasic.java
+++ b/src/main/java/freemarker/core/BuiltInsForStringsBasic.java
@@ -536,7 +536,7 @@ class BuiltInsForStringsBasic {
                 long flags = argCnt > 1 ? RegexpHelper.parseFlagString((String) args.get(1)) : 0;
                 String[] result = null;
                 if ((flags & RegexpHelper.RE_FLAG_REGEXP) == 0) {
-                    RegexpHelper.checkNonRegexpFlags("split", flags);
+                    RegexpHelper.checkNonRegexpFlags(key, flags);
                     result = StringUtil.split(s, splitString,
                             (flags & RegexpHelper.RE_FLAG_CASE_INSENSITIVE) != 0);
                 } else {

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/cb5f3276/src/main/java/freemarker/template/utility/StringUtil.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/template/utility/StringUtil.java b/src/main/java/freemarker/template/utility/StringUtil.java
index a5156aa..1238dd9 100644
--- a/src/main/java/freemarker/template/utility/StringUtil.java
+++ b/src/main/java/freemarker/template/utility/StringUtil.java
@@ -739,34 +739,45 @@ public class StringUtil {
 
     /**
      * Splits a string at the specified string.
+     * 
+     * @param sep
+     *            The string that separates the items of the resulting array. Since 2.3.28, if this is 0 length, then
+     *            each character will be a separate item in the array.
      */
     public static String[] split(String s, String sep, boolean caseInsensitive) {
-        String splitString = caseInsensitive ? sep.toLowerCase() : sep;
-        String input = caseInsensitive ? s.toLowerCase() : s;
-        int i, b, e;
-        int cnt;
-        String res[];
-        int ln = s.length();
-        int sln = sep.length();
+        int sepLn = sep.length();
 
-        if (sln == 0) throw new IllegalArgumentException(
-                "The separator string has 0 length");
+        String convertedS = caseInsensitive ? s.toLowerCase() : s;
+        int sLn = s.length();
+        
+        if (sepLn == 0) {
+            String[] res = new String[sLn];
+            for (int i = 0; i < sLn; i++) {
+                res[i] = String.valueOf(s.charAt(i));
+            }
+            return res;
+        }
 
-        i = 0;
-        cnt = 1;
-        while ((i = input.indexOf(splitString, i)) != -1) {
-            cnt++;
-            i += sln;
+        String splitString = caseInsensitive ? sep.toLowerCase() : sep;
+        String res[];
+        
+        {
+            int next = 0;
+            int count = 1;
+            while ((next = convertedS.indexOf(splitString, next)) != -1) {
+                count++;
+                next += sepLn;
+            }
+            res = new String[count];
         }
-        res = new String[cnt];
 
-        i = 0;
-        b = 0;
-        while (b <= ln) {
-            e = input.indexOf(splitString, b);
-            if (e == -1) e = ln;
-            res[i++] = s.substring(b, e);
-            b = e + sln;
+        int dst = 0;
+        int next = 0;
+        while (next <= sLn) {
+            int end = convertedS.indexOf(splitString, next);
+            if (end == -1) end = sLn;
+            res[dst++] = s.substring(next, end);
+            next = end + sepLn;
         }
         return res;
     }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/cb5f3276/src/manual/en_US/book.xml
----------------------------------------------------------------------
diff --git a/src/manual/en_US/book.xml b/src/manual/en_US/book.xml
index 349319c..eb4470f 100644
--- a/src/manual/en_US/book.xml
+++ b/src/manual/en_US/book.xml
@@ -14441,6 +14441,10 @@ foobar</programlisting>
           <literal>?split(",", "r")</literal> in the last example the last
           <literal>""</literal> would be missing from the output.</para>
 
+          <para>If the 1st parameter is an empty string, the string will be
+          split to characters (since FreeMarker 2.3.28 - earlier this has only
+          worked with the <literal>r</literal> flag).</para>
+
           <note>
             <para>To check if a strings ends with something and append it
             otherwise, use <link linkend="ref_builtin_ensure_ends_with">the
@@ -27635,6 +27639,15 @@ TemplateModel x = env.getVariable("x");  // get variable x</programlisting>
               evaluated in the context of the called macro or
               function.)</para>
             </listitem>
+
+            <listitem>
+              <para>Bug fixed: When
+              <literal><replaceable>string</replaceable>?split(<replaceable>separator</replaceable>)</literal>
+              is called with <literal>""</literal> as the argument, the string
+              will be split to characters now. Earlier it has thrown an
+              <literal>IllegalArgumentException</literal> (unless the
+              <literal>r</literal> flag was specified).</para>
+            </listitem>
           </itemizedlist>
         </section>
 


[3/7] incubator-freemarker git commit: Better error message when <#assign x++> and such fails because x doesn't exist in the same scope as the target scope.

Posted by dd...@apache.org.
Better error message when <#assign x++> and such fails because x doesn't exist in the same scope as the target scope.


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

Branch: refs/heads/2.3
Commit: 470971a2381fceee421337a7a5070d500c2b0d4a
Parents: afccb10
Author: ddekany <dd...@apache.org>
Authored: Tue Mar 20 18:55:31 2018 +0100
Committer: ddekany <dd...@apache.org>
Committed: Tue Mar 20 18:55:31 2018 +0100

----------------------------------------------------------------------
 src/main/java/freemarker/core/Assignment.java          | 13 +++++++++++--
 .../freemarker/core/InvalidReferenceException.java     |  6 +++---
 .../java/freemarker/core/MiscErrorMessagesTest.java    |  7 +++++++
 3 files changed, 21 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/470971a2/src/main/java/freemarker/core/Assignment.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/Assignment.java b/src/main/java/freemarker/core/Assignment.java
index 0f15112..0495f14 100644
--- a/src/main/java/freemarker/core/Assignment.java
+++ b/src/main/java/freemarker/core/Assignment.java
@@ -152,7 +152,7 @@ final class Assignment extends TemplateElement {
                     if (env.isClassicCompatible()) {
                         lhoValue = TemplateScalarModel.EMPTY_STRING;
                     } else {
-                        throw InvalidReferenceException.getInstance(
+                        throw InvalidReferenceException.getInstance(scope,
                                 variableName, getOperatorTypeAsString(), env);
                     }
                 }
@@ -171,7 +171,7 @@ final class Assignment extends TemplateElement {
                 if (lhoValue instanceof TemplateNumberModel) {
                     lhoNumber = EvalUtil.modelToNumber((TemplateNumberModel) lhoValue, null);
                 } else if (lhoValue == null) {
-                    throw InvalidReferenceException.getInstance(variableName, getOperatorTypeAsString(), env);
+                    throw InvalidReferenceException.getInstance(scope, variableName, getOperatorTypeAsString(), env);
                 } else {
                     throw new NonNumericalException(variableName, lhoValue, null, env);
                 }
@@ -292,4 +292,13 @@ final class Assignment extends TemplateElement {
         }
     }
     
+    static String scopeAsString(int scope) {
+        switch (scope) {
+        case NAMESPACE: return "template namespace";
+        case LOCAL: return "local scope";
+        case GLOBAL: return "global scope";
+        default: throw new AssertionError("Unsupported scope: " + scope);
+        }
+    }
+    
 }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/470971a2/src/main/java/freemarker/core/InvalidReferenceException.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/InvalidReferenceException.java b/src/main/java/freemarker/core/InvalidReferenceException.java
index 791263b..d6a75bf 100644
--- a/src/main/java/freemarker/core/InvalidReferenceException.java
+++ b/src/main/java/freemarker/core/InvalidReferenceException.java
@@ -141,7 +141,7 @@ public class InvalidReferenceException extends TemplateException {
     /**
      * Used for assignments that use operators like {@code +=}, when the target variable was null/missing. 
      */
-    static InvalidReferenceException getInstance(String missingAssignedVarName, String assignmentOperator,
+    static InvalidReferenceException getInstance(int scope, String missingAssignedVarName, String assignmentOperator,
             Environment env) {
         if (env != null && env.getFastInvalidReferenceExceptions()) {
             return FAST_INSTANCE;
@@ -149,8 +149,8 @@ public class InvalidReferenceException extends TemplateException {
             final _ErrorDescriptionBuilder errDescBuilder = new _ErrorDescriptionBuilder(
                             "The target variable of the assignment, ",
                             new _DelayedJQuote(missingAssignedVarName),
-                            ", was null or missing, but the \"",
-                            assignmentOperator, "\" operator needs to get its value before assigning to it."
+                            ", was null or missing in the " + Assignment.scopeAsString(scope) + ", and the \"",
+                            assignmentOperator, "\" operator must get its value from there before assigning to it."
                     );
             if (missingAssignedVarName.startsWith("$")) {
                 errDescBuilder.tips(TIP_NO_DOLLAR, TIP_MISSING_ASSIGNMENT_TARGET);

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/470971a2/src/test/java/freemarker/core/MiscErrorMessagesTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/core/MiscErrorMessagesTest.java b/src/test/java/freemarker/core/MiscErrorMessagesTest.java
index 5799c12..df10fde 100644
--- a/src/test/java/freemarker/core/MiscErrorMessagesTest.java
+++ b/src/test/java/freemarker/core/MiscErrorMessagesTest.java
@@ -56,4 +56,11 @@ public class MiscErrorMessagesTest extends TemplateTest {
         assertEquals((Integer) 2, ((TemplateException) e).getLineNumber());
     }
     
+    @Test
+    public void incrementalAssignmentsTest() throws Exception {
+        assertErrorContains("<#assign x++>", "\"x\"", "++", "template namespace");
+        assertErrorContains("<#global x += 2>", "\"x\"", "+=", "global scope");
+        assertErrorContains("<#macro m><#local x--></#macro><@m/>", "\"x\"", "--", "local scope");
+    }
+    
 }