Repository: incubator-freemarker
Updated Branches:
  refs/heads/3 d0a9c2bb5 -> 557ee7c8c


Forward ported from 2.3-gae: Bug fixed: Comments were not allowed by the parser 
between the switch tag and the first case tag.

See: 1dba510cc690898523e138385dd8eb4111b32453, 
c3672d96544e1cb96454410cd76a737ec4cf80e5


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

Branch: refs/heads/3
Commit: ab5c1d883150d37ff45c977dc65fa00ee31b8824
Parents: d0a9c2b
Author: ddekany <ddek...@apache.org>
Authored: Sun Jul 9 17:18:49 2017 +0200
Committer: ddekany <ddek...@apache.org>
Committed: Sun Jul 9 17:18:49 2017 +0200

----------------------------------------------------------------------
 .../core/templatesuite/expected/switch.txt      |  2 +
 .../core/templatesuite/templates/switch.ftl     |  3 +
 .../apache/freemarker/core/ASTDirSwitch.java    | 33 ++++++++--
 freemarker-core/src/main/javacc/FTL.jj          | 66 ++++++++++++++++++--
 4 files changed, 93 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ab5c1d88/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/switch.txt
----------------------------------------------------------------------
diff --git 
a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/switch.txt
 
b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/switch.txt
index 5d42785..d0dbd27 100644
--- 
a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/switch.txt
+++ 
b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/switch.txt
@@ -63,6 +63,8 @@
 
 []
 
+[]
+
   ""
   "1234"
   "234"

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ab5c1d88/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/switch.ftl
----------------------------------------------------------------------
diff --git 
a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/switch.ftl
 
b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/switch.ftl
index 6bbab3c..c1b4cb7 100644
--- 
a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/switch.ftl
+++ 
b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/switch.ftl
@@ -97,6 +97,7 @@
     <#case 3>
       3
       <#switch x*2>
+        <#--  Comment is allowed here -->
         <#case 1>
           i1
           <#break>
@@ -122,6 +123,8 @@
   <#case 1>sadas
 </#switch>]
 
