emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master 64fbdc9 2/2: Add mode local overrides to xref-find-


From: Stephen Leake
Subject: [Emacs-diffs] master 64fbdc9 2/2: Add mode local overrides to xref-find-definitions
Date: Wed, 26 Aug 2015 21:59:16 +0000

branch: master
commit 64fbdc9825ad98ebbc8c021442c1f3c3ba0fd1b1
Author: Stephen Leake <address@hidden>
Commit: Stephen Leake <address@hidden>

    Add mode local overrides to xref-find-definitions
    
    * lisp/cedet/mode-local.el (xref-mode-local--override-present,
    xref-mode-local-overload): New; add mode local overrides to
    xref-find-definitions.
    
    * test/automated/elisp-mode-tests.el: Add mode local override tests.
    (xref-elisp-test-run): Handle indented defuns.
    (xref-elisp-generic-*): Improve doc strings.
    
    * lisp/progmodes/elisp-mode.el (elisp-xref-find-def-functions): New.
    (elisp--xref-find-definitions): Use it.
---
 etc/NEWS                           |    7 +-
 lisp/cedet/mode-local.el           |   98 ++++++++++++
 lisp/progmodes/elisp-mode.el       |  302 +++++++++++++++++++-----------------
 test/automated/elisp-mode-tests.el |  116 +++++++++++++--
 4 files changed, 367 insertions(+), 156 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index cf0804d..bfcce36 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -88,9 +88,10 @@ command line when `initial-buffer-choice' is non-nil.
 
 * Changes in Emacs 25.1
 
-** `describe-function' now displays information about mode local
-   overrides (defined by cedet/mode-local.el
-   `define-overloadable-function' and `define-mode-local-overrides'.
+** `xref-find-definitions' and `describe-function' now display
+   information about mode local overrides (defined by
+   cedet/mode-local.el `define-overloadable-function' and
+   `define-mode-local-overrides').
 
 ** New `display-buffer' action function `display-buffer-use-some-frame'
 This displays the buffer in an existing frame other than the current
diff --git a/lisp/cedet/mode-local.el b/lisp/cedet/mode-local.el
index ce30a98..9ee8750 100644
--- a/lisp/cedet/mode-local.el
+++ b/lisp/cedet/mode-local.el
@@ -48,6 +48,13 @@
 
 (eval-when-compile (require 'cl))
 
+(require 'find-func)
+;; For find-function-regexp-alist. It is tempting to replace this
+;; ‘require‘ by (defvar find-function-regexp-alist) and
+;; with-eval-after-load, but model-local.el is typically loaded when a
+;; semantic autoload is invoked, and something in semantic loads
+;; find-func.el before mode-local.el, so the eval-after-load is lost.
+
 ;;; Misc utilities
 ;;
 (defun mode-local-map-file-buffers (function &optional predicate buffers)
@@ -649,6 +656,97 @@ SYMBOL is a function that can be overridden."
 
 (add-hook 'help-fns-describe-function-functions 'describe-mode-local-overload)
 
+(declare-function xref-item-location "xref" (xref))
+
+(defun xref-mode-local--override-present (sym xrefs)
+  "Return non-nil if SYM is in XREFS."
+  (let (result)
+    (while (and (null result)
+               xrefs)
+      (when (equal sym (car (xref-elisp-location-symbol (xref-item-location 
(pop xrefs)))))
+       (setq result t)))
+    result))
+
+(defun xref-mode-local-overload (symbol)
+  "For ‘elisp-xref-find-def-functions’; add overloads for SYMBOL."
+  ;; Current buffer is the buffer where xref-find-definitions was invoked.
+  (when (get symbol 'mode-local-overload)
+    (let* ((symbol-file (find-lisp-object-file-name symbol (symbol-function 
symbol)))
+          (default (intern-soft (format "%s-default" (symbol-name symbol))))
+          (default-file (when default (find-lisp-object-file-name default 
(symbol-function default))))
+          modes
+          xrefs)
+
+      (mapatoms
+       (lambda (sym) (when (get sym 'mode-local-symbol-table) (push sym 
modes)))
+       obarray)
+
+      ;; mode-local-overrides are inherited from parent modes; we
+      ;; don't want to list the same function twice. So order ‘modes’
+      ;; with parents first, and check for duplicates.
+
+      (setq modes
+           (sort modes
+                 (lambda (a b)
+                   (not (equal b (get a 'mode-local-parent)))))) ;; a is not a 
child, or not a child of b
+
+      (dolist (mode modes)
+       (let* ((major-mode mode)
+              (override (fetch-overload symbol))
+              (override-file (when override (find-lisp-object-file-name 
override (symbol-function override)))))
+
+         (when (and override override-file)
+           (let ((meta-name (cons override major-mode))
+                 ;; For the declaration:
+                 ;;
+                 ;;(define-mode-local-override xref-elisp-foo c-mode
+                 ;;
+                 ;; The override symbol name is
+                 ;; "xref-elisp-foo-c-mode". The summary should match
+                 ;; the declaration, so strip the mode from the
+                 ;; symbol name.
+                 (summary (format elisp--xref-format-extra
+                                  'define-mode-local-override
+                                  (substring (symbol-name override) 0 (- (1+ 
(length (symbol-name major-mode)))))
+                                  major-mode)))
+
+             (unless (xref-mode-local--override-present override xrefs)
+               (push (elisp--xref-make-xref
+                      'define-mode-local-override meta-name override-file 
summary)
+                     xrefs))))))
+
+      ;; %s-default is interned whether it is a separate function or
+      ;; not, so we have to check that here.
+      (when (and (functionp default) default-file)
+       (push (elisp--xref-make-xref nil default default-file) xrefs))
+
+      (when symbol-file
+       (push (elisp--xref-make-xref 'define-overloadable-function symbol 
symbol-file) xrefs))
+
+      xrefs)))
+
+(add-hook 'elisp-xref-find-def-functions 'xref-mode-local-overload)
+
+(defconst xref-mode-local-find-overloadable-regexp
+  "(\\(\\(define-overloadable-function\\)\\|\\(define-overload\\)\\) +%s"
+  "Regexp used by ‘xref-find-definitions’ when searching for a
+  mode-local overloadable function definition.")
+
+(defun xref-mode-local-find-override (meta-name)
+  "Function used by ‘xref-find-definitions’ when searching for an
+  override of a mode-local overloadable function.
+META-NAME is a cons (OVERLOADABLE-SYMBOL . MAJOR-MODE)."
+  (let* ((override (car meta-name))
+        (mode (cdr meta-name))
+        (regexp (format "(define-mode-local-override +%s +%s"
+                        (substring (symbol-name override) 0 (- (1+ (length 
(symbol-name mode)))))
+                        mode)))
+    (re-search-forward regexp nil t)
+    ))
+
+(add-to-list 'find-function-regexp-alist '(define-overloadable-function . 
xref-mode-local-find-overloadable-regexp))
+(add-to-list 'find-function-regexp-alist (cons 'define-mode-local-override 
#'xref-mode-local-find-override))
+
 ;; Help for mode-local bindings.
 (defun mode-local-print-binding (symbol)
   "Print the SYMBOL binding."
diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el
index a96fca1..e76728d 100644
--- a/lisp/progmodes/elisp-mode.el
+++ b/lisp/progmodes/elisp-mode.el
@@ -620,7 +620,7 @@ It can be quoted, or be inside a quoted form."
     (put-text-property 4 6 'face 'font-lock-function-name-face str)
     str))
 
-(defvar find-feature-regexp)
+(defvar find-feature-regexp);; in find-func.el
 
 (defun elisp--xref-make-xref (type symbol file &optional summary)
   "Return an xref for TYPE SYMBOL in FILE.
@@ -631,149 +631,167 @@ otherwise build the summary from TYPE and SYMBOL."
                 (format elisp--xref-format (or type 'defun) symbol))
             (xref-make-elisp-location symbol type file)))
 
+(defvar elisp-xref-find-def-functions nil
+  "List of functions to be run from ‘elisp--xref-find-definitions’ to add 
additional xrefs.
+Called with one arg; the symbol whose definition is desired.
+Each function should return a list of xrefs, or nil; the first
+non-nil result supercedes the xrefs produced by
+‘elisp--xref-find-definitions’.")
+
+;; FIXME: name should be singular; match xref-find-definition
 (defun elisp--xref-find-definitions (symbol)
   ;; The file name is not known when `symbol' is defined via interactive eval.
-  (let (xrefs)
-    ;; alphabetical by result type symbol
-
-    ;; FIXME: advised function; list of advice functions
-
-    ;; FIXME: aliased variable
-
-    (when (and (symbolp symbol)
-               (symbol-function symbol)
-              (symbolp (symbol-function symbol)))
-      ;; aliased function
-      (let* ((alias-symbol symbol)
-            (alias-file (symbol-file alias-symbol))
-            (real-symbol  (symbol-function symbol))
-            (real-file (find-lisp-object-file-name real-symbol 'defun)))
-
-       (when real-file
-         (push (elisp--xref-make-xref nil real-symbol real-file) xrefs))
-
-       (when alias-file
-         (push (elisp--xref-make-xref 'defalias alias-symbol alias-file) 
xrefs))))
-
-    (when (facep symbol)
-      (let ((file (find-lisp-object-file-name symbol 'defface)))
-       (when file
-         (push (elisp--xref-make-xref 'defface symbol file) xrefs))))
-
-    (when (fboundp symbol)
-      (let ((file (find-lisp-object-file-name symbol (symbol-function symbol)))
-           generic doc)
-       (when file
-         (cond
-          ((eq file 'C-source)
-            ;; First call to find-lisp-object-file-name for an object
-            ;; defined in C; the doc strings from the C source have
-            ;; not been loaded yet.  Second call will return "src/*.c"
-            ;; in file; handled by 't' case below.
-           (push (elisp--xref-make-xref nil symbol (help-C-file-name 
(symbol-function symbol) 'subr)) xrefs))
-
-           ((and (setq doc (documentation symbol t))
-                 ;; This doc string is defined in cl-macs.el cl-defstruct
-                 (string-match "Constructor for objects of type `\\(.*\\)'" 
doc))
-            ;; `symbol' is a name for the default constructor created by
-            ;; cl-defstruct, so return the location of the cl-defstruct.
-            (let* ((type-name (match-string 1 doc))
-                   (type-symbol (intern type-name))
-                   (file (find-lisp-object-file-name type-symbol 'define-type))
-                   (summary (format elisp--xref-format-extra
-                                    'cl-defstruct
-                                    (concat "(" type-name)
-                                    (concat "(:constructor " (symbol-name 
symbol) "))"))))
-              (push (elisp--xref-make-xref 'define-type type-symbol file 
summary) xrefs)
-              ))
-
-          ((setq generic (cl--generic symbol))
-            ;; A generic function. If there is a default method, it
-            ;; will appear in the method table, with no
-            ;; specializers.
-            ;;
-            ;; If the default method is declared by the cl-defgeneric
-            ;; declaration, it will have the same location as the
-            ;; cl-defgeneric, so we want to exclude it from the
-            ;; result. In this case, it will have a null doc
-            ;; string. User declarations of default methods may also
-            ;; have null doc strings, but we hope that is
-            ;; rare. Perhaps this heuristic will discourage that.
-           (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))
-                    (met-name (cons symbol specializers))
-                    (file (find-lisp-object-file-name met-name 'cl-defmethod)))
-               (when (and file
-                           (or specializers   ;; default method has null 
specializers
-                               (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))))
-                        (push (elisp--xref-make-xref 'cl-defmethod met-name 
file summary) xrefs))
-
-                    (let ((summary (format elisp--xref-format-extra 
'cl-defmethod symbol "()")))
-                      (push (elisp--xref-make-xref 'cl-defmethod met-name file 
summary) xrefs))))
-               ))
-
-            (if (and (setq doc (documentation symbol t))
-                     ;; This doc string is created somewhere in
-                     ;; cl--generic-make-function for an implicit
-                     ;; defgeneric.
-                     (string-match "\n\n(fn ARG &rest ARGS)" doc))
-                ;; This symbol is an implicitly defined defgeneric, so
-                ;; don't return it.
-                nil
-              (push (elisp--xref-make-xref 'cl-defgeneric symbol file) xrefs))
-           )
-
-          (t
-           (push (elisp--xref-make-xref nil symbol file) xrefs))
-          ))))
-
-    (when (boundp symbol)
-      ;; A variable
-      (let ((file (find-lisp-object-file-name symbol 'defvar)))
-       (when file
-          (cond
-           ((eq file 'C-source)
-            ;; The doc strings from the C source have not been loaded
-            ;; yet; help-C-file-name does that.  Second call will
-            ;; return "src/*.c" in file; handled below.
-            (push (elisp--xref-make-xref 'defvar symbol (help-C-file-name 
symbol 'var)) xrefs))
-
-           ((string= "src/" (substring file 0 4))
-            ;; The variable is defined in a C source file; don't check
-            ;; for define-minor-mode.
-            (push (elisp--xref-make-xref 'defvar symbol file) xrefs))
-
-           ((memq symbol minor-mode-list)
-            ;; The symbol is a minor mode. These should be defined by
-            ;; "define-minor-mode", which means the variable and the
-            ;; function are declared in the same place. So we return only
-            ;; the function, arbitrarily.
-            ;;
-            ;; There is an exception, when the variable is defined in C
-            ;; code, as for abbrev-mode.
-            ;;
-            ;; IMPROVEME: If the user is searching for the identifier at
-            ;; point, we can determine whether it is a variable or
-            ;; function by looking at the source code near point.
-            ;;
-            ;; IMPROVEME: The user may actually be asking "do any
-            ;; variables by this name exist"; we need a way to specify
-            ;; that.
-            nil)
-
-           (t
-            (push (elisp--xref-make-xref 'defvar symbol file) xrefs))
-
-           ))))
-
-    (when (featurep symbol)
-      (let ((file (ignore-errors
-                   (find-library-name (symbol-name symbol)))))
-       (when file
-         (push (elisp--xref-make-xref 'feature symbol file) xrefs))))
+  (let (xrefs temp)
+
+    (let ((temp elisp-xref-find-def-functions))
+      (while (and (null xrefs)
+                  temp)
+        (setq xrefs (append xrefs (funcall (pop temp) symbol)))))
+
+    (unless xrefs
+      ;; alphabetical by result type symbol
+
+      ;; FIXME: advised function; list of advice functions
+
+      ;; FIXME: aliased variable
+
+      (when (and (symbolp symbol)
+                 (symbol-function symbol)
+                 (symbolp (symbol-function symbol)))
+        ;; aliased function
+        (let* ((alias-symbol symbol)
+               (alias-file (symbol-file alias-symbol))
+               (real-symbol  (symbol-function symbol))
+               (real-file (find-lisp-object-file-name real-symbol 'defun)))
+
+          (when real-file
+            (push (elisp--xref-make-xref nil real-symbol real-file) xrefs))
+
+          (when alias-file
+            (push (elisp--xref-make-xref 'defalias alias-symbol alias-file) 
xrefs))))
+
+      (when (facep symbol)
+        (let ((file (find-lisp-object-file-name symbol 'defface)))
+          (when file
+            (push (elisp--xref-make-xref 'defface symbol file) xrefs))))
+
+      (when (fboundp symbol)
+        (let ((file (find-lisp-object-file-name symbol (symbol-function 
symbol)))
+              generic doc)
+          (when file
+            (cond
+             ((eq file 'C-source)
+              ;; First call to find-lisp-object-file-name for an object
+              ;; defined in C; the doc strings from the C source have
+              ;; not been loaded yet.  Second call will return "src/*.c"
+              ;; in file; handled by 't' case below.
+              (push (elisp--xref-make-xref nil symbol (help-C-file-name 
(symbol-function symbol) 'subr)) xrefs))
+
+             ((and (setq doc (documentation symbol t))
+                   ;; This doc string is defined in cl-macs.el cl-defstruct
+                   (string-match "Constructor for objects of type `\\(.*\\)'" 
doc))
+              ;; `symbol' is a name for the default constructor created by
+              ;; cl-defstruct, so return the location of the cl-defstruct.
+              (let* ((type-name (match-string 1 doc))
+                     (type-symbol (intern type-name))
+                     (file (find-lisp-object-file-name type-symbol 
'define-type))
+                     (summary (format elisp--xref-format-extra
+                                      'cl-defstruct
+                                      (concat "(" type-name)
+                                      (concat "(:constructor " (symbol-name 
symbol) "))"))))
+                (push (elisp--xref-make-xref 'define-type type-symbol file 
summary) xrefs)
+                ))
+
+             ((setq generic (cl--generic symbol))
+              ;; FIXME: move this to elisp-xref-find-def-functions, in 
cl-generic.el
+
+              ;; A generic function. If there is a default method, it
+              ;; will appear in the method table, with no
+              ;; specializers.
+              ;;
+              ;; If the default method is declared by the cl-defgeneric
+              ;; declaration, it will have the same location as the
+              ;; cl-defgeneric, so we want to exclude it from the
+              ;; result. In this case, it will have a null doc
+              ;; string. User declarations of default methods may also
+              ;; have null doc strings, but we hope that is
+              ;; rare. Perhaps this heuristic will discourage that.
+              (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))
+                       (met-name (cons symbol specializers))
+                       (file (find-lisp-object-file-name met-name 
'cl-defmethod)))
+                  (when (and file
+                             (or specializers   ;; default method has null 
specializers
+                                 (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))))
+                          (push (elisp--xref-make-xref 'cl-defmethod met-name 
file summary) xrefs))
+
+                      (let ((summary (format elisp--xref-format-extra 
'cl-defmethod symbol "()")))
+                        (push (elisp--xref-make-xref 'cl-defmethod met-name 
file summary) xrefs))))
+                  ))
+
+              (if (and (setq doc (documentation symbol t))
+                       ;; This doc string is created somewhere in
+                       ;; cl--generic-make-function for an implicit
+                       ;; defgeneric.
+                       (string-match "\n\n(fn ARG &rest ARGS)" doc))
+                  ;; This symbol is an implicitly defined defgeneric, so
+                  ;; don't return it.
+                  nil
+                (push (elisp--xref-make-xref 'cl-defgeneric symbol file) 
xrefs))
+              )
+
+             (t
+              (push (elisp--xref-make-xref nil symbol file) xrefs))
+             ))))
+
+      (when (boundp symbol)
+        ;; A variable
+        (let ((file (find-lisp-object-file-name symbol 'defvar)))
+          (when file
+            (cond
+             ((eq file 'C-source)
+              ;; The doc strings from the C source have not been loaded
+              ;; yet; help-C-file-name does that.  Second call will
+              ;; return "src/*.c" in file; handled below.
+              (push (elisp--xref-make-xref 'defvar symbol (help-C-file-name 
symbol 'var)) xrefs))
+
+             ((string= "src/" (substring file 0 4))
+              ;; The variable is defined in a C source file; don't check
+              ;; for define-minor-mode.
+              (push (elisp--xref-make-xref 'defvar symbol file) xrefs))
+
+             ((memq symbol minor-mode-list)
+              ;; The symbol is a minor mode. These should be defined by
+              ;; "define-minor-mode", which means the variable and the
+              ;; function are declared in the same place. So we return only
+              ;; the function, arbitrarily.
+              ;;
+              ;; There is an exception, when the variable is defined in C
+              ;; code, as for abbrev-mode.
+              ;;
+              ;; IMPROVEME: If the user is searching for the identifier at
+              ;; point, we can determine whether it is a variable or
+              ;; function by looking at the source code near point.
+              ;;
+              ;; IMPROVEME: The user may actually be asking "do any
+              ;; variables by this name exist"; we need a way to specify
+              ;; that.
+              nil)
+
+             (t
+              (push (elisp--xref-make-xref 'defvar symbol file) xrefs))
+
+             ))))
+
+      (when (featurep symbol)
+        (let ((file (ignore-errors
+                      (find-library-name (symbol-name symbol)))))
+          (when file
+            (push (elisp--xref-make-xref 'feature symbol file) xrefs))))
+      );; 'unless xrefs'
 
     xrefs))
 
diff --git a/test/automated/elisp-mode-tests.el 
b/test/automated/elisp-mode-tests.el
index 64b3f66..ec01477 100644
--- a/test/automated/elisp-mode-tests.el
+++ b/test/automated/elisp-mode-tests.el
@@ -186,6 +186,7 @@
                      (or (when (consp expected) (car expected)) expected)))
 
       (xref--goto-location (xref-item-location xref))
+      (back-to-indentation)
       (should (looking-at (or (when (consp expected) (cdr expected))
                               (xref-elisp-test-descr-to-target expected)))))
     ))
@@ -258,50 +259,55 @@ to (xref-elisp-test-descr-to-target xref)."
   slot-1)
 
 (cl-defgeneric xref-elisp-generic-no-methods ()
-  "doc string no-methods"
+  "doc string generic no-methods"
   ;; No default implementation, no methods, but fboundp is true for
   ;; this symbol; it calls cl-no-applicable-method
   )
 
+;; WORKAROUND: ‘this’ is unused, and the byte compiler complains, so
+;; it should be spelled ‘_this’. But for some unknown reason, that
+;; 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))
-  "doc string no-default xref-elisp-root-type"
+  "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 ()
-  "doc string no-default generic"
+  "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 ()
-  "doc string co-located-default generic"
+  "doc string generic co-located-default"
   "co-located default")
 
 (cl-defmethod xref-elisp-generic-co-located-default ((this 
xref-elisp-root-type))
-  "doc string co-located-default xref-elisp-root-type"
+  "doc string generic co-located-default xref-elisp-root-type"
   "non-default for co-located-default")
 
 (cl-defgeneric xref-elisp-generic-separate-default ()
-  "doc string separate-default generic"
+  "doc string generic separate-default"
   ;; default implementation provided separately
   )
 
 (cl-defmethod xref-elisp-generic-separate-default ()
-  "doc string separate-default default"
+  "doc string generic separate-default default"
   "separate default")
 
 (cl-defmethod xref-elisp-generic-separate-default ((this xref-elisp-root-type))
-  "doc string separate-default xref-elisp-root-type"
+  "doc string generic separate-default xref-elisp-root-type"
   "non-default for separate-default")
 
 (cl-defmethod xref-elisp-generic-implicit-generic ()
-  "doc string implicit-generic default"
+  "doc string generic implicit-generic default"
   "default for implicit generic")
 
 (cl-defmethod xref-elisp-generic-implicit-generic ((this xref-elisp-root-type))
-  "doc string implicit-generic xref-elisp-root-type"
+  "doc string generic implicit-generic xref-elisp-root-type"
   "non-default for implicit generic")
 
 
@@ -351,7 +357,6 @@ to (xref-elisp-test-descr-to-target xref)."
               (xref-make-elisp-location
                '(xref-elisp-generic-separate-default) '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-elisp-location
               '(xref-elisp-generic-separate-default xref-elisp-root-type) 
'cl-defmethod
@@ -410,6 +415,95 @@ to (xref-elisp-test-descr-to-target xref)."
   (elisp--xref-find-definitions (eval '(cl-defgeneric 
stephe-leake-cl-defgeneric ())))
   nil)
 
+;; Define some mode-local overloadable/overridden functions for xref to find
+(require 'mode-local)
+
+(define-overloadable-function xref-elisp-overloadable-no-methods ()
+  "doc string overloadable no-methods")
+
+(define-overloadable-function xref-elisp-overloadable-no-default ()
+  "doc string overloadable no-default")
+
+;; FIXME: byte compiler complains about unused lexical arguments
+;; generated by this macro.
+(define-mode-local-override xref-elisp-overloadable-no-default c-mode
+  (start end &optional nonterminal depth returnonerror)
+  "doc string overloadable no-default c-mode."
+  "result overloadable no-default c-mode.")
+
+(define-overloadable-function xref-elisp-overloadable-co-located-default ()
+  "doc string overloadable co-located-default"
+  "result overloadable co-located-default.")
+
+(define-mode-local-override xref-elisp-overloadable-co-located-default c-mode
+  (start end &optional nonterminal depth returnonerror)
+  "doc string overloadable co-located-default c-mode."
+  "result overloadable co-located-default c-mode.")
+
+(define-overloadable-function xref-elisp-overloadable-separate-default ()
+  "doc string overloadable separate-default.")
+
+(defun xref-elisp-overloadable-separate-default-default ()
+  "doc string overloadable separate-default default"
+  "result overloadable separate-default.")
+
+(define-mode-local-override xref-elisp-overloadable-separate-default c-mode
+  (start end &optional nonterminal depth returnonerror)
+  "doc string overloadable separate-default c-mode."
+  "result overloadable separate-default c-mode.")
+
+(xref-elisp-deftest find-defs-define-overload-no-methods
+  (elisp--xref-find-definitions 'xref-elisp-overloadable-no-methods)
+  (list
+   (xref-make "(define-overloadable-function 
xref-elisp-overloadable-no-methods)"
+              (xref-make-elisp-location
+               'xref-elisp-overloadable-no-methods 
'define-overloadable-function
+               (expand-file-name "elisp-mode-tests.el" emacs-test-dir)))
+   ))
+
+(xref-elisp-deftest find-defs-define-overload-no-default
+  (elisp--xref-find-definitions 'xref-elisp-overloadable-no-default)
+  (list
+   (xref-make "(define-overloadable-function 
xref-elisp-overloadable-no-default)"
+              (xref-make-elisp-location
+               'xref-elisp-overloadable-no-default 
'define-overloadable-function
+               (expand-file-name "elisp-mode-tests.el" emacs-test-dir)))
+   (xref-make "(define-mode-local-override xref-elisp-overloadable-no-default 
c-mode)"
+              (xref-make-elisp-location
+               '(xref-elisp-overloadable-no-default-c-mode . c-mode) 
'define-mode-local-override
+               (expand-file-name "elisp-mode-tests.el" emacs-test-dir)))
+   ))
+
+(xref-elisp-deftest find-defs-define-overload-co-located-default
+  (elisp--xref-find-definitions 'xref-elisp-overloadable-co-located-default)
+  (list
+   (xref-make "(define-overloadable-function 
xref-elisp-overloadable-co-located-default)"
+              (xref-make-elisp-location
+               'xref-elisp-overloadable-co-located-default 
'define-overloadable-function
+               (expand-file-name "elisp-mode-tests.el" emacs-test-dir)))
+   (xref-make "(define-mode-local-override 
xref-elisp-overloadable-co-located-default c-mode)"
+              (xref-make-elisp-location
+               '(xref-elisp-overloadable-co-located-default-c-mode . c-mode) 
'define-mode-local-override
+               (expand-file-name "elisp-mode-tests.el" emacs-test-dir)))
+   ))
+
+(xref-elisp-deftest find-defs-define-overload-separate-default
+  (elisp--xref-find-definitions 'xref-elisp-overloadable-separate-default)
+  (list
+   (xref-make "(define-overloadable-function 
xref-elisp-overloadable-separate-default)"
+              (xref-make-elisp-location
+               'xref-elisp-overloadable-separate-default 
'define-overloadable-function
+               (expand-file-name "elisp-mode-tests.el" emacs-test-dir)))
+   (xref-make "(defun xref-elisp-overloadable-separate-default-default)"
+              (xref-make-elisp-location
+               'xref-elisp-overloadable-separate-default-default nil
+               (expand-file-name "elisp-mode-tests.el" emacs-test-dir)))
+   (xref-make "(define-mode-local-override 
xref-elisp-overloadable-separate-default c-mode)"
+              (xref-make-elisp-location
+               '(xref-elisp-overloadable-separate-default-c-mode . c-mode) 
'define-mode-local-override
+               (expand-file-name "elisp-mode-tests.el" emacs-test-dir)))
+   ))
+
 (xref-elisp-deftest find-defs-defun-el
   (elisp--xref-find-definitions 'xref-find-definitions)
   (list



reply via email to

[Prev in Thread] Current Thread [Next in Thread]