freemarker-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ddek...@apache.org
Subject [freemarker] branch 2.3-gae updated: When a macro uses .args, and has catch-all parameter, allow positional macro arguments when the actual catch-all length is 0. Also, added some tests for 0 argument calls.
Date Fri, 25 Oct 2019 22:07:05 GMT
This is an automated email from the ASF dual-hosted git repository.

ddekany pushed a commit to branch 2.3-gae
in repository https://gitbox.apache.org/repos/asf/freemarker.git


The following commit(s) were added to refs/heads/2.3-gae by this push:
     new 22f0e13  When a macro uses .args, and has catch-all parameter, allow positional macro
arguments when the actual catch-all length is 0. Also, added some tests for 0 argument calls.
22f0e13 is described below

commit 22f0e13d1ac79cfc5406a626dc7db6de8acea502
Author: ddekany <ddekany@apache.org>
AuthorDate: Sat Oct 26 00:05:54 2019 +0200

    When a macro uses .args, and has catch-all parameter, allow positional macro arguments
when the actual catch-all length is 0. Also, added some tests for 0 argument calls.
---
 src/main/java/freemarker/core/Macro.java           | 15 +++++++++----
 .../freemarker/template/utility/Constants.java     | 11 +++++++---
 src/manual/en_US/book.xml                          |  3 ++-
 .../freemarker/core/ArgsSpecialVariableTest.java   | 25 ++++++++++++++++------
 4 files changed, 40 insertions(+), 14 deletions(-)

diff --git a/src/main/java/freemarker/core/Macro.java b/src/main/java/freemarker/core/Macro.java
index b64e9e4..17c63f6 100644
--- a/src/main/java/freemarker/core/Macro.java
+++ b/src/main/java/freemarker/core/Macro.java
@@ -37,6 +37,7 @@ import freemarker.template.TemplateModelException;
 import freemarker.template.TemplateModelIterator;
 import freemarker.template.TemplateScalarModel;
 import freemarker.template.TemplateSequenceModel;
