From notifications-return-6158-archive-asf-public=cust-asf.ponee.io@freemarker.apache.org Fri Nov 1 18:40:57 2019 Return-Path: X-Original-To: archive-asf-public@cust-asf.ponee.io Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [207.244.88.153]) by mx-eu-01.ponee.io (Postfix) with SMTP id AAA86180626 for ; Fri, 1 Nov 2019 19:40:56 +0100 (CET) Received: (qmail 48396 invoked by uid 500); 1 Nov 2019 18:40:56 -0000 Mailing-List: contact notifications-help@freemarker.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@freemarker.apache.org Delivered-To: mailing list notifications@freemarker.apache.org Received: (qmail 48386 invoked by uid 99); 1 Nov 2019 18:40:56 -0000 Received: from ec2-52-202-80-70.compute-1.amazonaws.com (HELO gitbox.apache.org) (52.202.80.70) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 01 Nov 2019 18:40:56 +0000 Received: by gitbox.apache.org (ASF Mail Server at gitbox.apache.org, from userid 33) id EA191805E6; Fri, 1 Nov 2019 18:40:55 +0000 (UTC) Date: Fri, 01 Nov 2019 18:40:55 +0000 To: "notifications@freemarker.apache.org" Subject: [freemarker] branch 2.3-gae updated: Added special rule to allow using the directive name in the end-tag when ?with_args(...) was used in the start-tag, like <@myMacro?with_args(args)>.... MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Message-ID: <157263365585.4942.4429288968675588160@gitbox.apache.org> From: ddekany@apache.org X-Git-Host: gitbox.apache.org X-Git-Repo: freemarker X-Git-Refname: refs/heads/2.3-gae X-Git-Reftype: branch X-Git-Oldrev: bcde758d4a00b3a2e2de2deb4d7e6b56cfbaada7 X-Git-Newrev: ea7cd6ed00216cd2718a77ea3cd44e634e0ea8fd X-Git-Rev: ea7cd6ed00216cd2718a77ea3cd44e634e0ea8fd X-Git-NotificationType: ref_changed_plus_diff X-Git-Multimail-Version: 1.5.dev Auto-Submitted: auto-generated 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 ea7cd6e Added special rule to allow using the directive name in the end-tag when ?with_args(...) was used in the start-tag, like <@myMacro?with_args(args)>.... ea7cd6e is described below commit ea7cd6ed00216cd2718a77ea3cd44e634e0ea8fd Author: ddekany AuthorDate: Fri Nov 1 19:40:45 2019 +0100 Added special rule to allow using the directive name in the end-tag when ?with_args(...) was used in the start-tag, like <@myMacro?with_args(args)>.... --- src/main/java/freemarker/core/MethodCall.java | 4 ++ src/main/javacc/FTL.jj | 13 +++- src/manual/en_US/book.xml | 16 +++++ .../java/freemarker/core/EndTagSyntaxTest.java | 76 ++++++++++++++++++++++ 4 files changed, 107 insertions(+), 2 deletions(-) diff --git a/src/main/java/freemarker/core/MethodCall.java b/src/main/java/freemarker/core/MethodCall.java index 74e20a4..ab441aa 100644 --- a/src/main/java/freemarker/core/MethodCall.java +++ b/src/main/java/freemarker/core/MethodCall.java @@ -106,6 +106,10 @@ final class MethodCall extends Expression { return 1 + arguments.items.size(); } + Expression getTarget() { + return target; + } + @Override Object getParameterValue(int idx) { if (idx == 0) { diff --git a/src/main/javacc/FTL.jj b/src/main/javacc/FTL.jj index 184c8a4..cb80218 100644 --- a/src/main/javacc/FTL.jj +++ b/src/main/javacc/FTL.jj @@ -3585,8 +3585,17 @@ TemplateElement UnifiedMacroTransform() : start = exp = Expression() { - if (exp instanceof Identifier || (exp instanceof Dot && ((Dot) exp).onlyHasIdentifiers())) { - startTagNameExp = exp; + // To allow <@foo.bar?withArgs(...)>..., but we also remove superfluous (...): + Expression cleanedExp = exp; + if (cleanedExp instanceof MethodCall) { + Expression methodCallTarget = ((MethodCall) cleanedExp).getTarget(); + if (methodCallTarget instanceof BuiltInsForCallables.with_argsBI) { + cleanedExp = ((BuiltInsForCallables.with_argsBI) methodCallTarget).target; + } + } + + if (cleanedExp instanceof Identifier || (cleanedExp instanceof Dot && ((Dot) cleanedExp).onlyHasIdentifiers())) { + startTagNameExp = cleanedExp; } else { startTagNameExp = null; } diff --git a/src/manual/en_US/book.xml b/src/manual/en_US/book.xml index afe59d7..a99606f 100644 --- a/src/manual/en_US/book.xml +++ b/src/manual/en_US/book.xml @@ -19869,6 +19869,14 @@ Same as: m2 does things with 1, 2, 3 Delegate to m1: m1 does things with 1, 2, 3 + + FreeMarker syntax allows using the name before the + ?with_args(...) in the + end-tag, just as if the + ?with_args(...) wasn't + there: + + <@myMacro?with_args({'a': 1})>...</@myMacro> @@ -24273,6 +24281,14 @@ Or all above but with positional parameter passing (<@a_hash.foo>...</@a_hash.foo> is OK. + + There's also a special rule that says that if the + user_def_dir_exp + ends with ?with_args(...), + then that's ignored when the end-tag is matched, so you can write + something like + <@myMacro?with_args(args)>...</@myMacro>.
diff --git a/src/test/java/freemarker/core/EndTagSyntaxTest.java b/src/test/java/freemarker/core/EndTagSyntaxTest.java new file mode 100644 index 0000000..f4e7500 --- /dev/null +++ b/src/test/java/freemarker/core/EndTagSyntaxTest.java @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package freemarker.core; + +import java.io.IOException; + +import org.junit.Before; +import org.junit.Test; + +import freemarker.template.Configuration; +import freemarker.template.TemplateException; +import freemarker.test.TemplateTest; + +public class EndTagSyntaxTest extends TemplateTest { + + @Override + protected Configuration createConfiguration() throws Exception { + return new Configuration(Configuration.VERSION_2_3_29); + } + + @Before + public void setup() { + addTemplate("common.ftl", + "<#macro m a=1>${a}[<#nested />]" + + "<#assign ns={'m':m}>"); + getConfiguration().addAutoInclude("common.ftl"); + } + + @Test + public void testSimple() throws IOException, TemplateException { + assertOutput("<@m>nested", "1[nested]"); + assertOutput("<@m a=2>nested", "2[nested]"); + + assertOutput("<@ns.m>nested", "1[nested]"); + assertOutput("<@ns.m a=2>nested", "2[nested]"); + + assertOutput("<@m>nested", "1[nested]"); + assertOutput("<@m a=2>nested", "2[nested]"); + + assertOutput("<@ns.m>nested", "1[nested]"); + assertOutput("<@ns.m a=2>nested", "2[nested]"); + + assertErrorContains("<@ns.m a=2>nested", ""); + assertErrorContains("<@m a=2>nested", ""); + } + + @Test + public void testWithArgs() throws IOException, TemplateException { + assertOutput("<@m?withArgs({})>nested", "1[nested]"); + assertOutput("<@m?withArgs({}) a=2>nested", "2[nested]"); + + assertOutput("<@ns.m?withArgs({})>nested", "1[nested]"); + assertOutput("<@ns.m?withArgs({}) a=2>nested", "2[nested]"); + + assertErrorContains("<@ns.m?withArgs({})>nested", ""); + assertErrorContains("<@m?withArgs({})>nested", ""); + } + +}