Improve the resolution of the extension point to bind to: - first try the extension point which might be in the same file - then try the one in the root file Still some work to do: there might be intermediate file in the import stack which we would to resolve the name against, but the ProjectHelper doesn't hold the prefix stacking. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@1373326 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -88,6 +88,9 @@ Other changes: | |||
| and extension points. | |||
| Bugzilla Report 53549. | |||
| * Make extension point bindable to imported prefixed targets | |||
| Bugzilla Report 53550. | |||
| Changes from Ant 1.8.3 TO Ant 1.8.4 | |||
| =================================== | |||
| @@ -629,27 +629,52 @@ public class ProjectHelper { | |||
| public void resolveExtensionOfAttributes(Project project) | |||
| throws BuildException { | |||
| for (String[] extensionInfo : getExtensionStack()) { | |||
| String tgName = extensionInfo[0]; | |||
| String name = extensionInfo[1]; | |||
| String extPointName = extensionInfo[0]; | |||
| String targetName = extensionInfo[1]; | |||
| OnMissingExtensionPoint missingBehaviour = OnMissingExtensionPoint.valueOf(extensionInfo[2]); | |||
| // if the file has been included or imported, it may have a prefix | |||
| // we should consider when trying to resolve the target it is | |||
| // extending | |||
| String prefixAndSep = extensionInfo.length > 3 ? extensionInfo[3] : null; | |||
| // find the target we're extending | |||
| Hashtable projectTargets = project.getTargets(); | |||
| if (!projectTargets.containsKey(tgName)) { | |||
| String message = "can't add target " + name | |||
| + " to extension-point " + tgName | |||
| Target extPoint = null; | |||
| if (prefixAndSep == null) { | |||
| // no prefix - not from an imported/included build file | |||
| extPoint = (Target) projectTargets.get(extPointName); | |||
| } else { | |||
| // we have a prefix, which means we came from an include/import | |||
| // FIXME: here we handle no particular level of include. We try | |||
| // the fully prefixed name, and then the non-prefixed name. But | |||
| // there might be intermediate project in the import stack, | |||
| // which prefix should be tested before testing the non-prefix | |||
| // root name. | |||
| extPoint = (Target) projectTargets.get(prefixAndSep + extPointName); | |||
| if (extPoint == null) { | |||
| extPoint = (Target) projectTargets.get(extPointName); | |||
| } | |||
| } | |||
| // make sure we found a point to extend on | |||
| if (extPoint == null) { | |||
| String message = "can't add target " + targetName | |||
| + " to extension-point " + extPointName | |||
| + " because the extension-point is unknown."; | |||
| if (missingBehaviour == OnMissingExtensionPoint.FAIL) { | |||
| throw new BuildException(message); | |||
| } else if (missingBehaviour == OnMissingExtensionPoint.WARN) { | |||
| Target target = (Target) projectTargets.get(name); | |||
| project.log(target, "Warning: " + message, Project.MSG_WARN); | |||
| Target t = (Target) projectTargets.get(targetName); | |||
| project.log(t, "Warning: " + message, Project.MSG_WARN); | |||
| } | |||
| } else { | |||
| Target t = (Target) projectTargets.get(tgName); | |||
| if (!(t instanceof ExtensionPoint)) { | |||
| throw new BuildException("referenced target " + tgName | |||
| if (!(extPoint instanceof ExtensionPoint)) { | |||
| throw new BuildException("referenced target " + extPointName | |||
| + " is not an extension-point"); | |||
| } | |||
| t.addDependency(name); | |||
| extPoint.addDependency(targetName); | |||
| } | |||
| } | |||
| } | |||
| @@ -1011,17 +1011,24 @@ public class ProjectHelper2 extends ProjectHelper { | |||
| ProjectHelper helper = | |||
| (ProjectHelper) context.getProject(). | |||
| getReference(ProjectHelper.PROJECTHELPER_REFERENCE); | |||
| for (String tgName : Target.parseDepends(extensionPoint, name, "extensionOf")) { | |||
| if (isInIncludeMode()) { | |||
| tgName = prefix + sep + tgName; | |||
| } | |||
| for (String extPointName : Target.parseDepends(extensionPoint, name, "extensionOf")) { | |||
| if (extensionPointMissing == null) { | |||
| extensionPointMissing = OnMissingExtensionPoint.FAIL; | |||
| } | |||
| // defer extensionpoint resolution until the full | |||
| // import stack has been processed | |||
| helper.getExtensionStack().add(new String[] { | |||
| tgName, name, extensionPointMissing.name() }); | |||
| if (isInIncludeMode()) { | |||
| // if in include mode, provide prefix we're including by | |||
| // so that we can try and resolve extension point from | |||
| // the local file first | |||
| helper.getExtensionStack().add( | |||
| new String[] {extPointName, target.getName(), | |||
| extensionPointMissing.name(), prefix + sep}); | |||
| } else { | |||
| helper.getExtensionStack().add( | |||
| new String[] {extPointName, target.getName(), | |||
| extensionPointMissing.name()}); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,34 @@ | |||
| <?xml version="1.0"?> | |||
| <!-- | |||
| 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. | |||
| --> | |||
| <project xmlns:au="antlib:org.apache.ant.antunit" default="antunit"> | |||
| <import file="../../antunit-base.xml" /> | |||
| <!-- declare a target that depends on the extension point --> | |||
| <target name="compile" depends="all.compile" /> | |||
| <!-- declare our extension point --> | |||
| <extension-point name="all.compile" /> | |||
| <!-- import all our modules --> | |||
| <import file="module1.xml" as="module1" /> | |||
| <target name="testImport" depends="compile"> | |||
| <au:assertLogContains text="In module1 compile. Yay!" /> | |||
| </target> | |||
| </project> | |||
| @@ -0,0 +1,25 @@ | |||
| <?xml version="1.0"?> | |||
| <!-- | |||
| 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. | |||
| --> | |||
| <project name="module1"> | |||
| <!-- declare a target with the same name as one in the master --> | |||
| <target name="compile" extensionOf="all.compile"> | |||
| <echo message="In module1 compile. Yay!"/> | |||
| </target> | |||
| </project> | |||