|
5071 | 5071 |
|
5072 | 5072 | (defonce ^:dynamic |
5073 | 5073 | ^{:private true |
5074 | | - :doc "the set of paths currently being loaded by this thread"} |
5075 | | - *pending-paths* #{}) |
| 5074 | + :doc "A stack of paths currently being loaded by this thread"} |
| 5075 | + *pending-paths* ()) |
5076 | 5076 |
|
5077 | 5077 | (defonce ^:dynamic |
5078 | 5078 | ^{:private true :doc |
|
5206 | 5206 | (doseq [arg args] |
5207 | 5207 | (apply load-lib prefix (prependss arg opts)))))))) |
5208 | 5208 |
|
5209 | | -;; Public |
| 5209 | +(defn- check-cyclic-dependency |
| 5210 | + "Detects and rejects non-trivial cyclic load dependencies. The |
| 5211 | + exception message shows the dependency chain with the cycle |
| 5212 | + highlighted. Ignores the trivial case of a file attempting to load |
| 5213 | + itself because that can occur when a gen-class'd class loads its |
| 5214 | + implementation." |
| 5215 | + [path] |
| 5216 | + (when (some #{path} (rest *pending-paths*)) |
| 5217 | + (let [pending (map #(if (= % path) (str "[ " % " ]") %) |
| 5218 | + (cons path *pending-paths*)) |
| 5219 | + chain (apply str (interpose "->" pending))] |
| 5220 | + (throw (Exception. (str "Cyclic load dependency: " chain)))))) |
5210 | 5221 |
|
| 5222 | +;; Public |
5211 | 5223 |
|
5212 | 5224 | (defn require |
5213 | 5225 | "Loads libs, skipping any that are already loaded. Each argument is |
|
5300 | 5312 | (when *loading-verbosely* |
5301 | 5313 | (printf "(clojure.core/load \"%s\")\n" path) |
5302 | 5314 | (flush)) |
5303 | | -; (throw-if (*pending-paths* path) |
5304 | | -; "cannot load '%s' again while it is loading" |
5305 | | -; path) |
5306 | | - (when-not (*pending-paths* path) |
| 5315 | + (check-cyclic-dependency path) |
| 5316 | + (when-not (= path (first *pending-paths*)) |
5307 | 5317 | (binding [*pending-paths* (conj *pending-paths* path)] |
5308 | | - (clojure.lang.RT/load (.substring path 1))))))) |
| 5318 | + (clojure.lang.RT/load (.substring path 1))))))) |
5309 | 5319 |
|
5310 | 5320 | (defn compile |
5311 | 5321 | "Compiles the namespace named by the symbol lib into a set of |
|
0 commit comments