Add 2010 to copyright years.
[bpt/emacs.git] / lisp / cedet / semantic / analyze / complete.el
CommitLineData
a6de3d1a
CY
1;;; semantic/analyze/complete.el --- Smart Completions
2
114f9c96 3;; Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
a6de3d1a
CY
4
5;; Author: Eric M. Ludlam <zappo@gnu.org>
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;;
9bf6c65c 24;; Calculate smart completions.
a6de3d1a
CY
25;;
26;; Uses the analyzer context routine to determine the best possible
27;; list of completions.
28;;
29;;; History:
30;;
31;; Code was moved here from semantic-analyze.el
32
33(require 'semantic/analyze)
34
06b43459
CY
35;; For semantic-find-* macros:
36(eval-when-compile (require 'semantic/find))
37
a6de3d1a
CY
38;;; Code:
39
40;;; Helper Fcns
41;;
42;;
55b522b2 43;;;###autoload
a6de3d1a
CY
44(define-overloadable-function semantic-analyze-type-constants (type)
45 "For the tag TYPE, return any constant symbols of TYPE.
46Used as options when completing.")
47
48(defun semantic-analyze-type-constants-default (type)
49 "Do nothing with TYPE."
50 nil)
51
a6de3d1a
CY
52(defun semantic-analyze-tags-of-class-list (tags classlist)
53 "Return the tags in TAGS that are of classes in CLASSLIST."
54 (let ((origc tags))
55 ;; Accept only tags that are of the datatype specified by
56 ;; the desired classes.
57 (setq tags (apply 'nconc ;; All input lists are permutable.
58 (mapcar (lambda (class)
59 (semantic-find-tags-by-class class origc))
60 classlist)))
61 tags))
62
63;;; MAIN completion calculator
64;;
3d9d8486 65;;;###autoload
a6de3d1a
CY
66(define-overloadable-function semantic-analyze-possible-completions (context)
67 "Return a list of semantic tags which are possible completions.
68CONTEXT is either a position (such as point), or a precalculated
69context. Passing in a context is useful if the caller also needs
70to access parts of the analysis.
71Completions run through the following filters:
72 * Elements currently in scope
73 * Constants currently in scope
74 * Elements match the :prefix in the CONTEXT.
75 * Type of the completion matches the type of the context.
76Context type matching can identify the following:
77 * No specific type
78 * Assignment into a variable of some type.
79 * Argument to a function with type constraints.
80When called interactively, displays the list of possible completions
81in a buffer."
82 (interactive "d")
83 ;; In theory, we don't need the below since the context will
84 ;; do it for us.
85 ;;(semantic-refresh-tags-safe)
86 (with-syntax-table semantic-lex-syntax-table
87 (let* ((context (if (semantic-analyze-context-child-p context)
88 context
89 (semantic-analyze-current-context context)))
90 (ans (if (not context)
9bf6c65c 91 (error "Nothing to complete")
a6de3d1a
CY
92 (:override))))
93 ;; If interactive, display them.
2054a44c 94 (when (called-interactively-p 'any)
a6de3d1a
CY
95 (with-output-to-temp-buffer "*Possible Completions*"
96 (semantic-analyze-princ-sequence ans "" (current-buffer)))
97 (shrink-window-if-larger-than-buffer
98 (get-buffer-window "*Possible Completions*")))
99 ans)))
100
101(defun semantic-analyze-possible-completions-default (context)
102 "Default method for producing smart completions.
103Argument CONTEXT is an object specifying the locally derived context."
104 (let* ((a context)
105 (desired-type (semantic-analyze-type-constraint a))
106 (desired-class (oref a prefixclass))
107 (prefix (oref a prefix))
108 (prefixtypes (oref a prefixtypes))
109 (completetext nil)
110 (completetexttype nil)
111 (scope (oref a scope))
112 (localvar (oref scope localvar))
113 (c nil))
114
115 ;; Calculate what our prefix string is so that we can
116 ;; find all our matching text.
117 (setq completetext (car (reverse prefix)))
118 (if (semantic-tag-p completetext)
119 (setq completetext (semantic-tag-name completetext)))
120
121 (if (and (not completetext) (not desired-type))
122 (error "Nothing to complete"))
123
124 (if (not completetext) (setq completetext ""))
125
126 ;; This better be a reasonable type, or we should fry it.
127 ;; The prefixtypes should always be at least 1 less than
128 ;; the prefix since the type is never looked up for the last
129 ;; item when calculating a sequence.
130 (setq completetexttype (car (reverse prefixtypes)))
131 (when (or (not completetexttype)
132 (not (and (semantic-tag-p completetexttype)
133 (eq (semantic-tag-class completetexttype) 'type))))
134 ;; What should I do here? I think this is an error condition.
135 (setq completetexttype nil)
136 ;; If we had something that was a completetexttype but it wasn't
137 ;; valid, then express our dismay!
138 (when (> (length prefix) 1)
139 (let* ((errprefix (car (cdr (reverse prefix)))))
140 (error "Cannot find types for `%s'"
141 (cond ((semantic-tag-p errprefix)
142 (semantic-format-tag-prototype errprefix))
143 (t
144 (format "%S" errprefix)))))
145 ))
146
147 ;; There are many places to get our completion stream for.
148 ;; Here we go.
149 (if completetexttype
150
151 (setq c (semantic-find-tags-for-completion
152 completetext
153 (semantic-analyze-scoped-type-parts completetexttype scope)
154 ))
155
156 ;; No type based on the completetext. This is a free-range
157 ;; var or function. We need to expand our search beyond this
158 ;; scope into semanticdb, etc.
159 (setq c (nconc
160 ;; Argument list and local variables
161 (semantic-find-tags-for-completion completetext localvar)
162 ;; The current scope
163 (semantic-find-tags-for-completion completetext (oref scope fullscope))
164 ;; The world
165 (semantic-analyze-find-tags-by-prefix completetext))
166 )
167 )
168
169 (let ((origc c)
170 (dtname (semantic-tag-name desired-type)))
171
172 ;; Reset c.
173 (setq c nil)
174
175 ;; Loop over all the found matches, and catagorize them
176 ;; as being possible features.
177 (while origc
178
179 (cond
180 ;; Strip operators
181 ((semantic-tag-get-attribute (car origc) :operator-flag)
182 nil
183 )
184
185 ;; If we are completing from within some prefix,
186 ;; then we want to exclude constructors and destructors
187 ((and completetexttype
188 (or (semantic-tag-get-attribute (car origc) :constructor-flag)
189 (semantic-tag-get-attribute (car origc) :destructor-flag)))
190 nil
191 )
192
193 ;; If there is a desired type, we need a pair of restrictions
194 (desired-type
195
196 (cond
197 ;; Ok, we now have a completion list based on the text we found
198 ;; we want to complete on. Now filter that stream against the
199 ;; type we want to search for.
200 ((string= dtname (semantic-analyze-type-to-name (semantic-tag-type (car origc))))
201 (setq c (cons (car origc) c))
202 )
203
204 ;; Now anything that is a compound type which could contain
205 ;; additional things which are of the desired type
206 ((semantic-tag-type (car origc))
207 (let ((att (semantic-analyze-tag-type (car origc) scope))
208 )
209 (if (and att (semantic-tag-type-members att))
210 (setq c (cons (car origc) c))))
211 )
212
213 ) ; cond
214 ); desired type
215
216 ;; No desired type, no other restrictions. Just add.
217 (t
218 (setq c (cons (car origc) c)))
219
220 ); cond
221
222 (setq origc (cdr origc)))
223
224 (when desired-type
225 ;; Some types, like the enum in C, have special constant values that
226 ;; we could complete with. Thus, if the target is an enum, we can
227 ;; find possible symbol values to fill in that value.
228 (let ((constants
229 (semantic-analyze-type-constants desired-type)))
230 (if constants
231 (progn
232 ;; Filter
233 (setq constants
234 (semantic-find-tags-for-completion
235 completetext constants))
236 ;; Add to the list
237 (setq c (nconc c constants)))
238 )))
239 )
240
241 (when desired-class
242 (setq c (semantic-analyze-tags-of-class-list c desired-class)))
243
244 ;; Pull out trash.
245 ;; NOTE TO SELF: Is this too slow?
246 ;; OTHER NOTE: Do we not want to strip duplicates by name and
247 ;; only by position? When are duplicate by name but not by tag
248 ;; useful?
249 (setq c (semantic-unique-tag-table-by-name c))
250
251 ;; All done!
252
253 c))
254
a6de3d1a
CY
255(provide 'semantic/analyze/complete)
256
3d9d8486
CY
257;; Local variables:
258;; generated-autoload-file: "../loaddefs.el"
06b43459 259;; generated-autoload-load-name: "semantic/analyze/complete"
3d9d8486
CY
260;; End:
261
3999968a 262;; arch-tag: 97071c7e-2459-4e7a-8875-8cc5bbbc1f4d
a6de3d1a 263;;; semantic/analyze/complete.el ends here