diff options
| author | Stefan Monnier | 2017-07-28 12:02:01 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2017-07-28 12:02:01 -0400 |
| commit | bfb8d33fd18b1d9fd5868204d472cb19f5bcafbe (patch) | |
| tree | 3ca8b55d994ad39e94fd972b02e6d7d539339c25 | |
| parent | b2225a374f24f1ee1a881bfd5d3c1f7b57447e47 (diff) | |
| download | emacs-bfb8d33fd18b1d9fd5868204d472cb19f5bcafbe.tar.gz emacs-bfb8d33fd18b1d9fd5868204d472cb19f5bcafbe.zip | |
* lisp/subr.el (define-symbol-prop): New function
(symbol-file): Make it find symbol property definitions.
* lisp/emacs-lisp/pcase.el (pcase-defmacro):
* lisp/emacs-lisp/ert.el (ert-set-test): Use it instead of `put'.
(ert-describe-test): Adjust call to symbol-file accordingly.
| -rw-r--r-- | etc/NEWS | 2 | ||||
| -rw-r--r-- | lisp/emacs-lisp/ert.el | 11 | ||||
| -rw-r--r-- | lisp/emacs-lisp/pcase.el | 4 | ||||
| -rw-r--r-- | lisp/loadhist.el | 5 | ||||
| -rw-r--r-- | lisp/subr.el | 57 | ||||
| -rw-r--r-- | test/lisp/emacs-lisp/ert-tests.el | 2 |
6 files changed, 51 insertions, 30 deletions
| @@ -1175,6 +1175,8 @@ break. | |||
| 1175 | 1175 | ||
| 1176 | * Lisp Changes in Emacs 26.1 | 1176 | * Lisp Changes in Emacs 26.1 |
| 1177 | 1177 | ||
| 1178 | ** New function `define-symbol-prop'. | ||
| 1179 | |||
| 1178 | +++ | 1180 | +++ |
| 1179 | ** New optional argument TESTFN in 'alist-get', 'map-elt' and 'map-put'. | 1181 | ** New optional argument TESTFN in 'alist-get', 'map-elt' and 'map-put'. |
| 1180 | 1182 | ||
diff --git a/lisp/emacs-lisp/ert.el b/lisp/emacs-lisp/ert.el index 5186199cfce..d7bd331c11b 100644 --- a/lisp/emacs-lisp/ert.el +++ b/lisp/emacs-lisp/ert.el | |||
| @@ -135,16 +135,9 @@ Emacs bug 6581 at URL `http://debbugs.gnu.org/cgi/bugreport.cgi?bug=6581'." | |||
| 135 | ;; Note that nil is still a valid value for the `name' slot in | 135 | ;; Note that nil is still a valid value for the `name' slot in |
| 136 | ;; ert-test objects. It designates an anonymous test. | 136 | ;; ert-test objects. It designates an anonymous test. |
| 137 | (error "Attempt to define a test named nil")) | 137 | (error "Attempt to define a test named nil")) |
| 138 | (put symbol 'ert--test definition) | 138 | (define-symbol-prop symbol 'ert--test definition) |
| 139 | ;; Register in load-history, so `symbol-file' can find us, and so | ||
| 140 | ;; unload-feature can unload our tests. | ||
| 141 | (cl-pushnew `(ert-deftest . ,symbol) current-load-list :test #'equal) | ||
| 142 | definition) | 139 | definition) |
| 143 | 140 | ||
| 144 | (cl-defmethod loadhist-unload-element ((x (head ert-deftest))) | ||
| 145 | (let ((name (cdr x))) | ||
| 146 | (put name 'ert--test nil))) | ||
| 147 | |||
| 148 | (defun ert-make-test-unbound (symbol) | 141 | (defun ert-make-test-unbound (symbol) |
| 149 | "Make SYMBOL name no test. Return SYMBOL." | 142 | "Make SYMBOL name no test. Return SYMBOL." |
| 150 | (cl-remprop symbol 'ert--test) | 143 | (cl-remprop symbol 'ert--test) |
| @@ -2539,7 +2532,7 @@ To be used in the ERT results buffer." | |||
| 2539 | (insert (if test-name (format "%S" test-name) "<anonymous test>")) | 2532 | (insert (if test-name (format "%S" test-name) "<anonymous test>")) |
| 2540 | (insert " is a test") | 2533 | (insert " is a test") |
| 2541 | (let ((file-name (and test-name | 2534 | (let ((file-name (and test-name |
| 2542 | (symbol-file test-name 'ert-deftest)))) | 2535 | (symbol-file test-name 'ert--test)))) |
| 2543 | (when file-name | 2536 | (when file-name |
| 2544 | (insert (format-message " defined in `%s'" | 2537 | (insert (format-message " defined in `%s'" |
| 2545 | (file-name-nondirectory file-name))) | 2538 | (file-name-nondirectory file-name))) |
diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el index b40161104d2..253b60e7534 100644 --- a/lisp/emacs-lisp/pcase.el +++ b/lisp/emacs-lisp/pcase.el | |||
| @@ -418,8 +418,8 @@ to this macro." | |||
| 418 | (when decl (setq body (remove decl body))) | 418 | (when decl (setq body (remove decl body))) |
| 419 | `(progn | 419 | `(progn |
| 420 | (defun ,fsym ,args ,@body) | 420 | (defun ,fsym ,args ,@body) |
| 421 | (put ',fsym 'edebug-form-spec ',(cadr (assq 'debug decl))) | 421 | (define-symbol-prop ',fsym 'edebug-form-spec ',(cadr (assq 'debug decl))) |
| 422 | (put ',name 'pcase-macroexpander #',fsym)))) | 422 | (define-symbol-prop ',name 'pcase-macroexpander #',fsym)))) |
| 423 | 423 | ||
| 424 | (defun pcase--match (val upat) | 424 | (defun pcase--match (val upat) |
| 425 | "Build a MATCH structure, hoisting all `or's and `and's outside." | 425 | "Build a MATCH structure, hoisting all `or's and `and's outside." |
diff --git a/lisp/loadhist.el b/lisp/loadhist.el index b83d023ccf8..18c30f781f0 100644 --- a/lisp/loadhist.el +++ b/lisp/loadhist.el | |||
| @@ -221,6 +221,11 @@ restore a previous autoload if possible.") | |||
| 221 | ;; Remove the struct. | 221 | ;; Remove the struct. |
| 222 | (setf (cl--find-class name) nil))) | 222 | (setf (cl--find-class name) nil))) |
| 223 | 223 | ||
| 224 | (cl-defmethod loadhist-unload-element ((x (head define-symbol-props))) | ||
| 225 | (pcase-dolist (`(,symbol . ,props) (cdr x)) | ||
| 226 | (dolist (prop props) | ||
| 227 | (put symbol prop nil)))) | ||
| 228 | |||
| 224 | ;;;###autoload | 229 | ;;;###autoload |
| 225 | (defun unload-feature (feature &optional force) | 230 | (defun unload-feature (feature &optional force) |
| 226 | "Unload the library that provided FEATURE. | 231 | "Unload the library that provided FEATURE. |
diff --git a/lisp/subr.el b/lisp/subr.el index 90a78cf68a0..b3f9f902349 100644 --- a/lisp/subr.el +++ b/lisp/subr.el | |||
| @@ -1999,6 +1999,25 @@ If TOGGLE has a `:menu-tag', that is used for the menu item's label." | |||
| 1999 | ;; "Return the name of the file from which AUTOLOAD will be loaded. | 1999 | ;; "Return the name of the file from which AUTOLOAD will be loaded. |
| 2000 | ;; \n\(fn AUTOLOAD)") | 2000 | ;; \n\(fn AUTOLOAD)") |
| 2001 | 2001 | ||
| 2002 | (defun define-symbol-prop (symbol prop val) | ||
| 2003 | "Define the property PROP of SYMBOL to be VAL. | ||
| 2004 | This is to `put' what `defalias' is to `fset'." | ||
| 2005 | ;; Can't use `cl-pushnew' here (nor `push' on (cdr foo)). | ||
| 2006 | ;; (cl-pushnew symbol (alist-get prop | ||
| 2007 | ;; (alist-get 'define-symbol-props | ||
| 2008 | ;; current-load-list))) | ||
| 2009 | (let ((sps (assq 'define-symbol-props current-load-list))) | ||
| 2010 | (unless sps | ||
| 2011 | (setq sps (list 'define-symbol-props)) | ||
| 2012 | (push sps current-load-list)) | ||
| 2013 | (let ((ps (assq prop sps))) | ||
| 2014 | (unless ps | ||
| 2015 | (setq ps (list prop)) | ||
| 2016 | (setcdr sps (cons ps (cdr sps)))) | ||
| 2017 | (unless (member symbol (cdr ps)) | ||
| 2018 | (setcdr ps (cons symbol (cdr ps)))))) | ||
| 2019 | (put symbol prop val)) | ||
| 2020 | |||
| 2002 | (defun symbol-file (symbol &optional type) | 2021 | (defun symbol-file (symbol &optional type) |
| 2003 | "Return the name of the file that defined SYMBOL. | 2022 | "Return the name of the file that defined SYMBOL. |
| 2004 | The value is normally an absolute file name. It can also be nil, | 2023 | The value is normally an absolute file name. It can also be nil, |
| @@ -2008,28 +2027,30 @@ file name without extension. | |||
| 2008 | 2027 | ||
| 2009 | If TYPE is nil, then any kind of definition is acceptable. If | 2028 | If TYPE is nil, then any kind of definition is acceptable. If |
| 2010 | TYPE is `defun', `defvar', or `defface', that specifies function | 2029 | TYPE is `defun', `defvar', or `defface', that specifies function |
| 2011 | definition, variable definition, or face definition only." | 2030 | definition, variable definition, or face definition only. |
| 2031 | Otherwise TYPE is assumed to be a symbol property." | ||
| 2012 | (if (and (or (null type) (eq type 'defun)) | 2032 | (if (and (or (null type) (eq type 'defun)) |
| 2013 | (symbolp symbol) | 2033 | (symbolp symbol) |
| 2014 | (autoloadp (symbol-function symbol))) | 2034 | (autoloadp (symbol-function symbol))) |
| 2015 | (nth 1 (symbol-function symbol)) | 2035 | (nth 1 (symbol-function symbol)) |
| 2016 | (let ((files load-history) | 2036 | (catch 'found |
| 2017 | file match) | 2037 | (pcase-dolist (`(,file . ,elems) load-history) |
| 2018 | (while files | 2038 | (when (if type |
| 2019 | (if (if type | 2039 | (if (eq type 'defvar) |
| 2020 | (if (eq type 'defvar) | 2040 | ;; Variables are present just as their names. |
| 2021 | ;; Variables are present just as their names. | 2041 | (member symbol elems) |
| 2022 | (member symbol (cdr (car files))) | 2042 | ;; Many other types are represented as (TYPE . NAME). |
| 2023 | ;; Other types are represented as (TYPE . NAME). | 2043 | (or (member (cons type symbol) elems) |
| 2024 | (member (cons type symbol) (cdr (car files)))) | 2044 | (memq symbol (alist-get type |
| 2025 | ;; We accept all types, so look for variable def | 2045 | (alist-get 'define-symbol-props |
| 2026 | ;; and then for any other kind. | 2046 | elems))))) |
| 2027 | (or (member symbol (cdr (car files))) | 2047 | ;; We accept all types, so look for variable def |
| 2028 | (and (setq match (rassq symbol (cdr (car files)))) | 2048 | ;; and then for any other kind. |
| 2029 | (not (eq 'require (car match)))))) | 2049 | (or (member symbol elems) |
| 2030 | (setq file (car (car files)) files nil)) | 2050 | (let ((match (rassq symbol elems))) |
| 2031 | (setq files (cdr files))) | 2051 | (and match |
| 2032 | file))) | 2052 | (not (eq 'require (car match))))))) |
| 2053 | (throw 'found file)))))) | ||
| 2033 | 2054 | ||
| 2034 | (defun locate-library (library &optional nosuffix path interactive-call) | 2055 | (defun locate-library (library &optional nosuffix path interactive-call) |
| 2035 | "Show the precise file name of Emacs library LIBRARY. | 2056 | "Show the precise file name of Emacs library LIBRARY. |
diff --git a/test/lisp/emacs-lisp/ert-tests.el b/test/lisp/emacs-lisp/ert-tests.el index 317838b250f..57463ad932d 100644 --- a/test/lisp/emacs-lisp/ert-tests.el +++ b/test/lisp/emacs-lisp/ert-tests.el | |||
| @@ -352,7 +352,7 @@ This macro is used to test if macroexpansion in `should' works." | |||
| 352 | (let ((abc (ert-get-test 'ert-test-abc))) | 352 | (let ((abc (ert-get-test 'ert-test-abc))) |
| 353 | (should (equal (ert-test-tags abc) '(bar))) | 353 | (should (equal (ert-test-tags abc) '(bar))) |
| 354 | (should (equal (ert-test-documentation abc) "foo"))) | 354 | (should (equal (ert-test-documentation abc) "foo"))) |
| 355 | (should (equal (symbol-file 'ert-test-deftest 'ert-deftest) | 355 | (should (equal (symbol-file 'ert-test-deftest 'ert--test) |
| 356 | (symbol-file 'ert-test--which-file 'defun))) | 356 | (symbol-file 'ert-test--which-file 'defun))) |
| 357 | 357 | ||
| 358 | (ert-deftest ert-test-def () :expected-result ':passed) | 358 | (ert-deftest ert-test-def () :expected-result ':passed) |