Skip to content

Commit d17f911

Browse files
author
dnolen
committed
allow cljc files to supplied anywhere cljs files are (wip)
1 parent 3125bfc commit d17f911

File tree

7 files changed

+106
-86
lines changed

7 files changed

+106
-86
lines changed

src/clj/cljs/analyzer.clj

+29-23
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,10 @@
108108
(str "Use of undeclared Var " (:prefix info) "/" (:suffix info)))
109109

110110
(defmethod error-message :undeclared-ns
111-
[warning-type {:keys [ns-sym path] :as info}]
111+
[warning-type {:keys [ns-sym] :as info}]
112112
(str "No such namespace: " ns-sym
113-
(when path
114-
(str ", could not locate " path))))
113+
", could not locate " (util/ns->relpath ns-sym :cljc)
114+
" or " (util/ns->relpath ns-sym :cljs)))
115115

116116
(defmethod error-message :dynamic
117117
[warning-type info]
@@ -433,8 +433,8 @@
433433
(nil? (get-in @env/*compiler* [::namespaces ns-sym]))
434434
;; macros may refer to namespaces never explicitly required
435435
;; confirm that the library at least exists
436-
(nil? (io/resource (util/ns->relpath ns-sym))))
437-
(warning :undeclared-ns env {:ns-sym ns-sym :path (util/ns->relpath ns-sym)})))
436+
(nil? (util/ns->source ns-sym)))
437+
(warning :undeclared-ns env {:ns-sym ns-sym})))
438438

439439
(declare get-expander)
440440

@@ -1211,13 +1211,19 @@
12111211

12121212
(declare analyze-file)
12131213

1214-
(defn locate-src [relpath]
1215-
(or (io/resource relpath)
1216-
(let [root (:root @env/*compiler*)
1217-
root-path (when root (.getPath ^File root))
1218-
f (io/file root-path relpath)]
1219-
(when (and (.exists f) (.isFile f))
1220-
f))))
1214+
(defn locate-src
1215+
"Given a namespace return the corresponding ClojureScript (.cljc or .cljs)
1216+
resource on the classpath or file from the root of the build."
1217+
[ns]
1218+
(or (util/ns->source ns)
1219+
(let [rootp (when-let [root (:root @env/*compiler*)]
1220+
(.getPath ^File root))
1221+
cljcf (io/file rootp (util/ns->relpath ns :cljc))
1222+
cljsf (io/file rootp (util/ns->relpath ns :cljs))]
1223+
(if (and (.exists cljcf) (.isFile cljcf))
1224+
cljcf
1225+
(if (and (.exists cljsf) (.isFile cljsf))
1226+
cljsf)))))
12211227

12221228
(defn foreign-dep? [dep]
12231229
{:pre [(symbol? dep)]}
@@ -1237,13 +1243,11 @@
12371243
(when-not (or (not-empty (get-in compiler [::namespaces dep :defs]))
12381244
(contains? (:js-dependency-index compiler) (name dep))
12391245
(deps/find-classpath-lib dep))
1240-
(let [relpath (util/ns->relpath dep)
1241-
src (locate-src relpath)]
1242-
(if src
1243-
(analyze-file src opts)
1244-
(throw
1245-
(error env
1246-
(error-message :undeclared-ns {:ns-sym dep :path relpath})))))))))))
1246+
(if-let [src (locate-src dep)]
1247+
(analyze-file src opts)
1248+
(throw
1249+
(error env
1250+
(error-message :undeclared-ns {:ns-sym dep}))))))))))
12471251

12481252
(defn check-uses [uses env]
12491253
(doseq [[sym lib] uses]
@@ -1373,8 +1377,8 @@
13731377
(let [ns (if (sequential? form) (first form) form)
13741378
{:keys [use-macros require-macros]}
13751379
(or (get-in @env/*compiler* [::namespaces ns])
1376-
(when-let [res (io/resource (util/ns->relpath ns))]
1377-
(:ast (parse-ns res))))]
1380+
(when-let [res (util/ns->source ns)]
1381+
(:ast (parse-ns res))))]
13781382
(or (some #{ns} (vals use-macros))
13791383
(some #{ns} (vals require-macros))))))
13801384

@@ -2023,7 +2027,7 @@
20232027
([src dest opts]
20242028
(env/ensure
20252029
(let [src (if (symbol? src)
2026-
(io/resource (util/ns->relpath src))
2030+
(util/ns->source src)
20272031
src)
20282032
compiler-env @env/*compiler*
20292033
[ijs compiler-env']
@@ -2085,7 +2089,9 @@
20852089
(= (:ns ns-info) 'cljs.core)
20862090
(io/resource "cljs/core.cljs.cache.aot.edn"))]
20872091
core-cache
2088-
(io/file (str (util/to-target-file output-dir ns-info "cljs") ".cache.edn")))))
2092+
(let [target-file (util/to-target-file output-dir ns-info
2093+
(util/ext (:source-file ns-info)))]
2094+
(io/file (str target-file ".cache.edn"))))))
20892095

20902096
(defn requires-analysis?
20912097
([src] (requires-analysis? src "out"))

src/clj/cljs/closure.clj

+31-21
Original file line numberDiff line numberDiff line change
@@ -479,26 +479,35 @@
479479
(-compile uri (merge opts {:output-file js-file}))))
480480

481481
(defn cljs-source-for-namespace
482-
"Returns a map containing :relative-path, :uri referring to the resource that
483-
should contain the source for the given namespace name."
482+
"Given a namespace return the corresponding source with either a .cljc or
483+
.cljs extension."
484484
[ns]
485-
(as-> (munge ns) %
486-
(string/replace % \. \/)
487-
(str % ".cljs")
488-
{:relative-path % :uri (io/resource %)}))
485+
(let [path (-> (munge ns) (string/replace \. \/))
486+
relpath (str path ".cljc")]
487+
(if-let [res (io/resource relpath)]
488+
{:relative-path relpath :uri res}
489+
(let [relpath (str path ".cljs")]
490+
(if-let [res (io/resource relpath)]
491+
{:relative-path relpath :uri res})))))
489492

490493
(defn source-for-namespace
494+
"Given a namespace and compilation environment return the relative path and
495+
uri of the corresponding source regardless of the source language extension:
496+
.cljc, .cljs, .js"
491497
[ns compiler-env]
492498
(let [ns-str (str (comp/munge ns {}))
493499
path (string/replace ns-str \. \/)
494-
relpath (str path ".cljs")]
495-
(if-let [cljs-res (io/resource relpath)]
496-
{:relative-path relpath :uri cljs-res}
497-
(let [relpath (:file (get-in @compiler-env [:js-dependency-index ns-str]))]
498-
(if-let [js-res (and relpath (io/resource relpath))]
499-
{:relative-path relpath :uri js-res}
500-
(throw
501-
(IllegalArgumentException. (str "Namespace " ns " does not exist"))))))))
500+
relpath (str path ".cljc")]
501+
(if-let [cljc-res (io/resource relpath)]
502+
{:relative-path relpath :uri cljc-res}
503+
(let [relpath (str path ".cljs")]
504+
(if-let [cljs-res (io/resource relpath)]
505+
{:relative-path relpath :uri cljs-res}
506+
(let [relpath (:file (get-in @compiler-env [:js-dependency-index ns-str]))]
507+
(if-let [js-res (and relpath (io/resource relpath))]
508+
{:relative-path relpath :uri js-res}
509+
(throw
510+
(IllegalArgumentException. (str "Namespace " ns " does not exist"))))))))))
502511

503512
(defn cljs-dependencies
504513
"Given a list of all required namespaces, return a list of
@@ -814,7 +823,7 @@ should contain the source for the given namespace name."
814823
(if (and provides source-url)
815824
(assoc relpaths
816825
(.getPath ^URL source-url)
817-
(util/ns->relpath (first provides)))
826+
(util/ns->relpath (first provides) (util/ext source-url)))
818827
relpaths))
819828
(if-let [url (:url source)]
820829
(let [path (.getPath ^URL url)]
@@ -1156,9 +1165,9 @@ should contain the source for the given namespace name."
11561165
(write-javascript opts js)
11571166
;; always copy original ClojureScript sources to the output directory
11581167
;; when source maps enabled
1159-
(let [out-file (if-let [ns (and (:source-map opts) (first (:provides js)))]
1168+
(let [out-file (when-let [ns (and (:source-map opts) (first (:provides js)))]
11601169
(io/file (io/file (util/output-directory opts))
1161-
(util/ns->relpath ns)))
1170+
(util/ns->relpath ns (util/ext (:source-url js)))))
11621171
source-url (:source-url js)]
11631172
(when (and out-file source-url
11641173
(or (not (.exists ^File out-file))
@@ -1551,7 +1560,8 @@ should contain the source for the given namespace name."
15511560
(some
15521561
(fn [^WatchEvent e]
15531562
(let [fstr (.. e context toString)]
1554-
(and (or (. fstr (endsWith "cljs"))
1563+
(and (or (. fstr (endsWith "cljc"))
1564+
(. fstr (endsWith "cljs"))
15551565
(. fstr (endsWith "js")))
15561566
(not (. fstr (startsWith ".#"))))))
15571567
(seq (.pollEvents key))))
@@ -1596,9 +1606,9 @@ should contain the source for the given namespace name."
15961606
([src {:keys [wrap all-provides] :as options}]
15971607
(let [goog-ns
15981608
(case (util/ext src)
1599-
"cljs" (comp/munge (:ns (ana/parse-ns src)))
1600-
"js" (cond-> (:provides (parse-js-ns src))
1601-
(not all-provides) first)
1609+
("cljc" "cljs") (comp/munge (:ns (ana/parse-ns src)))
1610+
"js" (cond-> (:provides (parse-js-ns src))
1611+
(not all-provides) first)
16021612
(throw
16031613
(IllegalArgumentException.
16041614
(str "Can't create goog.require expression for " src))))]

src/clj/cljs/compiler.clj

+21-8
Original file line numberDiff line numberDiff line change
@@ -933,11 +933,22 @@
933933
(emits (interleave (concat segs (repeat nil))
934934
(concat args [nil]))))))
935935

936+
;; TODO: unify renaming helpers - this one was hard to find - David
937+
936938
(defn rename-to-js
937939
"Change the file extension from .cljs to .js. Takes a File or a
938940
String. Always returns a String."
939-
[file-str]
940-
(clojure.string/replace file-str #"\.cljs$" ".js"))
941+
[^String file-str]
942+
(cond
943+
(.endsWith file-str ".cljc")
944+
(clojure.string/replace file-str #"\.cljc$" ".js")
945+
946+
(.endsWith file-str ".cljs")
947+
(clojure.string/replace file-str #"\.cljs$" ".js")
948+
949+
:else
950+
(throw (IllegalArgumentException.
951+
(str "Invalid source file extension " file-str)))))
941952

942953
(defn with-core-cljs
943954
"Ensure that core.cljs has been loaded."
@@ -1125,13 +1136,15 @@
11251136
(throw (java.io.FileNotFoundException. (str "The file " src " does not exist."))))))))
11261137

11271138
(defn cljs-files-in
1128-
"Return a sequence of all .cljs files in the given directory."
1139+
"Return a sequence of all .cljc and .cljs files in the given directory."
11291140
[dir]
1130-
(filter #(let [name (.getName ^File %)]
1131-
(and (.endsWith name ".cljs")
1132-
(not= \. (first name))
1133-
(not (contains? cljs-reserved-file-names name))))
1134-
(file-seq dir)))
1141+
(filter
1142+
#(let [name (.getName ^File %)]
1143+
(and (or (.endsWith name ".cljc")
1144+
(.endsWith name ".cljs"))
1145+
(not= \. (first name))
1146+
(not (contains? cljs-reserved-file-names name))))
1147+
(file-seq dir)))
11351148

11361149
(defn compile-root
11371150
"Looks recursively in src-dir for .cljs files and compiles them to

src/clj/cljs/repl.clj

+11-6
Original file line numberDiff line numberDiff line change
@@ -202,12 +202,17 @@
202202

203203
(defn ^File js-src->cljs-src
204204
"Map a JavaScript output file back to the original ClojureScript source
205-
file."
205+
file (.cljc or .cljs)."
206206
[f]
207207
(let [f (io/file f)
208208
dir (.getParentFile f)
209-
name (.getName f)]
210-
(io/file dir (string/replace name ".js" ".cljs"))))
209+
base-name (string/replace (.getName f) ".js" "")
210+
cljcf (io/file dir (str base-name ".cljc"))]
211+
(if (.exists cljcf)
212+
cljcf
213+
(let [cljsf (io/file dir (str base-name ".cljs"))]
214+
(if (.exists cljsf)
215+
cljsf)))))
211216

212217
(defn read-source-map
213218
"Return the source map for the JavaScript source file."
@@ -298,8 +303,8 @@
298303
source-file
299304
(io/file rfile)))
300305
(str (System/getProperty "user.dir") File/separator) ""))
301-
url (or (and ns-info (io/resource (util/ns->relpath ns)))
302-
(and file (io/resource file)))]
306+
url (or (and ns-info (util/ns->source ns))
307+
(and file (io/resource file)))]
303308
(merge
304309
{:function name'
305310
:call call
@@ -494,7 +499,7 @@
494499
(when-let [ns (and (:source-map opts) (first (:provides compiled)))]
495500
(spit
496501
(io/file (io/file (util/output-directory opts))
497-
(util/ns->relpath ns))
502+
(util/ns->relpath ns (util/ext (:source-url compiled))))
498503
(slurp src)))
499504
;; need to load dependencies first
500505
(load-dependencies repl-env (:requires compiled) opts)

src/clj/cljs/repl/browser.clj

+2
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@
9090
".html" "text/html"
9191
".jpg" "image/jpeg"
9292
".js" "text/javascript"
93+
".cljc" "text/x-clojure"
9394
".cljs" "text/x-clojure"
9495
".map" "application/json"
9596
".png" "image/png"
@@ -107,6 +108,7 @@
107108
(or
108109
(= path "/")
109110
(.endsWith path ".js")
111+
(.endsWith path ".cljc")
110112
(.endsWith path ".cljs")
111113
(.endsWith path ".map")
112114
(.endsWith path ".html")

src/clj/cljs/repl/nashorn.clj

-26
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,6 @@
2525
;;
2626
;; Nashorn's load() function docs:
2727
;; http://docs.oracle.com/javase/8/docs/technotes/guides/scripting/nashorn/shell.html
28-
;;
29-
;; Some functions are copied from: https://github.com/bodil/cljs-nashorn and the node.js repl code
30-
31-
;;
32-
;; ** Usage from Leiningen:
33-
;;
34-
;; Create a file init_repl_test.clj containing (adjust :output-dir to your cljsbuild settings):
3528

3629
(comment
3730
(ns init-repl-test
@@ -43,25 +36,6 @@
4336
:cache-analysis true)
4437
)
4538

46-
;;
47-
;; Invoke it with:
48-
;; lein trampoline run -m clojure.main src-clj/init_repl_test.clj
49-
50-
;;
51-
;; ** Usage from nrepl / piggieback, execute the following at the nrepl prompt:
52-
;; (adjust :output-dir to your cljsbuild settings)
53-
54-
(comment
55-
(ns init-repl-piggieback
56-
(:require [cljs.repl.nashorn]
57-
[cemerick.piggieback]))
58-
59-
(cemerick.piggieback/cljs-repl
60-
:repl-env (cljs.repl.nashorn/repl-env)
61-
:output-dir "resources/public/compiled"
62-
:cache-analysis true)
63-
)
64-
6539
;; Implementation
6640

6741
(defn create-engine

src/clj/cljs/util.clj

+12-2
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,18 @@
4848
(defn munge-path [ss]
4949
(clojure.lang.Compiler/munge (str ss)))
5050

51-
(defn ns->relpath [s]
52-
(str (string/replace (munge-path s) \. \/) ".cljs"))
51+
(defn ns->relpath
52+
"Given a namespace as a symbol return the relative path. May optionally
53+
provide the file extension, defaults to :cljs."
54+
([ns] (ns->relpath ns :cljs))
55+
([ns ext]
56+
(str (string/replace (munge-path ns) \. \/) "." (name ext))))
57+
58+
(defn ns->source
59+
"Given a namespace as a symbol return the corresponding resource if it exists."
60+
[ns]
61+
(or (io/resource (ns->relpath ns :cljc))
62+
(io/resource (ns->relpath ns :cljs))))
5363

5464
(defn path-seq
5565
[file-str]

0 commit comments

Comments
 (0)