summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen C. Gilardi <scgilardi@gmail.com>2010-09-30 05:28:41 +0000
committerStuart Halloway <stu@thinkrelevance.com>2011-01-28 10:10:09 -0500
commitf79efe17adbcca1991d66598f027fd61f36e1f70 (patch)
treeac5822d45aa027f5accaa07208693c09df21c966
parent76c1a58fc6d77151022a190d736327b1ade8ffa7 (diff)
restore detection of cyclic load dependencies
Signed-off-by: Stuart Halloway <stu@thinkrelevance.com>
-rw-r--r--src/clj/clojure/core.clj26
-rw-r--r--src/script/run_tests.clj1
-rw-r--r--test/clojure/test_clojure/load.clj21
-rw-r--r--test/clojure/test_clojure/load/cyclic0.clj12
-rw-r--r--test/clojure/test_clojure/load/cyclic1.clj12
-rw-r--r--test/clojure/test_clojure/load/cyclic2.clj12
-rw-r--r--test/clojure/test_clojure/load/cyclic3.clj12
-rw-r--r--test/clojure/test_clojure/load/cyclic4.clj12
-rw-r--r--test/clojure/test_clojure/load/cyclic5.clj12
-rw-r--r--test/clojure/test_clojure/load/cyclic6.clj12
10 files changed, 124 insertions, 8 deletions
diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj
index 6fa139dd..16186d47 100644
--- a/src/clj/clojure/core.clj
+++ b/src/clj/clojure/core.clj
@@ -5071,8 +5071,8 @@
(defonce ^:dynamic
^{:private true
- :doc "the set of paths currently being loaded by this thread"}
- *pending-paths* #{})
+ :doc "A stack of paths currently being loaded by this thread"}
+ *pending-paths* ())
(defonce ^:dynamic
^{:private true :doc
@@ -5206,8 +5206,20 @@
(doseq [arg args]
(apply load-lib prefix (prependss arg opts))))))))
-;; Public
+(defn- check-cyclic-dependency
+ "Detects and rejects non-trivial cyclic load dependencies. The
+ exception message shows the dependency chain with the cycle
+ highlighted. Ignores the trivial case of a file attempting to load
+ itself because that can occur when a gen-class'd class loads its
+ implementation."
+ [path]
+ (when (some #{path} (rest *pending-paths*))
+ (let [pending (map #(if (= % path) (str "[ " % " ]") %)
+ (cons path *pending-paths*))
+ chain (apply str (interpose "->" pending))]
+ (throw (Exception. (str "Cyclic load dependency: " chain))))))
+;; Public
(defn require
"Loads libs, skipping any that are already loaded. Each argument is
@@ -5300,12 +5312,10 @@
(when *loading-verbosely*
(printf "(clojure.core/load \"%s\")\n" path)
(flush))
-; (throw-if (*pending-paths* path)
-; "cannot load '%s' again while it is loading"
-; path)
- (when-not (*pending-paths* path)
+ (check-cyclic-dependency path)
+ (when-not (= path (first *pending-paths*))
(binding [*pending-paths* (conj *pending-paths* path)]
- (clojure.lang.RT/load (.substring path 1)))))))
+ (clojure.lang.RT/load (.substring path 1)))))))
(defn compile
"Compiles the namespace named by the symbol lib into a set of
diff --git a/src/script/run_tests.clj b/src/script/run_tests.clj
index 5b4ba07e..ef29cd43 100644
--- a/src/script/run_tests.clj
+++ b/src/script/run_tests.clj
@@ -23,6 +23,7 @@ clojure.test-clojure.java.javadoc
clojure.test-clojure.java.shell
clojure.test-clojure.java-interop
clojure.test-clojure.keywords
+clojure.test-clojure.load
clojure.test-clojure.logic
clojure.test-clojure.macros
clojure.test-clojure.main
diff --git a/test/clojure/test_clojure/load.clj b/test/clojure/test_clojure/load.clj
new file mode 100644
index 00000000..31f3c39e
--- /dev/null
+++ b/test/clojure/test_clojure/load.clj
@@ -0,0 +1,21 @@
+; Copyright (c) Rich Hickey. All rights reserved.
+; The use and distribution terms for this software are covered by the
+; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
+; which can be found in the file epl-v10.html at the root of this distribution.
+; By using this software in any fashion, you are agreeing to be bound by
+; the terms of this license.
+; You must not remove this notice, or any other, from this software.
+
+(ns clojure.test-clojure.load
+ (:use clojure.test))
+
+(deftest test-load
+ (testing "Should ignore self-loads without comment"
+ (is (nil? (require 'clojure.test-clojure.load.cyclic0))))
+ (testing "Should reject cyclic dependencies"
+ (testing "a->b->a"
+ (is (thrown-with-msg? Exception #".*Cyclic load dependency.*"
+ (require 'clojure.test-clojure.load.cyclic1))))
+ (testing "a->b->c->d->b"
+ (is (thrown-with-msg? Exception #".*Cyclic load dependency.*"
+ (require 'clojure.test-clojure.load.cyclic3))))))
diff --git a/test/clojure/test_clojure/load/cyclic0.clj b/test/clojure/test_clojure/load/cyclic0.clj
new file mode 100644
index 00000000..66a3cc10
--- /dev/null
+++ b/test/clojure/test_clojure/load/cyclic0.clj
@@ -0,0 +1,12 @@
+; Copyright (c) Rich Hickey. All rights reserved.
+; The use and distribution terms for this software are covered by the
+; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
+; which can be found in the file epl-v10.html at the root of this distribution.
+; By using this software in any fashion, you are agreeing to be bound by
+; the terms of this license.
+; You must not remove this notice, or any other, from this software.
+;
+; Author: Stephen C. Gilardi
+
+(ns clojure.test-clojure.load.cyclic0
+ (:require clojure.test-clojure.load.cyclic0))
diff --git a/test/clojure/test_clojure/load/cyclic1.clj b/test/clojure/test_clojure/load/cyclic1.clj
new file mode 100644
index 00000000..bf341f7b
--- /dev/null
+++ b/test/clojure/test_clojure/load/cyclic1.clj
@@ -0,0 +1,12 @@
+; Copyright (c) Rich Hickey. All rights reserved.
+; The use and distribution terms for this software are covered by the
+; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
+; which can be found in the file epl-v10.html at the root of this distribution.
+; By using this software in any fashion, you are agreeing to be bound by
+; the terms of this license.
+; You must not remove this notice, or any other, from this software.
+;
+; Author: Stephen C. Gilardi
+
+(ns clojure.test-clojure.load.cyclic1
+ (:require clojure.test-clojure.load.cyclic2))
diff --git a/test/clojure/test_clojure/load/cyclic2.clj b/test/clojure/test_clojure/load/cyclic2.clj
new file mode 100644
index 00000000..180a1620
--- /dev/null
+++ b/test/clojure/test_clojure/load/cyclic2.clj
@@ -0,0 +1,12 @@
+; Copyright (c) Rich Hickey. All rights reserved.
+; The use and distribution terms for this software are covered by the
+; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
+; which can be found in the file epl-v10.html at the root of this distribution.
+; By using this software in any fashion, you are agreeing to be bound by
+; the terms of this license.
+; You must not remove this notice, or any other, from this software.
+;
+; Author: Stephen C. Gilardi
+
+(ns clojure.test-clojure.load.cyclic2
+ (:require clojure.test-clojure.load.cyclic1))
diff --git a/test/clojure/test_clojure/load/cyclic3.clj b/test/clojure/test_clojure/load/cyclic3.clj
new file mode 100644
index 00000000..51a8e454
--- /dev/null
+++ b/test/clojure/test_clojure/load/cyclic3.clj
@@ -0,0 +1,12 @@
+; Copyright (c) Rich Hickey. All rights reserved.
+; The use and distribution terms for this software are covered by the
+; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
+; which can be found in the file epl-v10.html at the root of this distribution.
+; By using this software in any fashion, you are agreeing to be bound by
+; the terms of this license.
+; You must not remove this notice, or any other, from this software.
+;
+; Author: Stephen C. Gilardi
+
+(ns clojure.test-clojure.load.cyclic3
+ (:require clojure.test-clojure.load.cyclic4))
diff --git a/test/clojure/test_clojure/load/cyclic4.clj b/test/clojure/test_clojure/load/cyclic4.clj
new file mode 100644
index 00000000..d66a0fce
--- /dev/null
+++ b/test/clojure/test_clojure/load/cyclic4.clj
@@ -0,0 +1,12 @@
+; Copyright (c) Rich Hickey. All rights reserved.
+; The use and distribution terms for this software are covered by the
+; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
+; which can be found in the file epl-v10.html at the root of this distribution.
+; By using this software in any fashion, you are agreeing to be bound by
+; the terms of this license.
+; You must not remove this notice, or any other, from this software.
+;
+; Author: Stephen C. Gilardi
+
+(ns clojure.test-clojure.load.cyclic4
+ (:require clojure.test-clojure.load.cyclic5))
diff --git a/test/clojure/test_clojure/load/cyclic5.clj b/test/clojure/test_clojure/load/cyclic5.clj
new file mode 100644
index 00000000..e825b745
--- /dev/null
+++ b/test/clojure/test_clojure/load/cyclic5.clj
@@ -0,0 +1,12 @@
+; Copyright (c) Rich Hickey. All rights reserved.
+; The use and distribution terms for this software are covered by the
+; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
+; which can be found in the file epl-v10.html at the root of this distribution.
+; By using this software in any fashion, you are agreeing to be bound by
+; the terms of this license.
+; You must not remove this notice, or any other, from this software.
+;
+; Author: Stephen C. Gilardi
+
+(ns clojure.test-clojure.load.cyclic5
+ (:require clojure.test-clojure.load.cyclic6))
diff --git a/test/clojure/test_clojure/load/cyclic6.clj b/test/clojure/test_clojure/load/cyclic6.clj
new file mode 100644
index 00000000..d607f052
--- /dev/null
+++ b/test/clojure/test_clojure/load/cyclic6.clj
@@ -0,0 +1,12 @@
+; Copyright (c) Rich Hickey. All rights reserved.
+; The use and distribution terms for this software are covered by the
+; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
+; which can be found in the file epl-v10.html at the root of this distribution.
+; By using this software in any fashion, you are agreeing to be bound by
+; the terms of this license.
+; You must not remove this notice, or any other, from this software.
+;
+; Author: Stephen C. Gilardi
+
+(ns clojure.test-clojure.load.cyclic6
+ (:require clojure.test-clojure.load.cyclic4))