+[<#switch 213></#switch>]
+
 <#-- Fall-through -->
 <#list [ 0, 1, 2, 3, 4 ] as x>
   "<#switch x><#case 1>1<#case 2>2<#case 3>3<#case 4>4</#switch>"

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ab5c1d88/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirSwitch.java
----------------------------------------------------------------------
diff --git 
a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirSwitch.java 
b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirSwitch.java
index 069d70e..97d58c3 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirSwitch.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirSwitch.java
@@ -28,13 +28,20 @@ final class ASTDirSwitch extends ASTDirective {
 
     private ASTDirCase defaultCase;
     private final ASTExpression searched;
+    private int firstCaseIndex;
 
     /**
      * @param searched the expression to be tested.
      */
-    ASTDirSwitch(ASTExpression searched) {
+    ASTDirSwitch(ASTExpression searched, ASTImplicitParent 
ignoredSectionBeforeFirstCase) {
         this.searched = searched;
-        setChildBufferCapacity(4);
+
+        int ignoredCnt = ignoredSectionBeforeFirstCase != null ? 
ignoredSectionBeforeFirstCase.getChildCount() : 0;
+        setChildBufferCapacity(ignoredCnt + 4);
+        for (int i = 0; i < ignoredCnt; i++) {
+            addChild(ignoredSectionBeforeFirstCase.getChild(i));
+        }
+        firstCaseIndex = ignoredCnt; // Note that normally postParseCleanup 
will overwrite this
     }
 
     void addCase(ASTDirCase cas) {
@@ -50,7 +57,7 @@ final class ASTDirSwitch extends ASTDirective {
         boolean processedCase = false;
         int ln = getChildCount();
         try {
-            for (int i = 0; i < ln; i++) {
+            for (int i = firstCaseIndex; i < ln; i++) {
                 ASTDirCase cas = (ASTDirCase) getChild(i);
                 boolean processCase = false;
 
@@ -91,8 +98,7 @@ final class ASTDirSwitch extends ASTDirective {
             buf.append('>');
             int ln = getChildCount();
             for (int i = 0; i < ln; i++) {
-                ASTDirCase cas = (ASTDirCase) getChild(i);
-                buf.append(cas.getCanonicalForm());
+                buf.append(getChild(i).getCanonicalForm());
             }
             buf.append("</").append(getASTNodeDescriptor()).append('>');
         }
@@ -125,5 +131,20 @@ final class ASTDirSwitch extends ASTDirective {
     boolean isNestedBlockRepeater() {
         return false;
     }
-    
+
+    @Override
+    ASTElement postParseCleanup(boolean stripWhitespace) throws ParseException 
{
+        ASTElement result = super.postParseCleanup(stripWhitespace);
+
+        // The first #case might have shifted in the child array, so we have 
to find it again:
+        int ln = getChildCount();
+        int i = 0;
+        while (i < ln && !(getChild(i) instanceof ASTDirCase)) {
+            i++;
+        }
+        firstCaseIndex = i;
+
+        return result;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ab5c1d88/freemarker-core/src/main/javacc/FTL.jj
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/javacc/FTL.jj 
b/freemarker-core/src/main/javacc/FTL.jj
index 84608ea..7968e1e 100644
--- a/freemarker-core/src/main/javacc/FTL.jj
+++ b/freemarker-core/src/main/javacc/FTL.jj
@@ -3198,18 +3198,22 @@ ASTStaticText NoParse() :
 ASTDirSwitch Switch() :
 {
     ASTDirSwitch switchBlock;
+    ASTImplicitParent ignoredSectionBeforeFirstCase = null;
     ASTDirCase caseIns;
     ASTExpression switchExp;
     Token start, end;
     boolean defaultFound = false;
 }
 {
-    start = <SWITCH>
-    switchExp = ASTExpression()
-    <DIRECTIVE_END>
+    (
+           start = <SWITCH>
+           switchExp = ASTExpression()
+           <DIRECTIVE_END>
+        [ ignoredSectionBeforeFirstCase = WhitespaceAndComments() ]
+    )
     {
         breakableDirectiveNesting++;
-        switchBlock = new ASTDirSwitch(switchExp);
+        switchBlock = new ASTDirSwitch(switchExp, 
ignoredSectionBeforeFirstCase);
     }
     (
         LOOKAHEAD(2)
@@ -3241,7 +3245,6 @@ ASTDirCase ASTDirCase() :
     Token start;
 }
 {
-    [<STATIC_TEXT_WS>]
     (
         start = <CASE> exp = ASTExpression() <DIRECTIVE_END>
         |
@@ -3601,6 +3604,21 @@ ASTStaticText PCData() :
     }
 }
 
+ASTStaticText WhitespaceText() :
+{
+    Token t = null, start = null;
+}
+{
+    t = <STATIC_TEXT_WS>
+    {
+        if (stripText && mixedContentNesting == 1) return null;
+
+        ASTStaticText result = new ASTStaticText(t.image, false);
+        result.setLocation(template, t, t);
+        return result;
+    }
+}
+
 /**
  * Production for dealing with unparsed content,
  * i.e. what is inside a comment or noparse tag.
@@ -3753,6 +3771,44 @@ ASTElement FreeMarkerText() :
     }
 }
 
+/**
+ * To be used between tags that in theory has nothing between, such between 
#switch and the first #case.
+ */
+ASTImplicitParent WhitespaceAndComments() :
+{
+    ASTImplicitParent nodes = new ASTImplicitParent();
+    ASTElement elem, begin = null;
+}
+{
+    (
+        (
+            elem = WhitespaceText()
+            |
+            elem = Comment()
+        )
+        {
+            if (elem != null) { // not removed by stripText
+                   if (begin == null) {
+                       begin = elem;
+                   }
+                   nodes.addChild(elem);
+            }
+        }
+    )+
+    {
+        if (begin == null // Was is removed by stripText?
+                // Nodes here won't be ever executed anyway, but whitespace 
stripping should still remove the
+                // lonely ASTStaticText from the AST, as that's purely source 
code formatting. If it's not lonely, then
+                // there must be a comment, in which case the generic 
whitespace stripping algorithm will kick in.
+                || stripWhitespace
+                        && nodes.getChildCount() == 1 && nodes.getChild(0) 
instanceof ASTStaticText) {
+            return null;
+        }
+        nodes.setLocation(template, begin, elem);
+        return nodes;
+    }
+}
+
 void HeaderElement() :
 {
     Token key;

Reply via email to