Commit | Line | Data |
---|---|---|
07a79ce4 | 1 | ;;; semantic/db-typecache.el --- Manage Datatypes |
f273dfc6 | 2 | |
ab422c4d | 3 | ;; Copyright (C) 2007-2013 Free Software Foundation, Inc. |
f273dfc6 CY |
4 | |
5 | ;; Author: Eric M. Ludlam <eric@siege-engine.com> | |
6 | ||
7 | ;; This file is part of GNU Emacs. | |
8 | ||
9 | ;; GNU Emacs is free software: you can redistribute it and/or modify | |
10 | ;; it under the terms of the GNU General Public License as published by | |
11 | ;; the Free Software Foundation, either version 3 of the License, or | |
12 | ;; (at your option) any later version. | |
13 | ||
14 | ;; GNU Emacs is distributed in the hope that it will be useful, | |
15 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | ;; GNU General Public License for more details. | |
18 | ||
19 | ;; You should have received a copy of the GNU General Public License | |
20 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |
21 | ||
22 | ;;; Commentary: | |
23 | ;; | |
24 | ;; Manage a datatype cache. | |
25 | ;; | |
26 | ;; For typed languages like C++ collect all known types from various | |
27 | ;; headers, merge namespaces, and expunge duplicates. | |
28 | ;; | |
29 | ;; It is likely this feature will only be needed for C/C++. | |
30 | ||
3d9d8486 | 31 | (require 'semantic) |
f273dfc6 CY |
32 | (require 'semantic/db) |
33 | (require 'semantic/db-find) | |
691a065e | 34 | (require 'semantic/analyze/fcn) |
3d9d8486 CY |
35 | |
36 | ;; For semantic-find-tags-by-* macros | |
37 | (eval-when-compile (require 'semantic/find)) | |
38 | ||
691a065e CY |
39 | (declare-function data-debug-insert-thing "data-debug") |
40 | (declare-function data-debug-new-buffer "data-debug") | |
3d9d8486 CY |
41 | (declare-function semantic-sort-tags-by-name-then-type-increasing "semantic/sort") |
42 | (declare-function semantic-scope-tag-clone-with-scope "semantic/scope") | |
f273dfc6 CY |
43 | |
44 | ;;; Code: | |
45 | ||
46 | \f | |
47 | ;;; TABLE TYPECACHE | |
ccd7dc02 | 48 | ;;;###autoload |
f273dfc6 CY |
49 | (defclass semanticdb-typecache () |
50 | ((filestream :initform nil | |
51 | :documentation | |
52 | "Fully sorted/merged list of tags within this buffer.") | |
53 | (includestream :initform nil | |
54 | :documentation | |
55 | "Fully sorted/merged list of tags from this file's includes list.") | |
56 | (stream :initform nil | |
57 | :documentation | |
58 | "The searchable tag stream for this cache. | |
59 | NOTE: Can I get rid of this? Use a hashtable instead?") | |
60 | (dependants :initform nil | |
61 | :documentation | |
62 | "Any other object that is dependent on typecache results. | |
63 | Said object must support `semantic-reset' methods.") | |
64 | ;; @todo - add some sort of fast-hash. | |
65 | ;; @note - Rebuilds in large projects already take a while, and the | |
66 | ;; actual searches are pretty fast. Really needed? | |
67 | ) | |
68 | "Structure for maintaining a typecache.") | |
69 | ||
70 | (defmethod semantic-reset ((tc semanticdb-typecache)) | |
71 | "Reset the object IDX." | |
72 | (oset tc filestream nil) | |
73 | (oset tc includestream nil) | |
74 | ||
75 | (oset tc stream nil) | |
76 | ||
77 | (mapc 'semantic-reset (oref tc dependants)) | |
78 | (oset tc dependants nil) | |
79 | ) | |
80 | ||
81 | (defmethod semanticdb-typecache-notify-reset ((tc semanticdb-typecache)) | |
82 | "Do a reset from a notify from a table we depend on." | |
83 | (oset tc includestream nil) | |
84 | (mapc 'semantic-reset (oref tc dependants)) | |
85 | (oset tc dependants nil) | |
86 | ) | |
87 | ||
88 | (defmethod semanticdb-partial-synchronize ((tc semanticdb-typecache) | |
89 | new-tags) | |
90 | "Reset the typecache based on a partial reparse." | |
91 | (when (semantic-find-tags-by-class 'include new-tags) | |
92 | (oset tc includestream nil) | |
93 | (mapc 'semantic-reset (oref tc dependants)) | |
94 | (oset tc dependants nil) | |
95 | ) | |
96 | ||
97 | (when (semantic-find-tags-by-class 'type new-tags) | |
98 | ;; Reset our index | |
99 | (oset tc filestream nil) | |
0b381c7e | 100 | t ;; Return true, our core file tags have changed in a relevant way. |
f273dfc6 CY |
101 | ) |
102 | ||
103 | ;; NO CODE HERE | |
104 | ) | |
105 | ||
106 | (defun semanticdb-typecache-add-dependant (dep) | |
107 | "Add into the local typecache a dependant DEP." | |
108 | (let* ((table semanticdb-current-table) | |
109 | ;;(idx (semanticdb-get-table-index table)) | |
110 | (cache (semanticdb-get-typecache table)) | |
111 | ) | |
112 | (object-add-to-list cache 'dependants dep))) | |
113 | ||
0472835f | 114 | (defun semanticdb-typecache-length (thing) |
f273dfc6 CY |
115 | "How long is THING? |
116 | Debugging function." | |
117 | (cond ((semanticdb-typecache-child-p thing) | |
118 | (length (oref thing stream))) | |
119 | ((semantic-tag-p thing) | |
120 | (length (semantic-tag-type-members thing))) | |
121 | ((and (listp thing) (semantic-tag-p (car thing))) | |
122 | (length thing)) | |
123 | ((null thing) | |
124 | 0) | |
125 | (t -1) )) | |
126 | ||
127 | ||
128 | (defmethod semanticdb-get-typecache ((table semanticdb-abstract-table)) | |
129 | "Retrieve the typecache from the semanticdb TABLE. | |
130 | If there is no table, create one, and fill it in." | |
131 | (semanticdb-refresh-table table) | |
132 | (let* ((idx (semanticdb-get-table-index table)) | |
133 | (cache (oref idx type-cache)) | |
134 | ) | |
135 | ||
136 | ;; Make sure we have a cache object in the DB index. | |
137 | (when (not cache) | |
138 | ;; The object won't change as we fill it with stuff. | |
139 | (setq cache (semanticdb-typecache (semanticdb-full-filename table))) | |
140 | (oset idx type-cache cache)) | |
141 | ||
142 | cache)) | |
143 | ||
144 | (defmethod semanticdb-have-typecache-p ((table semanticdb-abstract-table)) | |
145 | "Return non-nil (the typecache) if TABLE has a pre-calculated typecache." | |
146 | (let* ((idx (semanticdb-get-table-index table))) | |
147 | (oref idx type-cache))) | |
148 | ||
149 | \f | |
150 | ;;; DATABASE TYPECACHE | |
151 | ;; | |
152 | ;; A full database can cache the types across its files. | |
153 | ;; | |
154 | ;; Unlike file based caches, this one is a bit simpler, and just needs | |
155 | ;; to get reset when a table gets updated. | |
156 | ||
ccd7dc02 | 157 | ;;;###autoload |
f273dfc6 CY |
158 | (defclass semanticdb-database-typecache (semanticdb-abstract-db-cache) |
159 | ((stream :initform nil | |
160 | :documentation | |
161 | "The searchable tag stream for this cache.") | |
162 | ) | |
163 | "Structure for maintaining a typecache.") | |
164 | ||
165 | (defmethod semantic-reset ((tc semanticdb-database-typecache)) | |
166 | "Reset the object IDX." | |
167 | (oset tc stream nil) | |
168 | ) | |
169 | ||
170 | (defmethod semanticdb-synchronize ((cache semanticdb-database-typecache) | |
171 | new-tags) | |
172 | "Synchronize a CACHE with some NEW-TAGS." | |
173 | ) | |
174 | ||
175 | (defmethod semanticdb-partial-synchronize ((cache semanticdb-database-typecache) | |
176 | new-tags) | |
177 | "Synchronize a CACHE with some changed NEW-TAGS." | |
178 | ) | |
179 | ||
180 | (defmethod semanticdb-get-typecache ((db semanticdb-project-database)) | |
181 | "Retrieve the typecache from the semantic database DB. | |
182 | If there is no table, create one, and fill it in." | |
183 | (semanticdb-cache-get db semanticdb-database-typecache) | |
184 | ) | |
185 | ||
186 | \f | |
187 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
188 | ||
189 | ;;; MERGING | |
190 | ;; | |
191 | ;; Managing long streams of tags representing data types. | |
192 | ;; | |
193 | (defun semanticdb-typecache-apply-filename (file stream) | |
194 | "Apply the filename FILE to all tags in STREAM." | |
195 | (let ((new nil)) | |
196 | (while stream | |
197 | (setq new (cons (semantic-tag-copy (car stream) nil file) | |
198 | new)) | |
199 | ;The below is handled by the tag-copy fcn. | |
200 | ;(semantic--tag-put-property (car new) :filename file) | |
201 | (setq stream (cdr stream))) | |
202 | (nreverse new))) | |
203 | ||
204 | ||
205 | (defsubst semanticdb-typecache-safe-tag-members (tag) | |
206 | "Return a list of members for TAG that are safe to permute." | |
207 | (let ((mem (semantic-tag-type-members tag)) | |
208 | (fname (semantic-tag-file-name tag))) | |
209 | (if fname | |
210 | (setq mem (semanticdb-typecache-apply-filename fname mem)) | |
211 | (copy-sequence mem)))) | |
212 | ||
213 | (defsubst semanticdb-typecache-safe-tag-list (tags table) | |
214 | "Make the tag list TAGS found in TABLE safe for the typecache. | |
215 | Adds a filename and copies the tags." | |
216 | (semanticdb-typecache-apply-filename | |
217 | (semanticdb-full-filename table) | |
218 | tags)) | |
219 | ||
dd9af436 CY |
220 | (defun semanticdb-typecache-faux-namespace (name members) |
221 | "Create a new namespace tag with NAME and a set of MEMBERS. | |
222 | The new tag will be a faux tag, used as a placeholder in a typecache." | |
223 | (let ((tag (semantic-tag-new-type name "namespace" members nil))) | |
224 | ;; Make sure we mark this as a fake tag. | |
225 | (semantic-tag-set-faux tag) | |
226 | tag)) | |
227 | ||
f273dfc6 CY |
228 | (defun semanticdb-typecache-merge-streams (cache1 cache2) |
229 | "Merge into CACHE1 and CACHE2 together. The Caches will be merged in place." | |
230 | (if (or (and (not cache1) (not cache2)) | |
231 | (and (not (cdr cache1)) (not cache2)) | |
232 | (and (not cache1) (not (cdr cache2)))) | |
233 | ;; If all caches are empty OR | |
234 | ;; cache1 is length 1 and no cache2 OR | |
235 | ;; no cache1 and length 1 cache2 | |
236 | ;; | |
237 | ;; then just return the cache, and skip all this merging stuff. | |
238 | (or cache1 cache2) | |
239 | ||
240 | ;; Assume we always have datatypes, as this typecache isn't really | |
241 | ;; useful without a typed language. | |
3d9d8486 | 242 | (require 'semantic/sort) |
f273dfc6 CY |
243 | (let ((S (semantic-sort-tags-by-name-then-type-increasing |
244 | ;; I used to use append, but it copied cache1 but not cache2. | |
245 | ;; Since sort was permuting cache2, I already had to make sure | |
246 | ;; the caches were permute-safe. Might as well use nconc here. | |
247 | (nconc cache1 cache2))) | |
248 | (ans nil) | |
249 | (next nil) | |
250 | (prev nil) | |
251 | (type nil)) | |
252 | ;; With all the tags in order, we can loop over them, and when | |
253 | ;; two have the same name, we can either throw one away, or construct | |
254 | ;; a fresh new tag merging the items together. | |
255 | (while S | |
256 | (setq prev (car ans)) | |
257 | (setq next (car S)) | |
258 | (if (or | |
259 | ;; CASE 1 - First item | |
260 | (null prev) | |
261 | ;; CASE 2 - New name | |
262 | (not (string= (semantic-tag-name next) | |
263 | (semantic-tag-name prev)))) | |
264 | (setq ans (cons next ans)) | |
265 | ;; ELSE - We have a NAME match. | |
266 | (setq type (semantic-tag-type next)) | |
dd9af436 CY |
267 | (if (or (semantic-tag-of-type-p prev type) ; Are they the same datatype |
268 | (semantic-tag-faux-p prev) | |
269 | (semantic-tag-faux-p next) ; or either a faux tag? | |
270 | ) | |
f273dfc6 CY |
271 | ;; Same Class, we can do a merge. |
272 | (cond | |
273 | ((and (semantic-tag-of-class-p next 'type) | |
274 | (string= type "namespace")) | |
275 | ;; Namespaces - merge the children together. | |
276 | (setcar ans | |
dd9af436 | 277 | (semanticdb-typecache-faux-namespace |
f273dfc6 | 278 | (semantic-tag-name prev) ; - they are the same |
f273dfc6 CY |
279 | (semanticdb-typecache-merge-streams |
280 | (semanticdb-typecache-safe-tag-members prev) | |
281 | (semanticdb-typecache-safe-tag-members next)) | |
f273dfc6 | 282 | )) |
f273dfc6 CY |
283 | ) |
284 | ((semantic-tag-prototype-p next) | |
285 | ;; NEXT is a prototype... so keep previous. | |
286 | nil ; - keep prev, do nothing | |
287 | ) | |
288 | ((semantic-tag-prototype-p prev) | |
289 | ;; PREV is a prototype, but not next.. so keep NEXT. | |
290 | ;; setcar - set by side-effect on top of prev | |
291 | (setcar ans next) | |
292 | ) | |
293 | (t | |
294 | ;;(message "Don't know how to merge %s. Keeping first entry." (semantic-tag-name next)) | |
295 | )) | |
296 | ;; Not same class... but same name | |
297 | ;(message "Same name, different type: %s, %s!=%s" | |
298 | ; (semantic-tag-name next) | |
299 | ; (semantic-tag-type next) | |
300 | ; (semantic-tag-type prev)) | |
301 | (setq ans (cons next ans)) | |
302 | )) | |
303 | (setq S (cdr S))) | |
304 | (nreverse ans)))) | |
305 | \f | |
306 | ;;; Refresh / Query API | |
307 | ;; | |
308 | ;; Queries that can be made for the typecache. | |
dd9af436 CY |
309 | (define-overloadable-function semanticdb-expand-nested-tag (tag) |
310 | "Expand TAG from fully qualified names. | |
311 | If TAG has fully qualified names, expand it to a series of nested | |
312 | namespaces instead." | |
313 | tag) | |
314 | ||
f273dfc6 CY |
315 | (defmethod semanticdb-typecache-file-tags ((table semanticdb-abstract-table)) |
316 | "No tags available from non-file based tables." | |
317 | nil) | |
318 | ||
319 | (defmethod semanticdb-typecache-file-tags ((table semanticdb-table)) | |
320 | "Update the typecache for TABLE, and return the file-tags. | |
321 | File-tags are those that belong to this file only, and excludes | |
322 | all included files." | |
323 | (let* (;(idx (semanticdb-get-table-index table)) | |
324 | (cache (semanticdb-get-typecache table)) | |
325 | ) | |
326 | ||
327 | ;; Make sure our file-tags list is up to date. | |
328 | (when (not (oref cache filestream)) | |
dd9af436 CY |
329 | (let ((tags (semantic-find-tags-by-class 'type table)) |
330 | (exptags nil)) | |
f273dfc6 CY |
331 | (when tags |
332 | (setq tags (semanticdb-typecache-safe-tag-list tags table)) | |
dd9af436 CY |
333 | (dolist (T tags) |
334 | (push (semanticdb-expand-nested-tag T) exptags)) | |
335 | (oset cache filestream (semanticdb-typecache-merge-streams exptags nil))))) | |
f273dfc6 CY |
336 | |
337 | ;; Return our cache. | |
338 | (oref cache filestream) | |
339 | )) | |
340 | ||
341 | (defmethod semanticdb-typecache-include-tags ((table semanticdb-abstract-table)) | |
342 | "No tags available from non-file based tables." | |
343 | nil) | |
344 | ||
345 | (defmethod semanticdb-typecache-include-tags ((table semanticdb-table)) | |
346 | "Update the typecache for TABLE, and return the merged types from the include tags. | |
347 | Include-tags are the tags brought in via includes, all merged together into | |
348 | a master list." | |
349 | (let* ((cache (semanticdb-get-typecache table)) | |
350 | ) | |
351 | ||
352 | ;; Make sure our file-tags list is up to date. | |
353 | (when (not (oref cache includestream)) | |
354 | (let (;; Calc the path first. This will have a nice side -effect of | |
355 | ;; getting the cache refreshed if a refresh is needed. Most of the | |
356 | ;; time this value is itself cached, so the query is fast. | |
357 | (incpath (semanticdb-find-translate-path table nil)) | |
358 | (incstream nil)) | |
359 | ;; Get the translated path, and extract all the type tags, then merge | |
360 | ;; them all together. | |
361 | (dolist (i incpath) | |
362 | ;; don't include ourselves in this crazy list. | |
363 | (when (and i (not (eq i table)) | |
364 | ;; @todo - This eieio fcn can be slow! Do I need it? | |
365 | ;; (semanticdb-table-child-p i) | |
366 | ) | |
367 | (setq incstream | |
368 | (semanticdb-typecache-merge-streams | |
369 | incstream | |
370 | ;; Getting the cache from this table will also cause this | |
cd1181db | 371 | ;; file to update its cache from its descendants. |
f273dfc6 CY |
372 | ;; |
373 | ;; In theory, caches are only built for most includes | |
374 | ;; only once (in the loop before this one), so this ends | |
375 | ;; up being super fast as we edit our file. | |
376 | (copy-sequence | |
377 | (semanticdb-typecache-file-tags i)))) | |
378 | )) | |
379 | ||
380 | ;; Save... | |
381 | (oset cache includestream incstream))) | |
382 | ||
383 | ;; Return our cache. | |
384 | (oref cache includestream) | |
385 | )) | |
386 | ||
387 | \f | |
388 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
389 | ||
390 | ;;; Search Routines | |
dd9af436 | 391 | ;; |
3d9d8486 | 392 | ;;;###autoload |
f273dfc6 CY |
393 | (define-overloadable-function semanticdb-typecache-find (type &optional path find-file-match) |
394 | "Search the typecache for TYPE in PATH. | |
395 | If type is a string, split the string, and search for the parts. | |
396 | If type is a list, treat the type as a pre-split string. | |
397 | PATH can be nil for the current buffer, or a semanticdb table. | |
398 | FIND-FILE-MATCH is non-nil to force all found tags to be loaded into a buffer.") | |
399 | ||
400 | (defun semanticdb-typecache-find-default (type &optional path find-file-match) | |
401 | "Default implementation of `semanticdb-typecache-find'. | |
402 | TYPE is the datatype to find. | |
0472835f | 403 | PATH is the search path, which should be one table object. |
f273dfc6 CY |
404 | If FIND-FILE-MATCH is non-nil, then force the file belonging to the |
405 | found tag to be loaded." | |
ac73b1fa | 406 | (if (not (and (featurep 'semantic/db) semanticdb-current-database)) |
dd9af436 CY |
407 | nil ;; No DB, no search |
408 | (save-excursion | |
409 | (semanticdb-typecache-find-method (or path semanticdb-current-table) | |
410 | type find-file-match)))) | |
f273dfc6 CY |
411 | |
412 | (defun semanticdb-typecache-find-by-name-helper (name table) | |
413 | "Find the tag with NAME in TABLE, which is from a typecache. | |
414 | If more than one tag has NAME in TABLE, we will prefer the tag that | |
415 | is of class 'type." | |
416 | (let* ((names (semantic-find-tags-by-name name table)) | |
dd9af436 CY |
417 | (nmerge (semanticdb-typecache-merge-streams names nil)) |
418 | (types (semantic-find-tags-by-class 'type nmerge))) | |
419 | (or (car-safe types) (car-safe nmerge)))) | |
f273dfc6 CY |
420 | |
421 | (defmethod semanticdb-typecache-find-method ((table semanticdb-abstract-table) | |
422 | type find-file-match) | |
423 | "Search the typecache in TABLE for the datatype TYPE. | |
424 | If type is a string, split the string, and search for the parts. | |
425 | If type is a list, treat the type as a pre-split string. | |
426 | If FIND-FILE-MATCH is non-nil, then force the file belonging to the | |
427 | found tag to be loaded." | |
428 | ;; convert string to a list. | |
429 | (when (stringp type) (setq type (semantic-analyze-split-name type))) | |
430 | (when (stringp type) (setq type (list type))) | |
431 | ||
432 | ;; Search for the list in our typecache. | |
433 | (let* ((file (semanticdb-typecache-file-tags table)) | |
434 | (inc (semanticdb-typecache-include-tags table)) | |
435 | (stream nil) | |
436 | (f-ans nil) | |
437 | (i-ans nil) | |
438 | (ans nil) | |
439 | (notdone t) | |
440 | (lastfile nil) | |
441 | (thisfile nil) | |
442 | (lastans nil) | |
443 | (calculated-scope nil) | |
444 | ) | |
445 | ;; 1) Find first symbol in the two master lists and then merge | |
446 | ;; the found streams. | |
447 | ||
448 | ;; We stripped duplicates, so these will be super-fast! | |
449 | (setq f-ans (semantic-find-first-tag-by-name (car type) file)) | |
450 | (setq i-ans (semantic-find-first-tag-by-name (car type) inc)) | |
451 | (if (and f-ans i-ans) | |
452 | (progn | |
453 | ;; This trick merges the two identified tags, making sure our lists are | |
454 | ;; complete. The second find then gets the new 'master' from the list of 2. | |
455 | (setq ans (semanticdb-typecache-merge-streams (list f-ans) (list i-ans))) | |
456 | (setq ans (semantic-find-first-tag-by-name (car type) ans)) | |
457 | ) | |
458 | ||
459 | ;; The answers are already sorted and merged, so if one misses, | |
460 | ;; no need to do any special work. | |
461 | (setq ans (or f-ans i-ans))) | |
462 | ||
463 | ;; 2) Loop over the remaining parts. | |
464 | (while (and type notdone) | |
465 | ||
466 | ;; For pass > 1, stream will be non-nil, so do a search, otherwise | |
467 | ;; ans is from outside the loop. | |
468 | (when stream | |
469 | (setq ans (semanticdb-typecache-find-by-name-helper (car type) stream)) | |
470 | ||
471 | ;; NOTE: The below test to make sure we get a type is only relevant | |
472 | ;; for the SECOND pass or later. The first pass can only ever | |
473 | ;; find a type/namespace because everything else is excluded. | |
474 | ||
475 | ;; If this is not the last entry from the list, then it | |
c7015153 | 476 | ;; must be a type or a namespace. Let's double check. |
f273dfc6 CY |
477 | (when (cdr type) |
478 | ||
479 | ;; From above, there is only one tag in ans, and we prefer | |
480 | ;; types. | |
481 | (when (not (semantic-tag-of-class-p ans 'type)) | |
482 | ||
483 | (setq ans nil))) | |
484 | ) | |
485 | ||
62a81506 CY |
486 | ;; The typecache holds all the known types and elements. Some databases |
487 | ;; may provide tags that are simplified by name, and are proxies. These | |
488 | ;; proxies must be resolved in order to extract type members. | |
489 | (setq ans (semantic-tag-resolve-proxy ans)) | |
490 | ||
f273dfc6 CY |
491 | (push ans calculated-scope) |
492 | ||
493 | ;; Track most recent file. | |
494 | (setq thisfile (semantic-tag-file-name ans)) | |
495 | (when (and thisfile (stringp thisfile)) | |
496 | (setq lastfile thisfile)) | |
497 | ||
498 | ;; If we have a miss, exit, otherwise, update the stream to | |
499 | ;; the next set of members. | |
500 | (if (not ans) | |
501 | (setq notdone nil) | |
502 | (setq stream (semantic-tag-type-members ans))) | |
503 | ||
504 | (setq lastans ans | |
505 | ans nil | |
506 | type (cdr type))) | |
507 | ||
508 | (if (or type (not notdone)) | |
509 | ;; If there is stuff left over, then we failed. Just return | |
510 | ;; nothing. | |
511 | nil | |
512 | ||
513 | ;; We finished, so return everything. | |
514 | ||
515 | (if (and find-file-match lastfile) | |
516 | ;; This won't liven up the tag since we have a copy, but | |
517 | ;; we ought to be able to get there and go to the right line. | |
518 | (find-file-noselect lastfile) | |
c7015153 | 519 | ;; We don't want to find-file match, so instead let's |
f273dfc6 CY |
520 | ;; push the filename onto the return tag. |
521 | (when lastans | |
522 | (setq lastans (semantic-tag-copy lastans nil lastfile)) | |
523 | ;; We used to do the below, but we would erroneously be putting | |
524 | ;; attributes on tags being shred with other lists. | |
525 | ;;(semantic--tag-put-property lastans :filename lastfile) | |
526 | ) | |
527 | ) | |
528 | ||
529 | (if (and lastans calculated-scope) | |
530 | ||
531 | ;; Put our discovered scope into the tag if we have a tag | |
3d9d8486 CY |
532 | (progn |
533 | (require 'semantic/scope) | |
534 | (semantic-scope-tag-clone-with-scope | |
535 | lastans (reverse (cdr calculated-scope)))) | |
f273dfc6 CY |
536 | |
537 | ;; Else, just return | |
538 | lastans | |
539 | )))) | |
540 | \f | |
541 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
542 | ||
543 | ;;; BRUTISH Typecache | |
544 | ;; | |
545 | ;; Routines for a typecache that crosses all tables in a given database | |
546 | ;; for a matching major-mode. | |
547 | (defmethod semanticdb-typecache-for-database ((db semanticdb-project-database) | |
548 | &optional mode) | |
549 | "Return the typecache for the project database DB. | |
550 | If there isn't one, create it. | |
551 | " | |
552 | (let ((lmode (or mode major-mode)) | |
553 | (cache (semanticdb-get-typecache db)) | |
554 | (stream nil) | |
555 | ) | |
556 | (dolist (table (semanticdb-get-database-tables db)) | |
557 | (when (eq lmode (oref table :major-mode)) | |
558 | (setq stream | |
559 | (semanticdb-typecache-merge-streams | |
560 | stream | |
561 | (copy-sequence | |
562 | (semanticdb-typecache-file-tags table)))) | |
563 | )) | |
564 | (oset cache stream stream) | |
565 | cache)) | |
566 | ||
567 | (defun semanticdb-typecache-refresh-for-buffer (buffer) | |
568 | "Refresh the typecache for BUFFER." | |
0816d744 | 569 | (with-current-buffer buffer |
f273dfc6 CY |
570 | (let* ((tab semanticdb-current-table) |
571 | ;(idx (semanticdb-get-table-index tab)) | |
572 | (tc (semanticdb-get-typecache tab))) | |
573 | (semanticdb-typecache-file-tags tab) | |
574 | (semanticdb-typecache-include-tags tab) | |
575 | tc))) | |
576 | ||
577 | \f | |
578 | ;;; DEBUG | |
579 | ;; | |
580 | (defun semanticdb-typecache-complete-flush () | |
581 | "Flush all typecaches referenced by the current buffer." | |
582 | (interactive) | |
583 | (let* ((path (semanticdb-find-translate-path nil nil))) | |
584 | (dolist (P path) | |
62a81506 CY |
585 | (condition-case nil |
586 | (oset P pointmax nil) | |
735135f9 | 587 | ;; Pointmax may not exist for all tables discovered in the |
62a81506 CY |
588 | ;; path. |
589 | (error nil)) | |
f273dfc6 CY |
590 | (semantic-reset (semanticdb-get-typecache P))))) |
591 | ||
592 | (defun semanticdb-typecache-dump () | |
593 | "Dump the typecache for the current buffer." | |
594 | (interactive) | |
595 | (require 'data-debug) | |
596 | (let* ((start (current-time)) | |
597 | (tc (semanticdb-typecache-refresh-for-buffer (current-buffer))) | |
598 | (end (current-time)) | |
599 | ) | |
600 | (data-debug-new-buffer "*TypeCache ADEBUG*") | |
601 | (message "Calculating Cache took %.2f seconds." | |
602 | (semantic-elapsed-time start end)) | |
603 | ||
604 | (data-debug-insert-thing tc "]" "") | |
605 | ||
606 | )) | |
607 | ||
608 | (defun semanticdb-db-typecache-dump () | |
609 | "Dump the typecache for the current buffer's database." | |
610 | (interactive) | |
611 | (require 'data-debug) | |
612 | (let* ((tab semanticdb-current-table) | |
613 | (idx (semanticdb-get-table-index tab)) | |
614 | (junk (oset idx type-cache nil)) ;; flush! | |
615 | (start (current-time)) | |
616 | (tc (semanticdb-typecache-for-database (oref tab parent-db))) | |
617 | (end (current-time)) | |
618 | ) | |
619 | (data-debug-new-buffer "*TypeCache ADEBUG*") | |
620 | (message "Calculating Cache took %.2f seconds." | |
621 | (semantic-elapsed-time start end)) | |
622 | ||
623 | (data-debug-insert-thing tc "]" "") | |
624 | ||
625 | )) | |
626 | ||
f273dfc6 | 627 | (provide 'semantic/db-typecache) |
3d9d8486 CY |
628 | |
629 | ;; Local variables: | |
630 | ;; generated-autoload-file: "loaddefs.el" | |
996bc9bf | 631 | ;; generated-autoload-load-name: "semantic/db-typecache" |
3d9d8486 CY |
632 | ;; End: |
633 | ||
07a79ce4 | 634 | ;;; semantic/db-typecache.el ends here |