Skip to content

Instantly share code, notes, and snippets.

@shaunlebron
Forked from ptaoussanis/CLJS-866.clj
Last active August 29, 2015 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shaunlebron/43f79cab0d8705a6352e to your computer and use it in GitHub Desktop.
Save shaunlebron/43f79cab0d8705a6352e to your computer and use it in GitHub Desktop.
Fix for desugar-ns-specs
(comment
;; Bug report for CLJS-721 (support :include-macros true modifier in :require),
;; Ref. http://dev.clojure.org/jira/browse/CLJS-721,
;; http://goo.gl/MQ3fWd (GitHub commit de6ee41b3)
;; desugar-ns-specs from clojurescript/src/clj/cljs/analyzer.clj
;; (`cljs.analyzer` ns)
(desugar-ns-specs '[(:require [foo.bar :as bar :include-macros true])])
;; =>
((:require-macros (foo.bar :as bar))
(:require (foo.bar :as bar))) ; Correct
;; Fix =>
((:require-macros (foo.bar :as bar))
(:require (foo.bar :as bar)))
(desugar-ns-specs '[(:require [foo.bar :as bar :include-macros true :refer [baz]])])
;; =>
((:require-macros (foo.bar :as bar :refer [baz]))
(:require (foo.bar :as bar))) ; Seems off, but what's the intended behaviour?
;; Fix =>
((:require-macros (foo.bar :as bar))
(:require (foo.bar :as bar :refer [baz])))
(desugar-ns-specs '[(:require [foo.bar :as bar :refer [baz] :include-macros true])])
;; =>
((:require-macros (foo.bar :as bar :refer [baz]))
(:require (foo.bar :as bar :refer [baz])))
;; Fix =>
((:require-macros (foo.bar :as bar))
(:require (foo.bar :as bar :refer [baz])))
;; Is the position of `:include-macros true` supposed to influence expansion
;; like this?
;; And is the interaction between `:include-macros true` and `:refer` as
;; intended? I would have expected something like this:
(desugar-ns-specs '[(:require [foo.bar :as bar :include-macros true :refer [baz]])])
;; =
(desugar-ns-specs '[(:require [foo.bar :as bar :refer [baz] :include-macros true])])
;; =>
((:require-macros (foo.bar :as bar)) ; No :refer
(:require (foo.bar :as bar :refer [baz])))
;; (Fix produces same for both as well)
;;; --------------------------------------------------------------------------
;; There's an additional problem with `:refer` + `:refer-macros`:
(desugar-ns-specs '[(:require [foo.bar :as bar :refer [baz] :refer-macros [qux]])])
;; =>
((:require-macros (foo.bar :as bar :refer [baz] :refer [qux])) ; Faulty
(:require (foo.bar :as bar :refer [baz])))
;; Fix =>
((:require-macros (foo.bar :as bar :refer [qux]))
(:require (foo.bar :as bar :refer [baz])))
;; I believe the correct expansion should be:
((:require-macros (foo.bar :as bar :refer [qux]))
(:require (foo.bar :as bar :refer [baz]))))
From c76fbf85581ebe6df0370c1d8bb0017a837c30d6 Mon Sep 17 00:00:00 2001
From: Shaun Williams <shaunewilliams@gmail.com>
Date: Thu, 2 Oct 2014 00:43:00 -0500
Subject: [PATCH] fix desugar-ns-specs
---
src/clj/cljs/analyzer.clj | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/clj/cljs/analyzer.clj b/src/clj/cljs/analyzer.clj
index 08f2ad0..d7911bc 100644
--- a/src/clj/cljs/analyzer.clj
+++ b/src/clj/cljs/analyzer.clj
@@ -1131,17 +1131,22 @@
(map (fn [[k & specs]] [k (into [] specs)]))
(into {}))
sugar-keys #{:include-macros :refer-macros}
+ remove-refer
+ (fn [spec]
+ (let [[l r] (split-with #(not= :refer %) spec)]
+ (concat l (drop 2 r))))
to-macro-specs
(fn [specs]
(->> specs
(filter #(and (sequential? %) (some sugar-keys %)))
(map #(->> % (remove #{:include-macros true})
+ remove-refer
(map (fn [x] (if (= x :refer-macros) :refer x)))))))
remove-sugar
(fn [spec]
(if (and (sequential? spec) (some sugar-keys spec))
- (let [[l & r] (split-with #(not (contains? sugar-keys %)) spec)]
- (concat l (drop 2 r)))
+ (let [[l r] (split-with #(not (contains? sugar-keys %)) spec)]
+ (recur (concat l (drop 2 r))))
spec))]
(if-let [require-specs (seq (to-macro-specs require))]
(map (fn [[k v]] (cons k (map remove-sugar v)))
--
1.9.1
(defn desugar-ns-specs [args]
(let [{:keys [require] :as indexed}
(->> args
(map (fn [[k & specs]] [k (into [] specs)]))
(into {}))
sugar-keys #{:include-macros :refer-macros}
remove-refer
(fn [spec]
(let [[l r] (split-with #(not= :refer %) spec)]
(concat l (drop 2 r))))
to-macro-specs
(fn [specs]
(->> specs
(filter #(and (sequential? %) (some sugar-keys %)))
(map #(->> % (remove #{:include-macros true})
remove-refer
(map (fn [x] (if (= x :refer-macros) :refer x)))))))
remove-sugar
(fn [spec]
(if (and (sequential? spec) (some sugar-keys spec))
(let [[l r] (split-with #(not (contains? sugar-keys %)) spec)]
(recur (concat l (drop 2 r))))
spec))]
(if-let [require-specs (seq (to-macro-specs require))]
(map (fn [[k v]] (cons k (map remove-sugar v)))
(update-in indexed [:require-macros] (fnil into []) require-specs))
args)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment