Skip to content

Commit 9a07ad4

Browse files
author
Stuart Sierra
committed
Port dependency, parse, and track to .cljc
Affects these namespaces: - clojure.tools.namespace.dependency - clojure.tools.namespace.parse - clojure.tools.namespace.track With minor changes, these files are platform-neutral. c.t.n.dependency is a general-purpose library which has many applications outside of tools.namespace. The uses for c.t.n.parse and c.t.n.track in ClojureScript are less apparent, but they are easy to port. Perhaps by porting other namespaces it will be possible in the future to have a version of c.t.n.repl that works on non-JVM platforms.
1 parent 8251495 commit 9a07ad4

File tree

4 files changed

+56
-38
lines changed

4 files changed

+56
-38
lines changed

pom.xml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,20 @@
1010
<version>0.1.2</version>
1111
</parent>
1212

13+
<dependencies>
14+
<dependency>
15+
<groupId>org.clojure</groupId>
16+
<artifactId>clojure</artifactId>
17+
<version>1.7.0</version>
18+
<scope>provided</scope>
19+
</dependency>
20+
<dependency>
21+
<groupId>org.clojure</groupId>
22+
<artifactId>tools.reader</artifactId>
23+
<version>0.10.0-alpha1</version>
24+
</dependency>
25+
</dependencies>
26+
1327
<properties>
1428
<clojure.warnOnReflection>true</clojure.warnOnReflection>
1529
</properties>
@@ -26,4 +40,5 @@
2640
<url>git@github.com:clojure/tools.namespace.git</url>
2741
<tag>HEAD</tag>
2842
</scm>
43+
2944
</project>

src/main/clojure/clojure/tools/namespace/dependency.clj renamed to src/main/clojure/clojure/tools/namespace/dependency.cljc

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,13 +142,16 @@
142142
(remove-node g' node)
143143
(clojure.set/union (set more) (set add)))))))
144144

145+
(def ^:private max-number
146+
#?(:clj Long/MAX_VALUE
147+
:cljs js/Number.MAX_VALUE))
148+
145149
(defn topo-comparator
146150
"Returns a comparator fn which produces a topological sort based on
147151
the dependencies in graph. Nodes not present in the graph will sort
148152
after nodes in the graph."
149153
[graph]
150154
(let [pos (zipmap (topo-sort graph) (range))]
151155
(fn [a b]
152-
(compare (get pos a Long/MAX_VALUE)
153-
(get pos b Long/MAX_VALUE)))))
154-
156+
(compare (get pos a max-number)
157+
(get pos b max-number)))))

src/main/clojure/clojure/tools/namespace/parse.clj renamed to src/main/clojure/clojure/tools/namespace/parse.cljc

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,9 @@
1010
:doc "Parse Clojure namespace (ns) declarations and extract
1111
dependencies."}
1212
clojure.tools.namespace.parse
13-
(:require [clojure.set :as set]))
14-
15-
(defn- read-clj
16-
"Calls clojure.core/read. If reader conditionals are
17-
supported (Clojure 1.7) then adds options {:read-cond :allow}."
18-
[rdr]
19-
(if (resolve 'clojure.core/reader-conditional?)
20-
(read {:read-cond :allow} rdr)
21-
(read rdr)))
22-
23-
(defn- force-errors
24-
"Forces reader errors to be thrown immediately. Some versions of
25-
Clojure accept invalid forms in the reader and only throw an
26-
exception when they are printed.
27-
See http://dev.clojure.org/jira/browse/TNS-1"
28-
[form]
29-
(str form) ; str forces errors
30-
form)
13+
(:require #?(:clj [clojure.tools.reader :as reader]
14+
:cljs [cljs.tools.reader :as reader])
15+
[clojure.set :as set]))
3116

3217
(defn comment?
3318
"Returns true if form is a (comment ...)"
@@ -40,21 +25,23 @@
4025
(and (list? form) (= 'ns (first form))))
4126

4227
(defn read-ns-decl
43-
"Attempts to read a (ns ...) declaration from a
44-
java.io.PushbackReader, and returns the unevaluated form. Returns
45-
the first top-level ns form found. Returns nil if read fails or if a
46-
ns declaration cannot be found. Note that read can execute code
47-
(controlled by *read-eval*), and as such should be used only with
48-
trusted sources."
49-
[rdr]
50-
{:pre [(instance? java.io.PushbackReader rdr)]}
51-
(try
28+
"Attempts to read a (ns ...) declaration from a reader, and returns
29+
the unevaluated form. Returns the first top-level ns form found.
30+
Returns nil if a ns declaration cannot be found. Note that read can
31+
execute code (controlled by tools.reader/*read-eval*), and as such
32+
should be used only with trusted sources. read-opts is passed
33+
through to tools.reader/read, defaults to allow conditional reader
34+
expressions with :clj"
35+
([rdr]
36+
(read-ns-decl rdr {:read-cond :allow
37+
:features #{:clj}}))
38+
([rdr read-opts]
5239
(loop []
53-
(let [form (force-errors (read-clj rdr))]
54-
(if (ns-decl? form)
55-
form
56-
(recur))))
57-
(catch Exception e nil)))
40+
(let [form (reader/read (assoc read-opts :eof ::eof) rdr)]
41+
(cond
42+
(ns-decl? form) form
43+
(= ::eof form) nil
44+
:else (recur))))))
5845

5946
;;; Parsing dependencies
6047

@@ -91,12 +78,25 @@
9178
(keyword? form) ; Some people write (:require ... :reload-all)
9279
nil
9380
:else
94-
(throw (IllegalArgumentException.
95-
(pr-str "Unparsable namespace form:" form)))))
81+
(throw (ex-info "Unparsable namespace form"
82+
{:reason ::unparsable-ns-form
83+
:form form}))))
84+
85+
(def ^:private ns-clause-head-names
86+
"Set of symbol/keyword names which can appear as the head of a
87+
clause in the ns form."
88+
#{"use" "require" "use-macros" "require-macros"})
89+
90+
(def ^:private ns-clause-heads
91+
"Set of all symbols and keywords which can appear at the head of a
92+
dependency clause in the ns form."
93+
(set (mapcat (fn [name] (list (keyword name)
94+
(symbol name)))
95+
ns-clause-head-names)))
9696

9797
(defn- deps-from-ns-form [form]
9898
(when (and (sequential? form) ; should be list but sometimes is not
99-
(contains? #{:use :require 'use 'require} (first form)))
99+
(contains? ns-clause-heads (first form)))
100100
(mapcat #(deps-from-libspec nil %) (rest form))))
101101

102102
(defn deps-from-ns-decl

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy