(eval-when-compile (require 'cl-lib))
+(defsubst scope-local-get (sym local)
+ "Get binding position of symbol SYM in local context LOCAL."
+ (alist-get sym local))
+
+(defsubst scope-local-new (sym pos &optional local)
+ "Return new local context with SYM bound at POS.
+
+Optional argument LOCAL is a local context to extend."
+ (cons (cons sym pos) local))
+
(defun scope-s (local sym)
(let* ((beg (symbol-with-pos-pos sym))
(bare (bare-symbol sym))
(len (length (symbol-name bare))))
(unless (or (booleanp bare) (keywordp bare))
- (list (list beg len (alist-get bare local))))))
+ (list (list beg len (scope-local-get bare local))))))
(defun scope-let (local bindings body)
(nconc
(len (length (symbol-name bare))))
(list (list beg len beg)))))
bindings)
- (scope-n
- (append (mapcar
- (lambda (binding)
- (let ((sym (if (consp binding) (car binding) binding)))
- (cons (bare-symbol sym) (symbol-with-pos-pos sym))))
- bindings)
- local)
- body)))
+ (let ((l local))
+ (dolist (binding bindings)
+ (let ((sym (if (consp binding) (car binding) binding)))
+ (setq l (scope-local-new (bare-symbol sym) (symbol-with-pos-pos sym) l))))
+ (scope-n l body))))
(defun scope-let* (local bindings body)
(if bindings
(bare (bare-symbol sym)))
(list (list beg (length (symbol-name bare)) beg))))
(scope-let*
- (cons (let ((sym (if (consp binding) (car binding) binding)))
- (cons (bare-symbol sym) (symbol-with-pos-pos sym)))
- local)
+ (let ((sym (if (consp binding) (car binding) binding)))
+ (scope-local-new (bare-symbol sym) (symbol-with-pos-pos sym) local))
(cdr bindings)
body)))
(scope-n local body)))
(cons
(list beg (length (symbol-name bare)) beg)
(nconc (scope-1 local (cadr binding))
- (scope-if-let* (cons (cons bare beg) local)
+ (scope-if-let* (scope-local-new bare beg local)
(cdr bindings) body))))
;; BINDING is (VALUEFORM).
(nconc (scope-1 local (car binding))
(bare (bare-symbol sym)))
(cons
(list beg (length (symbol-name bare)) beg)
- (scope-if-let* (cons (cons bare beg) local)
+ (scope-if-let* (scope-local-new bare beg local)
(cdr bindings) body)))))
(scope-n local body)))
args)
(scope-1 local doc-form)
(scope-1 local int-spec)
- (scope-n (append
- (seq-keep (lambda (arg)
- (and (symbol-with-pos-p arg)
- (not (memq (bare-symbol arg) '(&optional &rest)))
- (cons (bare-symbol arg) (symbol-with-pos-pos arg))))
- args)
- local)
- body))))
+ (let ((l local))
+ (dolist (arg args)
+ (when (and (symbol-with-pos-p arg) (not (memq (bare-symbol arg) '(&optional &rest))))
+ (setq l (scope-local-new (bare-symbol arg) (symbol-with-pos-pos arg) l))))
+ (scope-n l body)))))
(defun scope-defmethod-1 (local0 local name args body)
(if args
(eq 'eql (bare-symbol head))
(not (or (symbolp form) (symbol-with-pos-p form)))
(scope-1 local0 form)))))
- (scope-defmethod-1 local0 (cons (cons bare beg) local) name (cdr args) body)))))
+ (scope-defmethod-1 local0 (scope-local-new bare beg local) name (cdr args) body)))))
((consp var)
;; VAR is (&key (VAR INIT SVAR)) or (&key VAR).
(let ((var (cadr var)))
(eq 'eql (bare-symbol head))
(not (or (symbolp form) (symbol-with-pos-p form)))
(scope-1 local0 form)))))
- (scope-defmethod-1 local0 (cons (cons bare beg) local) name (cdr args) body)))))
+ (scope-defmethod-1 local0 (scope-local-new bare beg local) name (cdr args) body)))))
((consp var)
(let* ((init (cadr var))
(svar (caddr var))
(let ((sbeg (symbol-with-pos-pos svar)))
(list (list sbeg (length (symbol-name (bare-symbol svar)))
sbeg))))
- (scope-defmethod-1 local0 (cons (cons bare beg)
- (append
- (when svar
- (list (cons (bare-symbol svar)
- (symbol-with-pos-pos svar))))
- local))
- name (cdr args) body)))))))))))
+ (scope-defmethod-1
+ local0
+ (scope-local-new bare beg
+ (if svar
+ (scope-local-new (bare-symbol svar)
+ (symbol-with-pos-pos svar)
+ local)
+ local))
+ name (cdr args) body)))))))))))
((symbol-with-pos-p arg)
(cond
((memq (bare-symbol arg) '(&optional &rest &body _))
(len (length (symbol-name bare))))
(cons
(list beg len beg)
- (scope-defmethod-1 local0 (cons (cons bare beg) local)
+ (scope-defmethod-1 local0 (scope-local-new bare beg local)
name (cdr args) body))))))))
(scope-n local body)))
(list (list beg (length (symbol-name bare)) beg))))
(scope-1 local bodyform)
(mapcan
- (let ((l (if var (cons (cons (bare-symbol var) (symbol-with-pos-pos var)) local) local)))
+ (let ((l (if var (scope-local-new (bare-symbol var) (symbol-with-pos-pos var) local) local)))
(lambda (handler) (scope-n l (cdr handler))))
handlers)))
(nconc
(scope-1 local lst)
(scope-1 local res)
- (let ((l (cons (cons (bare-symbol var) (symbol-with-pos-pos var)) local)))
+ (let ((l (scope-local-new (bare-symbol var) (symbol-with-pos-pos var) local)))
(scope-n l body)))))
(defun scope-pcase-qpat (local qpat)
(let ((bare (bare-symbol pattern)))
(if (eq bare '_) (list local)
(let* ((beg (symbol-with-pos-pos pattern)))
- (cons (cons (cons bare beg) local)
+ (cons (scope-local-new bare beg local)
(list (list beg (length (symbol-name bare)) beg)))))))
((consp pattern)
(cond
fun))
(scope-n local body)))
-(defun scope-backquote (depth local elements)
+(defun scope--backquote (local elements depth)
(cond
((zerop depth) (scope-n local elements))
((consp elements)
(cond
((memq (car elements) '(\, \,@))
- (scope-backquote (1- depth) local (cdr elements)))
+ (scope--backquote local (cdr elements) (1- depth)))
((eq (car elements) '\`)
- (scope-backquote (1+ depth) local (cdr elements)))
- (t (nconc (scope-backquote depth local (car elements))
- (scope-backquote depth local (cdr elements))))))
+ (scope--backquote local (cdr elements) (1+ depth)))
+ (t (nconc (scope--backquote local (car elements) depth)
+ (scope--backquote local (cdr elements) depth)))))
((vectorp elements)
- (scope-backquote depth local (append elements nil)))))
+ (scope--backquote local (append elements nil) depth))))
+
+(defun scope-backquote (local elements &optional depth)
+ (scope--backquote local elements (or depth 1)))
(defvar scope-flet-list nil)
(scope-1 local (car exps)))
(let ((scope-flet-list (cons (bare-symbol func) scope-flet-list)))
(scope-flet
- (cons (cons (bare-symbol func) (symbol-with-pos-pos func))
- local)
+ (scope-local-new (bare-symbol func) (symbol-with-pos-pos func)
+ local)
(cdr defs) body)))))
(scope-n local body)))
(list (symbol-with-pos-pos func) (length (symbol-name (bare-symbol func)))
(symbol-with-pos-pos func))
(let ((scope-flet-list (cons (bare-symbol func) scope-flet-list))
- (l (cons (cons (bare-symbol func) (symbol-with-pos-pos func)) local)))
+ (l (scope-local-new (bare-symbol func) (symbol-with-pos-pos func) local)))
(nconc
(scope-defun l nil args body)
(scope-flet l (cdr defs) forms)))))
(scope-n local forms)))
-(defun scope-function (local arg)
+(defun scope-sharpquote (local arg)
(and (or (and (symbol-with-pos-p arg) (memq (bare-symbol arg) scope-flet-list))
(consp arg))
(scope-1 local arg)))
(len (length (symbol-name bare))))
(cons
(list beg len beg)
- (scope-cl-defun-aux (cons (cons bare beg) local)
+ (scope-cl-defun-aux (scope-local-new bare beg local)
name (cdr args) body))))
((consp arg)
(let* ((var (car arg))
(list beg len beg)
(nconc
(scope-1 local init)
- (scope-cl-defun-aux (cons (cons bare beg) local)
+ (scope-cl-defun-aux (scope-local-new bare beg local)
name (cdr args) body)))))))
(scope-n local body)))
(len (length (symbol-name bare))))
(cons
(list beg len beg)
- (scope-cl-defun-key (cons (cons bare beg) local)
+ (scope-cl-defun-key (scope-local-new bare beg local)
name (cdr args) body))))))
((consp arg)
(let* ((var (car arg))
(let ((sbeg (symbol-with-pos-pos svar)))
(list (list sbeg (length (symbol-name (bare-symbol svar)))
sbeg))))
- (scope-cl-defun-key (cons (cons bare beg)
- (append
- (when svar
- (list (cons (bare-symbol svar)
- (symbol-with-pos-pos svar))))
- local))
- name (cdr args) body)))))))
+ (scope-cl-defun-key
+ (scope-local-new bare beg
+ (if svar
+ (scope-local-new (bare-symbol svar)
+ (symbol-with-pos-pos svar)
+ local)
+ local))
+ name (cdr args) body)))))))
(scope-n local body)))
(defun scope-cl-defun-rest (local name args body)
(beg (symbol-with-pos-pos var))
(bare (bare-symbol var))
(len (length (symbol-name bare)))
- (l (cons (cons bare beg) local)))
+ (l (scope-local-new bare beg local)))
(cons
(list beg len beg)
(if (cdr args)
(len (length (symbol-name bare))))
(cons
(list beg len beg)
- (scope-cl-defun-optional (cons (cons bare beg) local)
+ (scope-cl-defun-optional (scope-local-new bare beg local)
name (cdr args) body))))))
((consp arg)
(let* ((var (car arg))
(let ((sbeg (symbol-with-pos-pos svar)))
(list (list sbeg (length (symbol-name (bare-symbol svar)))
sbeg))))
- (scope-cl-defun-optional (cons (cons bare beg)
- (append
- (when svar
- (list (cons (bare-symbol svar)
- (symbol-with-pos-pos svar))))
- local))
- name (cdr args) body)))))))
+ (scope-cl-defun-optional
+ (scope-local-new bare beg
+ (if svar
+ (scope-local-new (bare-symbol svar)
+ (symbol-with-pos-pos svar)
+ local)
+ local))
+ name (cdr args) body)))))))
(scope-n local body)))
(defun scope-cl-defun-1 (local name args body)
(len (length (symbol-name bare))))
(cons
(list beg len beg)
- (scope-cl-defun-1 (cons (cons (bare-symbol arg)
- (symbol-with-pos-pos arg))
+ (scope-cl-defun-1 (scope-local-new (bare-symbol arg)
+ (symbol-with-pos-pos arg)
local)
name (cdr args) body))))))
(scope-n local body)))
(len (length (symbol-name bare))))
(list beg len beg)))
args)
- (scope-n (append
- (mapcar (lambda (arg)
- (cons (bare-symbol arg) (symbol-with-pos-pos arg)))
- args)
- local)
- body)))
+ (let ((l local))
+ (dolist (arg args)
+ (when (and (symbol-with-pos-p arg) (not (memq (bare-symbol arg) '(&rest))))
+ (setq l (scope-local-new (bare-symbol arg) (symbol-with-pos-pos arg) l))))
+ (scope-n l body))))
(defun scope-pcase-lambda (local lambda-list body)
(if lambda-list
(sym (car binder))
(bare (bare-symbol sym))
(beg (symbol-with-pos-pos sym))
- (l (cons (cons bare beg) local))
+ (l (scope-local-new bare beg local))
(form (cadr binder)))
(cons
(list beg (length (symbol-name bare)) beg)
(scope-letrec l (cdr binders) body))))
(scope-n local body)))
-(defun scope-f (local f)
- "Return function that scope-analyzes arguments of F in context LOCAL."
- (cond
- ((symbol-with-pos-p f)
- (let ((bare (bare-symbol f)))
- (cond
- ((functionp bare) (apply-partially #'scope-n local))
- ((macrop bare)
- (cond
- ((eq (get bare 'edebug-form-spec) t)
- (apply-partially #'scope-n local))
- ((memq bare '( setf with-memoization cl-assert cl-incf cl-decf
- eval-when-compile eval-and-compile with-eval-after-load
- ;; We could recognize contant symbols bindings
- ;; in `cl-progv', but it is not really worth the
- ;; trouble since this macro is specifically
- ;; intended for computing bindings at run time.
- cl-progv))
- (apply-partially #'scope-n local))
- ((memq bare '( defun defmacro defsubst define-inline))
- (lambda (forms) (scope-defun local (car forms) (cadr forms) (cddr forms))))
- ((memq bare '( cl-defgeneric))
- (lambda (forms) (scope-defgeneric local (car forms) (cadr forms) (cddr forms))))
- ((memq bare '(cl-case))
- (lambda (forms) (scope-case local (car forms) (cdr forms))))
- ((memq bare '( cl-defun))
- (lambda (forms) (scope-cl-defun local (car forms) (cadr forms) (cddr forms))))
- ((memq bare '( cl-defmethod))
- (lambda (forms) (scope-defmethod local (car forms) (cdr forms))))
- ((memq bare '(lambda))
- (lambda (forms) (scope-defun local nil (car forms) (cdr forms))))
- ((memq bare '(declare-function))
- (lambda (forms) (scope-declare-function local (car forms) (cadr forms)
- (caddr forms) (cadddr forms))))
- ((memq bare '(if-let when-let and-let))
- (lambda (forms) (scope-if-let local (car forms) (cdr forms))))
- ((memq bare '(if-let* when-let* and-let* while-let))
- (lambda (forms) (scope-if-let* local (car forms) (cdr forms))))
- ((memq bare '( defvar-local defcustom))
- (lambda (forms) (scope-defvar local (car forms) (cadr forms))))
- ((memq bare '(dolist dotimes))
- (lambda (forms) (scope-dotimes local (caar forms) (cadar forms) (caddar forms) (cdr forms))))
- ((memq bare '(pcase pcase-exhaustive))
- (lambda (forms) (scope-pcase local (car forms) (cdr forms))))
- ((memq bare '(pcase-lambda))
- (lambda (forms) (scope-pcase-lambda local (car forms) (cdr forms))))
- ((memq bare '(pcase-dolist))
- (lambda (forms) (scope-pcase-dolist local (caar forms) (cadar forms) (cdr forms))))
- ((memq bare '(pcase-let))
- (lambda (forms) (scope-pcase-let local (car forms) (cdr forms))))
- ((memq bare '(pcase-let*))
- (lambda (forms) (scope-pcase-let* local (car forms) (cdr forms))))
- ((memq bare '(setq-local setq-default))
- (apply-partially #'scope-setq local))
- ((memq bare '(push))
- (lambda (forms) (scope-push local (car forms) (cadr forms))))
- ((memq bare '(pop oref))
- (lambda (forms) (scope-1 local (car forms))))
- ((memq bare '(letrec))
- (lambda (forms) (scope-letrec local (car forms) (cdr forms))))
- ((memq bare '(cl-flet))
- (lambda (forms) (scope-flet local (car forms) (cdr forms))))
- ((memq bare '(cl-labels))
- (lambda (forms) (scope-labels local (car forms) (cdr forms))))
- ((memq bare '(minibuffer-with-setup-hook))
- (lambda (forms) (scope-minibuffer-with-setup-hook local (car forms) (cdr forms))))
- ((memq bare '(condition-case-unless-debug))
- (lambda (forms) (scope-condition-case local (car forms) (cadr forms) (cddr forms))))
- ((memq bare '(seq-let))
- (lambda (forms) (scope-seq-let local (car forms) (cadr forms) (cddr forms))))
- ((memq bare '( define-derived-mode))
- (lambda (forms)
- (scope-define-derived local (car forms) (cadr forms) (caddr forms) (cdddr forms))))
- ((memq bare '( define-minor-mode))
- (lambda (forms) (scope-define-minor local (car forms) (cadr forms) (cddr forms))))
- ((memq bare '(inline-quote))
- (lambda (forms) (scope-backquote 1 local (car forms))))
- ((memq bare '(inline-letevals))
- (lambda (forms) (scope-let local (car forms) (cdr forms))))
- ((memq bare '(with-suppressed-warnings))
- (lambda (forms) (scope-n local (cdr forms))))
- ((get bare 'scope-function) ;For custom extensions.
- (apply-partially (get bare 'scope-function) local))
- (t #'ignore)))
- ((special-form-p bare)
- (cond
- ((memq bare '( if and or while
- save-excursion save-restriction save-current-buffer
- catch unwind-protect
- progn prog1))
- (apply-partially #'scope-n local))
- ((eq bare 'let)
- (lambda (forms) (scope-let local (car forms) (cdr forms))))
- ((eq bare 'let*)
- (lambda (forms) (scope-let* local (car forms) (cdr forms))))
- ((eq bare 'cond) (apply-partially #'scope-cond local))
- ((eq bare 'setq) (apply-partially #'scope-setq local))
- ((memq bare '( defconst defvar))
- (lambda (forms) (scope-defvar local (car forms) (cadr forms))))
- ((eq bare 'condition-case)
- (lambda (forms) (scope-condition-case local (car forms) (cadr forms) (cddr forms))))
- (t #'ignore)))
- ((memq bare scope-flet-list)
- (lambda (forms) (nconc (scope-s local f)
- (scope-n local forms))))
- ;; FIXME: Assume unknown symbols refer to functions, unless at
- ;; top level.
- (t #'ignore))))
- ;; Symbol without position, a quotation marker that the reader
- ;; expands into a symbol but does not annotate with a position.
- ((symbolp f)
- (cond
- ((eq f '\`) (lambda (forms) (scope-backquote 1 local (car forms))))
- ((eq f 'function) (lambda (forms) (scope-function local (car forms))))
- (t #'ignore)))
- (t #'ignore)))
+(defvar scope-assume-func-p nil)
-(defun scope-1 (local form)
+(defun scope-1 (local form &optional top-level)
(cond
((consp form)
- (funcall (scope-f local (car form)) (cdr form)))
+ (let ((f (car form))
+ (forms (cdr form)))
+ (cond
+ ((symbol-with-pos-p f)
+ (let ((bare (bare-symbol f)))
+ (cond
+ ((or (functionp bare)
+ (memq bare '( if and or while
+ save-excursion save-restriction save-current-buffer
+ catch unwind-protect
+ progn prog1 eval-when-compile eval-and-compile with-eval-after-load
+ with-memoization cl-assert cl-incf cl-decf setf
+ ;; We could recognize contant symbols bindings
+ ;; in `cl-progv', but it is not really worth the
+ ;; trouble since this macro is specifically
+ ;; intended for computing bindings at run time.
+ cl-progv))
+ (eq (get bare 'edebug-form-spec) t))
+ (scope-n local forms))
+ ((macrop bare)
+ (cond
+ ((memq bare '( defun defmacro defsubst define-inline))
+ (scope-defun local (car forms) (cadr forms) (cddr forms)))
+ ((memq bare '( cl-defgeneric))
+ (scope-defgeneric local (car forms) (cadr forms) (cddr forms)))
+ ((memq bare '(cl-case))
+ (scope-case local (car forms) (cdr forms)))
+ ((memq bare '( cl-defun))
+ (scope-cl-defun local (car forms) (cadr forms) (cddr forms)))
+ ((memq bare '( cl-defmethod))
+ (scope-defmethod local (car forms) (cdr forms)))
+ ((memq bare '(lambda))
+ (scope-defun local nil (car forms) (cdr forms)))
+ ((memq bare '(declare-function))
+ (scope-declare-function local (car forms) (cadr forms)
+ (caddr forms) (cadddr forms)))
+ ((memq bare '(if-let when-let and-let))
+ (scope-if-let local (car forms) (cdr forms)))
+ ((memq bare '(if-let* when-let* and-let* while-let))
+ (scope-if-let* local (car forms) (cdr forms)))
+ ((memq bare '( defvar-local defcustom))
+ (scope-defvar local (car forms) (cadr forms)))
+ ((memq bare '(dolist dotimes))
+ (scope-dotimes local (caar forms) (cadar forms) (caddar forms) (cdr forms)))
+ ((memq bare '(pcase pcase-exhaustive))
+ (scope-pcase local (car forms) (cdr forms)))
+ ((memq bare '(pcase-lambda))
+ (scope-pcase-lambda local (car forms) (cdr forms)))
+ ((memq bare '(pcase-dolist))
+ (scope-pcase-dolist local (caar forms) (cadar forms) (cdr forms)))
+ ((memq bare '(pcase-let))
+ (scope-pcase-let local (car forms) (cdr forms)))
+ ((memq bare '(pcase-let*))
+ (scope-pcase-let* local (car forms) (cdr forms)))
+ ((memq bare '(setq-local setq-default))
+ (scope-setq local forms))
+ ((memq bare '(push))
+ (scope-push local (car forms) (cadr forms)))
+ ((memq bare '(pop oref))
+ (scope-1 local (car forms)))
+ ((memq bare '(letrec))
+ (scope-letrec local (car forms) (cdr forms)))
+ ((memq bare '(cl-flet))
+ (scope-flet local (car forms) (cdr forms)))
+ ((memq bare '(cl-labels))
+ (scope-labels local (car forms) (cdr forms)))
+ ((memq bare '(minibuffer-with-setup-hook))
+ (scope-minibuffer-with-setup-hook local (car forms) (cdr forms)))
+ ((memq bare '(condition-case-unless-debug))
+ (scope-condition-case local (car forms) (cadr forms) (cddr forms)))
+ ((memq bare '(seq-let))
+ (scope-seq-let local (car forms) (cadr forms) (cddr forms)))
+ ((memq bare '( define-derived-mode))
+ (scope-define-derived local (car forms) (cadr forms) (caddr forms) (cdddr forms)))
+ ((memq bare '( define-minor-mode))
+ (scope-define-minor local (car forms) (cadr forms) (cddr forms)))
+ ((memq bare '(inline-quote))
+ (scope-backquote local (car forms)))
+ ((memq bare '(inline-letevals))
+ (scope-let local (car forms) (cdr forms)))
+ ((memq bare '(with-suppressed-warnings))
+ (scope-n local (cdr forms)))
+ ((get bare 'scope-function) ;For custom extensions.
+ (funcall (get bare 'scope-function) local forms))))
+ ((special-form-p bare)
+ (cond
+ ((eq bare 'let)
+ (scope-let local (car forms) (cdr forms)))
+ ((eq bare 'let*)
+ (scope-let* local (car forms) (cdr forms)))
+ ((eq bare 'cond) (scope-cond local forms))
+ ((eq bare 'setq) (scope-setq local forms))
+ ((memq bare '( defconst defvar))
+ (scope-defvar local (car forms) (cadr forms)))
+ ((eq bare 'condition-case)
+ (scope-condition-case local (car forms) (cadr forms) (cddr forms)))
+ ((get bare 'scope-function)
+ (funcall (get bare 'scope-function) local forms))))
+ ((memq bare scope-flet-list)
+ (nconc (scope-s local f) (scope-n local forms)))
+ ((get bare 'scope-function)
+ (funcall (get bare 'scope-function) local forms))
+ ;; Assume nothing about unknown top-level forms.
+ (top-level nil)
+ (scope-assume-func-p (scope-n local forms)))))
+ ;; Symbol without position, a quotation marker that the reader
+ ;; expands into a symbol but does not annotate with a position.
+ ((symbolp f)
+ (cond
+ ((eq f '\`) (scope-backquote local (car forms)))
+ ((eq f 'function) (scope-sharpquote local (car forms))))))))
((symbol-with-pos-p form)
(scope-s local form))))
position where a symbol of length LEN occurs, which is bound by another
occurrence of the same symbol that starts at position BINDING. If
OCCURRENCE is itself a binding occurrence, then BINDING and OCCURRENCE
-are equal. If OCCURRENCE is not lexically bound, then BINDING is nil."
- (scope-1 nil (read-positioning-symbols stream)))
+are equal. If OCCURRENCE is not lexically bound, then BINDING is nil.
+
+This function recursively analyzes Lisp forms (HEAD . TAIL), usually
+starting with a top-level form, by inspecting HEAD at each level:
+
+- If HEAD satisfies `functionp', which means it is a function in the
+ running Emacs session, analzye the form as a function call.
+
+- Standard macros and special forms, such as `defun', `if', `let',
+ `pcase', quotes, backquotes and more, are handled specially according
+ to their particular semantics.
+
+- If HEAD has the property symbol `scope-function', the value of this
+ property is used to analyze TAIL. It should be a function that takes
+ two arguments, LOCAL and TAIL, and returns a bindings graph for TAIL.
+ LOCAL represents the local context around the current form, the
+ `scope-function' can pass LOCAL to functions such as `scope-1' and
+ `scope-n' to obtain bindings graphs for sub-forms. See also
+ `scope-local-new' for extending LOCAL with local bindings in TAIL.
+
+- If within the code under analysis HEAD is a `cl-letf'-bound local
+ function name, analyze the form as a function call.
+
+- Otherwise, HEAD is unknown. If the HEAD of the top-level form that
+ this function reads from STREAM is unknown, this function ignores it
+ and returns nil. If an unknown HEAD occurs in a nested form, by
+ default it is similarly ignored, but if you set `scope-assume-func-p'
+ to non-nil, then this function assumes that such HEADs are functions."
+ (scope-1 nil (read-positioning-symbols stream) t))
(provide 'scope)
;;; scope.el ends here