]> code.delx.au - gnu-emacs/blobdiff - lisp/cedet/semantic/db.el
Fix bug #8487 with invisible text at EOB under bidi.
[gnu-emacs] / lisp / cedet / semantic / db.el
index 807b7b3cfb08bc546fac6fbbbb720957087924a6..fa8de392b629905b5d6a5b83060c478804bbe492 100644 (file)
@@ -1,7 +1,6 @@
-;;; db.el --- Semantic tag database manager
+;;; semantic/db.el --- Semantic tag database manager
 
-;;; Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
-;;; 2008, 2009 Free Software Foundation, Inc.
+;; Copyright (C) 2000-2011  Free Software Foundation, Inc.
 
 ;; Author: Eric M. Ludlam <zappo@gnu.org>
 ;; Keywords: tags
 ;; By default, assume one database per directory.
 ;;
 
-(require 'eieio)
-;; (require 'inversion)
-;; (eval-and-compile
-;;   (inversion-require 'eieio "1.0"))
+;;; Code:
+
 (require 'eieio-base)
 (require 'semantic)
-(eval-when-compile
-  (require 'semantic/lex-spp))
+
+(declare-function semantic-lex-spp-save-table "semantic/lex-spp")
 
 ;;; Variables:
 (defgroup semanticdb nil
   "Parser Generator Persistent Database interface."
-  :group 'semantic
-  )
-;;; Code:
+  :group 'semantic)
+
 (defvar semanticdb-database-list nil
   "List of all active databases.")
 
@@ -56,9 +52,18 @@ mechanism.")
 
 (defvar semanticdb-default-find-index-class 'semanticdb-find-search-index
   "The default type of search index to use for a `semanticdb-table's.
-This can be changed to try out new types of search indicies.")
+This can be changed to try out new types of search indices.")
 (make-variable-buffer-local 'semanticdb-default-find=index-class)
 
+;;;###autoload
+(defvar semanticdb-current-database nil
+  "For a given buffer, this is the currently active database.")
+(make-variable-buffer-local 'semanticdb-current-database)
+
+;;;###autoload
+(defvar semanticdb-current-table nil
+  "For a given buffer, this is the currently active database table.")
+(make-variable-buffer-local 'semanticdb-current-table)
 
 ;;; ABSTRACT CLASSES
 ;;
@@ -190,6 +195,23 @@ If one doesn't exist, create it."
   )
 
 
+;;; SEARCH RESULTS TABLE
+;;
+;; Needed for system databases that may not provide
+;; a semanticdb-table associated with a file.
+;;
+(defclass semanticdb-search-results-table (semanticdb-abstract-table)
+  (
+   )
+  "Table used for search results when there is no file or table association.
+Examples include search results from external sources such as from
+Emacs' own symbol table, or from external libraries.")
+
+(defmethod semanticdb-refresh-table ((obj semanticdb-search-results-table) &optional force)
+  "If the tag list associated with OBJ is loaded, refresh it.
+This will call `semantic-fetch-tags' if that file is in memory."
+  nil)
+
 ;;; CONCRETE TABLE CLASSES
 ;;
 (defclass semanticdb-table (semanticdb-abstract-table)
@@ -250,7 +272,9 @@ If the buffer is in memory, return that buffer."
 If the buffer is in memory, return that buffer.
 If the buffer is not in memory, load it with `find-file-noselect'."
   (or (semanticdb-in-buffer-p obj)
-      (find-file-noselect (semanticdb-full-filename obj) t)))
+      ;; Save match data to protect against odd stuff in mode hooks.
+      (save-match-data
+       (find-file-noselect (semanticdb-full-filename obj) t))))
 
 (defmethod semanticdb-set-buffer ((obj semanticdb-table))
   "Set the current buffer to be a buffer owned by OBJ.
@@ -425,7 +449,8 @@ See the file semantic-scope.el for an example."
   "Get a cache object on TABLE of class DESIRED-CLASS.
 This method will create one if none exists with no init arguments
 other than :table."
-  (assert (child-of-class-p desired-class 'semanticdb-abstract-cache))
+  (unless (child-of-class-p desired-class 'semanticdb-abstract-cache)
+    (error "Invalid SemanticDB cache"))
   (let ((cache (oref table cache))
        (obj nil))
     (while (and (not obj) cache)
@@ -475,7 +500,8 @@ See the file semantic-scope.el for an example."
   "Get a cache object on DB of class DESIRED-CLASS.
 This method will create one if none exists with no init arguments
 other than :table."
-  (assert (child-of-class-p desired-class 'semanticdb-abstract-db-cache))
+  (unless (child-of-class-p desired-class 'semanticdb-abstract-cache)
+    (error "Invalid SemanticDB cache"))
   (let ((cache (oref db cache))
        (obj nil))
     (while (and (not obj) cache)
@@ -515,10 +541,25 @@ Optional argument FORCE will force a refresh even if the file in question
 is not in a buffer.  Avoid using FORCE for most uses, as an old cache
 may be sufficient for the general case.  Forced updates can be slow.
 This will call `semantic-fetch-tags' if that file is in memory."
-  (when (or (semanticdb-in-buffer-p obj) force)
+  (cond
+   ;;
+   ;; Already in a buffer, just do it.
+   ((semanticdb-in-buffer-p obj)
+    (semanticdb-set-buffer obj)
+    (semantic-fetch-tags))
+   ;;
+   ;; Not in a buffer.  Forcing a load.
+   (force
+    ;; Patch from Iain Nicol. --
+    ;; @TODO: I wonder if there is a way to recycle
+    ;;        semanticdb-create-table-for-file-not-in-buffer
     (save-excursion
-      (semanticdb-set-buffer obj)
-      (semantic-fetch-tags))))
+      (let ((buff (semantic-find-file-noselect
+                  (semanticdb-full-filename obj))))
+       (set-buffer buff)
+       (semantic-fetch-tags)
+       ;; Kill off the buffer if it didn't exist when we were called.
+       (kill-buffer buff))))))
 
 (defmethod semanticdb-needs-refresh-p ((obj semanticdb-table))
   "Return non-nil of OBJ's tag list is out of date.
@@ -527,8 +568,7 @@ The file associated with OBJ does not need to be in a buffer."
         (buff (semanticdb-in-buffer-p obj))
         )
     (if buff
-       (save-excursion
-         (set-buffer buff)
+       (with-current-buffer buff
          ;; Use semantic's magic tracker to determine of the buffer is up
          ;; to date or not.
          (not (semantic-parse-tree-up-to-date-p))
@@ -564,7 +604,7 @@ The file associated with OBJ does not need to be in a buffer."
   ;; Assume it is now up to date.
   (oset table unmatched-syntax semantic-unmatched-syntax-cache)
   ;; The lexical table should be good too.
-  (when (featurep 'semantic-lex-spp)
+  (when (featurep 'semantic/lex-spp)
     (oset table lexical-table (semantic-lex-spp-save-table)))
   ;; this implies dirtyness
   (semanticdb-set-dirty table)
@@ -593,7 +633,7 @@ The file associated with OBJ does not need to be in a buffer."
   (semanticdb-set-dirty table)
 
   ;; The lexical table may be modified.
-  (when (featurep 'semantic-lex-spp)
+  (when (featurep 'semantic/lex-spp)
     (oset table lexical-table (semantic-lex-spp-save-table)))
 
   ;; Incremental parser doesn't mokey around with this.
@@ -631,11 +671,16 @@ form."
   (semanticdb-save-db semanticdb-current-database)
   (message "Saving current tag summaries...done"))
 
+;; This prevents Semanticdb from querying multiple times if the users
+;; answers "no" to creating the Semanticdb directory.
+(defvar semanticdb--inhibit-create-file-directory)
+
 (defun semanticdb-save-all-db ()
   "Save all semantic tag databases."
   (interactive)
   (message "Saving tag summaries...")
-  (mapc 'semanticdb-save-db semanticdb-database-list)
+  (let ((semanticdb--inhibit-make-directory nil))
+    (mapc 'semanticdb-save-db semanticdb-database-list))
   (message "Saving tag summaries...done"))
 
 (defun semanticdb-save-all-db-idle ()
@@ -679,14 +724,14 @@ Uses `semanticdb-persistent-path' to determine the return value."
       nil))
 
 (defvar semanticdb-match-any-mode nil
-  "Non-nil to temporarilly search any major mode for a tag.
+  "Non-nil to temporarily search any major mode for a tag.
 If a particular major mode wants to search any mode, put the
 `semantic-match-any-mode' symbol onto the symbol of that major mode.
 Do not set the value of this variable permanently.")
 
 (defmacro semanticdb-with-match-any-mode (&rest body)
-  "A Semanticdb search occuring withing BODY will search tags in all modes.
-This temporarilly sets `semanticdb-match-any-mode' while executing BODY."
+  "A Semanticdb search occurring withing BODY will search tags in all modes.
+This temporarily sets `semanticdb-match-any-mode' while executing BODY."
   `(let ((semanticdb-match-any-mode t))
      ,@body))
 (put 'semanticdb-with-match-any-mode 'lisp-indent-function 0)
@@ -704,13 +749,13 @@ all files of any type."
 
 (defmethod semanticdb-equivalent-mode ((table semanticdb-abstract-table) &optional buffer)
   "Return non-nil if TABLE's mode is equivalent to BUFFER.
-Equivalent modes are specified by by `semantic-equivalent-major-modes'
+Equivalent modes are specified by the `semantic-equivalent-major-modes'
 local variable."
   nil)
 
 (defmethod semanticdb-equivalent-mode ((table semanticdb-table) &optional buffer)
   "Return non-nil if TABLE's mode is equivalent to BUFFER.
-Equivalent modes are specified by by `semantic-equivalent-major-modes'
+Equivalent modes are specified by the `semantic-equivalent-major-modes'
 local variable."
   (save-excursion
     (if buffer (set-buffer buffer))
@@ -734,7 +779,7 @@ local variable."
 (defcustom semanticdb-project-roots nil
   "*List of directories, where each directory is the root of some project.
 All subdirectories of a root project are considered a part of one project.
-Values in this string can be overriden by project management programs
+Values in this string can be overridden by project management programs
 via the `semanticdb-project-root-functions' variable."
   :group 'semanticdb
   :type '(repeat string))
@@ -777,12 +822,14 @@ Always append `semanticdb-project-system-databases' if
     (setq root (run-hook-with-args-until-success
                'semanticdb-project-root-functions
                dir))
-    ;; Find roots based on strings
-    (while (and roots (not root))
-      (let ((r (file-truename (car roots))))
-       (if (string-match (concat "^" (regexp-quote r)) dir)
-           (setq root r)))
-      (setq roots (cdr roots)))
+    (if root
+       (setq root (file-truename root))
+      ;; Else, Find roots based on strings
+      (while roots
+       (let ((r (file-truename (car roots))))
+         (if (string-match (concat "^" (regexp-quote r)) dir)
+             (setq root r)))
+       (setq roots (cdr roots))))
 
     ;; If no roots are found, use this directory.
     (unless root (setq root dir))
@@ -825,6 +872,7 @@ Does not use `file-truename'."
   "For FILE, associate DBTABLE in the hash table."
   (puthash file dbtable semanticdb-file-table-hash))
 
+;;;###autoload
 (defun semanticdb-file-table-object (file &optional dontload)
   "Return a semanticdb table belonging to FILE, make it up to date.
 If file has database tags available in the database, return it.
@@ -986,4 +1034,9 @@ If file does not have tags available, then load the file, and create them."
 
 (provide 'semantic/db)
 
-;;; semanticdb.el ends here
+;; Local variables:
+;; generated-autoload-file: "loaddefs.el"
+;; generated-autoload-load-name: "semantic/db"
+;; End:
+
+;;; semantic/db.el ends here