]> 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
 
-;; Copyright (C) 2008-2015 Free Software Foundation, Inc.
+;; Copyright (C) 2008-2016 Free Software Foundation, Inc.
 
 ;; 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)
+(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")
@@ -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.
-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
@@ -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.
-                         (oref rootproj :metasubproject)
+                         (oref rootproj metasubproject)
                        (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.
-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'.
@@ -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.
-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'."
@@ -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.
-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'."
@@ -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.
-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'."
@@ -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.
-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'."
@@ -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.
-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'."
-  (interactive "sEgrep style Regexp: ")
+  (interactive "sGrep -E style 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))))
   )
 
+;;; 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.
@@ -314,11 +390,11 @@ Use the  `semantic-symref-hit-tags' method to get this list.")
    )
   "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."
-  (if (slot-boundp result :hit-files)
+  (if (slot-boundp 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))
@@ -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 ()
-  "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."
@@ -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)
   )
-  
-(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."
-  (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.
-    (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
@@ -390,7 +466,7 @@ already."
              (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.
@@ -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
-    (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))
-          (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)
           )
-      (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)))
@@ -472,8 +546,12 @@ buffers that were opened."
     (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))
@@ -497,80 +575,6 @@ buffers that were opened."
       (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: