-
-
Save swannodette/6e5f5d25adc3f112128e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; 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