diff options
| author | Stephen Leake | 2015-08-13 12:54:39 -0500 |
|---|---|---|
| committer | Stephen Leake | 2015-08-13 13:16:47 -0500 |
| commit | 0382fd42c6979bbedc9230b789503258a5e963eb (patch) | |
| tree | 989b157edeb659f5e0b2b3e8b884ec143dcbe3fd /test | |
| parent | 9c13a81a9e1aa74901cd958d7adb3ca71966dbef (diff) | |
| download | emacs-0382fd42c6979bbedc9230b789503258a5e963eb.tar.gz emacs-0382fd42c6979bbedc9230b789503258a5e963eb.zip | |
xref-find-definitions: Exclude more generic function items.
* lisp/emacs-lisp/cl-generic.el (cl--generic-search-method): Add doc string.
(cl--generic-find-defgeneric-regexp): New.
(find-function-regexp-alist): Add it.
* lisp/emacs-lisp/find-func.el (find-feature-regexp): Move here from
elisp-mode.el, change to search for ";;; Code:"
(find-alias-regexp): Move here from elisp-mode.el, cleaned up.
(find-function-regexp-alist): Add them.
* lisp/progmodes/elisp-mode.el:
(elisp--xref-format, elisp--xref-format-extra): Change back to defvar due
to bug#21237.
(elisp--xref-find-definitions): Exclude co-located default methods for
generic functions. Also exclude implicitly declared defgeneric.
(elisp--xref-find-definitions): Handle C source properly. Exclude minor
mode variables defined by 'define-minor-mode'.
* test/automated/elisp-mode-tests.el: Declare generic functions, add
tests for them.
(xref-elisp-test-run): Fix bug.
(emacs-test-dir): Improve initial value.
(find-defs-defun-defvar-el): Don't expect defvar.
(find-defs-feature-el): Match change to find-feature-regexp.
Diffstat (limited to 'test')
| -rw-r--r-- | test/automated/elisp-mode-tests.el | 170 |
1 files changed, 154 insertions, 16 deletions
diff --git a/test/automated/elisp-mode-tests.el b/test/automated/elisp-mode-tests.el index 9b4014a8a55..47212e919c6 100644 --- a/test/automated/elisp-mode-tests.el +++ b/test/automated/elisp-mode-tests.el | |||
| @@ -177,8 +177,8 @@ | |||
| 177 | 177 | ||
| 178 | 178 | ||
| 179 | (defun xref-elisp-test-run (xrefs expecteds) | 179 | (defun xref-elisp-test-run (xrefs expecteds) |
| 180 | (should (= (length xrefs) (length expecteds))) | ||
| 180 | (while xrefs | 181 | (while xrefs |
| 181 | (should (= (length xrefs) (length expecteds))) | ||
| 182 | (let ((xref (pop xrefs)) | 182 | (let ((xref (pop xrefs)) |
| 183 | (expected (pop expecteds))) | 183 | (expected (pop expecteds))) |
| 184 | 184 | ||
| @@ -204,8 +204,9 @@ to (xref-elisp-test-descr-to-target xref)." | |||
| 204 | 204 | ||
| 205 | ;; When tests are run from the Makefile, 'default-directory' is $HOME, | 205 | ;; When tests are run from the Makefile, 'default-directory' is $HOME, |
| 206 | ;; so we must provide this dir to expand-file-name in the expected | 206 | ;; so we must provide this dir to expand-file-name in the expected |
| 207 | ;; results. The Makefile sets EMACS_TEST_DIRECTORY. | 207 | ;; results. This also allows running these tests from other |
| 208 | (defconst emacs-test-dir (getenv "EMACS_TEST_DIRECTORY")) | 208 | ;; directories. |
| 209 | (defconst emacs-test-dir (file-name-directory (or load-file-name (buffer-file-name)))) | ||
| 209 | 210 | ||
| 210 | ;; alphabetical by test name | 211 | ;; alphabetical by test name |
| 211 | 212 | ||
| @@ -244,12 +245,144 @@ to (xref-elisp-test-descr-to-target xref)." | |||
| 244 | 245 | ||
| 245 | ;; FIXME: defconst | 246 | ;; FIXME: defconst |
| 246 | 247 | ||
| 248 | ;; FIXME: eieio defclass | ||
| 249 | |||
| 250 | ;; Possible ways of defining the default method implementation for a | ||
| 251 | ;; generic function. We declare these here, so we know we cover all | ||
| 252 | ;; cases, and we don't rely on other code not changing. | ||
| 253 | ;; | ||
| 254 | ;; When the generic and default method are declared in the same place, | ||
| 255 | ;; elisp--xref-find-definitions only returns one. | ||
| 256 | |||
| 257 | (cl-defstruct (xref-elisp-root-type) | ||
| 258 | slot-1) | ||
| 259 | |||
| 260 | (cl-defgeneric xref-elisp-generic-no-methods () | ||
| 261 | "doc string no-methods" | ||
| 262 | ;; No default implementation, no methods, but fboundp is true for | ||
| 263 | ;; this symbol; it calls cl-no-applicable-method | ||
| 264 | ) | ||
| 265 | |||
| 266 | (cl-defmethod xref-elisp-generic-no-default ((this xref-elisp-root-type)) | ||
| 267 | "doc string no-default xref-elisp-root-type" | ||
| 268 | "non-default for no-default") | ||
| 269 | |||
| 270 | ;; defgeneric after defmethod in file to ensure the fallback search | ||
| 271 | ;; method of just looking for the function name will fail. | ||
| 272 | (cl-defgeneric xref-elisp-generic-no-default () | ||
| 273 | "doc string no-default generic" | ||
| 274 | ;; No default implementation; this function calls the cl-generic | ||
| 275 | ;; dispatching code. | ||
| 276 | ) | ||
| 277 | |||
| 278 | (cl-defgeneric xref-elisp-generic-co-located-default () | ||
| 279 | "doc string co-located-default generic" | ||
| 280 | "co-located default") | ||
| 281 | |||
| 282 | (cl-defmethod xref-elisp-generic-co-located-default ((this xref-elisp-root-type)) | ||
| 283 | "doc string co-located-default xref-elisp-root-type" | ||
| 284 | "non-default for co-located-default") | ||
| 285 | |||
| 286 | (cl-defgeneric xref-elisp-generic-separate-default () | ||
| 287 | "doc string separate-default generic" | ||
| 288 | ;; default implementation provided separately | ||
| 289 | ) | ||
| 290 | |||
| 291 | (cl-defmethod xref-elisp-generic-separate-default () | ||
| 292 | "doc string separate-default default" | ||
| 293 | "separate default") | ||
| 294 | |||
| 295 | (cl-defmethod xref-elisp-generic-separate-default ((this xref-elisp-root-type)) | ||
| 296 | "doc string separate-default xref-elisp-root-type" | ||
| 297 | "non-default for separate-default") | ||
| 298 | |||
| 299 | (cl-defmethod xref-elisp-generic-implicit-generic () | ||
| 300 | "doc string implict-generic default" | ||
| 301 | "default for implicit generic") | ||
| 302 | |||
| 303 | (cl-defmethod xref-elisp-generic-implicit-generic ((this xref-elisp-root-type)) | ||
| 304 | "doc string implict-generic xref-elisp-root-type" | ||
| 305 | "non-default for implicit generic") | ||
| 306 | |||
| 307 | |||
| 308 | (xref-elisp-deftest find-defs-defgeneric-no-methods | ||
| 309 | (elisp--xref-find-definitions 'xref-elisp-generic-no-methods) | ||
| 310 | (list | ||
| 311 | (xref-make "(cl-defgeneric xref-elisp-generic-no-methods)" | ||
| 312 | (xref-make-elisp-location | ||
| 313 | 'xref-elisp-generic-no-methods 'cl-defgeneric | ||
| 314 | (expand-file-name "elisp-mode-tests.el" emacs-test-dir))) | ||
| 315 | )) | ||
| 316 | |||
| 317 | (xref-elisp-deftest find-defs-defgeneric-no-default | ||
| 318 | (elisp--xref-find-definitions 'xref-elisp-generic-no-default) | ||
| 319 | (list | ||
| 320 | (xref-make "(cl-defgeneric xref-elisp-generic-no-default)" | ||
| 321 | (xref-make-elisp-location | ||
| 322 | 'xref-elisp-generic-no-default 'cl-defgeneric | ||
| 323 | (expand-file-name "elisp-mode-tests.el" emacs-test-dir))) | ||
| 324 | (xref-make "(cl-defmethod xref-elisp-generic-no-default ((this xref-elisp-root-type)))" | ||
| 325 | (xref-make-elisp-location | ||
| 326 | '(xref-elisp-generic-no-default xref-elisp-root-type) 'cl-defmethod | ||
| 327 | (expand-file-name "elisp-mode-tests.el" emacs-test-dir))) | ||
| 328 | )) | ||
| 329 | |||
| 330 | (xref-elisp-deftest find-defs-defgeneric-co-located-default | ||
| 331 | (elisp--xref-find-definitions 'xref-elisp-generic-co-located-default) | ||
| 332 | (list | ||
| 333 | (xref-make "(cl-defgeneric xref-elisp-generic-co-located-default)" | ||
| 334 | (xref-make-elisp-location | ||
| 335 | 'xref-elisp-generic-co-located-default 'cl-defgeneric | ||
| 336 | (expand-file-name "elisp-mode-tests.el" emacs-test-dir))) | ||
| 337 | (xref-make "(cl-defmethod xref-elisp-generic-co-located-default ((this xref-elisp-root-type)))" | ||
| 338 | (xref-make-elisp-location | ||
| 339 | '(xref-elisp-generic-co-located-default xref-elisp-root-type) 'cl-defmethod | ||
| 340 | (expand-file-name "elisp-mode-tests.el" emacs-test-dir))) | ||
| 341 | )) | ||
| 342 | |||
| 343 | (xref-elisp-deftest find-defs-defgeneric-separate-default | ||
| 344 | (elisp--xref-find-definitions 'xref-elisp-generic-separate-default) | ||
| 345 | (list | ||
| 346 | (xref-make "(cl-defgeneric xref-elisp-generic-separate-default)" | ||
| 347 | (xref-make-elisp-location | ||
| 348 | 'xref-elisp-generic-separate-default 'cl-defgeneric | ||
| 349 | (expand-file-name "elisp-mode-tests.el" emacs-test-dir))) | ||
| 350 | (xref-make "(cl-defmethod xref-elisp-generic-separate-default ())" | ||
| 351 | (xref-make-elisp-location | ||
| 352 | '(xref-elisp-generic-separate-default) 'cl-defmethod | ||
| 353 | (expand-file-name "elisp-mode-tests.el" emacs-test-dir))) | ||
| 354 | |||
| 355 | (xref-make "(cl-defmethod xref-elisp-generic-separate-default ((this xref-elisp-root-type)))" | ||
| 356 | (xref-make-elisp-location | ||
| 357 | '(xref-elisp-generic-separate-default xref-elisp-root-type) 'cl-defmethod | ||
| 358 | (expand-file-name "elisp-mode-tests.el" emacs-test-dir))) | ||
| 359 | )) | ||
| 360 | |||
| 361 | (xref-elisp-deftest find-defs-defgeneric-implicit-generic | ||
| 362 | (elisp--xref-find-definitions 'xref-elisp-generic-implicit-generic) | ||
| 363 | (list | ||
| 364 | (xref-make "(cl-defmethod xref-elisp-generic-implicit-generic ())" | ||
| 365 | (xref-make-elisp-location | ||
| 366 | '(xref-elisp-generic-implicit-generic) 'cl-defmethod | ||
| 367 | (expand-file-name "elisp-mode-tests.el" emacs-test-dir))) | ||
| 368 | (xref-make "(cl-defmethod xref-elisp-generic-implicit-generic ((this xref-elisp-root-type)))" | ||
| 369 | (xref-make-elisp-location | ||
| 370 | '(xref-elisp-generic-implicit-generic xref-elisp-root-type) 'cl-defmethod | ||
| 371 | (expand-file-name "elisp-mode-tests.el" emacs-test-dir))) | ||
| 372 | )) | ||
| 373 | |||
| 374 | ;; Test that we handle more than one method | ||
| 375 | |||
| 376 | ;; When run from the Makefile, etags is not loaded at compile time, | ||
| 377 | ;; but it is by the time this test is run. interactively; don't fail | ||
| 378 | ;; for that. | ||
| 379 | (require 'etags) | ||
| 247 | (xref-elisp-deftest find-defs-defgeneric-el | 380 | (xref-elisp-deftest find-defs-defgeneric-el |
| 248 | (elisp--xref-find-definitions 'xref-location-marker) | 381 | (elisp--xref-find-definitions 'xref-location-marker) |
| 249 | (list | 382 | (list |
| 250 | (xref-make "(cl-defgeneric xref-location-marker)" | 383 | (xref-make "(cl-defgeneric xref-location-marker)" |
| 251 | (xref-make-elisp-location | 384 | (xref-make-elisp-location |
| 252 | 'xref-location-marker nil | 385 | 'xref-location-marker 'cl-defgeneric |
| 253 | (expand-file-name "../../lisp/progmodes/xref.el" emacs-test-dir))) | 386 | (expand-file-name "../../lisp/progmodes/xref.el" emacs-test-dir))) |
| 254 | (xref-make "(cl-defmethod xref-location-marker ((l xref-elisp-location)))" | 387 | (xref-make "(cl-defmethod xref-location-marker ((l xref-elisp-location)))" |
| 255 | (xref-make-elisp-location | 388 | (xref-make-elisp-location |
| @@ -267,7 +400,10 @@ to (xref-elisp-test-descr-to-target xref)." | |||
| 267 | (xref-make-elisp-location | 400 | (xref-make-elisp-location |
| 268 | '(xref-location-marker xref-bogus-location) 'cl-defmethod | 401 | '(xref-location-marker xref-bogus-location) 'cl-defmethod |
| 269 | (expand-file-name "../../lisp/progmodes/xref.el" emacs-test-dir))) | 402 | (expand-file-name "../../lisp/progmodes/xref.el" emacs-test-dir))) |
| 270 | ;; etags is not loaded at test time | 403 | (xref-make "(cl-defmethod xref-location-marker ((l xref-etags-location)))" |
| 404 | (xref-make-elisp-location | ||
| 405 | '(xref-location-marker xref-etags-location) 'cl-defmethod | ||
| 406 | (expand-file-name "../../lisp/progmodes/etags.el" emacs-test-dir))) | ||
| 271 | )) | 407 | )) |
| 272 | 408 | ||
| 273 | (xref-elisp-deftest find-defs-defgeneric-eval | 409 | (xref-elisp-deftest find-defs-defgeneric-eval |
| @@ -318,20 +454,19 @@ to (xref-elisp-test-descr-to-target xref)." | |||
| 318 | ) | 454 | ) |
| 319 | 455 | ||
| 320 | ;; Source for both variable and defun is "(define-minor-mode | 456 | ;; Source for both variable and defun is "(define-minor-mode |
| 321 | ;; compilation-minor-mode". There is no way to tell that from the | 457 | ;; compilation-minor-mode". There is no way to tell that directly from |
| 322 | ;; symbol. find-function-regexp-alist uses find-function-regexp for | 458 | ;; the symbol, but we can use (memq sym minor-mode-list) to detect |
| 323 | ;; this, but that matches too many things for use in this test. | 459 | ;; that the symbol is a minor mode. See `elisp--xref-find-definitions' |
| 460 | ;; for more comments. | ||
| 461 | ;; | ||
| 462 | ;; IMPROVEME: return defvar instead of defun if source near starting | ||
| 463 | ;; point indicates the user is searching for a varible, not a | ||
| 464 | ;; function. | ||
| 324 | (require 'compile) ;; not loaded by default at test time | 465 | (require 'compile) ;; not loaded by default at test time |
| 325 | (xref-elisp-deftest find-defs-defun-defvar-el | 466 | (xref-elisp-deftest find-defs-defun-defvar-el |
| 326 | (elisp--xref-find-definitions 'compilation-minor-mode) | 467 | (elisp--xref-find-definitions 'compilation-minor-mode) |
| 327 | (list | 468 | (list |
| 328 | (cons | 469 | (cons |
| 329 | (xref-make "(defvar compilation-minor-mode)" | ||
| 330 | (xref-make-elisp-location | ||
| 331 | 'compilation-minor-mode 'defvar | ||
| 332 | (expand-file-name "../../lisp/progmodes/compile.el" emacs-test-dir))) | ||
| 333 | "(define-minor-mode compilation-minor-mode") | ||
| 334 | (cons | ||
| 335 | (xref-make "(defun compilation-minor-mode)" | 470 | (xref-make "(defun compilation-minor-mode)" |
| 336 | (xref-make-elisp-location | 471 | (xref-make-elisp-location |
| 337 | 'compilation-minor-mode nil | 472 | 'compilation-minor-mode nil |
| @@ -382,10 +517,13 @@ to (xref-elisp-test-descr-to-target xref)." | |||
| 382 | (xref-elisp-deftest find-defs-feature-el | 517 | (xref-elisp-deftest find-defs-feature-el |
| 383 | (elisp--xref-find-definitions 'xref) | 518 | (elisp--xref-find-definitions 'xref) |
| 384 | (list | 519 | (list |
| 385 | (xref-make "(feature xref)" | 520 | (cons |
| 521 | (xref-make "(feature xref)" | ||
| 386 | (xref-make-elisp-location | 522 | (xref-make-elisp-location |
| 387 | 'xref 'feature | 523 | 'xref 'feature |
| 388 | (expand-file-name "../../lisp/progmodes/xref.el" emacs-test-dir))))) | 524 | (expand-file-name "../../lisp/progmodes/xref.el" emacs-test-dir))) |
| 525 | ";;; Code:") | ||
| 526 | )) | ||
| 389 | 527 | ||
| 390 | (xref-elisp-deftest find-defs-feature-eval | 528 | (xref-elisp-deftest find-defs-feature-eval |
| 391 | (elisp--xref-find-definitions (eval '(provide 'stephe-leake-feature))) | 529 | (elisp--xref-find-definitions (eval '(provide 'stephe-leake-feature))) |