+import freemarker.template.utility.Constants;
 
 /**
  * An element representing a macro or function declaration.
@@ -323,7 +324,8 @@ public final class Macro extends TemplateElement implements TemplateModel
{
             
             if (argsSpecVarDraft != null) {
                 final String catchAllParamName = getMacro().catchAllParamName;
-                final TemplateModel catchAllArgValue = catchAllParamName != null ? localVars.get(catchAllParamName)
: null;
+                final TemplateModel catchAllArgValue = catchAllParamName != null
+                        ? localVars.get(catchAllParamName) : null;
 
                 if (getMacro().isFunction()) {
                     int lengthWithCatchAlls = argsSpecVarDraft.length;
@@ -350,10 +352,15 @@ public final class Macro extends TemplateElement implements TemplateModel
{
                     TemplateHashModelEx2 catchAllHash;
                     if (catchAllParamName != null) {
                         if (catchAllArgValue instanceof TemplateSequenceModel) {
-                            throw new _MiscTemplateException("The macro can only by called
with named arguments, " +
-                                    "because it uses both .", BuiltinVariable.ARGS, " and
catch-all parameter.");
+                            if (((TemplateSequenceModel) catchAllArgValue).size() != 0) {
+                                throw new _MiscTemplateException("The macro can only by called
with named arguments, " +
+                                        "because it uses both .", BuiltinVariable.ARGS, "
and a non-empty catch-all " +
+                                        "parameter.");
+                            }
+                            catchAllHash = Constants.EMPTY_HASH_EX2;
+                        } else {
+                            catchAllHash = (TemplateHashModelEx2) catchAllArgValue;
                         }
-                        catchAllHash = (TemplateHashModelEx2) catchAllArgValue;
                         lengthWithCatchAlls += catchAllHash.size();
                     } else {
                         catchAllHash = null;
diff --git a/src/main/java/freemarker/template/utility/Constants.java b/src/main/java/freemarker/template/utility/Constants.java
index 2162ef6..8392c01 100644
--- a/src/main/java/freemarker/template/utility/Constants.java
+++ b/src/main/java/freemarker/template/utility/Constants.java
@@ -95,9 +95,14 @@ public class Constants {
         }
         
     }
-    
-    public static final TemplateHashModelEx EMPTY_HASH = new EmptyHashModel();
-    
+
+    /**
+     * @since 2.3.30
+     */
+    public static final TemplateHashModelEx2 EMPTY_HASH_EX2 = new EmptyHashModel();
+
+    public static final TemplateHashModelEx EMPTY_HASH = EMPTY_HASH_EX2;
+
     /**
      * An empty hash. Since 2.3.27, it implements {@link TemplateHashModelEx2}, before that
it was only
      * {@link TemplateHashModelEx}.
diff --git a/src/manual/en_US/book.xml b/src/manual/en_US/book.xml
index 3b1432c..6c03186 100644
--- a/src/manual/en_US/book.xml
+++ b/src/manual/en_US/book.xml
@@ -24617,7 +24617,8 @@ There was no specific handler for node y
             </listitem>
 
             <listitem>
-              <para>If a macro has a catch-all argument, and the macro uses
+              <para>If a macro has a catch-all parameter, and the actual
+              catch-all argument is not empty, and the macro uses
               <literal>.args</literal> somewhere, it can only be called with
               named arguments (like <literal>&lt;@m a=1 b=2 /&gt;</literal>),
               and not with positional arguments (like <literal>&lt;@m 1 2
diff --git a/src/test/java/freemarker/core/ArgsSpecialVariableTest.java b/src/test/java/freemarker/core/ArgsSpecialVariableTest.java
index 1064744..bc94cef 100644
--- a/src/test/java/freemarker/core/ArgsSpecialVariableTest.java
+++ b/src/test/java/freemarker/core/ArgsSpecialVariableTest.java
@@ -41,6 +41,12 @@ public class ArgsSpecialVariableTest extends TemplateTest {
     }
 
     @Test
+    public void macroZeroArgsTest() throws IOException, TemplateException {
+        assertOutput("<#macro m>${.args?size}</#macro><@m />", "0");
+        assertOutput("<#macro m others...>${.args?size}</#macro><@m />",
"0");
+    }
+
+    @Test
     public void macroWithDefaultsTest() throws IOException, TemplateException {
         String macroDef = "<#macro m a b c=3><#list .args as k, v>${k}=${v}<#sep>,
</#list></#macro>";
         String expectedOutput = "" +
@@ -80,8 +86,8 @@ public class ArgsSpecialVariableTest extends TemplateTest {
 
     @Test
     public void macroWithCatchAllTest() throws IOException, TemplateException {
-        assertOutput("" +
-                        "<#macro m a b=2 others...><#list .args as k, v>${k}=${v}<#sep>,
</#list></#macro>" +
+        String macroDef = "<#macro m a b=2 others...><#list .args as k, v>${k}=${v}<#sep>,
</#list></#macro>";
+        assertOutput(macroDef +
                         "<@m a=11 b=22 c=33 d=44 />; " +
                         "<@m a=11 b=22 />; " +
                         "<@m a=11 />; " +
@@ -91,9 +97,9 @@ public class ArgsSpecialVariableTest extends TemplateTest {
                         "a=11, b=2; " +
                         "a=11, b=2, c=33");
 
-        assertErrorContains("" +
-                "<#macro m a b=2 others...><#list .args as k, v>${k}=${v}<#sep>,
</#list></#macro>" +
-                "<@m 1, 2 />",
+        assertOutput(macroDef + "<@m 1, 2 />",
+                "a=1, b=2");
+        assertErrorContains(macroDef + "<@m 1, 2, 3 />",
                 ".args", "catch-all");
     }
 
@@ -106,6 +112,13 @@ public class ArgsSpecialVariableTest extends TemplateTest {
                 expectedOutput);
     }
 
+
+    @Test
+    public void functionZeroArgsTest() throws IOException, TemplateException {
+        assertOutput("<#function f><#return .args?size></#function>${f()}",
"0");
+        assertOutput("<#function f others...><#return .args?size></#function>${f()}",
"0");
+    }
+    
     @Test
     public void functionWithDefaultsTest() throws IOException, TemplateException {
         String functionDef = "<#function f a b c=3><#return .args?join(', ')></#function>";
@@ -150,7 +163,7 @@ public class ArgsSpecialVariableTest extends TemplateTest {
                         "11, 2; " +
                         "11, 2, 33");
     }
-
+    
     @Test
     public void usedInWrongContextTest() throws IOException, TemplateException {
         assertErrorContains("${.args}", "args", "macro", "function");


Mime
View raw message