From 711a8eecd5f8abb46dbe6bafe10071ec0e58d85f Mon Sep 17 00:00:00 2001 From: Stephen Leake Date: Tue, 15 Sep 2015 14:40:49 -0500 Subject: [PATCH] Fix a bug in elisp--xref-find-definitions related to cl-generic defaults * lisp/progmodes/elisp-mode.el (elisp--xref-find-definitions): Fix bug with cl-generic defaults. (elisp--xref-find-references): Add doc string. * test/automated/elisp-mode-tests.el (xref-elisp-generic-*): Improve tests to find bug. --- doc/lispref/files.texi | 12 ++++---- lisp/progmodes/elisp-mode.el | 8 +++++- test/automated/elisp-mode-tests.el | 44 +++++++++++++++--------------- 3 files changed, 36 insertions(+), 28 deletions(-) diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi index 735e08eb324..edfb045a795 100644 --- a/doc/lispref/files.texi +++ b/doc/lispref/files.texi @@ -2421,11 +2421,13 @@ the file, which in some cases may cause a security hole. This section describes low-level subroutines for completing a file name. For higher level functions, see @ref{Reading File Names}. -@defun file-name-all-completions partial-filename directory -This function returns a list of all possible completions for a file -whose name starts with @var{partial-filename} in directory -@var{directory}. The order of the completions is the order of the files -in the directory, which is unpredictable and conveys no useful +@defun file-name-all-completions partial-filename directory &optional predicate +This function returns a list of all possible completions for a file in +directory @var{directory} whose name starts with +@var{partial-filename} and for which @var{predicate} (called with the +filename) returns non-nil. If @var{predicate} is nil (the default), it +is ignored. The order of the completions is the order of the files in +the directory, which is unpredictable and conveys no useful information. The argument @var{partial-filename} must be a file name containing no diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index 8afae150a1d..7614bacf1bb 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -720,10 +720,15 @@ non-nil result supercedes the xrefs produced by (dolist (method (cl--generic-method-table generic)) (let* ((info (cl--generic-method-info method));; qual-string combined-args doconly (specializers (cl--generic-method-specializers method)) + (non-default nil) (met-name (cons symbol specializers)) (file (find-lisp-object-file-name met-name 'cl-defmethod))) + (dolist (item specializers) + ;; default method has all 't' in specializers + (setq non-default (or non-default (not (equal t item))))) + (when (and file - (or specializers ;; default method has null specializers + (or non-default (nth 2 info))) ;; assuming only co-located default has null doc string (if specializers (let ((summary (format elisp--xref-format-extra 'cl-defmethod symbol (nth 1 info)))) @@ -800,6 +805,7 @@ non-nil result supercedes the xrefs produced by (declare-function project-current "project") (defun elisp--xref-find-references (symbol) + "Find all references to SYMBOL (a string) in the current project." (cl-mapcan (lambda (dir) (xref-collect-references symbol dir)) diff --git a/test/automated/elisp-mode-tests.el b/test/automated/elisp-mode-tests.el index 7886b557141..2f6675a2804 100644 --- a/test/automated/elisp-mode-tests.el +++ b/test/automated/elisp-mode-tests.el @@ -258,7 +258,7 @@ to (xref-elisp-test-descr-to-target xref)." (cl-defstruct (xref-elisp-root-type) slot-1) -(cl-defgeneric xref-elisp-generic-no-methods () +(cl-defgeneric xref-elisp-generic-no-methods (arg1 arg2) "doc string generic no-methods" ;; No default implementation, no methods, but fboundp is true for ;; this symbol; it calls cl-no-applicable-method @@ -269,44 +269,44 @@ to (xref-elisp-test-descr-to-target xref)." ;; causes the batch mode test to fail; the symbol shows up as ;; ‘this’. It passes in interactive tests, so I haven't been able to ;; track down the problem. -(cl-defmethod xref-elisp-generic-no-default ((this xref-elisp-root-type)) +(cl-defmethod xref-elisp-generic-no-default ((this xref-elisp-root-type) arg2) "doc string generic no-default xref-elisp-root-type" "non-default for no-default") ;; defgeneric after defmethod in file to ensure the fallback search ;; method of just looking for the function name will fail. -(cl-defgeneric xref-elisp-generic-no-default () +(cl-defgeneric xref-elisp-generic-no-default (arg1 arg2) "doc string generic no-default generic" ;; No default implementation; this function calls the cl-generic ;; dispatching code. ) -(cl-defgeneric xref-elisp-generic-co-located-default () +(cl-defgeneric xref-elisp-generic-co-located-default (arg1 arg2) "doc string generic co-located-default" "co-located default") -(cl-defmethod xref-elisp-generic-co-located-default ((this xref-elisp-root-type)) +(cl-defmethod xref-elisp-generic-co-located-default ((this xref-elisp-root-type) arg2) "doc string generic co-located-default xref-elisp-root-type" "non-default for co-located-default") -(cl-defgeneric xref-elisp-generic-separate-default () +(cl-defgeneric xref-elisp-generic-separate-default (arg1 arg2) "doc string generic separate-default" ;; default implementation provided separately ) -(cl-defmethod xref-elisp-generic-separate-default () +(cl-defmethod xref-elisp-generic-separate-default (arg1 arg2) "doc string generic separate-default default" "separate default") -(cl-defmethod xref-elisp-generic-separate-default ((this xref-elisp-root-type)) +(cl-defmethod xref-elisp-generic-separate-default ((this xref-elisp-root-type) arg2) "doc string generic separate-default xref-elisp-root-type" "non-default for separate-default") -(cl-defmethod xref-elisp-generic-implicit-generic () +(cl-defmethod xref-elisp-generic-implicit-generic (arg1 arg2) "doc string generic implicit-generic default" "default for implicit generic") -(cl-defmethod xref-elisp-generic-implicit-generic ((this xref-elisp-root-type)) +(cl-defmethod xref-elisp-generic-implicit-generic ((this xref-elisp-root-type) arg2) "doc string generic implicit-generic xref-elisp-root-type" "non-default for implicit generic") @@ -327,9 +327,9 @@ to (xref-elisp-test-descr-to-target xref)." (xref-make-elisp-location 'xref-elisp-generic-no-default 'cl-defgeneric (expand-file-name "elisp-mode-tests.el" emacs-test-dir))) - (xref-make "(cl-defmethod xref-elisp-generic-no-default ((this xref-elisp-root-type)))" + (xref-make "(cl-defmethod xref-elisp-generic-no-default ((this xref-elisp-root-type) arg2))" (xref-make-elisp-location - '(xref-elisp-generic-no-default xref-elisp-root-type) 'cl-defmethod + '(xref-elisp-generic-no-default xref-elisp-root-type t) 'cl-defmethod (expand-file-name "elisp-mode-tests.el" emacs-test-dir))) )) @@ -340,9 +340,9 @@ to (xref-elisp-test-descr-to-target xref)." (xref-make-elisp-location 'xref-elisp-generic-co-located-default 'cl-defgeneric (expand-file-name "elisp-mode-tests.el" emacs-test-dir))) - (xref-make "(cl-defmethod xref-elisp-generic-co-located-default ((this xref-elisp-root-type)))" + (xref-make "(cl-defmethod xref-elisp-generic-co-located-default ((this xref-elisp-root-type) arg2))" (xref-make-elisp-location - '(xref-elisp-generic-co-located-default xref-elisp-root-type) 'cl-defmethod + '(xref-elisp-generic-co-located-default xref-elisp-root-type t) 'cl-defmethod (expand-file-name "elisp-mode-tests.el" emacs-test-dir))) )) @@ -353,26 +353,26 @@ to (xref-elisp-test-descr-to-target xref)." (xref-make-elisp-location 'xref-elisp-generic-separate-default 'cl-defgeneric (expand-file-name "elisp-mode-tests.el" emacs-test-dir))) - (xref-make "(cl-defmethod xref-elisp-generic-separate-default ())" + (xref-make "(cl-defmethod xref-elisp-generic-separate-default (arg1 arg2))" (xref-make-elisp-location - '(xref-elisp-generic-separate-default) 'cl-defmethod + '(xref-elisp-generic-separate-default t t) 'cl-defmethod (expand-file-name "elisp-mode-tests.el" emacs-test-dir))) - (xref-make "(cl-defmethod xref-elisp-generic-separate-default ((this xref-elisp-root-type)))" + (xref-make "(cl-defmethod xref-elisp-generic-separate-default ((this xref-elisp-root-type) arg2))" (xref-make-elisp-location - '(xref-elisp-generic-separate-default xref-elisp-root-type) 'cl-defmethod + '(xref-elisp-generic-separate-default xref-elisp-root-type t) 'cl-defmethod (expand-file-name "elisp-mode-tests.el" emacs-test-dir))) )) (xref-elisp-deftest find-defs-defgeneric-implicit-generic (elisp--xref-find-definitions 'xref-elisp-generic-implicit-generic) (list - (xref-make "(cl-defmethod xref-elisp-generic-implicit-generic ())" + (xref-make "(cl-defmethod xref-elisp-generic-implicit-generic (arg1 arg2))" (xref-make-elisp-location - '(xref-elisp-generic-implicit-generic) 'cl-defmethod + '(xref-elisp-generic-implicit-generic t t) 'cl-defmethod (expand-file-name "elisp-mode-tests.el" emacs-test-dir))) - (xref-make "(cl-defmethod xref-elisp-generic-implicit-generic ((this xref-elisp-root-type)))" + (xref-make "(cl-defmethod xref-elisp-generic-implicit-generic ((this xref-elisp-root-type) arg2))" (xref-make-elisp-location - '(xref-elisp-generic-implicit-generic xref-elisp-root-type) 'cl-defmethod + '(xref-elisp-generic-implicit-generic xref-elisp-root-type t) 'cl-defmethod (expand-file-name "elisp-mode-tests.el" emacs-test-dir))) )) -- 2.39.2