Bug fixed: Comments were not allowed by the parser between the switch tag and 
the first case tag.


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

Branch: refs/heads/2.3
Commit: 1dba510cc690898523e138385dd8eb4111b32453
Parents: 9b87988
Author: ddekany <ddek...@apache.org>
Authored: Sat Jul 8 19:33:39 2017 +0200
Committer: ddekany <ddek...@apache.org>
Committed: Sat Jul 8 19:33:39 2017 +0200

----------------------------------------------------------------------
 src/main/java/freemarker/core/Case.java        |  4 +-
 src/main/java/freemarker/core/SwitchBlock.java | 31 ++++++++--
 src/main/javacc/FTL.jj                         | 66 +++++++++++++++++++--
 src/manual/en_US/book.xml                      |  6 ++
 4 files changed, 95 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1dba510c/src/main/java/freemarker/core/Case.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/Case.java 
b/src/main/java/freemarker/core/Case.java
index c580c4d..6d23716 100644
--- a/src/main/java/freemarker/core/Case.java
+++ b/src/main/java/freemarker/core/Case.java
@@ -24,8 +24,8 @@ package freemarker.core;
  */
 final class Case extends TemplateElement {
 
-    final int TYPE_CASE = 0;
-    final int TYPE_DEFAULT = 1;
+    static final int TYPE_CASE = 0;
+    static final int TYPE_DEFAULT = 1;
     
     Expression condition;
 

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1dba510c/src/main/java/freemarker/core/SwitchBlock.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/SwitchBlock.java 
b/src/main/java/freemarker/core/SwitchBlock.java
index cfa354c..15a5eea 100644
--- a/src/main/java/freemarker/core/SwitchBlock.java
+++ b/src/main/java/freemarker/core/SwitchBlock.java
@@ -30,13 +30,20 @@ final class SwitchBlock extends TemplateElement {
 
     private Case defaultCase;
     private final Expression searched;
+    private int firstCaseIndex;
 
     /**
      * @param searched the expression to be tested.
      */
-    SwitchBlock(Expression searched) {
+    SwitchBlock(Expression searched, MixedContent 
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 
     }
 
     /**
@@ -55,7 +62,7 @@ final class SwitchBlock extends TemplateElement {
         boolean processedCase = false;
         int ln = getChildCount();
         try {
-            for (int i = 0; i < ln; i++) {
+            for (int i = firstCaseIndex; i < ln; i++) {
                 Case cas = (Case) getChild(i);
                 boolean processCase = false;
 
@@ -94,8 +101,7 @@ final class SwitchBlock extends TemplateElement {
             buf.append('>');
             int ln = getChildCount();
             for (int i = 0; i < ln; i++) {
-                Case cas = (Case) getChild(i);
-                buf.append(cas.getCanonicalForm());
+                buf.append(getChild(i).getCanonicalForm());
             }
             buf.append("</").append(getNodeTypeSymbol()).append('>');
         }
@@ -128,5 +134,20 @@ final class SwitchBlock extends TemplateElement {
     boolean isNestedBlockRepeater() {
         return false;
     }
+
+    @Override
+    TemplateElement postParseCleanup(boolean stripWhitespace) throws 
ParseException {
+        TemplateElement 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 && !(getChildAt(i) instanceof Case)) {
+            i++;
+        }
+        firstCaseIndex = i;
+        
+        return result;
+    }
     
 }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1dba510c/src/main/javacc/FTL.jj
----------------------------------------------------------------------
diff --git a/src/main/javacc/FTL.jj b/src/main/javacc/FTL.jj
index 94338af..fb6106d 100644
--- a/src/main/javacc/FTL.jj
+++ b/src/main/javacc/FTL.jj
@@ -3581,18 +3581,22 @@ TransformBlock Transform() :
 SwitchBlock Switch() :
 {
     SwitchBlock switchBlock;
+    MixedContent ignoredSectionBeforeFirstCase = null;
     Case caseIns;
     Expression switchExp;
     Token start, end;
     boolean defaultFound = false;
 }
 {
-    start = <SWITCH>
-    switchExp = Expression()
-    <DIRECTIVE_END>
+    (
+           start = <SWITCH>
+           switchExp = Expression()
+           <DIRECTIVE_END>
+        [ ignoredSectionBeforeFirstCase = WhitespaceAndComments() ]
+    )
     {
         breakableDirectiveNesting++;
-        switchBlock = new SwitchBlock(switchExp);
+        switchBlock = new SwitchBlock(switchExp, 
ignoredSectionBeforeFirstCase);
     }
     (
         LOOKAHEAD(2)
@@ -3624,7 +3628,6 @@ Case Case() :
     Token start;
 }
 {
-    [<STATIC_TEXT_WS>]
     (
         start = <CASE> exp = Expression() <DIRECTIVE_END>
         |
@@ -3990,6 +3993,21 @@ TextBlock PCData() :
     }
 }
 
+TextBlock WhitespaceText() :
+{
+    Token t = null, start = null;
+}
+{
+    t = <STATIC_TEXT_WS>
+    {
+        if (stripText && mixedContentNesting == 1 && !preventStrippings) 
return null;
+
+        TextBlock result = new TextBlock(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.
@@ -4150,6 +4168,44 @@ TemplateElement FreeMarkerText() :
     }
 }
 
+/**
+ * To be used between tags that in theory has nothing between, such between 
#switch and the first #case.
+ */
+MixedContent WhitespaceAndComments() :
+{
+    MixedContent nodes = new MixedContent();
+    TemplateElement 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 TextBlock 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 && !preventStrippings
+                        && nodes.getChildCount() == 1 && nodes.getChild(0) 
instanceof TextBlock) {
+            return null;
+        }
+        nodes.setLocation(template, begin, elem);
+        return nodes;
+    }
+}
+
 void HeaderElement() :
 {
     Token key;

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1dba510c/src/manual/en_US/book.xml
----------------------------------------------------------------------
diff --git a/src/manual/en_US/book.xml b/src/manual/en_US/book.xml
index fbbee7e..3897385 100644
--- a/src/manual/en_US/book.xml
+++ b/src/manual/en_US/book.xml
@@ -26910,6 +26910,12 @@ TemplateModel x = env.getVariable("x");  // get 
variable x</programlisting>
               and <literal>and</literal> without <literal>\</literal> is not
               recognized for backward compatibility.</para>
             </listitem>
+
+            <listitem>
+              <para>Bug fixed: Comments were not allowed by the parser between
+              the <literal>switch</literal> tag and the first
+              <literal>case</literal> tag.</para>
+            </listitem>
           </itemizedlist>
         </section>
 

Reply via email to