git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@275186 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -162,4 +162,11 @@ | |||||
| <echo>test2 is ${test2}</echo> | <echo>test2 is ${test2}</echo> | ||||
| <echo>test1.x is ${test1.x}</echo> | <echo>test1.x is ${test1.x}</echo> | ||||
| </target> | </target> | ||||
| <target name="infinite-loop-via-depends"> | |||||
| <antcall target="dependent"/> | |||||
| </target> | |||||
| <target name="middleman" depends="infinite-loop-via-depends"/> | |||||
| <target name="dependent" depends="middleman"/> | |||||
| </project> | </project> | ||||
| @@ -1589,8 +1589,7 @@ public class Project { | |||||
| * Must not be <code>null</code>. | * Must not be <code>null</code>. | ||||
| * @param targets A map of names to targets (String to Target). | * @param targets A map of names to targets (String to Target). | ||||
| * Must not be <code>null</code>. | * Must not be <code>null</code>. | ||||
| * @return a vector of strings with the names of the targets in | |||||
| * sorted order. | |||||
| * @return a vector of Target objects in sorted order. | |||||
| * @exception BuildException if there is a cyclic dependency among the | * @exception BuildException if there is a cyclic dependency among the | ||||
| * targets, or if a named target does not exist. | * targets, or if a named target does not exist. | ||||
| */ | */ | ||||
| @@ -2096,4 +2095,4 @@ public class Project { | |||||
| // is private/protected. | // is private/protected. | ||||
| } | } | ||||
| } | } | ||||
| } | |||||
| } | |||||
| @@ -255,6 +255,22 @@ public class Target implements TaskContainer { | |||||
| } | } | ||||
| } | } | ||||
| /** | |||||
| * Does this target depend on the named target? | |||||
| * | |||||
| * @since Ant 1.6 | |||||
| */ | |||||
| public boolean dependsOn(String other) { | |||||
| if (getProject() != null) { | |||||
| List l = getProject().topoSort(getName(), | |||||
| getProject().getTargets()); | |||||
| int myIdx = l.indexOf(this); | |||||
| int otherIdx = l.indexOf(getProject().getTargets().get(other)); | |||||
| return myIdx >= otherIdx; | |||||
| } | |||||
| return false; | |||||
| } | |||||
| /** | /** | ||||
| * Sets the "if" condition to test on execution. This is the | * Sets the "if" condition to test on execution. This is the | ||||
| * name of a property to test for existence - if the property | * name of a property to test for existence - if the property | ||||
| @@ -68,6 +68,7 @@ import org.apache.tools.ant.DefaultLogger; | |||||
| import org.apache.tools.ant.Project; | import org.apache.tools.ant.Project; | ||||
| import org.apache.tools.ant.ProjectComponent; | import org.apache.tools.ant.ProjectComponent; | ||||
| import org.apache.tools.ant.ProjectHelper; | import org.apache.tools.ant.ProjectHelper; | ||||
| import org.apache.tools.ant.Target; | |||||
| import org.apache.tools.ant.Task; | import org.apache.tools.ant.Task; | ||||
| import org.apache.tools.ant.types.PropertySet; | import org.apache.tools.ant.types.PropertySet; | ||||
| import org.apache.tools.ant.util.FileUtils; | import org.apache.tools.ant.util.FileUtils; | ||||
| @@ -363,7 +364,10 @@ public class Ant extends Task { | |||||
| if (newProject.getProperty("ant.file") | if (newProject.getProperty("ant.file") | ||||
| .equals(getProject().getProperty("ant.file")) | .equals(getProject().getProperty("ant.file")) | ||||
| && getOwningTarget() != null) { | && getOwningTarget() != null) { | ||||
| if (getOwningTarget().getName().equals("")) { | |||||
| String owningTargetName = getOwningTarget().getName(); | |||||
| if (owningTargetName.equals("")) { | |||||
| if (getTaskName().equals("antcall")) { | if (getTaskName().equals("antcall")) { | ||||
| throw new BuildException("antcall must not be used at" | throw new BuildException("antcall must not be used at" | ||||
| + " the top level."); | + " the top level."); | ||||
| @@ -372,9 +376,20 @@ public class Ant extends Task { | |||||
| + " top level must not invoke" | + " top level must not invoke" | ||||
| + " its own build file."); | + " its own build file."); | ||||
| } | } | ||||
| } else if (getOwningTarget().getName().equals(target)) { | |||||
| } else if (owningTargetName.equals(target)) { | |||||
| throw new BuildException(getTaskName() + " task calling " | throw new BuildException(getTaskName() + " task calling " | ||||
| + "its own parent target."); | + "its own parent target."); | ||||
| } else { | |||||
| Target other = | |||||
| (Target) getProject().getTargets().get(target); | |||||
| if (other != null && other.dependsOn(owningTargetName)) { | |||||
| throw new BuildException(getTaskName() | |||||
| + " task calling a target" | |||||
| + " that depends on" | |||||
| + " its parent target \'" | |||||
| + owningTargetName | |||||
| + "\'."); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -302,6 +302,10 @@ public class AntTest extends BuildFileTest { | |||||
| assertTrue(getLog().indexOf("test1.x is 1") > -1); | assertTrue(getLog().indexOf("test1.x is 1") > -1); | ||||
| } | } | ||||
| public void testInfiniteLoopViaDepends() { | |||||
| expectBuildException("infinite-loop-via-depends", "recursive call"); | |||||
| } | |||||
| private class BasedirChecker implements BuildListener { | private class BasedirChecker implements BuildListener { | ||||
| private String[] expectedBasedirs; | private String[] expectedBasedirs; | ||||
| private int calls = 0; | private int calls = 0; | ||||