lisp/emacs-lisp/cl-*.el: Minor changes accumulated during new API design
* lisp/emacs-lisp/cl-macs.el (cl-deftype): Support dispatch on types that take arguments, as long as they can be used without arguments. * lisp/emacs-lisp/cl-generic.el (cl--generic-derived-mode-specializers): Rename from `cl--generic-derived-specializers` to clarify it's about derived modes and not derived types. (cl--generic-derived-mode-generalizer): Adjust accordingly and rename from `cl--generic-derived-generalizer` for the same reason. Ignore additional args in the tagcode function. (cl-generic-generalizers) <derived-mode>: Adjust accordingly. * lisp/emacs-lisp/macroexp.el (macroexp--dynamic-variable-p): Simplify.
This commit is contained in:
parent
13ec843352
commit
1e47f7492a
3 changed files with 38 additions and 12 deletions
|
|
@ -1047,7 +1047,7 @@ those methods.")
|
|||
('cl--generic-eql-generalizer '(eql 'x))
|
||||
('cl--generic-struct-generalizer 'cl--generic)
|
||||
('cl--generic-typeof-generalizer 'integer)
|
||||
('cl--generic-derived-generalizer '(derived-mode c-mode))
|
||||
('cl--generic-derived-mode-generalizer '(derived-mode c-mode))
|
||||
('cl--generic-oclosure-generalizer 'oclosure)
|
||||
(_ x))))
|
||||
|
||||
|
|
@ -1466,19 +1466,19 @@ This currently works for built-in types and types built on top of records."
|
|||
;; "&context (major-mode c-mode)" rather than
|
||||
;; "&context (major-mode (derived-mode c-mode))".
|
||||
|
||||
(defun cl--generic-derived-specializers (mode &rest _)
|
||||
(defun cl--generic-derived-mode-specializers (mode &rest _)
|
||||
;; FIXME: Handle (derived-mode <mode1> ... <modeN>)
|
||||
(mapcar (lambda (mode) `(derived-mode ,mode))
|
||||
(derived-mode-all-parents mode)))
|
||||
|
||||
(cl-generic-define-generalizer cl--generic-derived-generalizer
|
||||
90 (lambda (name) `(and (symbolp ,name) (functionp ,name) ,name))
|
||||
#'cl--generic-derived-specializers)
|
||||
(cl-generic-define-generalizer cl--generic-derived-mode-generalizer
|
||||
90 (lambda (name &rest _) `(and (symbolp ,name) (functionp ,name) ,name))
|
||||
#'cl--generic-derived-mode-specializers)
|
||||
|
||||
(cl-defmethod cl-generic-generalizers ((_specializer (head derived-mode)))
|
||||
"Support for (derived-mode MODE) specializers.
|
||||
Used internally for the (major-mode MODE) context specializers."
|
||||
(list cl--generic-derived-generalizer))
|
||||
(list cl--generic-derived-mode-generalizer))
|
||||
|
||||
(cl-generic-define-context-rewriter major-mode (mode &rest modes)
|
||||
`(major-mode ,(if (consp mode)
|
||||
|
|
|
|||
|
|
@ -3816,12 +3816,39 @@ If PARENTS is non-nil, ARGLIST must be nil."
|
|||
(cl-callf (lambda (x) (delq parent-decl x)) (cdr declares))
|
||||
(when (equal declares '(declare))
|
||||
(cl-callf (lambda (x) (delq declares x)) decls)))
|
||||
(and parents arglist
|
||||
(error "Parents specified, but arglist not empty"))
|
||||
(let* ((expander
|
||||
`(cl-function (lambda (&cl-defs ('*) ,@arglist) ,@decls ,@forms)))
|
||||
;; FIXME: Pass a better lexical context.
|
||||
(specifier (ignore-errors (funcall (eval expander t))))
|
||||
`(cl-function
|
||||
(lambda (&cl-defs ('*) ,@arglist) ,@decls ,@forms)))
|
||||
(specifier
|
||||
(condition-case nil
|
||||
;; FIXME: Pass a better lexical context.
|
||||
(funcall (eval expander t))
|
||||
;; We previously signaled an error when the type specified
|
||||
;; both non-nil parents and arglist, like `unsigned-byte'
|
||||
;; in below example:
|
||||
;;
|
||||
;; (cl-deftype my-integer ()
|
||||
;; 'integer)
|
||||
;;
|
||||
;; (cl-deftype unsigned-byte (&optional bits)
|
||||
;; "Unsigned integer."
|
||||
;; (declare (parents my-integer))
|
||||
;; `(integer 0 ,(if (memq bits '(nil *))
|
||||
;; bits
|
||||
;; (1- (ash 1 bits)))))
|
||||
;;
|
||||
;; In order to accept the above (correct) definition of
|
||||
;; `unsigned-byte', call the expander without arguments to
|
||||
;; check if the arglist is mandatory by catching a
|
||||
;; `wrong-number-of-arguments' error. If so, and the type
|
||||
;; specified both parents and arglist, there is a good
|
||||
;; chance that the type is not atomic, so signal it;
|
||||
;; otherwise, return nil as previously. Report any other
|
||||
;; error on type definition.
|
||||
(wrong-number-of-arguments
|
||||
(and parents arglist ;; type is not atomic
|
||||
(error "Type %S with parents may be not atomic: %S"
|
||||
name arglist)))))
|
||||
(predicate
|
||||
(pcase specifier
|
||||
(`(satisfies ,f) `#',f)
|
||||
|
|
|
|||
|
|
@ -399,7 +399,6 @@ change this."
|
|||
(defun macroexp--dynamic-variable-p (var)
|
||||
"Whether the variable VAR is dynamically scoped.
|
||||
Only valid during macro-expansion."
|
||||
(defvar byte-compile-bound-variables)
|
||||
(or (not lexical-binding)
|
||||
(special-variable-p var)
|
||||
(memq var macroexp--dynvars)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue