Skip to content

Commit 8c9cde9

Browse files
anmonteirodnolen
authored andcommitted
CLJS-1925: Use of undeclared Var cljs.user/RegExp when extending protocol for RegExp
This is a regression caused by an improper fix to CLJS-1607. This patch reverts the fix in CLJS-1607, adds a test for it that doesn't rely on internal details, and properly fixes the issue by not `dissoc`ing locals from env in `cljs.core/resolve-var`, because `specify!` creates a local binding via `let`.
1 parent b373fe9 commit 8c9cde9

File tree

3 files changed

+58
-38
lines changed

3 files changed

+58
-38
lines changed

src/main/clojure/cljs/compiler.cljc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -941,7 +941,7 @@
941941
;; ignore new type hints for now - David
942942
(and (not (set? tag))
943943
(not ('#{any clj clj-or-nil clj-nil number string boolean function object array} tag))
944-
(when-let [ps (:protocols (ana/resolve-existing-var env (symbol (name tag))))]
944+
(when-let [ps (:protocols (ana/resolve-existing-var env tag))]
945945
(ps protocol)))))))
946946
opt-not? (and (= (:name info) 'cljs.core/not)
947947
(= (ana/infer-tag env (first (:args expr))) 'boolean))

src/main/clojure/cljs/core.cljc

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1351,9 +1351,7 @@
13511351
(cljs.analyzer/warning :undeclared-protocol-symbol env {:protocol p})))))
13521352

13531353
(core/defn- resolve-var [env sym]
1354-
(core/let [ret (core/-> (dissoc env :locals)
1355-
(cljs.analyzer/resolve-var sym)
1356-
:name)]
1354+
(core/let [ret (:name (cljs.analyzer/resolve-var env sym))]
13571355
(core/assert ret (core/str "Can't resolve: " sym))
13581356
ret))
13591357

src/test/clojure/cljs/compiler_tests.clj

Lines changed: 56 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -155,44 +155,66 @@
155155
`(cljs.user/foo ~(tags/->JSValue []))
156156
'(cljs.user/foo (make-array 0))))))
157157

158-
;; CLJS-1607
159-
;; Commented out this test - too hard coded to unnecessary details - David
160-
161-
#_(deftest test-cljs-1607
162-
(let [define-Foo #(assoc-in % [::ana/namespaces 'cljs.user :defs 'Foo]
163-
{:ns 'cljs.user
164-
:name 'cljs.user/Foo
165-
:protocol-symbol true
166-
:protocol-info {:methods '{foo [[this]]}}
167-
:protocol 'cljs.user/Foo})
168-
define-foo #(assoc-in % [::ana/namespaces 'cljs.user :defs 'foo]
169-
{:ns 'cljs.user
170-
:name 'cljs.user/foo
171-
:fn-var true
172-
:method-params '([x])
173-
:protocol 'cljs.user/Foo})
174-
aenv-with-foo (-> aenv define-foo define-Foo)
175-
cenv-with-foo (-> @cenv define-foo define-Foo)]
176-
(binding [ana/*cljs-static-fns* true]
177-
(are [form]
178-
(empty?
179-
(capture-warnings
180-
(env/with-compiler-env (atom cenv-with-foo)
181-
(with-out-str
182-
(comp/emit
183-
(ana/analyze aenv-with-foo form))))))
184-
'(specify! []
185-
cljs.user/Foo
186-
(cljs.user/foo [this]
187-
:none)
188-
Object
189-
(bar [this]
190-
(cljs.user/foo this)))))))
191-
192158
(deftest test-cljs-1643
193159
(is (thrown-with-msg? Exception #"is not a valid ClojureScript constant."
194160
(comp/emit-constant clojure.core/inc))))
195161

162+
(def test-cljs-1925-code
163+
'(do
164+
(defprotocol X
165+
(x [x]))
166+
167+
(defprotocol Y
168+
(y [y]))
169+
170+
(extend-protocol X
171+
js/RegExp
172+
(x [x]
173+
(y x)))
174+
175+
(extend-protocol Y
176+
js/RegExp
177+
(y [y]
178+
:y))))
179+
180+
(def specify-test-code
181+
'(do
182+
(defprotocol IBug
183+
(bug [this other] "A sample protocol"))
184+
185+
(defn MyBug [])
186+
(specify! (.-prototype MyBug)
187+
IBug
188+
(bug [this other]
189+
"bug")
190+
Object
191+
(foo [this]
192+
(bug this 3)))))
193+
194+
(deftest test-cljs-1925
195+
(let [opts {:static-fns true}
196+
cenv (env/default-compiler-env opts)]
197+
(is (= [] (binding [ana/*unchecked-if* false
198+
ana/*cljs-static-fns* true]
199+
(capture-warnings
200+
(env/with-compiler-env cenv
201+
(with-out-str
202+
(comp/emit
203+
(comp/with-core-cljs
204+
opts
205+
(fn [] (ana/analyze aenv test-cljs-1925-code nil opts)))))))))))
206+
(let [opts {:static-fns true}
207+
cenv (env/default-compiler-env opts)]
208+
(is (= [] (binding [ana/*unchecked-if* false
209+
ana/*cljs-static-fns* true]
210+
(capture-warnings
211+
(env/with-compiler-env cenv
212+
(with-out-str
213+
(comp/emit
214+
(comp/with-core-cljs
215+
opts
216+
(fn [] (ana/analyze aenv specify-test-code nil opts))))))))))))
217+
196218
;; CLJS-1225
197219

198220
(comment

0 commit comments

Comments
 (0)