Remove non-free old and crusty clearcase pkg
[packages] / xemacs-packages / semantic / semanticdb-search.el
1 ;;; semanticdb-search.el --- Searching through semantic databases.
2
3 ;;; Copyright (C) 2000, 2001, 2002, 2003, 2004 Eric M. Ludlam
4
5 ;; Author: Eric M. Ludlam <zappo@gnu.org>
6 ;; Keywords: tags
7 ;; X-RCS: $Id: semanticdb-search.el,v 1.1 2007-11-26 15:10:47 michaels Exp $
8
9 ;; This file is not part of GNU Emacs.
10
11 ;; Semanticdb 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 2, or (at your option)
14 ;; any later version.
15
16 ;; This software 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; see the file COPYING.  If not, write to the
23 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24 ;; Boston, MA 02110-1301, USA.
25 ;; 
26 ;;; Commentary:
27 ;;
28 ;; Databases of various forms can all be searched.  These routines
29 ;; cover many common forms of searching.
30 ;;
31 ;; There are three types of searches that can be implemented:
32 ;;
33 ;; Basic Search:
34 ;;  These searches allow searching on specific attributes of tags,
35 ;;  such as name or type.
36 ;;
37 ;; Advanced Search:
38 ;;  These are searches that were needed to accomplish some tasks
39 ;;  during in utilities.  Advanced searches include matching methods
40 ;;  defined outside some parent class.
41 ;;
42 ;;  The reason for advanced searches are so that external
43 ;;  repositories such as the Emacs obarray, or java .class files can
44 ;;  quickly answer these needed questions without dumping the entire
45 ;;  symbol list into Emacs for a regular semanticdb search.
46 ;;
47 ;; Generic Search:
48 ;;  The generic search, `semanticdb-find-nonterminal-by-function'
49 ;;  accepts a Emacs Lisp predicate that tests tags in Semantic
50 ;;  format.  Most external searches cannot perform this search.
51
52 (require 'semanticdb)
53 (require 'semantic-find)
54
55 ;;; Code:
56 ;;
57 ;;; Classes:
58 (defclass semanticdb-search-results-table (semanticdb-abstract-table)
59   (
60    )
61   "Table used for search results when there is no file or table association.
62 Examples include search results from external sources such as from
63 Emacs' own symbol table, or from external libraries.")
64
65 (defmethod semanticdb-refresh-table ((obj semanticdb-search-results-table))
66   "If the tag list associated with OBJ is loaded, refresh it.
67 This will call `semantic-fetch-tags' if that file is in memory."
68   nil)
69
70 (defmethod semanticdb-printable-name ((table semanticdb-search-results-table))
71   "Return a string which is a short and logical printable name for TABLE.
72 A search result may not have a file assocated with it, so we need to
73 provide a reasonable identification."
74   (concat "System: " (object-name-string table))
75   )
76
77 ;;; Utils
78 ;;
79 ;; Convenience routines for searches
80 (defun semanticdb-collect-find-results (result-in-databases
81                                         result-finding-function
82                                         ignore-system
83                                         find-file-on-match)
84   "Collect results across RESULT-IN-DATABASES for RESULT-FINDING-FUNCTION.
85 If RESULT-IN-DATABASES is nil, search a range of associated databases
86 calculated by `semanticdb-current-database-list'.
87 RESULT-IN-DATABASES is a list of variable `semanticdb-project-database'
88 objects.
89 RESULT-FINDING-FUNCTION should accept one argument, the database being searched.
90 Argument IGNORE-SYSTEM specifies if any available system databases should
91 be ignored, or searched.
92 Argument FIND-FILE-ON-MATCH indicates that the found databases
93 should be capable of doing so."
94   (if (not (listp result-in-databases))
95       (signal 'wrong-type-argument (list 'listp result-in-databases)))
96   (let* ((semanticdb-search-system-databases
97           (if ignore-system
98               nil
99             semanticdb-search-system-databases))
100          (dbs (or result-in-databases
101                   ;; Calculate what database to use.
102                   ;; Something simple and dumb for now.
103                   (or (semanticdb-current-database-list)
104                       (list (semanticdb-current-database)))))
105          (case-fold-search semantic-case-fold)
106          (res (mapcar
107                (lambda (db)
108                  (if (or (not find-file-on-match)
109                          (not (child-of-class-p
110                                (oref db new-table-class)
111                                semanticdb-search-results-table)))
112                      (funcall result-finding-function db)))
113                dbs))
114          out)
115     ;; Flatten the list.  The DB is unimportant at this stage.
116     (setq res (apply 'append res))
117     (setq out nil)
118     ;; Move across results, and throw out empties.
119     (while res
120       (if (car res)
121           (setq out (cons (car res) out)))
122       (setq res (cdr res)))
123     ;; Results
124     out))
125
126 ;;; Programatic interfaces
127 ;;
128 ;; These routines all perform different types of searches, and are
129 ;; interfaces to the database methods used to also perform those searches.
130
131 ;;;###autoload
132 (defun semanticdb-find-nonterminal-by-token
133   (token &optional databases search-parts search-includes diff-mode find-file-match ignore-system)
134   "Find all occurances of nonterminals with token TOKEN in databases.
135 See `semanticdb-find-nonterminal-by-function' for details on DATABASES,
136 SEARCH-PARTS, SEARCH-INCLUDES, DIFF-MODE, FIND-FILE-MATCH and IGNORE-SYSTEM.
137 Return a list ((DB-TABLE . TOKEN-LIST) ...)."
138   (semanticdb-collect-find-results
139    databases
140    (lambda (db)
141      (semanticdb-find-nonterminal-by-token-method
142       db token search-parts search-includes diff-mode find-file-match))
143    ignore-system
144    find-file-match))
145 (make-obsolete 'semanticdb-find-nonterminal-by-token
146                "Please don't use this function")
147
148 ;;;###autoload
149 (defun semanticdb-find-nonterminal-by-name
150   (name &optional databases search-parts search-includes diff-mode find-file-match ignore-system)
151   "Find all occurances of nonterminals with name NAME in databases.
152 See `semanticdb-find-nonterminal-by-function' for details on DATABASES,
153 SEARCH-PARTS, SEARCH-INCLUDES, DIFF-MODE, FIND-FILE-MATCH and IGNORE-SYSTEM.
154 Return a list ((DB-TABLE . TOKEN) ...)."
155   (semanticdb-collect-find-results
156    databases
157    (lambda (db)
158      (semanticdb-find-nonterminal-by-name-method
159       db name search-parts search-includes diff-mode find-file-match))
160    ignore-system
161    find-file-match))
162 (make-obsolete 'semanticdb-find-nonterminal-by-name
163                "Please don't use this function")
164
165 ;;;###autoload
166 (defun semanticdb-find-nonterminal-by-name-regexp
167   (regex &optional databases search-parts search-includes diff-mode find-file-match ignore-system)
168   "Find all occurances of nonterminals with name matching REGEX in databases.
169 See `semanticdb-find-nonterminal-by-function' for details on DATABASES,
170 SEARCH-PARTS, SEARCH-INCLUDES DIFF-MODE, FIND-FILE-MATCH and IGNORE-SYSTEM.
171 Return a list ((DB-TABLE . TOKEN-LIST) ...)."
172   (semanticdb-collect-find-results
173    databases
174    (lambda (db)
175      (semanticdb-find-nonterminal-by-name-regexp-method
176       db regex search-parts search-includes diff-mode find-file-match))
177    ignore-system
178    find-file-match))
179 (make-obsolete 'semanticdb-find-nonterminal-by-name-regexp
180                "Please don't use this function")
181
182
183 ;;;###autoload
184 (defun semanticdb-find-nonterminal-by-type
185   (type &optional databases search-parts search-includes diff-mode find-file-match ignore-system)
186   "Find all nonterminals with a type of TYPE in databases.
187 See `semanticdb-find-nonterminal-by-function' for details on DATABASES,
188 SEARCH-PARTS, SEARCH-INCLUDES DIFF-MODE, FIND-FILE-MATCH and IGNORE-SYSTEM.
189 Return a list ((DB-TABLE . TOKEN-LIST) ...)."
190   (semanticdb-collect-find-results
191    databases
192    (lambda (db)
193      (semanticdb-find-nonterminal-by-type-method
194       db type search-parts search-includes diff-mode find-file-match))
195    ignore-system
196    find-file-match))
197 (make-obsolete 'semanticdb-find-nonterminal-by-type
198                "Please don't use this function")
199
200
201 ;;;###autoload
202 (defun semanticdb-find-nonterminal-by-property
203   (property value &optional databases search-parts search-includes diff-mode find-file-match ignore-system)
204   "Find all nonterminals with a PROPERTY equal to VALUE in databases.
205 See `semanticdb-find-nonterminal-by-function' for details on DATABASES,
206 SEARCH-PARTS, SEARCH-INCLUDES DIFF-MODE, FIND-FILE-MATCH and IGNORE-SYSTEM.
207 Return a list ((DB-TABLE . TOKEN-LIST) ...)."
208   (semanticdb-collect-find-results
209    databases
210    (lambda (db)
211      (semanticdb-find-nonterminal-by-property-method
212       db property value search-parts search-includes diff-mode find-file-match))
213    ignore-system
214    find-file-match))
215 (make-obsolete 'semanticdb-find-nonterminal-by-property
216                "Please don't use this function")
217
218 ;;;###autoload
219 (defun semanticdb-find-nonterminal-by-extra-spec
220   (spec &optional databases search-parts search-includes diff-mode find-file-match ignore-system)
221   "Find all nonterminals with a SPEC in databases.
222 See `semanticdb-find-nonterminal-by-function' for details on DATABASES,
223 SEARCH-PARTS, SEARCH-INCLUDES DIFF-MODE, FIND-FILE-MATCH and IGNORE-SYSTEM.
224 Return a list ((DB-TABLE . TOKEN-LIST) ...)."
225   (semanticdb-collect-find-results
226    databases
227    (lambda (db)
228      (semanticdb-find-nonterminal-by-extra-spec-method
229       db spec search-parts search-includes diff-mode find-file-match))
230    ignore-system
231    find-file-match))
232 (make-obsolete 'semanticdb-find-nonterminal-by-extra-spec
233                "Please don't use this function")
234
235 ;;;###autoload
236 (defun semanticdb-find-nonterminal-by-extra-spec-value
237   (spec value &optional databases search-parts search-includes diff-mode find-file-match ignore-system)
238   "Find all nonterminals with a SPEC equal to VALUE in databases.
239 See `semanticdb-find-nonterminal-by-function' for details on DATABASES,
240 SEARCH-PARTS, SEARCH-INCLUDES DIFF-MODE, FIND-FILE-MATCH and IGNORE-SYSTEM.
241 Return a list ((DB-TABLE . TOKEN-LIST) ...)."
242   (semanticdb-collect-find-results
243    databases
244    (lambda (db)
245      (semanticdb-find-nonterminal-by-extra-spec-value-method
246       db spec value search-parts search-includes diff-mode find-file-match))
247    ignore-system
248    find-file-match))
249 (make-obsolete 'semanticdb-find-nonterminal-by-extra-spec-value
250                "Please don't use this function")
251
252 ;;; Advanced Search Routines
253 ;;
254 (defun semanticdb-find-nonterminal-external-children-of-type
255   (type &optional databases search-parts search-includes diff-mode find-file-match ignore-system)
256   "Find all nonterminals which are child elements of TYPE.
257 See `semanticdb-find-nonterminal-by-function' for details on DATABASES,
258 SEARCH-PARTS, SEARCH-INCLUDES DIFF-MODE, FIND-FILE-MATCH and IGNORE-SYSTEM.
259 Return a list ((DB-TABLE . TOKEN-LIST) ...)."
260   (semanticdb-collect-find-results
261    databases
262    (lambda (db)
263      (semanticdb-find-nonterminal-external-children-of-type-method
264       db type search-parts search-includes diff-mode find-file-match))
265    ignore-system
266    find-file-match))
267
268 ;;; Generic Search routine
269 ;;
270
271 ;;;###autoload
272 (defun semanticdb-find-nonterminal-by-function
273   (function &optional databases search-parts search-includes diff-mode find-file-match ignore-system)
274   "Find all occurances of nonterminals which match FUNCTION.
275 Search in all DATABASES.  If DATABASES is nil, search a range of
276 associated databases calculated `semanticdb-current-database-list' and
277 DATABASES is a list of variable `semanticdb-project-database' objects.
278 When SEARCH-PARTS is non-nil the search will include children of tags.
279 When SEARCH-INCLUDES is non-nil, the search will include dependency files.
280 When DIFF-MODE is non-nil, search databases which are of a different mode.
281 A Mode is the `major-mode' that file was in when it was last parsed.
282 When FIND-FILE-MATCH is non-nil, the make sure any found token's file is
283 in an Emacs buffer.
284 When IGNORE-SYSTEM is non-nil, system libraries are not searched.
285 Return a list ((DB-TABLE . TOKEN-OR-TOKEN-LIST) ...)."
286   (semanticdb-collect-find-results
287    databases
288    (lambda (db)
289      (semanticdb-find-nonterminal-by-function-method
290       db function search-parts search-includes diff-mode find-file-match))
291    ignore-system
292    find-file-match))
293
294 ;;; Search Methods
295 ;;
296 ;; These are the base routines for searching semantic databases.
297 ;; Overload these with your subclasses to participate in the searching
298 ;; mechanism.
299 (defmethod semanticdb-find-nonterminal-by-token-method
300   ((database semanticdb-project-database) token search-parts search-includes diff-mode find-file-match)
301   "In DB, find all occurances of nonterminals with token TOKEN in databases.
302 See `semanticdb-find-nonterminal-by-function-method' for details on,
303 SEARCH-PARTS, SEARCH-INCLUDES, DIFF-MODE, and FIND-FILE-MATCH.
304 Return a list ((DB-TABLE . TOKEN-LIST) ...)."
305   (let ((goofy-token-name token))
306     (semanticdb-find-nonterminal-by-function-method
307      database (lambda (stream sp si)
308                 (semantic-brute-find-tag-by-class goofy-token-name stream sp si))
309      search-parts search-includes diff-mode find-file-match)))
310
311 (defmethod semanticdb-find-nonterminal-by-name-method
312   ((database semanticdb-project-database) name search-parts search-includes diff-mode find-file-match)
313   "Find all occurances of nonterminals with name NAME in databases.
314 See `semanticdb-find-nonterminal-by-function' for details on DATABASES,
315 SEARCH-PARTS, SEARCH-INCLUDES, DIFF-MODE, and FIND-FILE-MATCH.
316 Return a list ((DB-TABLE . TOKEN) ...)."
317   (semanticdb-find-nonterminal-by-function-method
318    database
319    (lambda (stream sp si)
320      (semantic-brute-find-first-tag-by-name name stream sp si))
321    search-parts search-includes diff-mode find-file-match))
322
323 (defmethod semanticdb-find-nonterminal-by-name-regexp-method
324   ((database semanticdb-project-database) regex search-parts search-includes diff-mode find-file-match)
325   "Find all occurances of nonterminals with name matching REGEX in databases.
326 See `semanticdb-find-nonterminal-by-function' for details on DATABASES,
327 SEARCH-PARTS, SEARCH-INCLUDES DIFF-MODE, and FIND-FILE-MATCH.
328 Return a list ((DB-TABLE . TOKEN-LIST) ...)."
329   (semanticdb-find-nonterminal-by-function-method
330    database
331    (lambda (stream sp si)
332      (semantic-brute-find-tag-by-name-regexp regex stream sp si))
333    search-parts search-includes diff-mode find-file-match))
334
335 (defmethod semanticdb-find-nonterminal-by-type-method
336   ((database semanticdb-project-database) type search-parts search-includes diff-mode find-file-match)
337   "Find all nonterminals with a type of TYPE in databases.
338 See `semanticdb-find-nonterminal-by-function' for details on DATABASES,
339 SEARCH-PARTS, SEARCH-INCLUDES DIFF-MODE, and FIND-FILE-MATCH.
340 Return a list ((DB-TABLE . TOKEN-LIST) ...)."
341   (semanticdb-find-nonterminal-by-function-method
342    database
343    (lambda (stream sp si)
344      (semantic-brute-find-tag-by-type type stream sp si))
345    search-parts search-includes diff-mode find-file-match))
346
347 (defmethod semanticdb-find-nonterminal-by-property-method
348   ((database semanticdb-project-database) property value search-parts search-includes diff-mode find-file-match)
349   "Find all nonterminals with a PROPERTY equal to VALUE in databases.
350 See `semanticdb-find-nonterminal-by-function' for details on DATABASES,
351 SEARCH-PARTS, SEARCH-INCLUDES DIFF-MODE, and FIND-FILE-MATCH.
352 Return a list ((DB-TABLE . TOKEN-LIST) ...)."
353   (semanticdb-find-nonterminal-by-function-method
354    database
355    (lambda (stream sp si)
356      (semantic-brute-find-tag-by-property property value stream sp si))
357    search-parts search-includes diff-mode find-file-match))
358
359 (defmethod semanticdb-find-nonterminal-by-extra-spec-method
360   ((database semanticdb-project-database) spec search-parts search-includes diff-mode find-file-match)
361   "Find all nonterminals with a SPEC in databases.
362 See `semanticdb-find-nonterminal-by-function' for details on DATABASES,
363 SEARCH-PARTS, SEARCH-INCLUDES DIFF-MODE, and FIND-FILE-MATCH.
364 Return a list ((DB-TABLE . TOKEN-LIST) ...)."
365   (semanticdb-find-nonterminal-by-function-method
366    database
367    (lambda (stream sp si)
368      (semantic-brute-find-tag-by-attribute spec stream sp si))
369    search-parts search-includes diff-mode find-file-match))
370
371 (defmethod semanticdb-find-nonterminal-by-extra-spec-value-method
372   ((database semanticdb-project-database) spec value search-parts search-includes diff-mode find-file-match)
373   "Find all nonterminals with a SPEC equal to VALUE in databases.
374 See `semanticdb-find-nonterminal-by-function' for details on DATABASES,
375 SEARCH-PARTS, SEARCH-INCLUDES DIFF-MODE, and FIND-FILE-MATCH.
376 Return a list ((DB-TABLE . TOKEN-LIST) ...)."
377   (semanticdb-find-nonterminal-by-function-method
378    database
379    (lambda (stream sp si)
380      (semantic-brute-find-tag-by-attribute-value spec value stream sp si))
381    search-parts search-includes diff-mode find-file-match))
382
383 ;;; Advanced Searches
384 ;;
385 (defmethod semanticdb-find-nonterminal-external-children-of-type-method
386   ((database semanticdb-project-database) type search-parts search-includes diff-mode find-file-match)
387   "Find all nonterminals which are child elements of TYPE
388 See `semanticdb-find-nonterminal-by-function' for details on DATABASES,
389 SEARCH-PARTS, SEARCH-INCLUDES DIFF-MODE, FIND-FILE-MATCH and IGNORE-SYSTEM.
390 Return a list ((DB-TABLE . TOKEN-LIST) ...)."
391   (semanticdb-find-nonterminal-by-function-method
392    database
393    `(lambda (stream sp si)
394       (semantic-brute-find-tag-by-function
395        (lambda (tok)
396          (let ((p (semantic-nonterminal-external-member-parent tok)))
397            (and (stringp p) (string= ,type p)))
398          )
399        stream sp si))
400    nil nil t))
401
402 ;;; Generic Search
403 ;;
404 (defmethod semanticdb-find-nonterminal-by-function-method
405   ((database semanticdb-project-database)
406    function &optional search-parts search-includes diff-mode find-file-match)
407   "In DATABASE, find all occurances of nonterminals which match FUNCTION.
408 When SEARCH-PARTS is non-nil the search will include children of tags.
409 When SEARCH-INCLUDES is non-nil, the search will include dependency files.
410 When DIFF-MODE is non-nil, search databases which are of a different mode.
411 A mode is the `major-mode' that file was in when it was last parsed.
412 When FIND-FILE-MATCH is non-nil, the make sure any found token's file is
413 in an Emacs buffer.
414 Return a list of matches."
415   (let* ((ret nil)
416          (files (semanticdb-get-database-tables database))
417          (found nil)
418          (orig-buffer (current-buffer)))
419     (while files
420       (when (or diff-mode
421                 (semanticdb-equivalent-mode (car files) orig-buffer))
422         ;; This can cause unneeded refreshes while typing with
423         ;; senator-eldoc mode.
424         ;;(semanticdb-refresh-table (car files))
425         (setq found (funcall function
426                              (semanticdb-get-tags (car files))
427                              search-parts
428                              search-includes
429                              )))
430       (if found
431           (progn
432             ;; When something is found, make sure we read in that buffer if it
433             ;; had not already been loaded.
434             (if find-file-match
435                 (save-excursion (semanticdb-set-buffer (car files))))
436             ;; In theory, the database is up-to-date with what is in the file, and
437             ;; these tags are ready to go.
438             ;; There is a bug lurking here I don't have time to fix.
439             (setq ret (cons (cons (car files) found) ret))
440             (setq found nil)))
441       (setq files (cdr files)))
442     (nreverse ret)))
443
444 (provide 'semanticdb-search)
445
446 ;;; semanticdb-search.el ends here