Return-Path: X-Original-To: apmail-ant-notifications-archive@minotaur.apache.org Delivered-To: apmail-ant-notifications-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id F29AFDA49 for ; Mon, 30 Jul 2012 21:23:01 +0000 (UTC) Received: (qmail 62868 invoked by uid 500); 30 Jul 2012 21:23:01 -0000 Delivered-To: apmail-ant-notifications-archive@ant.apache.org Received: (qmail 62835 invoked by uid 500); 30 Jul 2012 21:23:01 -0000 Mailing-List: contact notifications-help@ant.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@ant.apache.org Delivered-To: mailing list notifications@ant.apache.org Received: (qmail 62827 invoked by uid 99); 30 Jul 2012 21:23:01 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 30 Jul 2012 21:23:01 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 30 Jul 2012 21:22:54 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 057A623888FD for ; Mon, 30 Jul 2012 21:22:09 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1367311 - in /ant/sandbox/antdsl/trunk: org.apache.ant.antdsl/src/org/apache/ant/antdsl/ org.apache.ant.antdsl/src/org/apache/ant/antdsl/expr/ org.apache.ant.antdsl/src/org/apache/ant/antdsl/xtext/ test/ Date: Mon, 30 Jul 2012 21:22:08 -0000 To: notifications@ant.apache.org From: hibou@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120730212209.057A623888FD@eris.apache.org> Author: hibou Date: Mon Jul 30 21:22:07 2012 New Revision: 1367311 URL: http://svn.apache.org/viewvc?rev=1367311&view=rev Log: - use AntExpression rather than String as attributes of tasks - rework macros so they can hold expressions: - regular arguments become local properties - no more @{} substitution - renamed to 'function' so avoid the confusion with xml style macros => needs ant trunk, the build needs to be rework Added: ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/FunctionCall.java (with props) ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/FunctionDef.java (with props) Removed: ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/ExtensionPoint.java ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/Target.java Modified: ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/AbstractAntDslProjectHelper.java ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/AntDSL.g ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/expr/AntExpression.java ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/xtext/AntDSL.xtext ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/xtext/AntDslXTextProjectHelper.java ant/sandbox/antdsl/trunk/test/build.ant Modified: ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/AbstractAntDslProjectHelper.java URL: http://svn.apache.org/viewvc/ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/AbstractAntDslProjectHelper.java?rev=1367311&r1=1367310&r2=1367311&view=diff ============================================================================== --- ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/AbstractAntDslProjectHelper.java (original) +++ ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/AbstractAntDslProjectHelper.java Mon Jul 30 21:22:07 2012 @@ -389,7 +389,7 @@ public abstract class AbstractAntDslProj } public UnknownElement mapUnknown(Project project, AntDslContext context, InnerElement innerElement, boolean innerUnknown) { - RuntimeConfigurable parentWrapper = context.currentWrapper(); + RuntimeConfigurable parentWrapper = (RuntimeConfigurable) context.currentWrapper(); Object parent = null; if (parentWrapper != null) { @@ -427,7 +427,7 @@ public abstract class AbstractAntDslProj RuntimeConfigurable wrapper = new RuntimeConfigurable(element, element.getTaskName()); if (innerElement.attributes != null) { - for (Entry att : innerElement.attributes.entrySet()) { + for (Entry att : innerElement.attributes.entrySet()) { wrapper.setAttribute(att.getKey(), att.getValue()); } } @@ -485,7 +485,7 @@ public abstract class AbstractAntDslProj public String name; - public LinkedHashMap attributes; + public LinkedHashMap attributes; public List children; } Modified: ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/AntDSL.g URL: http://svn.apache.org/viewvc/ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/AntDSL.g?rev=1367311&r1=1367310&r2=1367311&view=diff ============================================================================== --- ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/AntDSL.g (original) +++ ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/AntDSL.g Mon Jul 30 21:22:07 2012 @@ -26,16 +26,13 @@ package org.apache.ant.antdsl.antlr; import org.apache.ant.antdsl.*; import org.apache.ant.antdsl.AbstractAntDslProjectHelper.InnerElement; +import org.apache.ant.antdsl.FunctionDef.LocalProperty; +import org.apache.ant.antdsl.FunctionDef.NestedSequential; +import org.apache.ant.antdsl.FunctionDef.TemplateElement; import org.apache.ant.antdsl.IfTask.ConditionnalSequential; -import org.apache.ant.antdsl.Target; -import org.apache.ant.antdsl.ExtensionPoint; import org.apache.ant.antdsl.expr.*; import org.apache.tools.ant.*; import org.apache.tools.ant.taskdefs.*; -import org.apache.tools.ant.taskdefs.MacroDef.Attribute; -import org.apache.tools.ant.taskdefs.MacroDef.NestedSequential; -import org.apache.tools.ant.taskdefs.MacroDef.TemplateElement; -import org.apache.tools.ant.taskdefs.MacroDef.Text; import org.apache.tools.ant.taskdefs.condition.*; import java.util.LinkedHashMap; } @@ -72,7 +69,7 @@ project: { for (Task t : tl) { context.getImplicitTarget().addTask(t); } } ( target | extensionPoint - | macrodef + | funcdef )* ; @@ -126,13 +123,13 @@ nsName returns [Pair ns (n=identifier { ns.first = n; } ':')? n=identifier { ns.second = n; } ; -arguments returns [LinkedHashMap args = new LinkedHashMap();]: +arguments returns [LinkedHashMap args = new LinkedHashMap();]: arg=argument { args.put(arg.first, arg.second); } (',' arg=argument { args.put(arg.first, arg.second); } )* ; -argument returns [Pair arg = new Pair()]: - n=identifier { arg.first = n; } '=' v=stringLiteral { arg.second = v; } +argument returns [Pair arg = new Pair()]: + n=identifier { arg.first = n; } '=' v=expr { arg.second = v; } ; innerElements returns [List ies = new ArrayList()]: @@ -188,56 +185,46 @@ conditionedTasks returns [ConditionnalSe tl=taskList { for (Task t : tl) { seq.addTask(t); } } ; -macrodef returns [MacroDef macroDef = new MacroDef()]: - ( d=doc { macroDef.setDescription(d); } )? - 'macrodef' n=identifier { macroDef.setName(n); } - '(' ( atts=attributes - { for (Object att : atts) { - if (att instanceof Attribute) { - macroDef.addConfiguredAttribute((Attribute) att); - } else if (att instanceof Text) { - macroDef.addConfiguredText((Text) att); - } else if (att instanceof TemplateElement) { - macroDef.addConfiguredElement((TemplateElement) att); +funcdef returns [FunctionDef funcDef = new FunctionDef()]: + ( d=doc { funcDef.setDescription(d); } )? + 'function' n=identifier { funcDef.setName(n); } + '(' ( args=funcArguments + { for (Object arg : args) { + if (arg instanceof LocalProperty) { + funcDef.addConfiguredLocalProperty((LocalProperty) arg); + } else if (arg instanceof TemplateElement) { + funcDef.addConfiguredElement((TemplateElement) arg); } else { - throw new IllegalArgumentException("Unsupported macro attribute " + att.getClass().getName()); + throw new IllegalArgumentException("Unsupported function argument " + arg.getClass().getName()); } } } )? ')' tl=taskList { - NestedSequential seq = macroDef.createSequential(); + NestedSequential seq = funcDef.createSequential(); for (Task t : tl) { seq.addTask(t); } - macroDef.setProject(project); - macroDef.execute(); + funcDef.setProject(project); + funcDef.execute(); } ; -attributes returns [List atts = new ArrayList()]: - att=attribute { atts.add(att); } - (',' att=attribute { atts.add(att); } )* +funcArguments returns [List args = new ArrayList()]: + arg=funcArgument { args.add(arg); } + (',' arg=funcArgument { args.add(arg); } )* ; -attribute returns [Object att]: - aatt=argAttribute { att = aatt; } - | tatt=textAttribute { att = tatt; } - | eatt=elementAttribute { att = eatt; } +funcArgument returns [Object arg]: + lparg=localPropFuncArgument { arg = lparg; } + | earg=elementFuncArgument { arg = earg; } ; -argAttribute returns [Attribute att = new Attribute()]: - 'arg' - n=identifier { att.setName(n); } - ('=' d=stringLiteral { att.setDefault(d); } )? -; - -textAttribute returns [Text text = new Text()]: - ('optional' { text.setOptional(true); } )? - ('trimmed' { text.setTrim(true); } )? - 'text' - n=identifier { text.setName(n); } +localPropFuncArgument returns [LocalProperty localProp = new LocalProperty()]: + 'local' + n=identifier { localProp.setName(n); } + ('=' d=expr { localProp.setDefault(d); } )? ; -elementAttribute returns [TemplateElement element = new TemplateElement()]: +elementFuncArgument returns [TemplateElement element = new TemplateElement()]: ('optional' { element.setOptional(true); } )? ('implicit' { element.setImplicit(true); } )? 'element' Added: ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/FunctionCall.java URL: http://svn.apache.org/viewvc/ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/FunctionCall.java?rev=1367311&view=auto ============================================================================== --- ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/FunctionCall.java (added) +++ ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/FunctionCall.java Mon Jul 30 21:22:07 2012 @@ -0,0 +1,265 @@ +/* + * 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 org.apache.ant.antdsl; + +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.apache.ant.antdsl.FunctionDef.LocalProperty; +import org.apache.ant.antdsl.FunctionDef.TemplateElement; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.DynamicObjectAttribute; +import org.apache.tools.ant.Evaluable; +import org.apache.tools.ant.ProjectHelper; +import org.apache.tools.ant.PropertyHelper; +import org.apache.tools.ant.RuntimeConfigurable; +import org.apache.tools.ant.Target; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.TaskContainer; +import org.apache.tools.ant.UnknownElement; +import org.apache.tools.ant.property.LocalProperties; + +/** + * The class to be placed in the ant type definition. It is given a pointer to the template definition, and makes a copy of the unknown element, + * substituting the parameter values in attributes and text. + * + */ +public class FunctionCall extends Task implements DynamicObjectAttribute, TaskContainer { + + private FunctionDef functionDef; + + private Map map = new HashMap(); + + private Map nsElements = null; + + private Map presentElements; + + private String implicitTag = null; + + private List unknownElements = new ArrayList(); + + public void setFunctionDef(FunctionDef functionDef) { + this.functionDef = functionDef; + } + + public FunctionDef getFunctionDef() { + return functionDef; + } + + /** + * A parameter name value pair as a xml attribute. + * + * @param name the name of the attribute + * @param value the value of the attribute + */ + public void setDynamicAttribute(String name, Object value) { + map.put(name, value); + } + + private Map getNsElements() { + if (nsElements == null) { + nsElements = new HashMap(); + for (Entry entry : functionDef.getElements().entrySet()) { + FunctionDef.TemplateElement te = entry.getValue(); + nsElements.put(entry.getKey(), te); + if (te.isImplicit()) { + implicitTag = te.getName(); + } + } + } + return nsElements; + } + + /** + * Add a unknownElement for the macro instances nested elements. + * + * @param nestedTask a nested element. + */ + public void addTask(Task nestedTask) { + unknownElements.add((UnknownElement) nestedTask); + } + + private void processTasks() { + if (implicitTag != null) { + return; + } + for (UnknownElement ue : unknownElements) { + String name = ProjectHelper.extractNameFromComponentName(ue.getTag()).toLowerCase(Locale.ENGLISH); + if (getNsElements().get(name) == null) { + throw new BuildException("unsupported element " + name); + } + if (presentElements.get(name) != null) { + throw new BuildException("Element " + name + " already present"); + } + presentElements.put(name, ue); + } + } + + /** + * Embedded element in macro instance + */ + public static class Element implements TaskContainer { + private List unknownElements = new ArrayList(); + + /** + * Add an unknown element (to be snipped into the macroDef instance) + * + * @param nestedTask an unknown element + */ + public void addTask(Task nestedTask) { + unknownElements.add((UnknownElement) nestedTask); + } + + /** + * @return the list of unknown elements + */ + public List getUnknownElements() { + return unknownElements; + } + } + + private UnknownElement copy(UnknownElement ue, boolean nested) { + UnknownElement ret = new UnknownElement(ue.getTag()); + ret.setNamespace(ue.getNamespace()); + ret.setProject(getProject()); + ret.setQName(ue.getQName()); + ret.setTaskType(ue.getTaskType()); + ret.setTaskName(ue.getTaskName()); + ret.setLocation(functionDef.getBackTrace() ? ue.getLocation() : getLocation()); + if (getOwningTarget() == null) { + Target t = new Target(); + t.setProject(getProject()); + ret.setOwningTarget(t); + } else { + ret.setOwningTarget(getOwningTarget()); + } + RuntimeConfigurable rc = new RuntimeConfigurable(ret, ue.getTaskName()); + rc.setPolyType(ue.getWrapper().getPolyType()); + Map m = ((RuntimeConfigurable) ue.getWrapper()).getAttributeMap(); + for (Entry entry : m.entrySet()) { + rc.setAttribute(entry.getKey(), entry.getValue()); + } + + @SuppressWarnings("unchecked") + Enumeration e = ue.getWrapper().getChildren(); + while (e.hasMoreElements()) { + RuntimeConfigurable r = e.nextElement(); + UnknownElement unknownElement = (UnknownElement) r.getProxy(); + String tag = unknownElement.getTaskType(); + if (tag != null) { + tag = tag.toLowerCase(Locale.ENGLISH); + } + FunctionDef.TemplateElement templateElement = (FunctionDef.TemplateElement) getNsElements().get(tag); + if (templateElement == null || nested) { + UnknownElement child = copy(unknownElement, nested); + rc.addChild(child.getWrapper()); + ret.addChild(child); + } else if (templateElement.isImplicit()) { + if (unknownElements.size() == 0 && !templateElement.isOptional()) { + throw new BuildException("Missing nested elements for implicit element " + templateElement.getName()); + } + for (UnknownElement elem : unknownElements) { + UnknownElement child = copy(elem, true); + rc.addChild(child.getWrapper()); + ret.addChild(child); + } + } else { + UnknownElement presentElement = presentElements.get(tag); + if (presentElement == null) { + if (!templateElement.isOptional()) { + throw new BuildException("Required nested element " + templateElement.getName() + " missing"); + } + continue; + } + @SuppressWarnings("unchecked") + List list = presentElement.getChildren(); + if (list != null) { + for (UnknownElement elem : list) { + UnknownElement child = copy(elem, true); + rc.addChild(child.getWrapper()); + ret.addChild(child); + } + } + } + } + return ret; + } + + /** + * Execute the templates instance. Copies the unknown element, substitutes the attributes, and calls perform on the unknown element. + * + */ + public void execute() { + presentElements = new HashMap(); + getNsElements(); + processTasks(); + + LocalProperties localProperties = LocalProperties.get(getProject()); + localProperties.enterScope(); + PropertyHelper propertyHelper = PropertyHelper.getPropertyHelper(getProject()); + + try { + Set copyKeys = new HashSet(map.keySet()); + for (LocalProperty localProperty : functionDef.getLocalProperties()) { + Object value = map.get(localProperty.getName()); + if (value == null) { + value = localProperty.getDefault(); + } + if (value == null) { + throw new BuildException("required argument " + localProperty.getName() + " not set"); + } + if (value instanceof Evaluable) { + value = ((Evaluable) value).eval(); + } + localProperties.addLocal(localProperty.getName()); + localProperties.setNew(localProperty.getName(), value, propertyHelper); + copyKeys.remove(localProperty.getName()); + } + if (copyKeys.contains("id")) { + copyKeys.remove("id"); + } + if (copyKeys.size() != 0) { + throw new BuildException("Unknown argument" + (copyKeys.size() > 1 ? "s " : " ") + copyKeys); + } + + // need to set the project on unknown element + UnknownElement c = copy(functionDef.getNestedTask(), false); + c.init(); + c.perform(); + } catch (BuildException ex) { + if (functionDef.getBackTrace()) { + throw ProjectHelper.addLocationToBuildException(ex, getLocation()); + } else { + ex.setLocation(getLocation()); + throw ex; + } + } finally { + presentElements = null; + localProperties.exitScope(); + } + } + +} Propchange: ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/FunctionCall.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/FunctionCall.java ------------------------------------------------------------------------------ svn:keywords = Date Revision Author HeadURL Id Propchange: ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/FunctionCall.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/FunctionDef.java URL: http://svn.apache.org/viewvc/ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/FunctionDef.java?rev=1367311&view=auto ============================================================================== --- ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/FunctionDef.java (added) +++ ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/FunctionDef.java Mon Jul 30 21:22:07 2012 @@ -0,0 +1,568 @@ +/* + * 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 org.apache.ant.antdsl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import org.apache.ant.antdsl.expr.AntExpression; +import org.apache.tools.ant.AntTypeDefinition; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.ComponentHelper; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.ProjectHelper; +import org.apache.tools.ant.RuntimeConfigurable; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.TaskContainer; +import org.apache.tools.ant.UnknownElement; +import org.apache.tools.ant.taskdefs.AntlibDefinition; + +public class FunctionDef extends AntlibDefinition { + + private NestedSequential nestedSequential; + + private String name; + + private boolean backTrace = true; + + private List localProperties = new ArrayList(); + + private Map elements = new HashMap(); + + private boolean hasImplicitElement = false; + + /** + * Name of the definition + * + * @param name the name of the definition + */ + public void setName(String name) { + this.name = name; + } + + /** + * Set the backTrace attribute. + * + * @param backTrace if true and the macro instance generates an error, a backtrace of the location within the macro and call to the macro will be + * output. if false, only the location of the call to the macro will be shown. Default is true. + * @since ant 1.7 + */ + public void setBackTrace(boolean backTrace) { + this.backTrace = backTrace; + } + + /** + * @return the backTrace attribute. + * @since ant 1.7 + */ + public boolean getBackTrace() { + return backTrace; + } + + /** + * This is the sequential nested element of the macrodef. + * + * @return a sequential element to be configured. + */ + public NestedSequential createSequential() { + if (this.nestedSequential != null) { + throw new BuildException("Only one sequential allowed"); + } + this.nestedSequential = new NestedSequential(); + return this.nestedSequential; + } + + /** + * The class corresponding to the sequential nested element. This is a simple task container. + */ + public static class NestedSequential implements TaskContainer { + + private List nested = new ArrayList(); + + public void addTask(Task task) { + nested.add(task); + } + + public List getNested() { + return nested; + } + + /** + * A compare function to compare this with another NestedSequential. It calls similar on the nested unknown elements. + * + * @param other the nested sequential to compare with. + * @return true if they are similar, false otherwise + */ + public boolean similar(NestedSequential other) { + final int size = nested.size(); + if (size != other.nested.size()) { + return false; + } + for (int i = 0; i < size; ++i) { + UnknownElement me = (UnknownElement) nested.get(i); + UnknownElement o = (UnknownElement) other.nested.get(i); + if (!me.similar(o)) { + return false; + } + } + return true; + } + } + + /** + * Convert the nested sequential to an unknown element + * + * @return the nested sequential as an unknown element. + */ + public UnknownElement getNestedTask() { + UnknownElement ret = new UnknownElement("sequential"); + ret.setTaskName("sequential"); + ret.setNamespace(""); + ret.setQName("sequential"); + new RuntimeConfigurable(ret, "sequential"); + final int size = nestedSequential.getNested().size(); + for (int i = 0; i < size; ++i) { + UnknownElement e = (UnknownElement) nestedSequential.getNested().get(i); + ret.addChild(e); + ret.getWrapper().addChild(e.getWrapper()); + } + return ret; + } + + public List getLocalProperties() { + return localProperties; + } + + /** + * Gets this macro's elements. + * + * @return the map nested elements, keyed by element name, with {@link TemplateElement} values. + */ + public Map getElements() { + return elements; + } + + /** + * Check if a character is a valid character for an element or attribute name. + * + * @param c the character to check + * @return true if the character is a letter or digit or '.' or '-' attribute name + */ + public static boolean isValidNameCharacter(char c) { + // ? is there an xml api for this ? + return Character.isLetterOrDigit(c) || c == '.' || c == '-'; + } + + /** + * Check if a string is a valid name for an element or attribute. + * + * @param name the string to check + * @return true if the name consists of valid name characters + */ + private static boolean isValidName(String name) { + if (name.length() == 0) { + return false; + } + for (int i = 0; i < name.length(); ++i) { + if (!isValidNameCharacter(name.charAt(i))) { + return false; + } + } + return true; + } + + /** + * Add a local property. + * + * @param localProperty a local property + */ + public void addConfiguredLocalProperty(LocalProperty localProperty) { + if (localProperty.getName() == null) { + throw new BuildException("the local property nested element needed a name"); + } + final int size = localProperties.size(); + for (int i = 0; i < size; ++i) { + LocalProperty att = (LocalProperty) localProperties.get(i); + if (att.getName().equals(localProperty.getName())) { + throw new BuildException("the name \"" + localProperty.getName() + "\" has already been used in another local property element"); + } + } + localProperties.add(localProperty); + } + + /** + * Add an element element. + * + * @param element an element nested element. + */ + public void addConfiguredElement(TemplateElement element) { + if (element.getName() == null) { + throw new BuildException("the element nested needed a name"); + } + if (elements.get(element.getName()) != null) { + throw new BuildException("the element " + element.getName() + " has already been specified"); + } + if (hasImplicitElement || (element.isImplicit() && elements.size() != 0)) { + throw new BuildException("Only one element allowed when using implicit elements"); + } + hasImplicitElement = element.isImplicit(); + elements.put(element.getName(), element); + } + + /** + * Create a new ant type based on the embedded tasks and types. + */ + public void execute() { + if (nestedSequential == null) { + throw new BuildException("Missing sequential element"); + } + if (name == null) { + throw new BuildException("Name not specified"); + } + + name = ProjectHelper.genComponentName(getURI(), name); + + FunctionTypeDefinition def = new FunctionTypeDefinition(this); + def.setName(name); + def.setClass(FunctionCall.class); + + ComponentHelper helper = ComponentHelper.getComponentHelper(getProject()); + + helper.addDataTypeDefinition(def); + log("creating macro " + name, Project.MSG_VERBOSE); + } + + public static class LocalProperty { + + private String name; + + private AntExpression defaultValue; + + private String description; + + public void setName(String name) { + if (!isValidName(name)) { + throw new BuildException("Illegal name [" + name + "] for argument"); + } + this.name = name.toLowerCase(Locale.ENGLISH); + } + + public String getName() { + return name; + } + + public void setDefault(AntExpression defaultValue) { + this.defaultValue = defaultValue; + } + + public AntExpression getDefault() { + return defaultValue; + } + + public void setDescription(String desc) { + description = desc; + } + + public String getDescription() { + return description; + } + + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (obj.getClass() != getClass()) { + return false; + } + LocalProperty other = (LocalProperty) obj; + if (name == null) { + if (other.name != null) { + return false; + } + } else if (!name.equals(other.name)) { + return false; + } + if (defaultValue == null) { + if (other.defaultValue != null) { + return false; + } + } else if (!defaultValue.equals(other.defaultValue)) { + return false; + } + return true; + } + + public int hashCode() { + return objectHashCode(defaultValue) + objectHashCode(name); + } + } + + /** + * A nested element for the MacroDef task. + */ + public static class TemplateElement { + + private String name; + private String description; + private boolean optional = false; + private boolean implicit = false; + + /** + * Sets the name of this element. + * + * @param name the name of the element + */ + public void setName(String name) { + if (!isValidName(name)) { + throw new BuildException("Illegal name [" + name + "] for function element"); + } + this.name = name.toLowerCase(Locale.ENGLISH); + } + + /** + * Gets the name of this element. + * + * @return the name of the element. + */ + public String getName() { + return name; + } + + /** + * Sets a textual description of this element, for build documentation purposes only. + * + * @param desc Description of the element. + * @since ant 1.6.1 + */ + public void setDescription(String desc) { + description = desc; + } + + /** + * Gets the description of this element. + * + * @return the description of the element, or null if no description is available. + * @since ant 1.6.1 + */ + public String getDescription() { + return description; + } + + /** + * Sets whether this element is optional. + * + * @param optional if true this element may be left out, default is false. + */ + public void setOptional(boolean optional) { + this.optional = optional; + } + + /** + * Gets whether this element is optional. + * + * @return the optional attribute + */ + public boolean isOptional() { + return optional; + } + + /** + * Sets whether this element is implicit. + * + * @param implicit if true this element may be left out, default is false. + */ + public void setImplicit(boolean implicit) { + this.implicit = implicit; + } + + /** + * Gets whether this element is implicit. + * + * @return the implicit attribute + */ + public boolean isImplicit() { + return implicit; + } + + /** + * equality method. + * + * @param obj an Object value + * @return a boolean value + */ + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj == null || !obj.getClass().equals(getClass())) { + return false; + } + TemplateElement t = (TemplateElement) obj; + return (name == null ? t.name == null : name.equals(t.name)) && optional == t.optional && implicit == t.implicit; + } + + /** + * @return a hash code value for this object. + */ + public int hashCode() { + return objectHashCode(name) + (optional ? 1 : 0) + (implicit ? 1 : 0); + } + + } // END static class TemplateElement + + /** + * same or similar equality method for macrodef, ignores project and runtime info. + * + * @param obj an Object value + * @param same if true test for sameness, otherwise just similiar + * @return a boolean value + */ + private boolean sameOrSimilar(Object obj, boolean same) { + if (obj == this) { + return true; + } + + if (obj == null) { + return false; + } + if (!obj.getClass().equals(getClass())) { + return false; + } + FunctionDef other = (FunctionDef) obj; + if (name == null) { + return other.name == null; + } + if (!name.equals(other.name)) { + return false; + } + // Allow two macro definitions with the same location + // to be treated as similar - bugzilla 31215 + if (other.getLocation() != null && other.getLocation().equals(getLocation()) && !same) { + return true; + } + if (getURI() == null || getURI().equals("") || getURI().equals(ProjectHelper.ANT_CORE_URI)) { + if (!(other.getURI() == null || other.getURI().equals("") || other.getURI().equals(ProjectHelper.ANT_CORE_URI))) { + return false; + } + } else { + if (!getURI().equals(other.getURI())) { + return false; + } + } + + if (!nestedSequential.similar(other.nestedSequential)) { + return false; + } + if (!localProperties.equals(other.localProperties)) { + return false; + } + if (!elements.equals(other.elements)) { + return false; + } + return true; + } + + /** + * Similar method for this definition + * + * @param obj another definition + * @return true if the definitions are similar + */ + public boolean similar(Object obj) { + return sameOrSimilar(obj, false); + } + + /** + * Equality method for this definition + * + * @param obj another definition + * @return true if the definitions are the same + */ + public boolean sameDefinition(Object obj) { + return sameOrSimilar(obj, true); + } + + /** + * extends AntTypeDefinition, on create of the object, the template macro definition is given. + */ + private static class FunctionTypeDefinition extends AntTypeDefinition { + private FunctionDef functionDef; + + public FunctionTypeDefinition(FunctionDef functionDef) { + this.functionDef = functionDef; + } + + /** + * Create an instance of the definition. The instance may be wrapped in a proxy class. + * + * @param project the current project + * @return the created object + */ + public Object create(Project project) { + Object o = super.create(project); + if (o == null) { + return null; + } + ((FunctionCall) o).setFunctionDef(functionDef); + return o; + } + + /** + * Equality method for this definition + * + * @param other another definition + * @param project the current project + * @return true if the definitions are the same + */ + public boolean sameDefinition(AntTypeDefinition other, Project project) { + if (!super.sameDefinition(other, project)) { + return false; + } + FunctionTypeDefinition otherDef = (FunctionTypeDefinition) other; + return functionDef.sameDefinition(otherDef.functionDef); + } + + /** + * Similar method for this definition + * + * @param other another definition + * @param project the current project + * @return true if the definitions are the same + */ + public boolean similarDefinition(AntTypeDefinition other, Project project) { + if (!super.similarDefinition(other, project)) { + return false; + } + FunctionTypeDefinition otherDef = (FunctionTypeDefinition) other; + return functionDef.similar(otherDef.functionDef); + } + } + + private static int objectHashCode(Object o) { + if (o == null) { + return 0; + } else { + return o.hashCode(); + } + } + +} Propchange: ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/FunctionDef.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/FunctionDef.java ------------------------------------------------------------------------------ svn:keywords = Date Revision Author HeadURL Id Propchange: ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/FunctionDef.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Modified: ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/expr/AntExpression.java URL: http://svn.apache.org/viewvc/ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/expr/AntExpression.java?rev=1367311&r1=1367310&r2=1367311&view=diff ============================================================================== --- ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/expr/AntExpression.java (original) +++ ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/expr/AntExpression.java Mon Jul 30 21:22:07 2012 @@ -17,9 +17,10 @@ */ package org.apache.ant.antdsl.expr; +import org.apache.tools.ant.Evaluable; import org.apache.tools.ant.Project; -public abstract class AntExpression { +public abstract class AntExpression implements Evaluable { private Project project; Modified: ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/xtext/AntDSL.xtext URL: http://svn.apache.org/viewvc/ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/xtext/AntDSL.xtext?rev=1367311&r1=1367310&r2=1367311&view=diff ============================================================================== --- ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/xtext/AntDSL.xtext (original) +++ ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/xtext/AntDSL.xtext Mon Jul 30 21:22:07 2012 @@ -30,7 +30,7 @@ EProject: ) ('namespaces' '{' namespaces+=ENamespace* '}')? tasks=ETaskLists? - (targets+=ETarget | extensionPoints+=EExtensionPoint | macrodDefs+=EMacrodef)* + (targets+=ETarget | extensionPoints+=EExtensionPoint | functionDefs+=EFunctionDef)* ; ENamespace: @@ -79,7 +79,7 @@ EArguments: ; EArgument: - name=Identifier '=' value=StringLiteral + name=Identifier '=' value=EExpr ; EInnerElements: @@ -115,30 +115,26 @@ EConditionedTasks: ; //////////////// -// Macro +// Functions //////////////// -EMacrodef: - description=DOC? 'macrodef' name=Identifier '(' attributes=EAttributes? ')' tasks=ETaskLists +EFunctionDef: + description=DOC? 'function' name=Identifier '(' arguments=EFuncArguments? ')' tasks=ETaskLists ; -EAttributes: - attributes+=EAttribute (',' attributes+=EAttribute)* +EFuncArguments: + arguments+=EFuncArgument (',' arguments+=EFuncArgument)* ; -EAttribute: - EArgAttribute | ETextAttribute | EElementAttribute +EFuncArgument: + ELocalPropertyFuncArgument | EElementFuncArgument ; -EArgAttribute: - 'arg' name=Identifier ('=' default=StringLiteral)? +ELocalPropertyFuncArgument: + 'local' name=Identifier ('=' default=EExpr)? ; -ETextAttribute: - (optional ?= 'optional')? (trimmed ?= 'trimmed')? 'text' name=Identifier -; - -EElementAttribute: +EElementFuncArgument: (optional ?= 'optional')? (implicit ?= 'implicit')? 'element' name=Identifier ; Modified: ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/xtext/AntDslXTextProjectHelper.java URL: http://svn.apache.org/viewvc/ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/xtext/AntDslXTextProjectHelper.java?rev=1367311&r1=1367310&r2=1367311&view=diff ============================================================================== --- ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/xtext/AntDslXTextProjectHelper.java (original) +++ ant/sandbox/antdsl/trunk/org.apache.ant.antdsl/src/org/apache/ant/antdsl/xtext/AntDslXTextProjectHelper.java Mon Jul 30 21:22:07 2012 @@ -30,10 +30,12 @@ import org.apache.ant.antdsl.AntDslConte import org.apache.ant.antdsl.AssignLocalTask; import org.apache.ant.antdsl.AssignPropertyTask; import org.apache.ant.antdsl.AssignReferenceTask; -import org.apache.ant.antdsl.ExtensionPoint; +import org.apache.ant.antdsl.FunctionDef; +import org.apache.ant.antdsl.FunctionDef.LocalProperty; +import org.apache.ant.antdsl.FunctionDef.NestedSequential; +import org.apache.ant.antdsl.FunctionDef.TemplateElement; import org.apache.ant.antdsl.IfTask; import org.apache.ant.antdsl.IfTask.ConditionnalSequential; -import org.apache.ant.antdsl.Target; import org.apache.ant.antdsl.expr.AddAntExpression; import org.apache.ant.antdsl.expr.AndAntExpression; import org.apache.ant.antdsl.expr.AntExpression; @@ -62,11 +64,8 @@ import org.apache.ant.antdsl.expr.Ternar import org.apache.ant.antdsl.expr.VariableAntExpression; import org.apache.ant.antdsl.xtext.antdsl.EAdditiveExpr; import org.apache.ant.antdsl.xtext.antdsl.EAndExpr; -import org.apache.ant.antdsl.xtext.antdsl.EArgAttribute; import org.apache.ant.antdsl.xtext.antdsl.EArgument; import org.apache.ant.antdsl.xtext.antdsl.EArguments; -import org.apache.ant.antdsl.xtext.antdsl.EAttribute; -import org.apache.ant.antdsl.xtext.antdsl.EAttributes; import org.apache.ant.antdsl.xtext.antdsl.EBooleanLiteralExpr; import org.apache.ant.antdsl.xtext.antdsl.EBranch; import org.apache.ant.antdsl.xtext.antdsl.ECharacterLiteralExpr; @@ -75,20 +74,23 @@ import org.apache.ant.antdsl.xtext.antds import org.apache.ant.antdsl.xtext.antdsl.EConditionnalExclusiveOrExpr; import org.apache.ant.antdsl.xtext.antdsl.EConditionnalInclusiveOrExpr; import org.apache.ant.antdsl.xtext.antdsl.EDecimalLiteralExpr; -import org.apache.ant.antdsl.xtext.antdsl.EElementAttribute; +import org.apache.ant.antdsl.xtext.antdsl.EElementFuncArgument; import org.apache.ant.antdsl.xtext.antdsl.EEqualityExpr; import org.apache.ant.antdsl.xtext.antdsl.EExclusiveOrExpr; import org.apache.ant.antdsl.xtext.antdsl.EExpr; import org.apache.ant.antdsl.xtext.antdsl.EExtensionPoint; import org.apache.ant.antdsl.xtext.antdsl.EFloatingPointLiteralExpr; +import org.apache.ant.antdsl.xtext.antdsl.EFuncArgument; +import org.apache.ant.antdsl.xtext.antdsl.EFuncArguments; import org.apache.ant.antdsl.xtext.antdsl.EFuncExpr; +import org.apache.ant.antdsl.xtext.antdsl.EFunctionDef; import org.apache.ant.antdsl.xtext.antdsl.EHexLiteralExpr; import org.apache.ant.antdsl.xtext.antdsl.EInclusiveOrExpr; import org.apache.ant.antdsl.xtext.antdsl.EInnerElement; import org.apache.ant.antdsl.xtext.antdsl.EInnerElements; import org.apache.ant.antdsl.xtext.antdsl.EInstanceOfExpr; import org.apache.ant.antdsl.xtext.antdsl.ELocalAssignment; -import org.apache.ant.antdsl.xtext.antdsl.EMacrodef; +import org.apache.ant.antdsl.xtext.antdsl.ELocalPropertyFuncArgument; import org.apache.ant.antdsl.xtext.antdsl.EMultiplicativeExpr; import org.apache.ant.antdsl.xtext.antdsl.ENamespace; import org.apache.ant.antdsl.xtext.antdsl.ENullExpr; @@ -104,17 +106,13 @@ import org.apache.ant.antdsl.xtext.antds import org.apache.ant.antdsl.xtext.antdsl.ETask; import org.apache.ant.antdsl.xtext.antdsl.ETaskLists; import org.apache.ant.antdsl.xtext.antdsl.ETernaryExpr; -import org.apache.ant.antdsl.xtext.antdsl.ETextAttribute; import org.apache.ant.antdsl.xtext.antdsl.EUnaryExpr; import org.apache.ant.antdsl.xtext.antdsl.EVariableExpr; import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.ExtensionPoint; import org.apache.tools.ant.Project; +import org.apache.tools.ant.Target; import org.apache.tools.ant.Task; -import org.apache.tools.ant.taskdefs.MacroDef; -import org.apache.tools.ant.taskdefs.MacroDef.Attribute; -import org.apache.tools.ant.taskdefs.MacroDef.NestedSequential; -import org.apache.tools.ant.taskdefs.MacroDef.TemplateElement; -import org.apache.tools.ant.taskdefs.MacroDef.Text; import org.apache.tools.ant.taskdefs.Sequential; import org.apache.tools.ant.taskdefs.condition.And; import org.apache.tools.ant.taskdefs.condition.Not; @@ -171,10 +169,10 @@ public class AntDslXTextProjectHelper ex } } - EList macros = eProject.getMacrodDefs(); - if (macros != null) { - for (EMacrodef macro : macros) { - mapMacro(project, context, macro); + EList efuncs = eProject.getFunctionDefs(); + if (efuncs != null) { + for (EFunctionDef efunc : efuncs) { + mapFunction(project, context, efunc); } } ETaskLists tasks = eProject.getTasks(); @@ -191,47 +189,40 @@ public class AntDslXTextProjectHelper ex } } - private void mapMacro(Project project, AntDslContext context, EMacrodef emacro) { - MacroDef macroDef = new MacroDef(); - macroDef.setDescription(emacro.getDescription()); - macroDef.setName(readIdentifier(emacro.getName())); - EAttributes eatts = emacro.getAttributes(); - if (eatts != null) { - for (EAttribute eatt : eatts.getAttributes()) { - if (eatt instanceof EArgAttribute) { - EArgAttribute eargatt = (EArgAttribute) eatt; - Attribute att = new Attribute(); - att.setName(readIdentifier(eargatt.getName())); - att.setDefault(readString(eargatt.getDefault())); - macroDef.addConfiguredAttribute(att); - } else if (eatt instanceof ETextAttribute) { - ETextAttribute etextatt = (ETextAttribute) eatt; - Text text = new Text(); - text.setName(readIdentifier(etextatt.getName())); - text.setTrim(etextatt.isTrimmed()); - text.setOptional(etextatt.isOptional()); - macroDef.addConfiguredText(text); - } else if (eatt instanceof EElementAttribute) { - EElementAttribute eelematt = (EElementAttribute) eatt; + private void mapFunction(Project project, AntDslContext context, EFunctionDef efunc) { + FunctionDef funcDef = new FunctionDef(); + funcDef.setDescription(efunc.getDescription()); + funcDef.setName(readIdentifier(efunc.getName())); + EFuncArguments eargs = efunc.getArguments(); + if (eargs != null) { + for (EFuncArgument earg : eargs.getArguments()) { + if (earg instanceof ELocalPropertyFuncArgument) { + ELocalPropertyFuncArgument elocalpropatt = (ELocalPropertyFuncArgument) earg; + LocalProperty localProp = new LocalProperty(); + localProp.setName(readIdentifier(elocalpropatt.getName())); + localProp.setDefault(mapExpr(project, context, elocalpropatt.getDefault())); + funcDef.addConfiguredLocalProperty(localProp); + } else if (earg instanceof EElementFuncArgument) { + EElementFuncArgument eelemarg = (EElementFuncArgument) earg; TemplateElement element = new TemplateElement(); - element.setImplicit(eelematt.isImplicit()); - element.setOptional(eelematt.isOptional()); - element.setName(readIdentifier(eelematt.getName())); - macroDef.addConfiguredElement(element); + element.setImplicit(eelemarg.isImplicit()); + element.setOptional(eelemarg.isOptional()); + element.setName(readIdentifier(eelemarg.getName())); + funcDef.addConfiguredElement(element); } else { - throw new IllegalArgumentException("Unsupported macro attribute " + eatt.getClass().getName()); + throw new IllegalArgumentException("Unsupported function argument " + earg.getClass().getName()); } } } - ETaskLists etasks = emacro.getTasks(); + ETaskLists etasks = efunc.getTasks(); if (etasks != null) { - NestedSequential seq = macroDef.createSequential(); + NestedSequential seq = funcDef.createSequential(); for (ETask etask : etasks.getTasks()) { seq.addTask(mapTask(project, context, etask)); } } - macroDef.setProject(project); - macroDef.execute(); + funcDef.setProject(project); + funcDef.execute(); } private Target mapTarget(Project project, AntDslContext context, ETarget eTarget) { @@ -300,7 +291,7 @@ public class AntDslXTextProjectHelper ex } if (eTask instanceof EInnerElement) { EInnerElement eInnerElement = (EInnerElement) eTask; - return mapUnknown(project, context, mapInnerElement(eInnerElement), false); + return mapUnknown(project, context, mapInnerElement(project, context, eInnerElement), false); } if (eTask instanceof EBranch) { EBranch eBranch = (EBranch) eTask; @@ -342,7 +333,7 @@ public class AntDslXTextProjectHelper ex throw new IllegalStateException("Unknown task type " + eTask.getClass().getName()); } - private InnerElement mapInnerElement(EInnerElement eInnerElement) { + private InnerElement mapInnerElement(Project project, AntDslContext context, EInnerElement eInnerElement) { if (eInnerElement == null) { return null; } @@ -352,9 +343,9 @@ public class AntDslXTextProjectHelper ex EArguments arguments = eInnerElement.getArguments(); if (arguments != null) { - innerElement.attributes = new LinkedHashMap(); + innerElement.attributes = new LinkedHashMap(); for (EArgument argument : arguments.getArguments()) { - innerElement.attributes.put(readIdentifier(argument.getName()), readString(argument.getValue())); + innerElement.attributes.put(readIdentifier(argument.getName()), mapExpr(project, context, argument.getValue())); } } @@ -362,7 +353,7 @@ public class AntDslXTextProjectHelper ex if (inners != null) { innerElement.children = new ArrayList(); for (EInnerElement inner : inners.getElements()) { - innerElement.children.add(mapInnerElement(inner)); + innerElement.children.add(mapInnerElement(project, context, inner)); } } @@ -596,7 +587,7 @@ public class AntDslXTextProjectHelper ex } if (eexpr instanceof EInnerElement) { EInnerElement elemExpr = (EInnerElement) eexpr; - return mapCallAntExpression(project, context, mapInnerElement(elemExpr)); + return mapCallAntExpression(project, context, mapInnerElement(project, context, elemExpr)); } if (eexpr instanceof EHexLiteralExpr) { EHexLiteralExpr eint = (EHexLiteralExpr) eexpr; Modified: ant/sandbox/antdsl/trunk/test/build.ant URL: http://svn.apache.org/viewvc/ant/sandbox/antdsl/trunk/test/build.ant?rev=1367311&r1=1367310&r2=1367311&view=diff ============================================================================== --- ant/sandbox/antdsl/trunk/test/build.ant (original) +++ ant/sandbox/antdsl/trunk/test/build.ant Mon Jul 30 21:22:07 2012 @@ -7,18 +7,18 @@ namespaces { { prop foo = "hello world!" - echo(message="${foo}") + echo(message = ${foo}) } -# Some documentation of the macro -macrodef mymacro(arg t = "mymacro") +# Some documentation of the function +function myfunction(local t = "myfunction") { - echo(message = "@{t}") + echo(message = ${t}) } -macrodef mymacro2(arg dest, implicit element source) +function myfunction2(local dest, implicit element source) { - copy(todir = "@{dest}" { + copy(todir = ${dest}, { source() }) } @@ -38,19 +38,19 @@ target notexecuted target build depends dep, notexecuted { - copy(file = "${basedir}/test/build.ant", tofile = "${basedir}/build/test/build.ant.copy") + copy(file = ${basedir} + "/test/build.ant", tofile = ${basedir} + "/build/test/build.ant.copy") // some comment - jar(file = "${basedir}/build/test/my.jar" { - fileset(dir="${basedir}/test", includes="*.ant") + jar(file = ${basedir} + "/build/test/my.jar" { + fileset(dir = ${basedir} + "/test", includes = "*.ant") }) - mymacro() - mymacro(t = "simple macro") + myfunction() + myfunction(t = "simple function") /* * Some multiline comment */ - if (available(file = "${basedir}/test/build.ant")) { - mymacro2(dest = "${basedir}/build/test/dest", { - fileset(dir = "${basedir}", includes="build.*") + if (available(file = ${basedir} + "/test/build.ant")) { + myfunction2(dest = ${basedir} + "/build/test/dest", { + fileset(dir = ${basedir}, includes = "build.*") }) } else { fail(message = "fail !") @@ -65,7 +65,8 @@ target build echo(message = "test encoding\nline") local test = "hello" + ' ' + "world !" - echo(message = "${test}") + echo(message = ${test}) local test2 = ((12345 + 6789) % 98765 == 12.4f) - echo(message = "${test2}") + echo(message = ${test2}) + echo(message = eval("${test2}")) }