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