Skip to content

Commit 9de75f3

Browse files
mfikesdnolen
authored andcommitted
CLJS-2413: Port core.specs.alpha to ClojureScript
1 parent 47aab44 commit 9de75f3

File tree

2 files changed

+244
-0
lines changed

2 files changed

+244
-0
lines changed
Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
; Copyright (c) Rich Hickey. All rights reserved.
2+
; The use and distribution terms for this software are covered by the
3+
; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
4+
; which can be found in the file epl-v10.html at the root of this distribution.
5+
; By using this software in any fashion, you are agreeing to be bound by
6+
; the terms of this license.
7+
; You must not remove this notice, or any other, from this software.
8+
9+
(ns cljs.core.specs.alpha
10+
(:require [clojure.spec.alpha :as s]
11+
#?(:clj [cljs.core :as core]
12+
:cljs [cljs.core$macros :as core])))
13+
14+
;;;; destructure
15+
16+
(s/def ::local-name (s/and simple-symbol? #(not= '& %)))
17+
18+
(s/def ::binding-form
19+
(s/or :sym ::local-name
20+
:seq ::seq-binding-form
21+
:map ::map-binding-form))
22+
23+
;; sequential destructuring
24+
25+
(s/def ::seq-binding-form
26+
(s/and vector?
27+
(s/cat :elems (s/* ::binding-form)
28+
:rest (s/? (s/cat :amp #{'&} :form ::binding-form))
29+
:as (s/? (s/cat :as #{:as} :sym ::local-name)))))
30+
31+
;; map destructuring
32+
33+
(s/def ::keys (s/coll-of ident? :kind vector?))
34+
(s/def ::syms (s/coll-of symbol? :kind vector?))
35+
(s/def ::strs (s/coll-of simple-symbol? :kind vector?))
36+
(s/def ::or (s/map-of simple-symbol? any?))
37+
(s/def ::as ::local-name)
38+
39+
(s/def ::map-special-binding
40+
(s/keys :opt-un [::as ::or ::keys ::syms ::strs]))
41+
42+
(s/def ::map-binding (s/tuple ::binding-form any?))
43+
44+
(s/def ::ns-keys
45+
(s/tuple
46+
(s/and qualified-keyword? #(-> % name #{"keys" "syms"}))
47+
(s/coll-of simple-symbol? :kind vector?)))
48+
49+
(s/def ::map-bindings
50+
(s/every (s/or :mb ::map-binding
51+
:nsk ::ns-keys
52+
:msb (s/tuple #{:as :or :keys :syms :strs} any?)) :into {}))
53+
54+
(s/def ::map-binding-form (s/merge ::map-bindings ::map-special-binding))
55+
56+
;; bindings
57+
58+
(s/def ::binding (s/cat :binding ::binding-form :init-expr any?))
59+
(s/def ::bindings (s/and vector? (s/* ::binding)))
60+
61+
;; let, if-let, when-let
62+
63+
(s/fdef core/let
64+
:args (s/cat :bindings ::bindings
65+
:body (s/* any?)))
66+
67+
(s/fdef core/if-let
68+
:args (s/cat :bindings (s/and vector? ::binding)
69+
:then any?
70+
:else (s/? any?)))
71+
72+
(s/fdef core/when-let
73+
:args (s/cat :bindings (s/and vector? ::binding)
74+
:body (s/* any?)))
75+
76+
;; defn, defn-, fn
77+
78+
(s/def ::arg-list
79+
(s/and
80+
vector?
81+
(s/cat :args (s/* ::binding-form)
82+
:varargs (s/? (s/cat :amp #{'&} :form ::binding-form)))))
83+
84+
(s/def ::args+body
85+
(s/cat :args ::arg-list
86+
:body (s/alt :prepost+body (s/cat :prepost map?
87+
:body (s/+ any?))
88+
:body (s/* any?))))
89+
90+
(s/def ::defn-args
91+
(s/cat :name simple-symbol?
92+
:docstring (s/? string?)
93+
:meta (s/? map?)
94+
:bs (s/alt :arity-1 ::args+body
95+
:arity-n (s/cat :bodies (s/+ (s/spec ::args+body))
96+
:attr (s/? map?)))))
97+
98+
(s/fdef core/defn
99+
:args ::defn-args
100+
:ret any?)
101+
102+
(s/fdef core/defn-
103+
:args ::defn-args
104+
:ret any?)
105+
106+
(s/fdef core/fn
107+
:args (s/cat :name (s/? simple-symbol?)
108+
:bs (s/alt :arity-1 ::args+body
109+
:arity-n (s/+ (s/spec ::args+body))))
110+
:ret any?)
111+
112+
;;;; ns
113+
114+
(s/def ::exclude (s/coll-of simple-symbol?))
115+
(s/def ::only (s/coll-of simple-symbol?))
116+
(s/def ::rename (s/map-of simple-symbol? simple-symbol?))
117+
(s/def ::filters (s/keys* :opt-un [::exclude ::only ::rename]))
118+
119+
(s/def ::ns-refer-clojure
120+
(s/spec (s/cat :clause #{:refer-clojure}
121+
:filters ::filters)))
122+
123+
(s/def ::refer (s/coll-of simple-symbol?))
124+
(s/def ::refer-macros (s/coll-of simple-symbol?))
125+
(s/def ::include-macros #{true})
126+
127+
(s/def ::lib (s/or :sym simple-symbol?
128+
:str string?))
129+
130+
(s/def ::libspec
131+
(s/alt :lib ::lib
132+
:lib+opts (s/spec (s/cat :lib ::lib
133+
:options (s/keys* :opt-un [::as ::refer ::refer-macros ::include-macros])))))
134+
135+
(s/def ::macros-libspec
136+
(s/alt :lib simple-symbol?
137+
:lib+opts (s/spec (s/cat :lib simple-symbol?
138+
:options (s/keys* :opt-un [::as ::refer])))))
139+
140+
(s/def ::ns-require
141+
(s/spec (s/cat :clause #{:require}
142+
:body (s/+ (s/alt :libspec ::libspec
143+
:flag #{:reload :reload-all :verbose})))))
144+
145+
(s/def ::ns-require-macros
146+
(s/spec (s/cat :clause #{:require-macros}
147+
:body (s/+ (s/alt :libspec ::macros-libspec
148+
:flag #{:reload :reload-all :verbose})))))
149+
150+
(s/def ::package-list
151+
(s/spec
152+
(s/cat :package simple-symbol?
153+
:classes (s/* simple-symbol?))))
154+
155+
(s/def ::import-list
156+
(s/* (s/alt :class simple-symbol?
157+
:package-list ::package-list)))
158+
159+
(s/def ::ns-import
160+
(s/spec
161+
(s/cat :clause #{:import}
162+
:classes ::import-list)))
163+
164+
;; same as ::libspec, but also supports the ::filters options in the libspec
165+
(s/def ::use-libspec
166+
(s/alt :lib ::lib
167+
:lib+opts (s/spec (s/cat :lib ::lib
168+
:options (s/keys* :req-un [::only] :opt-un [::rename])))))
169+
170+
(s/def ::ns-use
171+
(s/spec (s/cat :clause #{:use}
172+
:libs (s/+ (s/alt :libspec ::use-libspec
173+
:flag #{:reload :reload-all :verbose})))))
174+
175+
;; same as ::libspec-macros, but also supports the ::filters options in the libspec
176+
(s/def ::use-macros-libspec
177+
(s/alt :lib simple-symbol?
178+
:lib+opts (s/spec (s/cat :lib simple-symbol?
179+
:options (s/keys* :req-un [::only] :opt-un [::rename])))))
180+
181+
(s/def ::ns-use-macros
182+
(s/spec (s/cat :clause #{:use-macros}
183+
:libs (s/+ (s/alt :libspec ::use-macros-libspec
184+
:flag #{:reload :reload-all :verbose})))))
185+
186+
187+
(s/def ::ns-clauses
188+
(s/* (s/alt :refer-clojure ::ns-refer-clojure
189+
:require ::ns-require
190+
:require-macros ::ns-require-macros
191+
:import ::ns-import
192+
:use ::ns-use
193+
:use-macros ::ns-use-macros)))
194+
195+
(s/def ::ns-form
196+
(s/cat :name simple-symbol?
197+
:docstring (s/? string?)
198+
:attr-map (s/? map?)
199+
:clauses ::ns-clauses))
200+
201+
#_(s/fdef clojure.core/ns
202+
:args ::ns-form)
203+
204+
(defmacro ^:private quotable
205+
"Returns a spec that accepts both the spec and a (quote ...) form of the spec"
206+
[spec]
207+
`(s/or :spec ~spec :quoted-spec (s/cat :quote #{'quote} :spec ~spec)))
208+
209+
(s/def ::quotable-import-list
210+
(s/* (s/alt :class (quotable simple-symbol?)
211+
:package-list (quotable ::package-list))))
212+
213+
(s/fdef core/import
214+
:args ::quotable-import-list)
215+
216+
(s/fdef core/require
217+
:args (s/+ (s/spec (s/cat :quote #{'quote}
218+
:spec (s/alt :libspec ::libspec
219+
:flag #{:reload :reload-all :verbose})))))
220+
221+
(s/fdef core/require-macros
222+
:args (s/+ (s/spec (s/cat :quote #{'quote}
223+
:spec (s/alt :libspec ::macros-libspec
224+
:flag #{:reload :reload-all :verbose})))))
225+
226+
(s/fdef core/use
227+
:args (s/+ (s/spec (s/cat :quote #{'quote}
228+
:spec (s/alt :libspec ::use-libspec
229+
:flag #{:reload :reload-all :verbose})))))
230+
231+
(s/fdef core/use-macros
232+
:args (s/+ (s/spec (s/cat :quote #{'quote}
233+
:spec (s/alt :libspec ::use-macros-libspec
234+
:flag #{:reload :reload-all :verbose})))))
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
; Copyright (c) Rich Hickey. All rights reserved.
2+
; The use and distribution terms for this software are covered by the
3+
; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
4+
; which can be found in the file epl-v10.html at the root of this distribution.
5+
; By using this software in any fashion, you are agreeing to be bound by
6+
; the terms of this license.
7+
; You must not remove this notice, or any other, from this software.
8+
9+
(ns cljs.core.specs.alpha
10+
(:require-macros [cljs.core.specs.alpha]))

0 commit comments

Comments
 (0)