]> code.delx.au - gnu-emacs/blobdiff - lisp/cedet/semantic/symref.el
Merge from origin/emacs-25
[gnu-emacs] / lisp / cedet / semantic / symref.el
index 170495e5d612d5c7f843d9b03a70fc9fd3c51d53..0c1fe7e449b14ef21619b8ae5efc352701f60a4e 100644 (file)
@@ -1,6 +1,6 @@
 ;;; semantic/symref.el --- Symbol Reference API
 
 ;;; semantic/symref.el --- Symbol Reference API
 
-;; Copyright (C) 2008-2015 Free Software Foundation, Inc.
+;; Copyright (C) 2008-2016 Free Software Foundation, Inc.
 
 ;; Author: Eric M. Ludlam <eric@siege-engine.com>
 
 
 ;; Author: Eric M. Ludlam <eric@siege-engine.com>
 
@@ -65,6 +65,8 @@
 ;; Your tool should then create an instance of `semantic-symref-result'.
 
 (require 'semantic)
 ;; Your tool should then create an instance of `semantic-symref-result'.
 
 (require 'semantic)
+(eval-when-compile (require 'semantic/find)) ;For semantic-find-tags-*
+(eval-when-compile (require 'ede/proj)) ;For `metasubproject' warning.
 
 (defvar ede-minor-mode)
 (declare-function data-debug-new-buffer "data-debug")
 
 (defvar ede-minor-mode)
 (declare-function data-debug-new-buffer "data-debug")
@@ -101,7 +103,7 @@ If no tools are supported, then 'grep is assumed.")
 
 (defun semantic-symref-calculate-rootdir ()
   "Calculate the root directory for a symref search.
 
 (defun semantic-symref-calculate-rootdir ()
   "Calculate the root directory for a symref search.
-Start with and EDE project, or use the default directory."
+Start with an EDE project, or use the default directory."
   (let* ((rootproj (when (and (featurep 'ede) ede-minor-mode)
                     (ede-toplevel)))
         (rootdirbase (if rootproj
   (let* ((rootproj (when (and (featurep 'ede) ede-minor-mode)
                     (ede-toplevel)))
         (rootdirbase (if rootproj
@@ -109,7 +111,7 @@ Start with and EDE project, or use the default directory."
                        default-directory)))
     (if (and rootproj (condition-case nil
                          ;; Hack for subprojects.
                        default-directory)))
     (if (and rootproj (condition-case nil
                          ;; Hack for subprojects.
-                         (oref rootproj :metasubproject)
+                         (oref rootproj metasubproject)
                        (error nil)))
        (ede-up-directory rootdirbase)
       rootdirbase)))
                        (error nil)))
        (ede-up-directory rootdirbase)
       rootdirbase)))
@@ -162,7 +164,7 @@ ARGS are the initialization arguments to pass to the created class."
 ;;;###autoload
 (defun semantic-symref-find-references-by-name (name &optional scope tool-return)
   "Find a list of references to NAME in the current project.
 ;;;###autoload
 (defun semantic-symref-find-references-by-name (name &optional scope tool-return)
   "Find a list of references to NAME in the current project.
-Optional SCOPE specifies which file set to search.  Defaults to 'project.
+Optional SCOPE specifies which file set to search.  Defaults to `project'.
 Refers to `semantic-symref-tool', to determine the reference tool to use
 for the current buffer.
 Returns an object of class `semantic-symref-result'.
 Refers to `semantic-symref-tool', to determine the reference tool to use
 for the current buffer.
 Returns an object of class `semantic-symref-result'.
@@ -186,7 +188,7 @@ to perform the search.  This was added for use by a test harness."
 ;;;###autoload
 (defun semantic-symref-find-tags-by-name (name &optional scope)
   "Find a list of tags by NAME in the current project.
 ;;;###autoload
 (defun semantic-symref-find-tags-by-name (name &optional scope)
   "Find a list of tags by NAME in the current project.
-Optional SCOPE specifies which file set to search.  Defaults to 'project.
+Optional SCOPE specifies which file set to search.  Defaults to `project'.
 Refers to `semantic-symref-tool', to determine the reference tool to use
 for the current buffer.
 Returns an object of class `semantic-symref-result'."
 Refers to `semantic-symref-tool', to determine the reference tool to use
 for the current buffer.
 Returns an object of class `semantic-symref-result'."
@@ -206,7 +208,7 @@ Returns an object of class `semantic-symref-result'."
 ;;;###autoload
 (defun semantic-symref-find-tags-by-regexp (name &optional scope)
   "Find a list of references to NAME in the current project.
 ;;;###autoload
 (defun semantic-symref-find-tags-by-regexp (name &optional scope)
   "Find a list of references to NAME in the current project.
-Optional SCOPE specifies which file set to search.  Defaults to 'project.
+Optional SCOPE specifies which file set to search.  Defaults to `project'.
 Refers to `semantic-symref-tool', to determine the reference tool to use
 for the current buffer.
 Returns an object of class `semantic-symref-result'."
 Refers to `semantic-symref-tool', to determine the reference tool to use
 for the current buffer.
 Returns an object of class `semantic-symref-result'."
@@ -226,7 +228,7 @@ Returns an object of class `semantic-symref-result'."
 ;;;###autoload
 (defun semantic-symref-find-tags-by-completion (name &optional scope)
   "Find a list of references to NAME in the current project.
 ;;;###autoload
 (defun semantic-symref-find-tags-by-completion (name &optional scope)
   "Find a list of references to NAME in the current project.
-Optional SCOPE specifies which file set to search.  Defaults to 'project.
+Optional SCOPE specifies which file set to search.  Defaults to `project'.
 Refers to `semantic-symref-tool', to determine the reference tool to use
 for the current buffer.
 Returns an object of class `semantic-symref-result'."
 Refers to `semantic-symref-tool', to determine the reference tool to use
 for the current buffer.
 Returns an object of class `semantic-symref-result'."
@@ -246,7 +248,7 @@ Returns an object of class `semantic-symref-result'."
 ;;;###autoload
 (defun semantic-symref-find-file-references-by-name (name &optional scope)
   "Find a list of references to NAME in the current project.
 ;;;###autoload
 (defun semantic-symref-find-file-references-by-name (name &optional scope)
   "Find a list of references to NAME in the current project.
-Optional SCOPE specifies which file set to search.  Defaults to 'project.
+Optional SCOPE specifies which file set to search.  Defaults to `project'.
 Refers to `semantic-symref-tool', to determine the reference tool to use
 for the current buffer.
 Returns an object of class `semantic-symref-result'."
 Refers to `semantic-symref-tool', to determine the reference tool to use
 for the current buffer.
 Returns an object of class `semantic-symref-result'."
@@ -266,12 +268,12 @@ Returns an object of class `semantic-symref-result'."
 ;;;###autoload
 (defun semantic-symref-find-text (text &optional scope)
   "Find a list of occurrences of TEXT in the current project.
 ;;;###autoload
 (defun semantic-symref-find-text (text &optional scope)
   "Find a list of occurrences of TEXT in the current project.
-TEXT is a regexp formatted for use with egrep.
-Optional SCOPE specifies which file set to search.  Defaults to 'project.
+TEXT is a regexp formatted for use with grep -E.
+Optional SCOPE specifies which file set to search.  Defaults to `project'.
 Refers to `semantic-symref-tool', to determine the reference tool to use
 for the current buffer.
 Returns an object of class `semantic-symref-result'."
 Refers to `semantic-symref-tool', to determine the reference tool to use
 for the current buffer.
 Returns an object of class `semantic-symref-result'."
-  (interactive "sEgrep style Regexp: ")
+  (interactive "sGrep -E style Regexp: ")
   (let* ((inst (semantic-symref-instantiate
                :searchfor text
                :searchtype 'regexp
   (let* ((inst (semantic-symref-instantiate
                :searchfor text
                :searchtype 'regexp
@@ -284,6 +286,80 @@ Returns an object of class `semantic-symref-result'."
        (semantic-symref-data-debug-last-result))))
   )
 
        (semantic-symref-data-debug-last-result))))
   )
 
+;;; SYMREF TOOLS
+;;
+;; The base symref tool provides something to hang new tools off of
+;; for finding symbol references.
+(defclass semantic-symref-tool-baseclass ()
+  ((searchfor :initarg :searchfor
+             :type string
+             :documentation "The thing to search for.")
+   (searchtype :initarg :searchtype
+               :type symbol
+               :documentation "The type of search to do.
+Values could be 'symbol, 'regexp, 'tagname, or 'completion.")
+   (searchscope :initarg :searchscope
+               :type symbol
+               :documentation
+               "The scope to search for.
+Can be 'project, 'target, or 'file.")
+   (resulttype :initarg :resulttype
+              :type symbol
+              :documentation
+              "The kind of search results desired.
+Can be 'line, 'file, or 'tag.
+The type of result can be converted from 'line to 'file, or 'line to 'tag,
+but not from 'file to 'line or 'tag.")
+   )
+  "Baseclass for all symbol references tools.
+A symbol reference tool supplies functionality to identify the locations of
+where different symbols are used.
+
+Subclasses should be named `semantic-symref-tool-NAME', where
+NAME is the name of the tool used in the configuration variable
+`semantic-symref-tool'"
+  :abstract t)
+
+(cl-defmethod semantic-symref-get-result ((tool semantic-symref-tool-baseclass))
+  "Calculate the results of a search based on TOOL.
+The symref TOOL should already contain the search criteria."
+  (let ((answer (semantic-symref-perform-search tool))
+       )
+    (when answer
+      (let ((answersym (if (eq (oref tool resulttype) 'file)
+                          :hit-files
+                        (if (stringp (car answer))
+                            :hit-text
+                          :hit-lines))))
+       (semantic-symref-result (oref tool searchfor)
+                               answersym
+                               answer
+                               :created-by tool))
+      )
+    ))
+
+(cl-defmethod semantic-symref-perform-search ((_tool semantic-symref-tool-baseclass))
+  "Base search for symref tools should throw an error."
+  (error "Symref tool objects must implement `semantic-symref-perform-search'"))
+
+(cl-defmethod semantic-symref-parse-tool-output ((tool semantic-symref-tool-baseclass)
+                                             outputbuffer)
+  "Parse the entire OUTPUTBUFFER of a symref tool.
+Calls the method `semantic-symref-parse-tool-output-one-line' over and
+over until it returns nil."
+  (with-current-buffer outputbuffer
+    (goto-char (point-min))
+    (let ((result nil)
+         (hit nil))
+      (while (setq hit (semantic-symref-parse-tool-output-one-line tool))
+       (setq result (cons hit result)))
+      (nreverse result)))
+  )
+
+(cl-defmethod semantic-symref-parse-tool-output-one-line ((_tool semantic-symref-tool-baseclass))
+  "Base tool output parser is not implemented."
+  (error "Symref tool objects must implement `semantic-symref-parse-tool-output-one-line'"))
+
 ;;; RESULTS
 ;;
 ;; The results class and methods provide features for accessing hits.
 ;;; RESULTS
 ;;
 ;; The results class and methods provide features for accessing hits.
@@ -314,11 +390,11 @@ Use the  `semantic-symref-hit-tags' method to get this list.")
    )
   "The results from a symbol reference search.")
 
    )
   "The results from a symbol reference search.")
 
-(defmethod semantic-symref-result-get-files ((result semantic-symref-result))
+(cl-defmethod semantic-symref-result-get-files ((result semantic-symref-result))
   "Get the list of files from the symref result RESULT."
   "Get the list of files from the symref result RESULT."
-  (if (slot-boundp result :hit-files)
+  (if (slot-boundp result 'hit-files)
       (oref result hit-files)
       (oref result hit-files)
-    (let* ((lines  (oref result :hit-lines))
+    (let* ((lines  (oref result hit-lines))
           (files (mapcar (lambda (a) (cdr a)) lines))
           (ans nil))
       (setq ans (list (car files))
           (files (mapcar (lambda (a) (cdr a)) lines))
           (ans nil))
       (setq ans (list (car files))
@@ -337,7 +413,7 @@ Use the  `semantic-symref-hit-tags' method to get this list.")
   "List of buffers opened by `semantic-symref-result-get-tags'.")
 
 (defun semantic-symref-cleanup-recent-buffers-fcn ()
   "List of buffers opened by `semantic-symref-result-get-tags'.")
 
 (defun semantic-symref-cleanup-recent-buffers-fcn ()
-  "Hook function to be used in 'post-command-hook' to cleanup buffers.
+  "Hook function to be used in `post-command-hook' to cleanup buffers.
 Buffers collected during symref can result in some files being
 opened multiple times for one operation.  This will keep buffers open
 until the next command is executed."
 Buffers collected during symref can result in some files being
 opened multiple times for one operation.  This will keep buffers open
 until the next command is executed."
@@ -351,20 +427,20 @@ until the next command is executed."
   (setq semantic-symref-recently-opened-buffers nil)
   (remove-hook 'post-command-hook 'semantic-symref-cleanup-recent-buffers-fcn)
   )
   (setq semantic-symref-recently-opened-buffers nil)
   (remove-hook 'post-command-hook 'semantic-symref-cleanup-recent-buffers-fcn)
   )
-  
-(defmethod semantic-symref-result-get-tags ((result semantic-symref-result)
+
+(cl-defmethod semantic-symref-result-get-tags ((result semantic-symref-result)
                                            &optional open-buffers)
   "Get the list of tags from the symref result RESULT.
 Optional OPEN-BUFFERS indicates that the buffers that the hits are
 in should remain open after scanning.
 Note: This can be quite slow if most of the hits are not in buffers
 already."
                                            &optional open-buffers)
   "Get the list of tags from the symref result RESULT.
 Optional OPEN-BUFFERS indicates that the buffers that the hits are
 in should remain open after scanning.
 Note: This can be quite slow if most of the hits are not in buffers
 already."
-  (if (and (slot-boundp result :hit-tags) (oref result hit-tags))
+  (if (and (slot-boundp result 'hit-tags) (oref result hit-tags))
       (oref result hit-tags)
     ;; Calculate the tags.
       (oref result hit-tags)
     ;; Calculate the tags.
-    (let ((lines (oref result :hit-lines))
-         (txt (oref (oref result :created-by) :searchfor))
-         (searchtype (oref (oref result :created-by) :searchtype))
+    (let ((lines (oref result hit-lines))
+         (txt (oref (oref result created-by) searchfor))
+         (searchtype (oref (oref result created-by) searchtype))
          (ans nil)
          (out nil))
       (save-excursion
          (ans nil)
          (out nil))
       (save-excursion
@@ -390,7 +466,7 @@ already."
              (semantic--tag-put-property (car out) :hit lines)))
          ))
       ;; Out is reversed... twice
              (semantic--tag-put-property (car out) :hit lines)))
          ))
       ;; Out is reversed... twice
-      (oset result :hit-tags (nreverse out)))))
+      (oset result hit-tags (nreverse out)))))
 
 (defun semantic-symref-hit-to-tag-via-db (hit searchtxt searchtype)
   "Convert the symref HIT into a TAG by looking up the tag via a database.
 
 (defun semantic-symref-hit-to-tag-via-db (hit searchtxt searchtype)
   "Convert the symref HIT into a TAG by looking up the tag via a database.
@@ -403,20 +479,18 @@ If there is no database, of if the searchtype is wrong, return nil."
   ;; tagname, tagregexp, tagcompletions
   (if (not (memq searchtype '(tagname tagregexp tagcompletions)))
       nil
   ;; tagname, tagregexp, tagcompletions
   (if (not (memq searchtype '(tagname tagregexp tagcompletions)))
       nil
-    (let* ((line (car hit))
-          (file (cdr hit))
+    (let* ((file (cdr hit))
           ;; FAIL here vv - don't load is not obeyed if no table found.
           (db (semanticdb-file-table-object file t))
           ;; FAIL here vv - don't load is not obeyed if no table found.
           (db (semanticdb-file-table-object file t))
-          (found nil)
+          (found
+            (cond ((eq searchtype 'tagname)
+                   (semantic-find-tags-by-name searchtxt db))
+                  ((eq searchtype 'tagregexp)
+                   (semantic-find-tags-by-name-regexp searchtxt db))
+                  ((eq searchtype 'tagcompletions)
+                   (semantic-find-tags-for-completion searchtxt db))))
           (hit nil)
           )
           (hit nil)
           )
-      (cond ((eq searchtype 'tagname)
-            (setq found (semantic-find-tags-by-name searchtxt db)))
-           ((eq searchtype 'tagregexp)
-            (setq found (semantic-find-tags-by-name-regexp searchtxt db)))
-           ((eq searchtype 'tagcompletions)
-            (setq found (semantic-find-tags-for-completion searchtxt db)))
-           )
       ;; Loop over FOUND to see if we can line up a match with a line number.
       (when (= (length found) 1)
        (setq hit (car found)))
       ;; Loop over FOUND to see if we can line up a match with a line number.
       (when (= (length found) 1)
        (setq hit (car found)))
@@ -472,8 +546,12 @@ buffers that were opened."
     (goto-char (point-min))
     (forward-line (1- line))
 
     (goto-char (point-min))
     (forward-line (1- line))
 
-    ;; Search forward for the matching text
-    (when (re-search-forward (regexp-quote searchtxt)
+    ;; Search forward for the matching text.
+    ;; FIXME: This still fails if the regexp uses something specific
+    ;; to the extended syntax, like grouping.
+    (when (re-search-forward (if (memq searchtype '(regexp tagregexp))
+                                 searchtxt
+                               (regexp-quote searchtxt))
                             (point-at-eol)
                             t)
       (goto-char (match-beginning 0))
                             (point-at-eol)
                             t)
       (goto-char (match-beginning 0))
@@ -497,80 +575,6 @@ buffers that were opened."
       (semantic--tag-put-property tag :hit (list line)))
     tag))
 
       (semantic--tag-put-property tag :hit (list line)))
     tag))
 
-;;; SYMREF TOOLS
-;;
-;; The base symref tool provides something to hang new tools off of
-;; for finding symbol references.
-(defclass semantic-symref-tool-baseclass ()
-  ((searchfor :initarg :searchfor
-             :type string
-             :documentation "The thing to search for.")
-   (searchtype :initarg :searchtype
-               :type symbol
-               :documentation "The type of search to do.
-Values could be `symbol, `regexp, 'tagname, or 'completion.")
-   (searchscope :initarg :searchscope
-               :type symbol
-               :documentation
-               "The scope to search for.
-Can be 'project, 'target, or 'file.")
-   (resulttype :initarg :resulttype
-              :type symbol
-              :documentation
-              "The kind of search results desired.
-Can be 'line, 'file, or 'tag.
-The type of result can be converted from 'line to 'file, or 'line to 'tag,
-but not from 'file to 'line or 'tag.")
-   )
-  "Baseclass for all symbol references tools.
-A symbol reference tool supplies functionality to identify the locations of
-where different symbols are used.
-
-Subclasses should be named `semantic-symref-tool-NAME', where
-NAME is the name of the tool used in the configuration variable
-`semantic-symref-tool'"
-  :abstract t)
-
-(defmethod semantic-symref-get-result ((tool semantic-symref-tool-baseclass))
-  "Calculate the results of a search based on TOOL.
-The symref TOOL should already contain the search criteria."
-  (let ((answer (semantic-symref-perform-search tool))
-       )
-    (when answer
-      (let ((answersym (if (eq (oref tool :resulttype) 'file)
-                          :hit-files
-                        (if (stringp (car answer))
-                            :hit-text
-                          :hit-lines))))
-       (semantic-symref-result (oref tool searchfor)
-                               answersym
-                               answer
-                               :created-by tool))
-      )
-    ))
-
-(defmethod semantic-symref-perform-search ((tool semantic-symref-tool-baseclass))
-  "Base search for symref tools should throw an error."
-  (error "Symref tool objects must implement `semantic-symref-perform-search'"))
-
-(defmethod semantic-symref-parse-tool-output ((tool semantic-symref-tool-baseclass)
-                                             outputbuffer)
-  "Parse the entire OUTPUTBUFFER of a symref tool.
-Calls the method `semantic-symref-parse-tool-output-one-line' over and
-over until it returns nil."
-  (with-current-buffer outputbuffer
-    (goto-char (point-min))
-    (let ((result nil)
-         (hit nil))
-      (while (setq hit (semantic-symref-parse-tool-output-one-line tool))
-       (setq result (cons hit result)))
-      (nreverse result)))
-  )
-
-(defmethod semantic-symref-parse-tool-output-one-line ((tool semantic-symref-tool-baseclass))
-  "Base tool output parser is not implemented."
-  (error "Symref tool objects must implement `semantic-symref-parse-tool-output-one-line'"))
-
 (provide 'semantic/symref)
 
 ;; Local variables:
 (provide 'semantic/symref)
 
 ;; Local variables: