Function: elisp-scope-1

elisp-scope-1 is a byte-compiled function defined in elisp-scope.el.gz.

Signature

(elisp-scope-1 FORM &optional OUTSPEC)

Documentation

Analyze FORM as an evaluated form with expected output spec OUTSPEC.

If OUTSPEC is non-nil, it specifies FORM's expected "output spec". This guides the analysis of quoted (sub)forms. OUTSPEC can be one the following:

- t: FORM evaluates to an arbitrary object.
  In other words, OUTSPEC of t conveys no information about FORM.

- code: FORM evaluates to a form to be evaluated elsewhere.
  The quoted output of FORM will again be analyzed as an evaluated form,
  in a "clean" local environment.

- (symbol . ROLE): FORM evaluates to a symbol with role ROLE.
  See elisp-scope-define-symbol-role for more information about
  defining new symbol roles.

- (repeat . SPEC): FORM evaluates to a list with elements of spec SPEC.

- (cons CARSPEC . CDRSPEC): FORM evaluates to a cons cell whose car
  has spec CARSPEC and whose cdr has spec CDRSPEC.

- (list . SPECS): FORM evaluates to a list of the same length as SPECS,
  in which the ith element matches the ith spec in SPECS.

- (member . VALS): FORM evaluates to a member of VALS.

- (plist . VALSPECS): FORM evaluates to a plist. VALSPECS is an alist
  associating value specs to properties in the plist. For example, an
  entry (:face . (symbol . face)) in VALSPECS says that the value of the
  property :face in the plist is a face name.

- (or . SPECS): FORM evaluates to a value that matches one of SPECS.

- (and . SPECS): FORM evaluates to a value that matches all of SPECS.
  The last spec in SPECS determines how to analyze FORM if it matches.

For example, to analyze a FORM that evaluates to either a list of major mode names or just to a single major mode name, use OUTSPEC as follows:

  (elisp-scope-1 FORM '(or (repeat . (symbol . major-mode))
                           (symbol . major-mode)))

If FORM in this example is (if (something-p) 'foo '(bar baz)), then all of foo, bar and baz will be analyzed as major mode names.

See also elisp-scope-analyze-form for an details about how subforms are analyzed.

Source Code

;; Defined in /usr/src/emacs/lisp/emacs-lisp/elisp-scope.el.gz
(defun elisp-scope-1 (form &optional outspec)
  "Analyze FORM as an evaluated form with expected output spec OUTSPEC.

If OUTSPEC is non-nil, it specifies FORM's expected \"output spec\".
This guides the analysis of quoted (sub)forms.
OUTSPEC can be one the following:

- t: FORM evaluates to an arbitrary object.
  In other words, OUTSPEC of t conveys no information about FORM.

- `code': FORM evaluates to a form to be evaluated elsewhere.
  The quoted output of FORM will again be analyzed as an evaluated form,
  in a \"clean\" local environment.

- (symbol . ROLE): FORM evaluates to a symbol with role ROLE.
  See `elisp-scope-define-symbol-role' for more information about
  defining new symbol roles.

- (repeat . SPEC): FORM evaluates to a list with elements of spec SPEC.

- (cons CARSPEC . CDRSPEC): FORM evaluates to a cons cell whose `car'
  has spec CARSPEC and whose `cdr' has spec CDRSPEC.

- (list . SPECS): FORM evaluates to a list of the same length as SPECS,
  in which the `i'th element matches the `i'th spec in SPECS.

- (member . VALS): FORM evaluates to a `member' of VALS.

- (plist . VALSPECS): FORM evaluates to a plist.  VALSPECS is an alist
  associating value specs to properties in the plist.  For example, an
  entry (:face . (symbol . face)) in VALSPECS says that the value of the
  property `:face' in the plist is a face name.

- (or . SPECS): FORM evaluates to a value that matches one of SPECS.

- (and . SPECS): FORM evaluates to a value that matches all of SPECS.
  The last spec in SPECS determines how to analyze FORM if it matches.

For example, to analyze a FORM that evaluates to either a list of major
mode names or just to a single major mode name, use OUTSPEC as follows:

  (elisp-scope-1 FORM \\='(or (repeat . (symbol . major-mode))
                           (symbol . major-mode)))

If FORM in this example is (if (something-p) \\='foo \\='(bar baz)),
then all of `foo', `bar' and `baz' will be analyzed as major mode names.

See also `elisp-scope-analyze-form' for an details about how subforms
are analyzed."
  (cond
   ((consp form)
    (let* ((f (car form)) (bare (elisp-scope--sym-bare f))
           (forms (cdr form)) (this nil))
      (when bare
        (cond
         ((setq this (or (alist-get bare elisp-scope-local-definitions)
                         (function-get bare 'elisp-scope-analyzer)))
          (let ((elisp-scope-output-spec outspec)) (apply this form)))
         ((macrop bare) (elisp-scope-report-s f 'macro)
          (cond
           ((elisp-scope-safe-macro-p bare)
            (elisp-scope-1
             (let* ((warning-minimum-log-level :emergency)
                   (macroexp-inhibit-compiler-macros t)
                   (symbols-with-pos-enabled t)
                   (message-log-max nil)
                   (inhibit-message t)
                   (macroexpand-all-environment
                    (append (mapcar #'list elisp-scope-unsafe-macros) macroexpand-all-environment)))
               (ignore-errors (macroexpand-1 form macroexpand-all-environment)))
             outspec))
           ((eq (get bare 'edebug-form-spec) t) (elisp-scope-n forms))))
         ((functionp bare)
          (elisp-scope-report-s f 'function) (elisp-scope-n forms))
         (t
          (elisp-scope-report-s f 'unknown)
          (when elisp-scope-assume-func (elisp-scope-n forms)))))))
   ((symbol-with-pos-p form) (elisp-scope--symbol form))))