Commit | Line | Data |
---|---|---|
691a065e | 1 | ;;; semantic/db.el --- Semantic tag database manager |
7a0e7d33 | 2 | |
9bf6c65c | 3 | ;; Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, |
5df4f04c | 4 | ;; 2009, 2010, 2011 Free Software Foundation, Inc. |
7a0e7d33 CY |
5 | |
6 | ;; Author: Eric M. Ludlam <zappo@gnu.org> | |
7 | ;; Keywords: tags | |
8 | ||
9 | ;; This file is part of GNU Emacs. | |
10 | ||
11 | ;; GNU Emacs is free software: you can redistribute it and/or modify | |
12 | ;; it under the terms of the GNU General Public License as published by | |
13 | ;; the Free Software Foundation, either version 3 of the License, or | |
14 | ;; (at your option) any later version. | |
15 | ||
16 | ;; GNU Emacs is distributed in the hope that it will be useful, | |
17 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 | ;; GNU General Public License for more details. | |
20 | ||
21 | ;; You should have received a copy of the GNU General Public License | |
22 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |
23 | ||
24 | ;;; Commentary: | |
25 | ;; | |
26 | ;; Maintain a database of tags for a group of files and enable | |
27 | ;; queries into the database. | |
28 | ;; | |
29 | ;; By default, assume one database per directory. | |
30 | ;; | |
31 | ||
b90caf50 CY |
32 | ;;; Code: |
33 | ||
7a0e7d33 CY |
34 | (require 'eieio-base) |
35 | (require 'semantic) | |
b90caf50 CY |
36 | |
37 | (declare-function semantic-lex-spp-save-table "semantic/lex-spp") | |
7a0e7d33 CY |
38 | |
39 | ;;; Variables: | |
40 | (defgroup semanticdb nil | |
41 | "Parser Generator Persistent Database interface." | |
b90caf50 CY |
42 | :group 'semantic) |
43 | ||
7a0e7d33 CY |
44 | (defvar semanticdb-database-list nil |
45 | "List of all active databases.") | |
46 | ||
47 | (defvar semanticdb-new-database-class 'semanticdb-project-database-file | |
48 | "The default type of database created for new files. | |
49 | This can be changed on a per file basis, so that some directories | |
50 | are saved using one mechanism, and some directories via a different | |
51 | mechanism.") | |
52 | (make-variable-buffer-local 'semanticdb-new-database-class) | |
53 | ||
54 | (defvar semanticdb-default-find-index-class 'semanticdb-find-search-index | |
55 | "The default type of search index to use for a `semanticdb-table's. | |
9bf6c65c | 56 | This can be changed to try out new types of search indices.") |
7a0e7d33 CY |
57 | (make-variable-buffer-local 'semanticdb-default-find=index-class) |
58 | ||
3d9d8486 | 59 | ;;;###autoload |
691a065e CY |
60 | (defvar semanticdb-current-database nil |
61 | "For a given buffer, this is the currently active database.") | |
62 | (make-variable-buffer-local 'semanticdb-current-database) | |
63 | ||
3d9d8486 | 64 | ;;;###autoload |
691a065e CY |
65 | (defvar semanticdb-current-table nil |
66 | "For a given buffer, this is the currently active database table.") | |
67 | (make-variable-buffer-local 'semanticdb-current-table) | |
7a0e7d33 CY |
68 | |
69 | ;;; ABSTRACT CLASSES | |
70 | ;; | |
71 | (defclass semanticdb-abstract-table () | |
72 | ((parent-db ;; :initarg :parent-db | |
73 | ;; Do not set an initarg, or you get circular writes to disk. | |
74 | :documentation "Database Object containing this table.") | |
75 | (major-mode :initarg :major-mode | |
76 | :initform nil | |
77 | :documentation "Major mode this table belongs to. | |
78 | Sometimes it is important for a program to know if a given table has the | |
79 | same major mode as the current buffer.") | |
80 | (tags :initarg :tags | |
81 | :accessor semanticdb-get-tags | |
82 | :printer semantic-tag-write-list-slot-value | |
83 | :documentation "The tags belonging to this table.") | |
84 | (index :type semanticdb-abstract-search-index | |
85 | :documentation "The search index. | |
86 | Used by semanticdb-find to store additional information about | |
87 | this table for searching purposes. | |
88 | ||
89 | Note: This index will not be saved in a persistent file.") | |
90 | (cache :type list | |
91 | :initform nil | |
92 | :documentation "List of cache information for tools. | |
93 | Any particular tool can cache data to a database at runtime | |
94 | with `semanticdb-cache-get'. | |
95 | ||
96 | Using a semanticdb cache does not save any information to a file, | |
97 | so your cache will need to be recalculated at runtime. Caches can be | |
98 | referenced even when the file is not in a buffer. | |
99 | ||
100 | Note: This index will not be saved in a persistent file.") | |
101 | ) | |
102 | "A simple table for semantic tags. | |
103 | This table is the root of tables, and contains the minimum needed | |
104 | for a new table not associated with a buffer." | |
105 | :abstract t) | |
106 | ||
107 | (defmethod semanticdb-in-buffer-p ((obj semanticdb-abstract-table)) | |
108 | "Return a nil, meaning abstract table OBJ is not in a buffer." | |
109 | nil) | |
110 | ||
111 | (defmethod semanticdb-get-buffer ((obj semanticdb-abstract-table)) | |
112 | "Return a buffer associated with OBJ. | |
113 | If the buffer is not in memory, load it with `find-file-noselect'." | |
114 | nil) | |
115 | ||
116 | (defmethod semanticdb-full-filename ((obj semanticdb-abstract-table)) | |
117 | "Fetch the full filename that OBJ refers to. | |
118 | Abstract tables do not have file names associated with them." | |
119 | nil) | |
120 | ||
121 | (defmethod semanticdb-dirty-p ((obj semanticdb-abstract-table)) | |
122 | "Return non-nil if OBJ is 'dirty'." | |
123 | nil) | |
124 | ||
125 | (defmethod semanticdb-set-dirty ((obj semanticdb-abstract-table)) | |
126 | "Mark the abstract table OBJ dirty. | |
127 | Abstract tables can not be marked dirty, as there is nothing | |
128 | for them to synchronize against." | |
129 | ;; The abstract table can not be dirty. | |
130 | nil) | |
131 | ||
132 | (defmethod semanticdb-normalize-tags ((obj semanticdb-abstract-table) tags) | |
133 | "For the table OBJ, convert a list of TAGS, into standardized form. | |
134 | The default is to return TAGS. | |
135 | Some databases may default to searching and providing simplified tags | |
136 | based on whichever technique used. This method provides a hook for | |
137 | them to convert TAG into a more complete form." | |
138 | tags) | |
139 | ||
140 | (defmethod semanticdb-normalize-one-tag ((obj semanticdb-abstract-table) tag) | |
141 | "For the table OBJ, convert a TAG, into standardized form. | |
142 | This method returns a list of the form (DATABASE . NEWTAG). | |
143 | ||
144 | The default is to just return (OBJ TAG). | |
145 | ||
146 | Some databases may default to searching and providing simplified tags | |
147 | based on whichever technique used. This method provides a hook for | |
148 | them to convert TAG into a more complete form." | |
149 | (cons obj tag)) | |
150 | ||
151 | (defmethod object-print ((obj semanticdb-abstract-table) &rest strings) | |
152 | "Pretty printer extension for `semanticdb-table'. | |
153 | Adds the number of tags in this file to the object print name." | |
154 | (apply 'call-next-method obj | |
155 | (cons (format " (%d tags)" | |
156 | (length (semanticdb-get-tags obj)) | |
157 | ) | |
158 | strings))) | |
159 | ||
160 | ;;; Index Cache | |
161 | ;; | |
162 | (defclass semanticdb-abstract-search-index () | |
163 | ((table :initarg :table | |
164 | :type semanticdb-abstract-table | |
165 | :documentation "XRef to the table this belongs to.") | |
166 | ) | |
167 | "A place where semanticdb-find can store search index information. | |
168 | The search index will store data about which other tables might be | |
169 | needed, or perhaps create hash or index tables for the current buffer." | |
170 | :abstract t) | |
171 | ||
172 | (defmethod semanticdb-get-table-index ((obj semanticdb-abstract-table)) | |
173 | "Return the search index for the table OBJ. | |
174 | If one doesn't exist, create it." | |
175 | (if (slot-boundp obj 'index) | |
176 | (oref obj index) | |
177 | (let ((idx nil)) | |
178 | (setq idx (funcall semanticdb-default-find-index-class | |
179 | (concat (object-name obj) " index") | |
180 | ;; Fill in the defaults | |
181 | :table obj | |
182 | )) | |
183 | (oset obj index idx) | |
184 | idx))) | |
185 | ||
186 | (defmethod semanticdb-synchronize ((idx semanticdb-abstract-search-index) | |
187 | new-tags) | |
188 | "Synchronize the search index IDX with some NEW-TAGS." | |
189 | ;; The abstract class will do... NOTHING! | |
190 | ) | |
191 | ||
192 | (defmethod semanticdb-partial-synchronize ((idx semanticdb-abstract-search-index) | |
193 | new-tags) | |
194 | "Synchronize the search index IDX with some changed NEW-TAGS." | |
195 | ;; The abstract class will do... NOTHING! | |
196 | ) | |
197 | ||
198 | ||
5fcb5c7e CY |
199 | ;;; SEARCH RESULTS TABLE |
200 | ;; | |
201 | ;; Needed for system databases that may not provide | |
202 | ;; a semanticdb-table associated with a file. | |
203 | ;; | |
204 | (defclass semanticdb-search-results-table (semanticdb-abstract-table) | |
205 | ( | |
206 | ) | |
207 | "Table used for search results when there is no file or table association. | |
208 | Examples include search results from external sources such as from | |
209 | Emacs' own symbol table, or from external libraries.") | |
210 | ||
211 | (defmethod semanticdb-refresh-table ((obj semanticdb-search-results-table) &optional force) | |
212 | "If the tag list associated with OBJ is loaded, refresh it. | |
213 | This will call `semantic-fetch-tags' if that file is in memory." | |
214 | nil) | |
215 | ||
7a0e7d33 CY |
216 | ;;; CONCRETE TABLE CLASSES |
217 | ;; | |
218 | (defclass semanticdb-table (semanticdb-abstract-table) | |
219 | ((file :initarg :file | |
220 | :documentation "File name relative to the parent database. | |
221 | This is for the file whose tags are stored in this TABLE object.") | |
222 | (buffer :initform nil | |
223 | :documentation "The buffer associated with this table. | |
224 | If nil, the table's buffer is no in Emacs. If it has a value, then | |
225 | it is in Emacs.") | |
226 | (dirty :initform nil | |
227 | :documentation | |
228 | "Non nil if this table needs to be `Saved'.") | |
229 | (db-refs :initform nil | |
230 | :documentation | |
231 | "List of `semanticdb-table' objects refering to this one. | |
232 | These aren't saved, but are instead recalculated after load. | |
233 | See the file semanticdb-ref.el for how this slot is used.") | |
234 | (pointmax :initarg :pointmax | |
235 | :initform nil | |
236 | :documentation "Size of buffer when written to disk. | |
237 | Checked on retrieval to make sure the file is the same.") | |
238 | (fsize :initarg :fsize | |
239 | :initform nil | |
240 | :documentation "Size of the file when it was last referenced. | |
241 | Checked when deciding if a loaded table needs updating from changes | |
242 | outside of Semantic's control.") | |
243 | (lastmodtime :initarg :lastmodtime | |
244 | :initform nil | |
245 | :documentation "Last modification time of the file referenced. | |
246 | Checked when deciding if a loaded table needs updating from changes outside of | |
247 | Semantic's control.") | |
248 | ;; @todo - need to add `last parsed time', so we can also have | |
249 | ;; refresh checks if spp tables or the parser gets rebuilt. | |
250 | (unmatched-syntax :initarg :unmatched-syntax | |
251 | :documentation | |
252 | "List of vectors specifying unmatched syntax.") | |
253 | ||
254 | (lexical-table :initarg :lexical-table | |
255 | :initform nil | |
256 | :printer semantic-lex-spp-table-write-slot-value | |
257 | :documentation | |
258 | "Table that might be needed by the lexical analyzer. | |
259 | For C/C++, the C preprocessor macros can be saved here.") | |
260 | ) | |
261 | "A single table of tags derived from file.") | |
262 | ||
263 | (defmethod semanticdb-in-buffer-p ((obj semanticdb-table)) | |
264 | "Return a buffer associated with OBJ. | |
265 | If the buffer is in memory, return that buffer." | |
266 | (let ((buff (oref obj buffer))) | |
267 | (if (buffer-live-p buff) | |
268 | buff | |
269 | (oset obj buffer nil)))) | |
270 | ||
271 | (defmethod semanticdb-get-buffer ((obj semanticdb-table)) | |
272 | "Return a buffer associated with OBJ. | |
273 | If the buffer is in memory, return that buffer. | |
274 | If the buffer is not in memory, load it with `find-file-noselect'." | |
275 | (or (semanticdb-in-buffer-p obj) | |
1eac105a CY |
276 | ;; Save match data to protect against odd stuff in mode hooks. |
277 | (save-match-data | |
278 | (find-file-noselect (semanticdb-full-filename obj) t)))) | |
7a0e7d33 CY |
279 | |
280 | (defmethod semanticdb-set-buffer ((obj semanticdb-table)) | |
281 | "Set the current buffer to be a buffer owned by OBJ. | |
282 | If OBJ's file is not loaded, read it in first." | |
283 | (set-buffer (semanticdb-get-buffer obj))) | |
284 | ||
285 | (defmethod semanticdb-full-filename ((obj semanticdb-table)) | |
286 | "Fetch the full filename that OBJ refers to." | |
287 | (expand-file-name (oref obj file) | |
288 | (oref (oref obj parent-db) reference-directory))) | |
289 | ||
290 | (defmethod semanticdb-dirty-p ((obj semanticdb-table)) | |
291 | "Return non-nil if OBJ is 'dirty'." | |
292 | (oref obj dirty)) | |
293 | ||
294 | (defmethod semanticdb-set-dirty ((obj semanticdb-table)) | |
295 | "Mark the abstract table OBJ dirty." | |
296 | (oset obj dirty t) | |
297 | ) | |
298 | ||
299 | (defmethod object-print ((obj semanticdb-table) &rest strings) | |
300 | "Pretty printer extension for `semanticdb-table'. | |
301 | Adds the number of tags in this file to the object print name." | |
302 | (apply 'call-next-method obj | |
303 | (cons (if (oref obj dirty) ", DIRTY" "") strings))) | |
304 | ||
305 | ;;; DATABASE BASE CLASS | |
306 | ;; | |
307 | (defclass semanticdb-project-database (eieio-instance-tracker) | |
308 | ((tracking-symbol :initform semanticdb-database-list) | |
309 | (reference-directory :type string | |
310 | :documentation "Directory this database refers to. | |
311 | When a cache directory is specified, then this refers to the directory | |
312 | this database contains symbols for.") | |
313 | (new-table-class :initform semanticdb-table | |
314 | :type class | |
315 | :documentation | |
316 | "New tables created for this database are of this class.") | |
317 | (cache :type list | |
318 | :initform nil | |
319 | :documentation "List of cache information for tools. | |
320 | Any particular tool can cache data to a database at runtime | |
321 | with `semanticdb-cache-get'. | |
322 | ||
323 | Using a semanticdb cache does not save any information to a file, | |
324 | so your cache will need to be recalculated at runtime. | |
325 | ||
326 | Note: This index will not be saved in a persistent file.") | |
327 | (tables :initarg :tables | |
328 | :type list | |
329 | ;; Need this protection so apps don't try to access | |
330 | ;; the tables without using the accessor. | |
331 | :accessor semanticdb-get-database-tables | |
332 | :protection :protected | |
333 | :documentation "List of `semantic-db-table' objects.")) | |
334 | "Database of file tables.") | |
335 | ||
336 | (defmethod semanticdb-full-filename ((obj semanticdb-project-database)) | |
337 | "Fetch the full filename that OBJ refers to. | |
338 | Abstract tables do not have file names associated with them." | |
339 | nil) | |
340 | ||
341 | (defmethod semanticdb-dirty-p ((DB semanticdb-project-database)) | |
342 | "Return non-nil if DB is 'dirty'. | |
343 | A database is dirty if the state of the database changed in a way | |
344 | where it may need to resynchronize with some persistent storage." | |
345 | (let ((dirty nil) | |
346 | (tabs (oref DB tables))) | |
347 | (while (and (not dirty) tabs) | |
348 | (setq dirty (semanticdb-dirty-p (car tabs))) | |
349 | (setq tabs (cdr tabs))) | |
350 | dirty)) | |
351 | ||
352 | (defmethod object-print ((obj semanticdb-project-database) &rest strings) | |
353 | "Pretty printer extension for `semanticdb-project-database'. | |
354 | Adds the number of tables in this file to the object print name." | |
355 | (apply 'call-next-method obj | |
356 | (cons (format " (%d tables%s)" | |
357 | (length (semanticdb-get-database-tables obj)) | |
358 | (if (semanticdb-dirty-p obj) | |
359 | " DIRTY" "") | |
360 | ) | |
361 | strings))) | |
362 | ||
363 | (defmethod semanticdb-create-database :STATIC ((dbc semanticdb-project-database) directory) | |
364 | "Create a new semantic database of class DBC for DIRECTORY and return it. | |
365 | If a database for DIRECTORY has already been created, return it. | |
366 | If DIRECTORY doesn't exist, create a new one." | |
367 | (let ((db (semanticdb-directory-loaded-p directory))) | |
368 | (unless db | |
369 | (setq db (semanticdb-project-database | |
370 | (file-name-nondirectory directory) | |
371 | :tables nil)) | |
372 | ;; Set this up here. We can't put it in the constructor because it | |
373 | ;; would be saved, and we want DB files to be portable. | |
374 | (oset db reference-directory (file-truename directory))) | |
375 | db)) | |
376 | ||
377 | (defmethod semanticdb-flush-database-tables ((db semanticdb-project-database)) | |
378 | "Reset the tables in DB to be empty." | |
379 | (oset db tables nil)) | |
380 | ||
381 | (defmethod semanticdb-create-table ((db semanticdb-project-database) file) | |
382 | "Create a new table in DB for FILE and return it. | |
383 | The class of DB contains the class name for the type of table to create. | |
384 | If the table for FILE exists, return it. | |
385 | If the table for FILE does not exist, create one." | |
386 | (let ((newtab (semanticdb-file-table db file))) | |
387 | (unless newtab | |
388 | ;; This implementation will satisfy autoloaded classes | |
389 | ;; for tables. | |
390 | (setq newtab (funcall (oref db new-table-class) | |
391 | (file-name-nondirectory file) | |
392 | :file (file-name-nondirectory file) | |
393 | )) | |
394 | (oset newtab parent-db db) | |
395 | (object-add-to-list db 'tables newtab t)) | |
396 | newtab)) | |
397 | ||
398 | (defmethod semanticdb-file-table ((obj semanticdb-project-database) filename) | |
399 | "From OBJ, return FILENAME's associated table object." | |
400 | (object-assoc (file-relative-name (file-truename filename) | |
401 | (oref obj reference-directory)) | |
402 | 'file (oref obj tables))) | |
403 | ||
404 | ;; DATABASE FUNCTIONS | |
405 | (defun semanticdb-get-database (filename) | |
406 | "Get a database for FILENAME. | |
407 | If one isn't found, create one." | |
408 | (semanticdb-create-database semanticdb-new-database-class (file-truename filename))) | |
409 | ||
410 | (defun semanticdb-directory-loaded-p (path) | |
411 | "Return the project belonging to PATH if it was already loaded." | |
412 | (eieio-instance-tracker-find path 'reference-directory 'semanticdb-database-list)) | |
413 | ||
414 | (defun semanticdb-create-table-for-file (filename) | |
415 | "Initialize a database table for FILENAME, and return it. | |
416 | If FILENAME exists in the database already, return that. | |
417 | If there is no database for the table to live in, create one." | |
418 | (let ((cdb nil) | |
419 | (tbl nil) | |
420 | (dd (file-name-directory filename)) | |
421 | ) | |
422 | ;; Allow a database override function | |
423 | (setq cdb (semanticdb-create-database semanticdb-new-database-class | |
424 | dd)) | |
425 | ;; Get a table for this file. | |
426 | (setq tbl (semanticdb-create-table cdb filename)) | |
427 | ||
428 | ;; Return the pair. | |
429 | (cons cdb tbl) | |
430 | )) | |
431 | ||
432 | ;;; Cache Cache. | |
433 | ;; | |
434 | (defclass semanticdb-abstract-cache () | |
435 | ((table :initarg :table | |
436 | :type semanticdb-abstract-table | |
437 | :documentation | |
438 | "Cross reference to the table this belongs to.") | |
439 | ) | |
440 | "Abstract baseclass for tools to use to cache information in semanticdb. | |
441 | Tools needing a per-file cache must subclass this, and then get one as | |
442 | needed. Cache objects are identified in semanticdb by subclass. | |
443 | In order to keep your cache up to date, be sure to implement | |
444 | `semanticdb-synchronize', and `semanticdb-partial-synchronize'. | |
445 | See the file semantic-scope.el for an example." | |
446 | :abstract t) | |
447 | ||
448 | (defmethod semanticdb-cache-get ((table semanticdb-abstract-table) | |
449 | desired-class) | |
450 | "Get a cache object on TABLE of class DESIRED-CLASS. | |
451 | This method will create one if none exists with no init arguments | |
452 | other than :table." | |
f192624c CY |
453 | (unless (child-of-class-p desired-class 'semanticdb-abstract-cache) |
454 | (error "Invalid SemanticDB cache")) | |
7a0e7d33 CY |
455 | (let ((cache (oref table cache)) |
456 | (obj nil)) | |
457 | (while (and (not obj) cache) | |
458 | (if (eq (object-class-fast (car cache)) desired-class) | |
459 | (setq obj (car cache))) | |
460 | (setq cache (cdr cache))) | |
461 | (if obj | |
462 | obj ;; Just return it. | |
463 | ;; No object, lets create a new one and return that. | |
464 | (setq obj (funcall desired-class "Cache" :table table)) | |
465 | (object-add-to-list table 'cache obj) | |
466 | obj))) | |
467 | ||
468 | (defmethod semanticdb-cache-remove ((table semanticdb-abstract-table) | |
469 | cache) | |
470 | "Remove from TABLE the cache object CACHE." | |
471 | (object-remove-from-list table 'cache cache)) | |
472 | ||
473 | (defmethod semanticdb-synchronize ((cache semanticdb-abstract-cache) | |
474 | new-tags) | |
475 | "Synchronize a CACHE with some NEW-TAGS." | |
476 | ;; The abstract class will do... NOTHING! | |
477 | ) | |
478 | ||
479 | (defmethod semanticdb-partial-synchronize ((cache semanticdb-abstract-cache) | |
480 | new-tags) | |
481 | "Synchronize a CACHE with some changed NEW-TAGS." | |
482 | ;; The abstract class will do... NOTHING! | |
483 | ) | |
484 | ||
485 | (defclass semanticdb-abstract-db-cache () | |
486 | ((db :initarg :db | |
487 | :type semanticdb-project-database | |
488 | :documentation | |
489 | "Cross reference to the database this belongs to.") | |
490 | ) | |
491 | "Abstract baseclass for tools to use to cache information in semanticdb. | |
492 | Tools needing a database cache must subclass this, and then get one as | |
493 | needed. Cache objects are identified in semanticdb by subclass. | |
494 | In order to keep your cache up to date, be sure to implement | |
495 | `semanticdb-synchronize', and `semanticdb-partial-synchronize'. | |
496 | See the file semantic-scope.el for an example." | |
497 | :abstract t) | |
498 | ||
499 | (defmethod semanticdb-cache-get ((db semanticdb-project-database) | |
500 | desired-class) | |
501 | "Get a cache object on DB of class DESIRED-CLASS. | |
502 | This method will create one if none exists with no init arguments | |
503 | other than :table." | |
f192624c CY |
504 | (unless (child-of-class-p desired-class 'semanticdb-abstract-cache) |
505 | (error "Invalid SemanticDB cache")) | |
7a0e7d33 CY |
506 | (let ((cache (oref db cache)) |
507 | (obj nil)) | |
508 | (while (and (not obj) cache) | |
509 | (if (eq (object-class-fast (car cache)) desired-class) | |
510 | (setq obj (car cache))) | |
511 | (setq cache (cdr cache))) | |
512 | (if obj | |
513 | obj ;; Just return it. | |
514 | ;; No object, lets create a new one and return that. | |
515 | (setq obj (funcall desired-class "Cache" :db db)) | |
516 | (object-add-to-list db 'cache obj) | |
517 | obj))) | |
518 | ||
519 | (defmethod semanticdb-cache-remove ((db semanticdb-project-database) | |
520 | cache) | |
521 | "Remove from TABLE the cache object CACHE." | |
522 | (object-remove-from-list db 'cache cache)) | |
523 | ||
524 | ||
525 | (defmethod semanticdb-synchronize ((cache semanticdb-abstract-db-cache) | |
526 | new-tags) | |
527 | "Synchronize a CACHE with some NEW-TAGS." | |
528 | ;; The abstract class will do... NOTHING! | |
529 | ) | |
530 | ||
531 | (defmethod semanticdb-partial-synchronize ((cache semanticdb-abstract-db-cache) | |
532 | new-tags) | |
533 | "Synchronize a CACHE with some changed NEW-TAGS." | |
534 | ;; The abstract class will do... NOTHING! | |
535 | ) | |
536 | ||
537 | ;;; REFRESH | |
538 | ||
539 | (defmethod semanticdb-refresh-table ((obj semanticdb-table) &optional force) | |
540 | "If the tag list associated with OBJ is loaded, refresh it. | |
541 | Optional argument FORCE will force a refresh even if the file in question | |
542 | is not in a buffer. Avoid using FORCE for most uses, as an old cache | |
543 | may be sufficient for the general case. Forced updates can be slow. | |
544 | This will call `semantic-fetch-tags' if that file is in memory." | |
dd9af436 CY |
545 | (cond |
546 | ;; | |
547 | ;; Already in a buffer, just do it. | |
548 | ((semanticdb-in-buffer-p obj) | |
549 | (semanticdb-set-buffer obj) | |
550 | (semantic-fetch-tags)) | |
551 | ;; | |
552 | ;; Not in a buffer. Forcing a load. | |
553 | (force | |
554 | ;; Patch from Iain Nicol. -- | |
555 | ;; @TODO: I wonder if there is a way to recycle | |
556 | ;; semanticdb-create-table-for-file-not-in-buffer | |
7a0e7d33 | 557 | (save-excursion |
dd9af436 CY |
558 | (let ((buff (semantic-find-file-noselect |
559 | (semanticdb-full-filename obj)))) | |
560 | (set-buffer buff) | |
561 | (semantic-fetch-tags) | |
562 | ;; Kill off the buffer if it didn't exist when we were called. | |
563 | (kill-buffer buff)))))) | |
7a0e7d33 CY |
564 | |
565 | (defmethod semanticdb-needs-refresh-p ((obj semanticdb-table)) | |
566 | "Return non-nil of OBJ's tag list is out of date. | |
567 | The file associated with OBJ does not need to be in a buffer." | |
568 | (let* ((ff (semanticdb-full-filename obj)) | |
569 | (buff (semanticdb-in-buffer-p obj)) | |
570 | ) | |
571 | (if buff | |
0816d744 | 572 | (with-current-buffer buff |
7a0e7d33 CY |
573 | ;; Use semantic's magic tracker to determine of the buffer is up |
574 | ;; to date or not. | |
575 | (not (semantic-parse-tree-up-to-date-p)) | |
576 | ;; We assume that semanticdb is keeping itself up to date. | |
577 | ;; via all the clever hooks | |
578 | ) | |
579 | ;; Buffer isn't loaded. The only clue we have is if the file | |
580 | ;; is somehow different from our mark in the semanticdb table. | |
581 | (let* ((stats (file-attributes ff)) | |
582 | (actualsize (nth 7 stats)) | |
583 | (actualmod (nth 5 stats)) | |
584 | ) | |
585 | ||
586 | (or (not (slot-boundp obj 'tags)) | |
587 | ;; (not (oref obj tags)) --> not needed anymore? | |
588 | (/= (or (oref obj fsize) 0) actualsize) | |
589 | (not (equal (oref obj lastmodtime) actualmod)) | |
590 | ) | |
591 | )))) | |
592 | ||
593 | \f | |
594 | ;;; Synchronization | |
595 | ;; | |
596 | (defmethod semanticdb-synchronize ((table semanticdb-abstract-table) | |
597 | new-tags) | |
598 | "Synchronize the table TABLE with some NEW-TAGS." | |
599 | (oset table tags new-tags) | |
600 | (oset table pointmax (point-max)) | |
601 | (let ((fattr (file-attributes (semanticdb-full-filename table)))) | |
602 | (oset table fsize (nth 7 fattr)) | |
603 | (oset table lastmodtime (nth 5 fattr)) | |
604 | ) | |
605 | ;; Assume it is now up to date. | |
606 | (oset table unmatched-syntax semantic-unmatched-syntax-cache) | |
607 | ;; The lexical table should be good too. | |
a60f2e7b | 608 | (when (featurep 'semantic/lex-spp) |
7a0e7d33 CY |
609 | (oset table lexical-table (semantic-lex-spp-save-table))) |
610 | ;; this implies dirtyness | |
611 | (semanticdb-set-dirty table) | |
612 | ||
613 | ;; Synchronize the index | |
614 | (when (slot-boundp table 'index) | |
615 | (let ((idx (oref table index))) | |
616 | (when idx (semanticdb-synchronize idx new-tags)))) | |
617 | ||
618 | ;; Synchronize application caches. | |
619 | (dolist (C (oref table cache)) | |
620 | (semanticdb-synchronize C new-tags) | |
621 | ) | |
622 | ||
623 | ;; Update cross references | |
624 | ;; (semanticdb-refresh-references table) | |
625 | ) | |
626 | ||
627 | (defmethod semanticdb-partial-synchronize ((table semanticdb-abstract-table) | |
628 | new-tags) | |
629 | "Synchronize the table TABLE where some NEW-TAGS changed." | |
630 | ;; You might think we need to reset the tags, but since the partial | |
631 | ;; parser splices the lists, we don't need to do anything | |
632 | ;;(oset table tags new-tags) | |
633 | ;; We do need to mark ourselves dirty. | |
634 | (semanticdb-set-dirty table) | |
635 | ||
636 | ;; The lexical table may be modified. | |
a60f2e7b | 637 | (when (featurep 'semantic/lex-spp) |
7a0e7d33 CY |
638 | (oset table lexical-table (semantic-lex-spp-save-table))) |
639 | ||
640 | ;; Incremental parser doesn't mokey around with this. | |
641 | (oset table unmatched-syntax semantic-unmatched-syntax-cache) | |
642 | ||
643 | ;; Synchronize the index | |
644 | (when (slot-boundp table 'index) | |
645 | (let ((idx (oref table index))) | |
646 | (when idx (semanticdb-partial-synchronize idx new-tags)))) | |
647 | ||
648 | ;; Synchronize application caches. | |
649 | (dolist (C (oref table cache)) | |
650 | (semanticdb-synchronize C new-tags) | |
651 | ) | |
652 | ||
653 | ;; Update cross references | |
654 | ;;(when (semantic-find-tags-by-class 'include new-tags) | |
655 | ;; (semanticdb-refresh-references table)) | |
656 | ) | |
657 | ||
658 | ;;; SAVE/LOAD | |
659 | ;; | |
660 | (defmethod semanticdb-save-db ((DB semanticdb-project-database) | |
661 | &optional supress-questions) | |
662 | "Cause a database to save itself. | |
663 | The database base class does not save itself persistently. | |
664 | Subclasses could save themselves to a file, or to a database, or other | |
665 | form." | |
666 | nil) | |
667 | ||
668 | (defun semanticdb-save-current-db () | |
669 | "Save the current tag database." | |
670 | (interactive) | |
671 | (message "Saving current tag summaries...") | |
672 | (semanticdb-save-db semanticdb-current-database) | |
673 | (message "Saving current tag summaries...done")) | |
674 | ||
5bebb332 CY |
675 | ;; This prevents Semanticdb from querying multiple times if the users |
676 | ;; answers "no" to creating the Semanticdb directory. | |
677 | (defvar semanticdb--inhibit-create-file-directory) | |
678 | ||
7a0e7d33 CY |
679 | (defun semanticdb-save-all-db () |
680 | "Save all semantic tag databases." | |
681 | (interactive) | |
682 | (message "Saving tag summaries...") | |
5bebb332 CY |
683 | (let ((semanticdb--inhibit-make-directory nil)) |
684 | (mapc 'semanticdb-save-db semanticdb-database-list)) | |
7a0e7d33 CY |
685 | (message "Saving tag summaries...done")) |
686 | ||
687 | (defun semanticdb-save-all-db-idle () | |
688 | "Save all semantic tag databases from idle time. | |
689 | Exit the save between databases if there is user input." | |
690 | (semantic-safe "Auto-DB Save: %S" | |
691 | (semantic-exit-on-input 'semanticdb-idle-save | |
692 | (mapc (lambda (db) | |
693 | (semantic-throw-on-input 'semanticdb-idle-save) | |
694 | (semanticdb-save-db db t)) | |
695 | semanticdb-database-list)) | |
696 | )) | |
697 | ||
698 | ;;; Directory Project support | |
699 | ;; | |
700 | (defvar semanticdb-project-predicate-functions nil | |
701 | "List of predicates to try that indicate a directory belongs to a project. | |
702 | This list is used when `semanticdb-persistent-path' contains the value | |
703 | 'project. If the predicate list is nil, then presume all paths are valid. | |
704 | ||
705 | Project Management software (such as EDE and JDE) should add their own | |
706 | predicates with `add-hook' to this variable, and semanticdb will save tag | |
707 | caches in directories controlled by them.") | |
708 | ||
709 | (defmethod semanticdb-write-directory-p ((obj semanticdb-project-database)) | |
710 | "Return non-nil if OBJ should be written to disk. | |
711 | Uses `semanticdb-persistent-path' to determine the return value." | |
712 | nil) | |
713 | ||
714 | ;;; Utilities | |
715 | ;; | |
716 | ;; What is the current database, are two tables of an equivalent mode, | |
717 | ;; and what databases are a part of the same project. | |
718 | (defun semanticdb-current-database () | |
719 | "Return the currently active database." | |
720 | (or semanticdb-current-database | |
721 | (and default-directory | |
722 | (semanticdb-create-database semanticdb-new-database-class | |
723 | default-directory) | |
724 | ) | |
725 | nil)) | |
726 | ||
727 | (defvar semanticdb-match-any-mode nil | |
9bf6c65c | 728 | "Non-nil to temporarily search any major mode for a tag. |
7a0e7d33 CY |
729 | If a particular major mode wants to search any mode, put the |
730 | `semantic-match-any-mode' symbol onto the symbol of that major mode. | |
731 | Do not set the value of this variable permanently.") | |
732 | ||
733 | (defmacro semanticdb-with-match-any-mode (&rest body) | |
9bf6c65c GM |
734 | "A Semanticdb search occurring withing BODY will search tags in all modes. |
735 | This temporarily sets `semanticdb-match-any-mode' while executing BODY." | |
7a0e7d33 CY |
736 | `(let ((semanticdb-match-any-mode t)) |
737 | ,@body)) | |
738 | (put 'semanticdb-with-match-any-mode 'lisp-indent-function 0) | |
739 | ||
740 | (defmethod semanticdb-equivalent-mode-for-search (table &optional buffer) | |
741 | "Return non-nil if TABLE's mode is equivalent to BUFFER. | |
742 | See `semanticdb-equivalent-mode' for details. | |
743 | This version is used during searches. Major-modes that opt | |
744 | to set the `semantic-match-any-mode' property will be able to search | |
745 | all files of any type." | |
746 | (or (get major-mode 'semantic-match-any-mode) | |
747 | semanticdb-match-any-mode | |
748 | (semanticdb-equivalent-mode table buffer)) | |
749 | ) | |
750 | ||
751 | (defmethod semanticdb-equivalent-mode ((table semanticdb-abstract-table) &optional buffer) | |
752 | "Return non-nil if TABLE's mode is equivalent to BUFFER. | |
045b9da7 | 753 | Equivalent modes are specified by the `semantic-equivalent-major-modes' |
7a0e7d33 CY |
754 | local variable." |
755 | nil) | |
756 | ||
757 | (defmethod semanticdb-equivalent-mode ((table semanticdb-table) &optional buffer) | |
758 | "Return non-nil if TABLE's mode is equivalent to BUFFER. | |
045b9da7 | 759 | Equivalent modes are specified by the `semantic-equivalent-major-modes' |
7a0e7d33 CY |
760 | local variable." |
761 | (save-excursion | |
762 | (if buffer (set-buffer buffer)) | |
763 | (or | |
764 | ;; nil major mode in table means we don't know yet. Assume yes for now? | |
765 | (null (oref table major-mode)) | |
766 | ;; nil means the same as major-mode | |
767 | (and (not semantic-equivalent-major-modes) | |
768 | (mode-local-use-bindings-p major-mode (oref table major-mode))) | |
769 | (and semantic-equivalent-major-modes | |
770 | (member (oref table major-mode) semantic-equivalent-major-modes)) | |
771 | ) | |
772 | )) | |
773 | ||
774 | ||
775 | ;;; Associations | |
776 | ;; | |
777 | ;; These routines determine associations between a file, and multiple | |
778 | ;; associated databases. | |
779 | ||
780 | (defcustom semanticdb-project-roots nil | |
781 | "*List of directories, where each directory is the root of some project. | |
782 | All subdirectories of a root project are considered a part of one project. | |
9bf6c65c | 783 | Values in this string can be overridden by project management programs |
7a0e7d33 CY |
784 | via the `semanticdb-project-root-functions' variable." |
785 | :group 'semanticdb | |
786 | :type '(repeat string)) | |
787 | ||
788 | (defvar semanticdb-project-root-functions nil | |
789 | "List of functions used to determine a given directories project root. | |
790 | Functions in this variable can override `semanticdb-project-roots'. | |
791 | Functions set in the variable are given one argument (a directory) and | |
792 | must return a string, (the root directory) or a list of strings (multiple | |
793 | root directories in a more complex system). This variable should be used | |
794 | by project management programs like EDE or JDE.") | |
795 | ||
796 | (defvar semanticdb-project-system-databases nil | |
797 | "List of databases containing system library information. | |
798 | Mode authors can create their own system databases which know | |
799 | detailed information about the system libraries for querying purposes. | |
800 | Put those into this variable as a buffer-local, or mode-local | |
801 | value.") | |
802 | (make-variable-buffer-local 'semanticdb-project-system-databases) | |
803 | ||
804 | (defvar semanticdb-search-system-databases t | |
805 | "Non nil if search routines are to include a system database.") | |
806 | ||
807 | (defun semanticdb-current-database-list (&optional dir) | |
808 | "Return a list of databases associated with the current buffer. | |
809 | If optional argument DIR is non-nil, then use DIR as the starting directory. | |
810 | If this buffer has a database, but doesn't have a project associated | |
811 | with it, return nil. | |
812 | First, it checks `semanticdb-project-root-functions', and if that | |
813 | has no results, it checks `semanticdb-project-roots'. If that fails, | |
814 | it returns the results of function `semanticdb-current-database'. | |
815 | Always append `semanticdb-project-system-databases' if | |
816 | `semanticdb-search-system' is non-nil." | |
817 | (let ((root nil) ; found root directory | |
818 | (dbs nil) ; collected databases | |
819 | (roots semanticdb-project-roots) ;all user roots | |
820 | (dir (file-truename (or dir default-directory))) | |
821 | ) | |
822 | ;; Find the root based on project functions. | |
823 | (setq root (run-hook-with-args-until-success | |
824 | 'semanticdb-project-root-functions | |
825 | dir)) | |
dd9af436 CY |
826 | (if root |
827 | (setq root (file-truename root)) | |
828 | ;; Else, Find roots based on strings | |
829 | (while roots | |
830 | (let ((r (file-truename (car roots)))) | |
831 | (if (string-match (concat "^" (regexp-quote r)) dir) | |
832 | (setq root r))) | |
833 | (setq roots (cdr roots)))) | |
7a0e7d33 CY |
834 | |
835 | ;; If no roots are found, use this directory. | |
836 | (unless root (setq root dir)) | |
837 | ||
838 | ;; Find databases based on the root directory. | |
839 | (when root | |
840 | ;; The rootlist allows the root functions to possibly | |
841 | ;; return several roots which are in different areas but | |
842 | ;; all apart of the same system. | |
843 | (let ((regexp (concat "^" (regexp-quote root))) | |
844 | (adb semanticdb-database-list) ; all databases | |
845 | ) | |
846 | (while adb | |
847 | ;; I don't like this part, but close enough. | |
848 | (if (and (slot-boundp (car adb) 'reference-directory) | |
849 | (string-match regexp (oref (car adb) reference-directory))) | |
850 | (setq dbs (cons (car adb) dbs))) | |
851 | (setq adb (cdr adb)))) | |
852 | ) | |
853 | ;; Add in system databases | |
854 | (when semanticdb-search-system-databases | |
855 | (setq dbs (nconc dbs semanticdb-project-system-databases))) | |
856 | ;; Return | |
857 | dbs)) | |
858 | ||
859 | \f | |
860 | ;;; Generic Accessor Routines | |
861 | ;; | |
862 | ;; These routines can be used to get at tags in files w/out | |
863 | ;; having to know a lot about semanticDB. | |
864 | (defvar semanticdb-file-table-hash (make-hash-table :test 'equal) | |
865 | "Hash table mapping file names to database tables.") | |
866 | ||
867 | (defun semanticdb-file-table-object-from-hash (file) | |
868 | "Retrieve a DB table from the hash for FILE. | |
869 | Does not use `file-truename'." | |
870 | (gethash file semanticdb-file-table-hash 'no-hit)) | |
871 | ||
872 | (defun semanticdb-file-table-object-put-hash (file dbtable) | |
873 | "For FILE, associate DBTABLE in the hash table." | |
874 | (puthash file dbtable semanticdb-file-table-hash)) | |
875 | ||
3d9d8486 | 876 | ;;;###autoload |
7a0e7d33 CY |
877 | (defun semanticdb-file-table-object (file &optional dontload) |
878 | "Return a semanticdb table belonging to FILE, make it up to date. | |
879 | If file has database tags available in the database, return it. | |
880 | If file does not have tags available, and DONTLOAD is nil, | |
881 | then load the tags for FILE, and create a new table object for it. | |
882 | DONTLOAD does not affect the creation of new database objects." | |
883 | ;; (message "Object Translate: %s" file) | |
884 | (when (file-exists-p file) | |
885 | (let* ((default-directory (file-name-directory file)) | |
886 | (tab (semanticdb-file-table-object-from-hash file)) | |
887 | (fullfile nil)) | |
888 | ||
889 | ;; If it is not in the cache, then extract the more traditional | |
890 | ;; way by getting the database, and finding a table in that database. | |
891 | ;; Once we have a table, add it to the hash. | |
892 | (when (eq tab 'no-hit) | |
893 | (setq fullfile (file-truename file)) | |
894 | (let ((db (or ;; This line will pick up system databases. | |
895 | (semanticdb-directory-loaded-p default-directory) | |
896 | ;; this line will make a new one if needed. | |
897 | (semanticdb-get-database default-directory)))) | |
898 | (setq tab (semanticdb-file-table db fullfile)) | |
899 | (when tab | |
900 | (semanticdb-file-table-object-put-hash file tab) | |
901 | (when (not (string= fullfile file)) | |
902 | (semanticdb-file-table-object-put-hash fullfile tab) | |
903 | )) | |
904 | )) | |
905 | ||
906 | (cond | |
907 | ((and tab | |
908 | ;; Is this in a buffer? | |
909 | ;;(find-buffer-visiting (semanticdb-full-filename tab)) | |
910 | (semanticdb-in-buffer-p tab) | |
911 | ) | |
912 | (save-excursion | |
913 | ;;(set-buffer (find-buffer-visiting (semanticdb-full-filename tab))) | |
914 | (semanticdb-set-buffer tab) | |
915 | (semantic-fetch-tags) | |
916 | ;; Return the table. | |
917 | tab)) | |
918 | ((and tab dontload) | |
919 | ;; If we have table, and we don't want to load it, just return it. | |
920 | tab) | |
921 | ((and tab | |
922 | ;; Is table fully loaded, or just a proxy? | |
923 | (number-or-marker-p (oref tab pointmax)) | |
924 | ;; Is this table up to date with the file? | |
925 | (not (semanticdb-needs-refresh-p tab))) | |
926 | ;; A-ok! | |
927 | tab) | |
928 | ((or (and fullfile (get-file-buffer fullfile)) | |
929 | (get-file-buffer file)) | |
930 | ;; are these two calls this faster than `find-buffer-visiting'? | |
931 | ||
932 | ;; If FILE is being visited, but none of the above state is | |
933 | ;; true (meaning, there is no table object associated with it) | |
934 | ;; then it is a file not supported by Semantic, and can be safely | |
935 | ;; ignored. | |
936 | nil) | |
937 | ((not dontload) ;; We must load the file. | |
938 | ;; Full file should have been set by now. Debug why not? | |
939 | (when (and (not tab) (not fullfile)) | |
940 | ;; This case is if a 'nil is erroneously put into the hash table. This | |
941 | ;; would need fixing | |
942 | (setq fullfile (file-truename file)) | |
943 | ) | |
944 | ||
945 | ;; If we have a table, but no fullfile, that's ok. Lets get the filename | |
946 | ;; from the table which is pre-truenamed. | |
947 | (when (and (not fullfile) tab) | |
948 | (setq fullfile (semanticdb-full-filename tab))) | |
949 | ||
950 | (setq tab (semanticdb-create-table-for-file-not-in-buffer fullfile)) | |
951 | ||
952 | ;; Save the new table. | |
953 | (semanticdb-file-table-object-put-hash file tab) | |
954 | (when (not (string= fullfile file)) | |
955 | (semanticdb-file-table-object-put-hash fullfile tab) | |
956 | ) | |
957 | ;; Done! | |
958 | tab) | |
959 | (t | |
960 | ;; Full file should have been set by now. Debug why not? | |
961 | ;; One person found this. Is it a file that failed to parse | |
962 | ;; in the past? | |
963 | (when (not fullfile) | |
964 | (setq fullfile (file-truename file))) | |
965 | ||
966 | ;; We were asked not to load the file in and parse it. | |
967 | ;; Instead just create a database table with no tags | |
968 | ;; and a claim of being empty. | |
969 | ;; | |
970 | ;; This will give us a starting point for storing | |
971 | ;; database cross-references so when it is loaded, | |
972 | ;; the cross-references will fire and caches will | |
973 | ;; be cleaned. | |
974 | (let ((ans (semanticdb-create-table-for-file file))) | |
975 | (setq tab (cdr ans)) | |
976 | ||
977 | ;; Save the new table. | |
978 | (semanticdb-file-table-object-put-hash file tab) | |
979 | (when (not (string= fullfile file)) | |
980 | (semanticdb-file-table-object-put-hash fullfile tab) | |
981 | ) | |
982 | ;; Done! | |
983 | tab)) | |
984 | ) | |
985 | ))) | |
986 | ||
987 | (defvar semanticdb-out-of-buffer-create-table-fcn nil | |
988 | "When non-nil, a function for creating a semanticdb table. | |
989 | This should take a filename to be parsed.") | |
990 | (make-variable-buffer-local 'semanticdb-out-of-buffer-create-table-fcn) | |
991 | ||
992 | (defun semanticdb-create-table-for-file-not-in-buffer (filename) | |
993 | "Create a table for the file FILENAME. | |
994 | If there are no language specific configurations, this | |
995 | function will read in the buffer, parse it, and kill the buffer." | |
996 | (if (and semanticdb-out-of-buffer-create-table-fcn | |
997 | (not (file-remote-p filename))) | |
998 | ;; Use external parser only of the file is accessible to the | |
999 | ;; local file system. | |
1000 | (funcall semanticdb-out-of-buffer-create-table-fcn filename) | |
1001 | (save-excursion | |
1002 | (let* ( ;; Remember the buffer to kill | |
1003 | (kill-buffer-flag (find-buffer-visiting filename)) | |
1004 | (buffer-to-kill (or kill-buffer-flag | |
1005 | (semantic-find-file-noselect filename t)))) | |
1006 | ||
1007 | ;; This shouldn't ever be set. Debug some issue here? | |
1008 | ;; (when kill-buffer-flag (debug)) | |
1009 | ||
1010 | (set-buffer buffer-to-kill) | |
1011 | ;; Find file should automatically do this for us. | |
1012 | ;; Sometimes the DB table doesn't contains tags and needs | |
1013 | ;; a refresh. For example, when the file is loaded for | |
1014 | ;; the first time, and the idle scheduler didn't get a | |
1015 | ;; chance to trigger a parse before the file buffer is | |
1016 | ;; killed. | |
1017 | (when semanticdb-current-table | |
1018 | (semantic-fetch-tags)) | |
1019 | (prog1 | |
1020 | semanticdb-current-table | |
1021 | (when (not kill-buffer-flag) | |
1022 | ;; If we had to find the file, then we should kill it | |
1023 | ;; to keep the master buffer list clean. | |
1024 | (kill-buffer buffer-to-kill) | |
1025 | ))))) | |
1026 | ) | |
1027 | ||
1028 | (defun semanticdb-file-stream (file) | |
1029 | "Return a list of tags belonging to FILE. | |
1030 | If file has database tags available in the database, return them. | |
1031 | If file does not have tags available, then load the file, and create them." | |
1032 | (let ((table (semanticdb-file-table-object file))) | |
1033 | (when table | |
1034 | (semanticdb-get-tags table)))) | |
1035 | ||
1036 | (provide 'semantic/db) | |
1037 | ||
3d9d8486 CY |
1038 | ;; Local variables: |
1039 | ;; generated-autoload-file: "loaddefs.el" | |
996bc9bf | 1040 | ;; generated-autoload-load-name: "semantic/db" |
3d9d8486 CY |
1041 | ;; End: |
1042 | ||
3999968a | 1043 | ;; arch-tag: d9f75280-737d-494f-9f70-09a649d27433 |
691a065e | 1044 | ;;; semantic/db.el ends here |