OSDN Git Service

It's 2011 now.
[qt-creator-jp/qt-creator-jp.git] / src / plugins / cpptools / searchsymbols.cpp
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
8 **
9 ** No Commercial Usage
10 **
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 **
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file.  Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Nokia gives you certain additional
26 ** rights.  These rights are described in the Nokia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
31 **
32 **************************************************************************/
33
34 #include "searchsymbols.h"
35
36 #include <Literals.h>
37 #include <Scope.h>
38 #include <Names.h>
39 #include <cplusplus/LookupContext.h>
40 #include <QDebug>
41
42 using namespace CPlusPlus;
43 using namespace CppTools::Internal;
44
45 SearchSymbols::SymbolTypes SearchSymbols::AllTypes =
46         SearchSymbols::Classes
47         | SearchSymbols::Functions
48         | SearchSymbols::Enums
49         | SearchSymbols::Declarations;
50
51 SearchSymbols::SearchSymbols():
52     symbolsToSearchFor(Classes | Functions | Enums),
53     separateScope(false)
54 {
55 }
56
57 void SearchSymbols::setSymbolsToSearchFor(SymbolTypes types)
58 {
59     symbolsToSearchFor = types;
60 }
61
62 void SearchSymbols::setSeparateScope(bool separateScope)
63 {
64     this->separateScope = separateScope;
65 }
66
67 QList<ModelItemInfo> SearchSymbols::operator()(Document::Ptr doc, const QString &scope)
68 {
69     QString previousScope = switchScope(scope);
70     items.clear();
71     for (unsigned i = 0; i < doc->globalSymbolCount(); ++i) {
72         accept(doc->globalSymbolAt(i));
73     }
74     (void) switchScope(previousScope);
75     QList<ModelItemInfo> result = items;
76     strings.clear();
77     items.clear();
78     m_paths.clear();
79     return result;
80 }
81
82 QString SearchSymbols::switchScope(const QString &scope)
83 {
84     QString previousScope = _scope;
85     _scope = scope;
86     return previousScope;
87 }
88
89 bool SearchSymbols::visit(Enum *symbol)
90 {
91     if (!(symbolsToSearchFor & Enums))
92         return false;
93
94     QString name = symbolName(symbol);
95     QString scopedName = scopedSymbolName(name);
96     QString previousScope = switchScope(scopedName);
97     appendItem(separateScope ? name : scopedName,
98                separateScope ? previousScope : QString(),
99                ModelItemInfo::Enum, symbol);
100     for (unsigned i = 0; i < symbol->memberCount(); ++i) {
101         accept(symbol->memberAt(i));
102     }
103     (void) switchScope(previousScope);
104     return false;
105 }
106
107 bool SearchSymbols::visit(Function *symbol)
108 {
109     if (!(symbolsToSearchFor & Functions))
110         return false;
111
112     QString extraScope;
113     if (const Name *name = symbol->name()) {
114         if (const QualifiedNameId *q = name->asQualifiedNameId()) {
115             if (q->base())
116                 extraScope = overview.prettyName(q->base());
117         }
118     }
119     QString fullScope = _scope;
120     if (!_scope.isEmpty() && !extraScope.isEmpty())
121         fullScope += QLatin1String("::");
122     fullScope += extraScope;
123     QString name = symbolName(symbol);
124     QString scopedName = scopedSymbolName(name);
125     QString type = overview.prettyType(symbol->type(),
126                                        separateScope ? symbol->unqualifiedName() : 0);
127     appendItem(separateScope ? type : scopedName,
128                separateScope ? fullScope : type,
129                ModelItemInfo::Method, symbol);
130     return false;
131 }
132
133 bool SearchSymbols::visit(Namespace *symbol)
134 {
135     QString name = scopedSymbolName(symbol);
136     QString previousScope = switchScope(name);
137     for (unsigned i = 0; i < symbol->memberCount(); ++i) {
138         accept(symbol->memberAt(i));
139     }
140     (void) switchScope(previousScope);
141     return false;
142 }
143
144 bool SearchSymbols::visit(Declaration *symbol)
145 {
146     if (!(symbolsToSearchFor & Declarations))
147         return false;
148
149     QString name = symbolName(symbol);
150     QString scopedName = scopedSymbolName(name);
151     QString type = overview.prettyType(symbol->type(),
152                                        separateScope ? symbol->unqualifiedName() : 0);
153     appendItem(separateScope ? type : scopedName,
154                separateScope ? _scope : type,
155                ModelItemInfo::Declaration, symbol);
156     return false;
157 }
158
159 bool SearchSymbols::visit(Class *symbol)
160 {
161     QString name = symbolName(symbol);
162     QString scopedName = scopedSymbolName(name);
163     QString previousScope = switchScope(scopedName);
164     if (symbolsToSearchFor & Classes) {
165         appendItem(separateScope ? name : scopedName,
166                    separateScope ? previousScope : QString(),
167                    ModelItemInfo::Class, symbol);
168     }
169     for (unsigned i = 0; i < symbol->memberCount(); ++i) {
170         accept(symbol->memberAt(i));
171     }
172     (void) switchScope(previousScope);
173     return false;
174 }
175
176 bool SearchSymbols::visit(CPlusPlus::UsingNamespaceDirective *)
177 {
178     return false;
179 }
180
181 bool SearchSymbols::visit(CPlusPlus::UsingDeclaration *)
182 {
183     return false;
184 }
185
186 bool SearchSymbols::visit(CPlusPlus::NamespaceAlias *)
187 {
188     return false;
189 }
190
191 bool SearchSymbols::visit(CPlusPlus::Argument *)
192 {
193     return false;
194 }
195
196 bool SearchSymbols::visit(CPlusPlus::TypenameArgument *)
197 {
198     return false;
199 }
200
201 bool SearchSymbols::visit(CPlusPlus::BaseClass *)
202 {
203     return false;
204 }
205
206 bool SearchSymbols::visit(CPlusPlus::Template *)
207 {
208     return true;
209 }
210
211 bool SearchSymbols::visit(CPlusPlus::Block *)
212 {
213     return false;
214 }
215
216 bool SearchSymbols::visit(CPlusPlus::ForwardClassDeclaration *)
217 {
218     return false;
219 }
220
221 bool SearchSymbols::visit(CPlusPlus::ObjCBaseClass *)
222 {
223     return false;
224 }
225
226 bool SearchSymbols::visit(CPlusPlus::ObjCBaseProtocol *)
227 {
228     return false;
229 }
230
231 bool SearchSymbols::visit(CPlusPlus::ObjCClass *)
232 {
233     return false;
234 }
235
236 bool SearchSymbols::visit(CPlusPlus::ObjCForwardClassDeclaration *)
237 {
238     return false;
239 }
240
241 bool SearchSymbols::visit(CPlusPlus::ObjCProtocol *)
242 {
243     return false;
244 }
245
246 bool SearchSymbols::visit(CPlusPlus::ObjCForwardProtocolDeclaration *)
247 {
248     return false;
249 }
250
251 bool SearchSymbols::visit(CPlusPlus::ObjCMethod *)
252 {
253     return false;
254 }
255
256 bool SearchSymbols::visit(CPlusPlus::ObjCPropertyDeclaration *)
257 {
258     return false;
259 }
260
261 QString SearchSymbols::scopedSymbolName(const QString &symbolName) const
262 {
263     QString name = _scope;
264     if (!name.isEmpty())
265         name += QLatin1String("::");
266     name += symbolName;
267     return name;
268 }
269
270 QString SearchSymbols::scopedSymbolName(const Symbol *symbol) const
271 {
272     return scopedSymbolName(symbolName(symbol));
273 }
274
275 QString SearchSymbols::symbolName(const Symbol *symbol) const
276 {
277     QString symbolName = overview.prettyName(symbol->name());
278     if (symbolName.isEmpty()) {
279         QString type;
280         if (symbol->isNamespace()) {
281             type = QLatin1String("namespace");
282         } else if (symbol->isEnum()) {
283             type = QLatin1String("enum");
284         } else if (const Class *c = symbol->asClass())  {
285             if (c->isUnion()) {
286                 type = QLatin1String("union");
287             } else if (c->isStruct()) {
288                 type = QLatin1String("struct");
289             } else {
290                 type = QLatin1String("class");
291             }
292         } else {
293             type = QLatin1String("symbol");
294         }
295         symbolName = QLatin1String("<anonymous ");
296         symbolName += type;
297         symbolName += QLatin1Char('>');
298     }
299     return symbolName;
300 }
301
302 void SearchSymbols::appendItem(const QString &name,
303                                const QString &info,
304                                ModelItemInfo::ItemType type,
305                                Symbol *symbol)
306 {
307     if (!symbol->name())
308         return;
309
310     QStringList fullyQualifiedName;
311     foreach (const Name *name, LookupContext::fullyQualifiedName(symbol))
312         fullyQualifiedName.append(findOrInsert(overview.prettyName(name)));
313
314     QString path = m_paths.value(symbol->fileId(), QString());
315     if (path.isEmpty()) {
316         path = QString::fromUtf8(symbol->fileName(), symbol->fileNameLength());
317         m_paths.insert(symbol->fileId(), path);
318     }
319
320     const QIcon icon = icons.iconForSymbol(symbol);
321     items.append(ModelItemInfo(findOrInsert(name), findOrInsert(info), type,
322                                fullyQualifiedName,
323                                path,
324                                symbol->line(),
325                                symbol->column() - 1, // 1-based vs 0-based column
326                                icon));
327 }