diff options
| author | Stefan Monnier | 2012-05-30 21:41:17 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2012-05-30 21:41:17 -0400 |
| commit | 500fcedc32199750ee61ce6caba3914fe204e629 (patch) | |
| tree | 48e4954b45900c121bda51f3de0209e5cd3736e7 | |
| parent | b03b4c00631aa0d43de33c0498db36a2403cd519 (diff) | |
| download | emacs-500fcedc32199750ee61ce6caba3914fe204e629.tar.gz emacs-500fcedc32199750ee61ce6caba3914fe204e629.zip | |
Add `declare' for `defun'. Align `defmacro's with it.
* lisp/emacs-lisp/easy-mmode.el (define-minor-mode)
(define-globalized-minor-mode): Don't autoload the var definitions.
* lisp/emacs-lisp/byte-run.el: Use lexical-binding.
(defun-declarations-alist, macro-declarations-alist): New vars.
(defmacro, defun): Use them.
(make-obsolete, define-obsolete-function-alias)
(make-obsolete-variable, define-obsolete-variable-alias):
Use `declare'.
(macro-declaration-function): Mark obsolete.
* lisp/emacs-lisp/autoload.el: Use lexical-binding.
(make-autoload): Add `expansion' arg. Rely more on macro expansion.
| -rw-r--r-- | etc/NEWS | 5 | ||||
| -rw-r--r-- | lisp/ChangeLog | 19 | ||||
| -rw-r--r-- | lisp/emacs-lisp/autoload.el | 127 | ||||
| -rw-r--r-- | lisp/emacs-lisp/byte-run.el | 173 | ||||
| -rw-r--r-- | lisp/emacs-lisp/easy-mmode.el | 7 |
5 files changed, 223 insertions, 108 deletions
| @@ -299,6 +299,11 @@ still be supported for Emacs 24.x. | |||
| 299 | 299 | ||
| 300 | * Lisp changes in Emacs 24.2 | 300 | * Lisp changes in Emacs 24.2 |
| 301 | 301 | ||
| 302 | ** `defun' also accepts a (declare DECLS) form, like `defmacro'. | ||
| 303 | The interpretation of the DECLS is determined by `defun-declarations-alist'. | ||
| 304 | |||
| 305 | ** `macro-declaration-function' is obsolete, use `macro-declarations-alist'. | ||
| 306 | |||
| 302 | ** New function `set-temporary-overlay-map'. | 307 | ** New function `set-temporary-overlay-map'. |
| 303 | 308 | ||
| 304 | ** New macros `setq-local' and `defvar-local'. | 309 | ** New macros `setq-local' and `defvar-local'. |
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 62405960593..acb87b0ac5f 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,9 +1,24 @@ | |||
| 1 | 2012-05-31 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 2 | |||
| 3 | Add `declare' for `defun'. Align `defmacro's with it. | ||
| 4 | * emacs-lisp/easy-mmode.el (define-minor-mode) | ||
| 5 | (define-globalized-minor-mode): Don't autoload the var definitions. | ||
| 6 | * emacs-lisp/byte-run.el: Use lexical-binding. | ||
| 7 | (defun-declarations-alist, macro-declarations-alist): New vars. | ||
| 8 | (defmacro, defun): Use them. | ||
| 9 | (make-obsolete, define-obsolete-function-alias) | ||
| 10 | (make-obsolete-variable, define-obsolete-variable-alias): | ||
| 11 | Use `declare'. | ||
| 12 | (macro-declaration-function): Mark obsolete. | ||
| 13 | * emacs-lisp/autoload.el: Use lexical-binding. | ||
| 14 | (make-autoload): Add `expansion' arg. Rely more on macro expansion. | ||
| 15 | |||
| 1 | 2012-05-30 Agustín Martín Domingo <agustin.martin@hispalinux.es> | 16 | 2012-05-30 Agustín Martín Domingo <agustin.martin@hispalinux.es> |
| 2 | 17 | ||
| 3 | * textmodes/ispell.el (ispell-with-no-warnings): | 18 | * textmodes/ispell.el (ispell-with-no-warnings): |
| 4 | Define as a macro. | 19 | Define as a macro. |
| 5 | (ispell-kill-ispell, ispell-change-dictionary): Use | 20 | (ispell-kill-ispell, ispell-change-dictionary): |
| 6 | `called-interactively-p' for Emacs instead of obsolete | 21 | Use `called-interactively-p' for Emacs instead of obsolete |
| 7 | `interactive-p'. | 22 | `interactive-p'. |
| 8 | 23 | ||
| 9 | 2012-05-30 Stefan Monnier <monnier@iro.umontreal.ca> | 24 | 2012-05-30 Stefan Monnier <monnier@iro.umontreal.ca> |
diff --git a/lisp/emacs-lisp/autoload.el b/lisp/emacs-lisp/autoload.el index 921b08b10a8..d9fc0fccf0e 100644 --- a/lisp/emacs-lisp/autoload.el +++ b/lisp/emacs-lisp/autoload.el | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | ;; autoload.el --- maintain autoloads in loaddefs.el | 1 | ;; autoload.el --- maintain autoloads in loaddefs.el -*- lexical-binding: t -*- |
| 2 | 2 | ||
| 3 | ;; Copyright (C) 1991-1997, 2001-2012 Free Software Foundation, Inc. | 3 | ;; Copyright (C) 1991-1997, 2001-2012 Free Software Foundation, Inc. |
| 4 | 4 | ||
| @@ -86,28 +86,67 @@ that text will be copied verbatim to `generated-autoload-file'.") | |||
| 86 | 86 | ||
| 87 | (defvar autoload-modified-buffers) ;Dynamically scoped var. | 87 | (defvar autoload-modified-buffers) ;Dynamically scoped var. |
| 88 | 88 | ||
| 89 | (defun make-autoload (form file) | 89 | (defun make-autoload (form file &optional expansion) |
| 90 | "Turn FORM into an autoload or defvar for source file FILE. | 90 | "Turn FORM into an autoload or defvar for source file FILE. |
| 91 | Returns nil if FORM is not a special autoload form (i.e. a function definition | 91 | Returns nil if FORM is not a special autoload form (i.e. a function definition |
| 92 | or macro definition or a defcustom)." | 92 | or macro definition or a defcustom). |
| 93 | If EXPANSION is non-nil, we're processing the macro expansion of an | ||
| 94 | expression, in which case we want to handle forms differently." | ||
| 93 | (let ((car (car-safe form)) expand) | 95 | (let ((car (car-safe form)) expand) |
| 94 | (cond | 96 | (cond |
| 97 | ((and expansion (eq car 'defalias)) | ||
| 98 | (pcase-let* | ||
| 99 | ((`(,_ ,_ ,arg . ,rest) form) | ||
| 100 | ;; `type' is non-nil if it defines a macro. | ||
| 101 | ;; `fun' is the function part of `arg' (defaults to `arg'). | ||
| 102 | ((or (and (or `(cons 'macro ,fun) `'(macro . ,fun)) (let type t)) | ||
| 103 | (and (let fun arg) (let type nil))) | ||
| 104 | arg) | ||
| 105 | ;; `lam' is the lambda expression in `fun' (or nil if not | ||
| 106 | ;; recognized). | ||
| 107 | (lam (if (memq (car-safe fun) '(quote function)) (cadr fun))) | ||
| 108 | ;; `args' is the list of arguments (or t if not recognized). | ||
| 109 | ;; `body' is the body of `lam' (or t if not recognized). | ||
| 110 | ((or `(lambda ,args . ,body) | ||
| 111 | (and (let args t) (let body t))) | ||
| 112 | lam) | ||
| 113 | ;; Get the `doc' from `body' or `rest'. | ||
| 114 | (doc (cond ((stringp (car-safe body)) (car body)) | ||
| 115 | ((stringp (car-safe rest)) (car rest)))) | ||
| 116 | ;; Look for an interactive spec. | ||
| 117 | (interactive (pcase body | ||
| 118 | ((or `((interactive . ,_) . ,_) | ||
| 119 | `(,_ (interactive . ,_) . ,_)) t)))) | ||
| 120 | ;; Add the usage form at the end where describe-function-1 | ||
| 121 | ;; can recover it. | ||
| 122 | (when (listp args) (setq doc (help-add-fundoc-usage doc args))) | ||
| 123 | ;; (message "autoload of %S" (nth 1 form)) | ||
| 124 | `(autoload ,(nth 1 form) ,file ,doc ,interactive ,type))) | ||
| 125 | |||
| 126 | ((and expansion (memq car '(progn prog1))) | ||
| 127 | (let ((end (memq :autoload-end form))) | ||
| 128 | (when end ;Cut-off anything after the :autoload-end marker. | ||
| 129 | (setq form (copy-sequence form)) | ||
| 130 | (setcdr (memq :autoload-end form) nil)) | ||
| 131 | (let ((exps (delq nil (mapcar (lambda (form) | ||
| 132 | (make-autoload form file expansion)) | ||
| 133 | (cdr form))))) | ||
| 134 | (when exps (cons 'progn exps))))) | ||
| 135 | |||
| 95 | ;; For complex cases, try again on the macro-expansion. | 136 | ;; For complex cases, try again on the macro-expansion. |
| 96 | ((and (memq car '(easy-mmode-define-global-mode define-global-minor-mode | 137 | ((and (memq car '(easy-mmode-define-global-mode define-global-minor-mode |
| 97 | define-globalized-minor-mode | 138 | define-globalized-minor-mode defun defmacro |
| 139 | ;; FIXME: we'd want `defmacro*' here as well, so as | ||
| 140 | ;; to handle its `declare', but when autoload is run | ||
| 141 | ;; CL is not loaded so macroexpand doesn't know how | ||
| 142 | ;; to expand it! | ||
| 98 | easy-mmode-define-minor-mode define-minor-mode)) | 143 | easy-mmode-define-minor-mode define-minor-mode)) |
| 99 | (setq expand (let ((load-file-name file)) (macroexpand form))) | 144 | (setq expand (let ((load-file-name file)) (macroexpand form))) |
| 100 | (eq (car expand) 'progn) | 145 | (memq (car expand) '(progn prog1 defalias))) |
| 101 | (memq :autoload-end expand)) | 146 | (make-autoload expand file 'expansion)) ;Recurse on the expansion. |
| 102 | (let ((end (memq :autoload-end expand))) | ||
| 103 | ;; Cut-off anything after the :autoload-end marker. | ||
| 104 | (setcdr end nil) | ||
| 105 | (cons 'progn | ||
| 106 | (mapcar (lambda (form) (make-autoload form file)) | ||
| 107 | (cdr expand))))) | ||
| 108 | 147 | ||
| 109 | ;; For special function-like operators, use the `autoload' function. | 148 | ;; For special function-like operators, use the `autoload' function. |
| 110 | ((memq car '(defun define-skeleton defmacro define-derived-mode | 149 | ((memq car '(define-skeleton define-derived-mode |
| 111 | define-compilation-mode define-generic-mode | 150 | define-compilation-mode define-generic-mode |
| 112 | easy-mmode-define-global-mode define-global-minor-mode | 151 | easy-mmode-define-global-mode define-global-minor-mode |
| 113 | define-globalized-minor-mode | 152 | define-globalized-minor-mode |
| @@ -124,40 +163,21 @@ or macro definition or a defcustom)." | |||
| 124 | (t))) | 163 | (t))) |
| 125 | (body (nthcdr (get car 'doc-string-elt) form)) | 164 | (body (nthcdr (get car 'doc-string-elt) form)) |
| 126 | (doc (if (stringp (car body)) (pop body)))) | 165 | (doc (if (stringp (car body)) (pop body)))) |
| 127 | (when (listp args) | 166 | ;; Add the usage form at the end where describe-function-1 |
| 128 | ;; Add the usage form at the end where describe-function-1 | 167 | ;; can recover it. |
| 129 | ;; can recover it. | 168 | (when (listp args) (setq doc (help-add-fundoc-usage doc args))) |
| 130 | (setq doc (help-add-fundoc-usage doc args))) | 169 | ;; `define-generic-mode' quotes the name, so take care of that |
| 131 | (let ((exp | 170 | (list 'autoload (if (listp name) name (list 'quote name)) |
| 132 | ;; `define-generic-mode' quotes the name, so take care of that | 171 | file doc |
| 133 | (list 'autoload (if (listp name) name (list 'quote name)) | 172 | (or (and (memq car '(define-skeleton define-derived-mode |
| 134 | file doc | 173 | define-generic-mode |
| 135 | (or (and (memq car '(define-skeleton define-derived-mode | 174 | easy-mmode-define-global-mode |
| 136 | define-generic-mode | 175 | define-global-minor-mode |
| 137 | easy-mmode-define-global-mode | 176 | define-globalized-minor-mode |
| 138 | define-global-minor-mode | 177 | easy-mmode-define-minor-mode |
| 139 | define-globalized-minor-mode | 178 | define-minor-mode)) t) |
| 140 | easy-mmode-define-minor-mode | 179 | (eq (car-safe (car body)) 'interactive)) |
| 141 | define-minor-mode)) t) | 180 | (if macrop (list 'quote 'macro) nil)))) |
| 142 | (eq (car-safe (car body)) 'interactive)) | ||
| 143 | (if macrop (list 'quote 'macro) nil)))) | ||
| 144 | (when macrop | ||
| 145 | ;; Special case to autoload some of the macro's declarations. | ||
| 146 | (let ((decls (nth (if (stringp (nth 3 form)) 4 3) form)) | ||
| 147 | (exps '())) | ||
| 148 | (when (eq (car-safe decls) 'declare) | ||
| 149 | ;; FIXME: We'd like to reuse macro-declaration-function, | ||
| 150 | ;; but we can't since it doesn't return anything. | ||
| 151 | (dolist (decl decls) | ||
| 152 | (case (car-safe decl) | ||
| 153 | (indent | ||
| 154 | (push `(put ',name 'lisp-indent-function ',(cadr decl)) | ||
| 155 | exps)) | ||
| 156 | (doc-string | ||
| 157 | (push `(put ',name 'doc-string-elt ',(cadr decl)) exps)))) | ||
| 158 | (when exps | ||
| 159 | (setq exp `(progn ,exp ,@exps)))))) | ||
| 160 | exp))) | ||
| 161 | 181 | ||
| 162 | ;; For defclass forms, use `eieio-defclass-autoload'. | 182 | ;; For defclass forms, use `eieio-defclass-autoload'. |
| 163 | ((eq car 'defclass) | 183 | ((eq car 'defclass) |
| @@ -190,6 +210,11 @@ or macro definition or a defcustom)." | |||
| 190 | (if (member ',file loads) nil | 210 | (if (member ',file loads) nil |
| 191 | (put ',groupname 'custom-loads (cons ',file loads)))))) | 211 | (put ',groupname 'custom-loads (cons ',file loads)))))) |
| 192 | 212 | ||
| 213 | ;; When processing a macro expansion, any expression | ||
| 214 | ;; before a :autoload-end should be included. These are typically (put | ||
| 215 | ;; 'fun 'prop val) and things like that. | ||
| 216 | ((and expansion (consp form)) form) | ||
| 217 | |||
| 193 | ;; nil here indicates that this is not a special autoload form. | 218 | ;; nil here indicates that this is not a special autoload form. |
| 194 | (t nil)))) | 219 | (t nil)))) |
| 195 | 220 | ||
| @@ -481,7 +506,7 @@ Return non-nil if and only if FILE adds no autoloads to OUTFILE | |||
| 481 | (search-forward generate-autoload-cookie) | 506 | (search-forward generate-autoload-cookie) |
| 482 | (skip-chars-forward " \t") | 507 | (skip-chars-forward " \t") |
| 483 | (if (eolp) | 508 | (if (eolp) |
| 484 | (condition-case err | 509 | (condition-case-unless-debug err |
| 485 | ;; Read the next form and make an autoload. | 510 | ;; Read the next form and make an autoload. |
| 486 | (let* ((form (prog1 (read (current-buffer)) | 511 | (let* ((form (prog1 (read (current-buffer)) |
| 487 | (or (bolp) (forward-line 1)))) | 512 | (or (bolp) (forward-line 1)))) |
| @@ -671,9 +696,9 @@ file binds `generated-autoload-file' as a file-local variable, | |||
| 671 | write its autoloads into the specified file instead." | 696 | write its autoloads into the specified file instead." |
| 672 | (interactive "DUpdate autoloads from directory: ") | 697 | (interactive "DUpdate autoloads from directory: ") |
| 673 | (let* ((files-re (let ((tmp nil)) | 698 | (let* ((files-re (let ((tmp nil)) |
| 674 | (dolist (suf (get-load-suffixes) | 699 | (dolist (suf (get-load-suffixes)) |
| 675 | (concat "^[^=.].*" (regexp-opt tmp t) "\\'")) | 700 | (unless (string-match "\\.elc" suf) (push suf tmp))) |
| 676 | (unless (string-match "\\.elc" suf) (push suf tmp))))) | 701 | (concat "^[^=.].*" (regexp-opt tmp t) "\\'"))) |
| 677 | (files (apply 'nconc | 702 | (files (apply 'nconc |
| 678 | (mapcar (lambda (dir) | 703 | (mapcar (lambda (dir) |
| 679 | (directory-files (expand-file-name dir) | 704 | (directory-files (expand-file-name dir) |
diff --git a/lisp/emacs-lisp/byte-run.el b/lisp/emacs-lisp/byte-run.el index 9b04e9889dd..df8f588ce01 100644 --- a/lisp/emacs-lisp/byte-run.el +++ b/lisp/emacs-lisp/byte-run.el | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | ;;; byte-run.el --- byte-compiler support for inlining | 1 | ;;; byte-run.el --- byte-compiler support for inlining -*- lexical-binding: t -*- |
| 2 | 2 | ||
| 3 | ;; Copyright (C) 1992, 2001-2012 Free Software Foundation, Inc. | 3 | ;; Copyright (C) 1992, 2001-2012 Free Software Foundation, Inc. |
| 4 | 4 | ||
| @@ -30,9 +30,8 @@ | |||
| 30 | 30 | ||
| 31 | ;;; Code: | 31 | ;;; Code: |
| 32 | 32 | ||
| 33 | ;; We define macro-declaration-function here because it is needed to | 33 | ;; `macro-declaration-function' are both obsolete (as marked at the end of this |
| 34 | ;; handle declarations in macro definitions and this is the first file | 34 | ;; file) but used in many .elc files. |
| 35 | ;; loaded by loadup.el that uses declarations in macros. | ||
| 36 | 35 | ||
| 37 | (defvar macro-declaration-function #'macro-declaration-function | 36 | (defvar macro-declaration-function #'macro-declaration-function |
| 38 | "Function to process declarations in a macro definition. | 37 | "Function to process declarations in a macro definition. |
| @@ -66,6 +65,45 @@ The return value of this function is not used." | |||
| 66 | (message "Unknown declaration %s" d))) | 65 | (message "Unknown declaration %s" d))) |
| 67 | (message "Invalid declaration %s" d)))))) | 66 | (message "Invalid declaration %s" d)))))) |
| 68 | 67 | ||
| 68 | ;; We define macro-declaration-alist here because it is needed to | ||
| 69 | ;; handle declarations in macro definitions and this is the first file | ||
| 70 | ;; loaded by loadup.el that uses declarations in macros. | ||
| 71 | |||
| 72 | (defvar defun-declarations-alist | ||
| 73 | ;; FIXME: Should we also add an `obsolete' property? | ||
| 74 | (list | ||
| 75 | ;; Too bad we can't use backquote yet at this stage of the bootstrap. | ||
| 76 | (list 'advertised-calling-convention | ||
| 77 | #'(lambda (f arglist when) | ||
| 78 | (list 'set-advertised-calling-convention | ||
| 79 | (list 'quote f) (list 'quote arglist) (list 'quote when)))) | ||
| 80 | (list 'doc-string | ||
| 81 | #'(lambda (f pos) | ||
| 82 | (list 'put (list 'quote f) ''doc-string-elt (list 'quote pos)))) | ||
| 83 | (list 'indent | ||
| 84 | #'(lambda (f val) | ||
| 85 | (list 'put (list 'quote f) | ||
| 86 | ''lisp-indent-function (list 'quote val))))) | ||
| 87 | "List associating function properties to their macro expansion. | ||
| 88 | Each element of the list takes the form (PROP FUN) where FUN is | ||
| 89 | a function. For each (PROP . VALUES) in a function's declaration, | ||
| 90 | the FUN corresponding to PROP is called with the function name | ||
| 91 | and the VALUES and should return the code to use to set this property.") | ||
| 92 | |||
| 93 | (defvar macro-declarations-alist | ||
| 94 | (cons | ||
| 95 | (list 'debug | ||
| 96 | #'(lambda (name spec) | ||
| 97 | (list 'progn :autoload-end | ||
| 98 | (list 'put (list 'quote name) | ||
| 99 | ''edebug-form-spec (list 'quote spec))))) | ||
| 100 | defun-declarations-alist) | ||
| 101 | "List associating properties of macros to their macro expansion. | ||
| 102 | Each element of the list takes the form (PROP FUN) where FUN is | ||
| 103 | a function. For each (PROP . VALUES) in a macro's declaration, | ||
| 104 | the FUN corresponding to PROP is called with the function name | ||
| 105 | and the VALUES and should return the code to use to set this property.") | ||
| 106 | |||
| 69 | (put 'defmacro 'doc-string-elt 3) | 107 | (put 'defmacro 'doc-string-elt 3) |
| 70 | (defalias 'defmacro | 108 | (defalias 'defmacro |
| 71 | (cons | 109 | (cons |
| @@ -76,21 +114,9 @@ When the macro is called, as in (NAME ARGS...), | |||
| 76 | the function (lambda ARGLIST BODY...) is applied to | 114 | the function (lambda ARGLIST BODY...) is applied to |
| 77 | the list ARGS... as it appears in the expression, | 115 | the list ARGS... as it appears in the expression, |
| 78 | and the result should be a form to be evaluated instead of the original. | 116 | and the result should be a form to be evaluated instead of the original. |
| 79 | 117 | DECL is a declaration, optional, of the form (declare DECLS...) where | |
| 80 | DECL is a declaration, optional, which can specify how to indent | 118 | DECLS is a list of elements of the form (PROP . VALUES). These are |
| 81 | calls to this macro, how Edebug should handle it, and which argument | 119 | interpreted according to `macro-declarations-alist'." |
| 82 | should be treated as documentation. It looks like this: | ||
| 83 | (declare SPECS...) | ||
| 84 | The elements can look like this: | ||
| 85 | (indent INDENT) | ||
| 86 | Set NAME's `lisp-indent-function' property to INDENT. | ||
| 87 | |||
| 88 | (debug DEBUG) | ||
| 89 | Set NAME's `edebug-form-spec' property to DEBUG. (This is | ||
| 90 | equivalent to writing a `def-edebug-spec' for the macro.) | ||
| 91 | |||
| 92 | (doc-string ELT) | ||
| 93 | Set NAME's `doc-string-elt' property to ELT." | ||
| 94 | (if (stringp docstring) nil | 120 | (if (stringp docstring) nil |
| 95 | (if decl (setq body (cons decl body))) | 121 | (if decl (setq body (cons decl body))) |
| 96 | (setq decl docstring) | 122 | (setq decl docstring) |
| @@ -104,28 +130,67 @@ The elements can look like this: | |||
| 104 | (let* ((fun (list 'function (cons 'lambda (cons arglist body)))) | 130 | (let* ((fun (list 'function (cons 'lambda (cons arglist body)))) |
| 105 | (def (list 'defalias | 131 | (def (list 'defalias |
| 106 | (list 'quote name) | 132 | (list 'quote name) |
| 107 | (list 'cons ''macro fun)))) | 133 | (list 'cons ''macro fun))) |
| 108 | (if decl | 134 | (declarations |
| 109 | (list 'progn | 135 | (mapcar |
| 110 | (list 'funcall 'macro-declaration-function | 136 | #'(lambda (x) |
| 111 | (list 'quote name) | 137 | (let ((f (cdr (assq (car x) macro-declarations-alist)))) |
| 112 | (list 'quote decl)) | 138 | (if f (apply (car f) name (cdr x)) |
| 113 | def) | 139 | (message "Warning: Unknown macro property %S in %S" |
| 140 | (car x) name)))) | ||
| 141 | (cdr decl)))) | ||
| 142 | (if declarations | ||
| 143 | (cons 'prog1 (cons def declarations)) | ||
| 114 | def))))) | 144 | def))))) |
| 115 | 145 | ||
| 116 | ;; Now that we defined defmacro we can use it! | 146 | ;; Now that we defined defmacro we can use it! |
| 117 | (defmacro defun (name arglist &optional docstring &rest body) | 147 | (defmacro defun (name arglist &optional docstring &rest body) |
| 118 | "Define NAME as a function. | 148 | "Define NAME as a function. |
| 119 | The definition is (lambda ARGLIST [DOCSTRING] BODY...). | 149 | The definition is (lambda ARGLIST [DOCSTRING] BODY...). |
| 120 | See also the function `interactive'." | 150 | See also the function `interactive'. |
| 151 | DECL is a declaration, optional, of the form (declare DECLS...) where | ||
| 152 | DECLS is a list of elements of the form (PROP . VALUES). These are | ||
| 153 | interpreted according to `defun-declarations-alist'. | ||
| 154 | |||
| 155 | \(fn NAME ARGLIST &optional DOCSTRING DECL &rest BODY)" | ||
| 156 | ;; We can't just have `decl' as an &optional argument, because we need | ||
| 157 | ;; to distinguish | ||
| 158 | ;; (defun foo (arg) (toto) nil) | ||
| 159 | ;; from | ||
| 160 | ;; (defun foo (arg) (toto)). | ||
| 121 | (declare (doc-string 3)) | 161 | (declare (doc-string 3)) |
| 122 | (if docstring (setq body (cons docstring body)) | 162 | (let ((decls (cond |
| 123 | (if (null body) (setq body '(nil)))) | 163 | ((eq (car-safe docstring) 'declare) |
| 124 | (list 'defalias | 164 | (prog1 (cdr docstring) (setq docstring nil))) |
| 125 | (list 'quote name) | 165 | ((eq (car-safe (car body)) 'declare) |
| 126 | (list 'function | 166 | (prog1 (cdr (car body)) (setq body (cdr body))))))) |
| 127 | (cons 'lambda | 167 | (if docstring (setq body (cons docstring body)) |
| 128 | (cons arglist body))))) | 168 | (if (null body) (setq body '(nil)))) |
| 169 | (let ((declarations | ||
| 170 | (mapcar | ||
| 171 | #'(lambda (x) | ||
| 172 | (let ((f (cdr (assq (car x) defun-declarations-alist)))) | ||
| 173 | (cond | ||
| 174 | (f (apply (car f) name (cdr x))) | ||
| 175 | ;; Yuck!! | ||
| 176 | ((and (featurep 'cl) | ||
| 177 | (memq (car x) ;C.f. cl-do-proclaim. | ||
| 178 | '(special inline notinline optimize warn))) | ||
| 179 | (if (null (stringp docstring)) | ||
| 180 | (push (list 'declare x) body) | ||
| 181 | (setcdr body (cons (list 'declare x) (cdr body)))) | ||
| 182 | nil) | ||
| 183 | (t (message "Warning: Unknown defun property %S in %S" | ||
| 184 | (car x) name))))) | ||
| 185 | decls)) | ||
| 186 | (def (list 'defalias | ||
| 187 | (list 'quote name) | ||
| 188 | (list 'function | ||
| 189 | (cons 'lambda | ||
| 190 | (cons arglist body)))))) | ||
| 191 | (if declarations | ||
| 192 | (cons 'prog1 (cons def declarations)) | ||
| 193 | def)))) | ||
| 129 | 194 | ||
| 130 | ;; Redefined in byte-optimize.el. | 195 | ;; Redefined in byte-optimize.el. |
| 131 | ;; This is not documented--it's not clear that we should promote it. | 196 | ;; This is not documented--it's not clear that we should promote it. |
| @@ -158,7 +223,6 @@ See also the function `interactive'." | |||
| 158 | ;; (list 'put x ''byte-optimizer nil))) | 223 | ;; (list 'put x ''byte-optimizer nil))) |
| 159 | ;; fns))) | 224 | ;; fns))) |
| 160 | 225 | ||
| 161 | ;; This has a special byte-hunk-handler in bytecomp.el. | ||
| 162 | (defmacro defsubst (name arglist &rest body) | 226 | (defmacro defsubst (name arglist &rest body) |
| 163 | "Define an inline function. The syntax is just like that of `defun'." | 227 | "Define an inline function. The syntax is just like that of `defun'." |
| 164 | (declare (debug defun) (doc-string 3)) | 228 | (declare (debug defun) (doc-string 3)) |
| @@ -172,7 +236,7 @@ See also the function `interactive'." | |||
| 172 | 236 | ||
| 173 | (defvar advertised-signature-table (make-hash-table :test 'eq :weakness 'key)) | 237 | (defvar advertised-signature-table (make-hash-table :test 'eq :weakness 'key)) |
| 174 | 238 | ||
| 175 | (defun set-advertised-calling-convention (function signature when) | 239 | (defun set-advertised-calling-convention (function signature _when) |
| 176 | "Set the advertised SIGNATURE of FUNCTION. | 240 | "Set the advertised SIGNATURE of FUNCTION. |
| 177 | This will allow the byte-compiler to warn the programmer when she uses | 241 | This will allow the byte-compiler to warn the programmer when she uses |
| 178 | an obsolete calling convention. WHEN specifies since when the calling | 242 | an obsolete calling convention. WHEN specifies since when the calling |
| @@ -187,15 +251,15 @@ If CURRENT-NAME is a string, that is the `use instead' message | |||
| 187 | \(it should end with a period, and not start with a capital). | 251 | \(it should end with a period, and not start with a capital). |
| 188 | WHEN should be a string indicating when the function | 252 | WHEN should be a string indicating when the function |
| 189 | was first made obsolete, for example a date or a release number." | 253 | was first made obsolete, for example a date or a release number." |
| 254 | (declare (advertised-calling-convention | ||
| 255 | ;; New code should always provide the `when' argument. | ||
| 256 | (obsolete-name current-name when) "23.1")) | ||
| 190 | (interactive "aMake function obsolete: \nxObsoletion replacement: ") | 257 | (interactive "aMake function obsolete: \nxObsoletion replacement: ") |
| 191 | (put obsolete-name 'byte-obsolete-info | 258 | (put obsolete-name 'byte-obsolete-info |
| 192 | ;; The second entry used to hold the `byte-compile' handler, but | 259 | ;; The second entry used to hold the `byte-compile' handler, but |
| 193 | ;; is not used any more nowadays. | 260 | ;; is not used any more nowadays. |
| 194 | (purecopy (list current-name nil when))) | 261 | (purecopy (list current-name nil when))) |
| 195 | obsolete-name) | 262 | obsolete-name) |
| 196 | (set-advertised-calling-convention | ||
| 197 | ;; New code should always provide the `when' argument. | ||
| 198 | 'make-obsolete '(obsolete-name current-name when) "23.1") | ||
| 199 | 263 | ||
| 200 | (defmacro define-obsolete-function-alias (obsolete-name current-name | 264 | (defmacro define-obsolete-function-alias (obsolete-name current-name |
| 201 | &optional when docstring) | 265 | &optional when docstring) |
| @@ -209,14 +273,13 @@ is equivalent to the following two lines of code: | |||
| 209 | \(make-obsolete 'old-fun 'new-fun \"22.1\") | 273 | \(make-obsolete 'old-fun 'new-fun \"22.1\") |
| 210 | 274 | ||
| 211 | See the docstrings of `defalias' and `make-obsolete' for more details." | 275 | See the docstrings of `defalias' and `make-obsolete' for more details." |
| 212 | (declare (doc-string 4)) | 276 | (declare (doc-string 4) |
| 277 | (advertised-calling-convention | ||
| 278 | ;; New code should always provide the `when' argument. | ||
| 279 | (obsolete-name current-name when &optional docstring) "23.1")) | ||
| 213 | `(progn | 280 | `(progn |
| 214 | (defalias ,obsolete-name ,current-name ,docstring) | 281 | (defalias ,obsolete-name ,current-name ,docstring) |
| 215 | (make-obsolete ,obsolete-name ,current-name ,when))) | 282 | (make-obsolete ,obsolete-name ,current-name ,when))) |
| 216 | (set-advertised-calling-convention | ||
| 217 | ;; New code should always provide the `when' argument. | ||
| 218 | 'define-obsolete-function-alias | ||
| 219 | '(obsolete-name current-name when &optional docstring) "23.1") | ||
| 220 | 283 | ||
| 221 | (defun make-obsolete-variable (obsolete-name current-name &optional when access-type) | 284 | (defun make-obsolete-variable (obsolete-name current-name &optional when access-type) |
| 222 | "Make the byte-compiler warn that OBSOLETE-NAME is obsolete. | 285 | "Make the byte-compiler warn that OBSOLETE-NAME is obsolete. |
| @@ -226,13 +289,13 @@ WHEN should be a string indicating when the variable | |||
| 226 | was first made obsolete, for example a date or a release number. | 289 | was first made obsolete, for example a date or a release number. |
| 227 | ACCESS-TYPE if non-nil should specify the kind of access that will trigger | 290 | ACCESS-TYPE if non-nil should specify the kind of access that will trigger |
| 228 | obsolescence warnings; it can be either `get' or `set'." | 291 | obsolescence warnings; it can be either `get' or `set'." |
| 292 | (declare (advertised-calling-convention | ||
| 293 | ;; New code should always provide the `when' argument. | ||
| 294 | (obsolete-name current-name when &optional access-type) "23.1")) | ||
| 229 | (put obsolete-name 'byte-obsolete-variable | 295 | (put obsolete-name 'byte-obsolete-variable |
| 230 | (purecopy (list current-name access-type when))) | 296 | (purecopy (list current-name access-type when))) |
| 231 | obsolete-name) | 297 | obsolete-name) |
| 232 | (set-advertised-calling-convention | 298 | |
| 233 | ;; New code should always provide the `when' argument. | ||
| 234 | 'make-obsolete-variable | ||
| 235 | '(obsolete-name current-name when &optional access-type) "23.1") | ||
| 236 | 299 | ||
| 237 | (defmacro define-obsolete-variable-alias (obsolete-name current-name | 300 | (defmacro define-obsolete-variable-alias (obsolete-name current-name |
| 238 | &optional when docstring) | 301 | &optional when docstring) |
| @@ -255,7 +318,10 @@ For the benefit of `custom-set-variables', if OBSOLETE-NAME has | |||
| 255 | any of the following properties, they are copied to | 318 | any of the following properties, they are copied to |
| 256 | CURRENT-NAME, if it does not already have them: | 319 | CURRENT-NAME, if it does not already have them: |
| 257 | 'saved-value, 'saved-variable-comment." | 320 | 'saved-value, 'saved-variable-comment." |
| 258 | (declare (doc-string 4)) | 321 | (declare (doc-string 4) |
| 322 | (advertised-calling-convention | ||
| 323 | ;; New code should always provide the `when' argument. | ||
| 324 | (obsolete-name current-name when &optional docstring) "23.1")) | ||
| 259 | `(progn | 325 | `(progn |
| 260 | (defvaralias ,obsolete-name ,current-name ,docstring) | 326 | (defvaralias ,obsolete-name ,current-name ,docstring) |
| 261 | ;; See Bug#4706. | 327 | ;; See Bug#4706. |
| @@ -264,10 +330,6 @@ CURRENT-NAME, if it does not already have them: | |||
| 264 | (null (get ,current-name prop)) | 330 | (null (get ,current-name prop)) |
| 265 | (put ,current-name prop (get ,obsolete-name prop)))) | 331 | (put ,current-name prop (get ,obsolete-name prop)))) |
| 266 | (make-obsolete-variable ,obsolete-name ,current-name ,when))) | 332 | (make-obsolete-variable ,obsolete-name ,current-name ,when))) |
| 267 | (set-advertised-calling-convention | ||
| 268 | ;; New code should always provide the `when' argument. | ||
| 269 | 'define-obsolete-variable-alias | ||
| 270 | '(obsolete-name current-name when &optional docstring) "23.1") | ||
| 271 | 333 | ||
| 272 | ;; FIXME This is only defined in this file because the variable- and | 334 | ;; FIXME This is only defined in this file because the variable- and |
| 273 | ;; function- versions are too. Unlike those two, this one is not used | 335 | ;; function- versions are too. Unlike those two, this one is not used |
| @@ -348,4 +410,9 @@ In interpreted code, this is entirely equivalent to `progn'." | |||
| 348 | ;; (file-format emacs19))" | 410 | ;; (file-format emacs19))" |
| 349 | ;; nil) | 411 | ;; nil) |
| 350 | 412 | ||
| 413 | (make-obsolete-variable 'macro-declaration-function | ||
| 414 | 'macro-declarations-alist "24.2") | ||
| 415 | (make-obsolete 'macro-declaration-function | ||
| 416 | 'macro-declarations-alist "24.2") | ||
| 417 | |||
| 351 | ;;; byte-run.el ends here | 418 | ;;; byte-run.el ends here |
diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el index a11f213e646..d522f07249a 100644 --- a/lisp/emacs-lisp/easy-mmode.el +++ b/lisp/emacs-lisp/easy-mmode.el | |||
| @@ -229,6 +229,7 @@ For example, you could write | |||
| 229 | (variable nil) | 229 | (variable nil) |
| 230 | ((not globalp) | 230 | ((not globalp) |
| 231 | `(progn | 231 | `(progn |
| 232 | :autoload-end | ||
| 232 | (defvar ,mode ,init-value ,(format "Non-nil if %s is enabled. | 233 | (defvar ,mode ,init-value ,(format "Non-nil if %s is enabled. |
| 233 | Use the command `%s' to change this variable." pretty-name mode)) | 234 | Use the command `%s' to change this variable." pretty-name mode)) |
| 234 | (make-variable-buffer-local ',mode))) | 235 | (make-variable-buffer-local ',mode))) |
| @@ -366,8 +367,10 @@ call another major mode in their body." | |||
| 366 | "-mode\\'" "" (symbol-name mode)))))) | 367 | "-mode\\'" "" (symbol-name mode)))))) |
| 367 | 368 | ||
| 368 | `(progn | 369 | `(progn |
| 369 | (defvar ,MODE-major-mode nil) | 370 | (progn |
| 370 | (make-variable-buffer-local ',MODE-major-mode) | 371 | :autoload-end |
| 372 | (defvar ,MODE-major-mode nil) | ||
| 373 | (make-variable-buffer-local ',MODE-major-mode)) | ||
| 371 | ;; The actual global minor-mode | 374 | ;; The actual global minor-mode |
| 372 | (define-minor-mode ,global-mode | 375 | (define-minor-mode ,global-mode |
| 373 | ;; Very short lines to avoid too long lines in the generated | 376 | ;; Very short lines to avoid too long lines in the generated |