Function: clojure--binding-sites

clojure--binding-sites is a byte-compiled function defined in clojure-mode.el.

Signature

(clojure--binding-sites TOP-LEVEL)

Documentation

Return the places in the TOP-LEVEL form that bind names.

Each is a list (VEC PATTERN END) of an arglist or the bindings of a let-like form, the vector pattern of what it binds, and the end of the form, the names being in scope from VEC to END. Quoted and syntax-quoted forms don't count, as they're data or a macro's template.

Source Code

;; Defined in ~/.emacs.d/elpa/clojure-mode-20261103.1226/clojure-mode.el
(defun clojure--binding-sites (top-level)
  "Return the places in the TOP-LEVEL form that bind names.
Each is a list (VEC PATTERN END) of an arglist or the bindings of a
let-like form, the vector pattern of what it binds, and the end of the
form, the names being in scope from VEC to END.  Quoted and
syntax-quoted forms don't count, as they're data or a macro's template."
  (let ((methods (make-hash-table))
        sites)
    (dolist (form (clojure--form-descendants top-level 'list t))
      (when-let* (((not (gethash (clojure--form-start form) methods)))
                  (name (clojure--core-form-name form))
                  (args (cdr (clojure--form-values form)))
                  (end (clojure--form-end form)))
        (pcase name
          ((or "let" "loop" "if-let" "when-let" "if-some" "when-some" "when-first"
               "for" "doseq")
           (when (eq (clojure--form-type (car args)) 'vector)
             (push (list (car args)
                         `(vec ,(car args)
                               ,@(delq nil (mapcar #'clojure--parse-pattern
                                                   (clojure--let-binding-forms (car args)))))
                         end)
                   sites)))
          ((or "letfn" "reify" "proxy" "deftype" "defrecord" "extend-type"
               "extend-protocol" "defprotocol" "definterface")
           ;; A method named like a core form, as in (letfn [(for [x] x)]),
           ;; isn't one.
           (dolist (method (if (equal name "letfn")
                               (and (eq (clojure--form-type (car args)) 'vector)
                                    (clojure--form-values (car args)))
                             args))
             (when-let* (((eq (clojure--form-type method) 'list))
                         (children (clojure--form-values method))
                         ((eq (clojure--form-type (car children)) 'symbol)))
               (puthash (clojure--form-start method) t methods)
               ;; Protocol and interface methods have no bodies.
               (unless (member name '("defprotocol" "definterface"))
                 (setq sites (append (clojure--fn-tail-sites
                                      (cdr children) (clojure--form-end method))
                                     sites))))))
          ;; The dispatch value can be a vector too.
          ("defmethod"
           (setq sites (append (clojure--fn-tail-sites (nthcdr 2 args) end) sites)))
          ((or "fn" "bound-fn" "defn" "defn-" "defmacro")
           (setq sites (append (clojure--fn-tail-sites args end) sites))))))
    sites))