diff options
-rw-r--r-- | src/clj/clojure/core.clj | 26 | ||||
-rw-r--r-- | src/script/run_tests.clj | 1 | ||||
-rw-r--r-- | test/clojure/test_clojure/load.clj | 21 | ||||
-rw-r--r-- | test/clojure/test_clojure/load/cyclic0.clj | 12 | ||||
-rw-r--r-- | test/clojure/test_clojure/load/cyclic1.clj | 12 | ||||
-rw-r--r-- | test/clojure/test_clojure/load/cyclic2.clj | 12 | ||||
-rw-r--r-- | test/clojure/test_clojure/load/cyclic3.clj | 12 | ||||
-rw-r--r-- | test/clojure/test_clojure/load/cyclic4.clj | 12 | ||||
-rw-r--r-- | test/clojure/test_clojure/load/cyclic5.clj | 12 | ||||
-rw-r--r-- | test/clojure/test_clojure/load/cyclic6.clj | 12 |
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)) |