Skip to content

Instantly share code, notes, and snippets.

@bensu
Created July 19, 2015 18:14
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save bensu/c71acf7594fe87d93dbd to your computer and use it in GitHub Desktop.
Save bensu/c71acf7594fe87d93dbd to your computer and use it in GitHub Desktop.
Var naming for cljs-1343 refactoring
;; 1 - The var associated to a def, (def my-var ...) - L1142
(DefExpr. :def env form var-name
;; TODO: check if this map should be a VarExpr - Sebastian
(assoc (analyze (-> env (dissoc :locals)
(assoc :context :expr)
(assoc :def-var true))
sym)
:op :var)
doc (:jsdoc sym-meta) init-expr
... )
;; 2 - The var in a fn bindings, (fn [my-var] ...) - L1160
;; Contains :line :column :shadow :info :binding-form?
(defn analyze-fn-method-param [env]
(fn [[locals params] name]
(let [line (get-line name env)
column (get-col name env)
nmeta (meta name)
tag (:tag nmeta)
shadow (when-not (nil? locals)
(locals name))
env (merge (select-keys env [:context])
{:line line :column column})
param {:op :var
:name name
:line line
:column column
:tag tag
:shadow shadow
;; Give the fn params the same shape
;; as a :var, so it gets routed
;; correctly in the compiler
:env env
:info {:name name :shadow shadow}
:binding-form? true}]
[(assoc locals name param) (conj params param)])))
;; 3 - The var in a let binding (let [my-var 1] ...) - L1400
;; Contains #{:local :tag} on top of #{:line :column :shadow :info :binding-form?} from the var fn-bindings
(defn analyze-let-bindings* [encl-env bindings]
(loop [bes []
env (assoc encl-env :context :expr)
bindings (seq (partition 2 bindings))]
(let [binding (first bindings)]
(if-not (nil? binding)
(let [[name init] binding]
(when (or (not (nil? (namespace name)))
#?(:clj (.contains (str name) ".")
:cljs ^boolean (goog.string/contains (str name) ".")))
(throw (error encl-env (str "Invalid local name: " name))))
(let [init-expr (analyze-let-binding-init env init (cons {:params bes} *loop-lets*))
line (get-line name env)
col (get-col name env)
be {:name name
:line line
:column col
:init init-expr
:tag (get-let-tag name init-expr)
:local true
:shadow (-> env :locals name)
;; Give let* bindings same shape as var so
;; they get routed correctly in the compiler
:op :var
:env {:line line :column col}
:info {:name name
:shadow (-> env :locals name)}
:binding-form? true}
be (if (= :fn (:op init-expr))
;; TODO: can we simplify - David
(merge be
{:fn-var true
:variadic (:variadic init-expr)
:max-fixed-arity (:max-fixed-arity init-expr)
:method-params (map :params (:methods init-expr))})
be)]
(recur (conj bes be)
(assoc-in env [:locals name] be)
(next bindings))))
[bes env]))))
;; 4 - The var associated to a symbol - L2185
;; Contains only :info on top of VarSpecialExpr
(defn analyze-symbol
"Finds the var associated with sym"
[env sym]
(if ^boolean (:quoted? env)
(analyze-wrap-meta (ConstExpr. :constant env sym 'cljs.core/Symbol))
(let [{:keys [line column]} (meta sym)
env (if-not (nil? line)
(assoc env :line line)
env)
env (if-not (nil? column)
(assoc env :column column)
env)
ret {:env env :form sym}
lcls (:locals env)
lb (get lcls sym)]
(if-not (nil? lb)
(assoc ret :op :var :info lb)
(if-not (true? (:def-var env))
(let [sym-meta (meta sym)
info (if-not (contains? sym-meta ::analyzed)
(resolve-existing-var env sym)
(resolve-var env sym))]
(assoc ret :op :var :info info))
(let [info (resolve-var env sym)]
(assoc ret :op :var :info info)))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment