Changeset View
Changeset View
Standalone View
Standalone View
duchain/topducontext.cpp
Show All 16 Lines | |||||
17 | #include "topducontext.h" | 17 | #include "topducontext.h" | ||
18 | 18 | | |||
19 | #include <language/duchain/topducontextutils.h> | 19 | #include <language/duchain/topducontextutils.h> | ||
20 | #include <language/duchain/persistentsymboltable.h> | 20 | #include <language/duchain/persistentsymboltable.h> | ||
21 | #include <language/duchain/duchainlock.h> | 21 | #include <language/duchain/duchainlock.h> | ||
22 | #include <language/duchain/duchain.h> | 22 | #include <language/duchain/duchain.h> | ||
23 | #include <language/duchain/namespacealiasdeclaration.h> | 23 | #include <language/duchain/namespacealiasdeclaration.h> | ||
24 | #include <language/duchain/duchainregister.h> | 24 | #include <language/duchain/duchainregister.h> | ||
25 | | ||||
26 | #include <language/duchain/classmemberdeclaration.h> | 25 | #include <language/duchain/classmemberdeclaration.h> | ||
27 | 26 | | |||
28 | #include "helpers.h" | 27 | #include "helpers.h" | ||
29 | 28 | | |||
30 | //#define DEBUG_SEARCH2 | 29 | //#define DEBUG_SEARCH2 | ||
31 | 30 | | |||
32 | using namespace KDevelop; | 31 | using namespace KDevelop; | ||
33 | 32 | | |||
Show All 13 Lines | |||||
47 | 46 | | |||
48 | struct TopDUContext::FindDeclarationsAcceptor | 47 | struct TopDUContext::FindDeclarationsAcceptor | ||
49 | { | 48 | { | ||
50 | FindDeclarationsAcceptor(DeclarationList& _target, const DeclarationChecker& _check) : target(_target), check(_check) { | 49 | FindDeclarationsAcceptor(DeclarationList& _target, const DeclarationChecker& _check) : target(_target), check(_check) { | ||
51 | } | 50 | } | ||
52 | 51 | | |||
53 | void operator() (Declaration* declaration) { | 52 | void operator() (Declaration* declaration) { | ||
54 | #ifdef DEBUG_SEARCH | 53 | #ifdef DEBUG_SEARCH | ||
55 | kDebug() << "accepting" << element->qualifiedIdentifier().toString(); | 54 | qDebug() << "accepting" << element->qualifiedIdentifier().toString(); | ||
56 | #endif | 55 | #endif | ||
57 | if (check(declaration)) { | 56 | if (check(declaration)) { | ||
58 | target.append(declaration); | 57 | target.append(declaration); | ||
59 | } | 58 | } | ||
60 | } | 59 | } | ||
61 | 60 | | |||
62 | DeclarationList& target; | 61 | DeclarationList& target; | ||
63 | const DeclarationChecker& check; | 62 | const DeclarationChecker& check; | ||
64 | }; | 63 | }; | ||
65 | 64 | | |||
66 | bool TopDUContext::findDeclarationsInternal(const SearchItem::PtrList& identifiers, const CursorInRevision& position, const AbstractType::Ptr& dataType, DeclarationList& ret, const KDevelop::TopDUContext* source, SearchFlags flags, uint depth) const | 65 | bool TopDUContext::findDeclarationsInternal(const SearchItem::PtrList& identifiers, const CursorInRevision& position, const AbstractType::Ptr& dataType, DeclarationList& ret, const KDevelop::TopDUContext* source, SearchFlags flags, uint depth) const | ||
67 | { | 66 | { | ||
68 | Q_UNUSED(source); | 67 | Q_UNUSED(source); | ||
69 | Q_UNUSED(depth); | 68 | Q_UNUSED(depth); | ||
70 | ENSURE_CAN_READ | 69 | ENSURE_CAN_READ | ||
71 | 70 | | |||
72 | Q_ASSERT(identifiers.count() >= 1); | 71 | Q_ASSERT(identifiers.count() >= 1); | ||
73 | 72 | | |||
74 | SearchItem::Ptr identifier = identifiers[0]; | 73 | SearchItem::Ptr identifier = identifiers[0]; | ||
75 | 74 | | |||
76 | DeclarationChecker check(this, position, dataType, flags); | 75 | DeclarationChecker check(this, position, dataType, flags); | ||
77 | FindDeclarationsAcceptor accept(ret, check); | 76 | FindDeclarationsAcceptor accept(ret, check); | ||
78 | 77 | | |||
79 | #ifdef DEBUG_SEARCH2 | 78 | #ifdef DEBUG_SEARCH2 | ||
80 | FOREACH_ARRAY(SearchItem::Ptr idTree, identifiers) | 79 | for (const SearchItem::Ptr &idTree : identifiers) | ||
80 | { | ||||
81 | foreach(const QualifiedIdentifier &id, idTree->toList()) | 81 | foreach(const QualifiedIdentifier &id, idTree->toList()) | ||
82 | kDebug() << "findDeclarationsInternal" << id.toString(); | 82 | qDebug() << "findDeclarationsInternal" << id.toString(); | ||
83 | } | ||||
83 | 84 | | |||
84 | bool nextEmpty = identifier->hasNext() ? identifier->next.isEmpty() : true; | 85 | bool nextEmpty = identifier->hasNext() ? identifier->next.isEmpty() : true; | ||
85 | kDebug() << "Do direct search? hasNext" << identifier->hasNext() << " isEmpty " << nextEmpty; | 86 | qDebug() << "Do direct search? hasNext" << identifier->hasNext() << " isEmpty " << nextEmpty; | ||
86 | #endif | 87 | #endif | ||
87 | 88 | | |||
88 | if (identifier->hasNext() && !identifier->next.isEmpty()) { | 89 | if (identifier->hasNext() && !identifier->next.isEmpty()) { | ||
89 | // This is a qualified identifier, do a direct lookup only | 90 | // This is a qualified identifier, do a direct lookup only | ||
90 | SearchItem::PtrList directLookup; | 91 | SearchItem::PtrList directLookup; | ||
91 | directLookup.append(identifier); | 92 | directLookup.append(identifier); | ||
92 | findJavaDeclarationsInternal(directLookup, accept, false); | 93 | findJavaDeclarationsInternal(directLookup, accept, false); | ||
93 | #ifdef DEBUG_SEARCH2 | 94 | #ifdef DEBUG_SEARCH2 | ||
94 | kDebug() << "Found directly " << ret.count(); | 95 | qDebug() << "Found directly " << ret.count(); | ||
95 | #endif | 96 | #endif | ||
96 | return true; | 97 | return true; | ||
97 | } | 98 | } | ||
98 | 99 | | |||
99 | SearchItem::PtrList singleTypeImports; | 100 | SearchItem::PtrList singleTypeImports; | ||
100 | SearchItem::PtrList typeImportsOnDemand; | 101 | SearchItem::PtrList typeImportsOnDemand; | ||
101 | SearchItem::PtrList singleStaticImports; | 102 | SearchItem::PtrList singleStaticImports; | ||
102 | SearchItem::PtrList staticImportsOnDemand; | 103 | SearchItem::PtrList staticImportsOnDemand; | ||
Show All 19 Lines | 122 | } else { | |||
122 | if (alias->importIdentifier().last() == identifier->identifier) { | 123 | if (alias->importIdentifier().last() == identifier->identifier) { | ||
123 | singleStaticImports.append( SearchItem::Ptr( new SearchItem( alias->importIdentifier() ) ) ) ; | 124 | singleStaticImports.append( SearchItem::Ptr( new SearchItem( alias->importIdentifier() ) ) ) ; | ||
124 | } | 125 | } | ||
125 | } | 126 | } | ||
126 | } | 127 | } | ||
127 | } | 128 | } | ||
128 | 129 | | |||
129 | #ifdef DEBUG_SEARCH | 130 | #ifdef DEBUG_SEARCH | ||
130 | FOREACH_ARRAY(SearchItem::Ptr idTree, singleTypeImports) | 131 | for (const SearchItem::Ptr &idTree : singleTypeImports) | ||
132 | { | ||||
131 | foreach(const QualifiedIdentifier &id, idTree->toList()) | 133 | foreach(const QualifiedIdentifier &id, idTree->toList()) | ||
132 | kDebug() << "Single type imported: " << id.toString(); | 134 | qDebug() << "Single type imported: " << id.toString(); | ||
135 | } | ||||
133 | 136 | | |||
134 | FOREACH_ARRAY(SearchItem::Ptr idTree, typeImportsOnDemand) | 137 | for (const SearchItem::Ptr &idTree : typeImportsOnDemand) | ||
138 | { | ||||
135 | foreach(const QualifiedIdentifier &id, idTree->toList()) | 139 | foreach(const QualifiedIdentifier &id, idTree->toList()) | ||
136 | kDebug() << "Type import on demand: " << id.toString(); | 140 | qDebug() << "Type import on demand: " << id.toString(); | ||
141 | } | ||||
137 | 142 | | |||
138 | FOREACH_ARRAY(SearchItem::Ptr idTree, singleStaticImports) | 143 | for (const SearchItem::Ptr &idTree : singleStaticImports) | ||
144 | { | ||||
139 | foreach(const QualifiedIdentifier &id, idTree->toList()) | 145 | foreach(const QualifiedIdentifier &id, idTree->toList()) | ||
140 | kDebug() << "Single static imported: " << id.toString(); | 146 | qDebug() << "Single static imported: " << id.toString(); | ||
147 | } | ||||
141 | 148 | | |||
142 | FOREACH_ARRAY(SearchItem::Ptr idTree, staticImportsOnDemand) | 149 | for (const SearchItem::Ptr &idTree : staticImportsOnDemand) | ||
150 | { | ||||
143 | foreach(const QualifiedIdentifier &id, idTree->toList()) | 151 | foreach(const QualifiedIdentifier &id, idTree->toList()) | ||
144 | kDebug() << "Statics imported on demand: " << id.toString(); | 152 | qDebug() << "Statics imported on demand: " << id.toString(); | ||
153 | } | ||||
145 | #endif | 154 | #endif | ||
146 | 155 | | |||
147 | ///The actual scopes are found within applyAliases, and each complete qualified identifier is given to FindDeclarationsAcceptor. | 156 | ///The actual scopes are found within applyAliases, and each complete qualified identifier is given to FindDeclarationsAcceptor. | ||
148 | ///That stores the found declaration to the output. | 157 | ///That stores the found declaration to the output. | ||
149 | 158 | | |||
150 | findJavaDeclarationsInternal(singleTypeImports, accept, false); | 159 | findJavaDeclarationsInternal(singleTypeImports, accept, false); | ||
151 | if (foundEnough(ret, flags)) { | 160 | if (foundEnough(ret, flags)) { | ||
152 | #ifdef DEBUG_SEARCH2 | 161 | #ifdef DEBUG_SEARCH2 | ||
153 | kDebug() << "Found from single type" << ret.count(); | 162 | qDebug() << "Found from single type" << ret.count(); | ||
154 | #endif | 163 | #endif | ||
155 | return true; | 164 | return true; | ||
156 | } | 165 | } | ||
157 | 166 | | |||
158 | findJavaDeclarationsInternal(singleStaticImports, accept, true); | 167 | findJavaDeclarationsInternal(singleStaticImports, accept, true); | ||
159 | if (foundEnough(ret, flags)) { | 168 | if (foundEnough(ret, flags)) { | ||
160 | #ifdef DEBUG_SEARCH2 | 169 | #ifdef DEBUG_SEARCH2 | ||
161 | kDebug() << "Found from single static" << ret.count(); | 170 | qDebug() << "Found from single static" << ret.count(); | ||
162 | #endif | 171 | #endif | ||
163 | return true; | 172 | return true; | ||
164 | } | 173 | } | ||
165 | 174 | | |||
166 | findJavaDeclarationsInternal(typeImportsOnDemand, accept, false); | 175 | findJavaDeclarationsInternal(typeImportsOnDemand, accept, false); | ||
167 | if (foundEnough(ret, flags)) { | 176 | if (foundEnough(ret, flags)) { | ||
168 | #ifdef DEBUG_SEARCH2 | 177 | #ifdef DEBUG_SEARCH2 | ||
169 | kDebug() << "Found from type on demand" << ret.count(); | 178 | qDebug() << "Found from type on demand" << ret.count(); | ||
170 | #endif | 179 | #endif | ||
171 | return true; | 180 | return true; | ||
172 | } | 181 | } | ||
173 | 182 | | |||
174 | findJavaDeclarationsInternal(staticImportsOnDemand, accept, true); | 183 | findJavaDeclarationsInternal(staticImportsOnDemand, accept, true); | ||
175 | if (foundEnough(ret, flags)) { | 184 | if (foundEnough(ret, flags)) { | ||
176 | #ifdef DEBUG_SEARCH2 | 185 | #ifdef DEBUG_SEARCH2 | ||
177 | kDebug() << "Found from static on demand" << ret.count(); | 186 | qDebug() << "Found from static on demand" << ret.count(); | ||
178 | #endif | 187 | #endif | ||
179 | return true; | 188 | return true; | ||
180 | } | 189 | } | ||
181 | 190 | | |||
182 | #ifdef DEBUG_SEARCH2 | 191 | #ifdef DEBUG_SEARCH2 | ||
183 | kDebug() << "None found" << ret.count(); | 192 | qDebug() << "None found" << ret.count(); | ||
184 | #endif | 193 | #endif | ||
185 | return true; | 194 | return true; | ||
186 | } | 195 | } | ||
187 | 196 | | |||
188 | template<class Acceptor> | 197 | template<class Acceptor> | ||
189 | void TopDUContext::findJavaDeclarationsInternal( const SearchItem::PtrList& identifiers, Acceptor& accept, bool staticOnly ) const | 198 | void TopDUContext::findJavaDeclarationsInternal( const SearchItem::PtrList& identifiers, Acceptor& accept, bool staticOnly ) const | ||
190 | { | 199 | { | ||
191 | FOREACH_ARRAY(SearchItem::Ptr identifier, identifiers) { | 200 | for (SearchItem::Ptr identifier : identifiers) | ||
201 | { | ||||
192 | QualifiedIdentifier id(identifier->identifier); | 202 | QualifiedIdentifier id(identifier->identifier); | ||
193 | while (identifier->hasNext()) { | 203 | while (identifier->hasNext()) { | ||
194 | identifier = *identifier->next.data(); | 204 | identifier = *identifier->next.data(); | ||
195 | id.push(identifier->identifier); | 205 | id.push(identifier->identifier); | ||
196 | } | 206 | } | ||
197 | 207 | | |||
198 | #ifdef DEBUG_SEARCH2 | 208 | #ifdef DEBUG_SEARCH2 | ||
199 | kDebug() << "checking" << id.toString(); | 209 | qDebug() << "checking" << id.toString(); | ||
200 | #endif | 210 | #endif | ||
201 | 211 | | |||
202 | if(!id.isEmpty()) { | 212 | if(!id.isEmpty()) { | ||
203 | PersistentSymbolTable::FilteredDeclarationIterator filter = PersistentSymbolTable::self().getFilteredDeclarations(id, recursiveImportIndices()); | 213 | PersistentSymbolTable::FilteredDeclarationIterator filter = PersistentSymbolTable::self().filteredDeclarations(id, recursiveImportIndices()); | ||
204 | 214 | | |||
205 | if (filter) { | 215 | if (filter) { | ||
206 | for(; filter; ++filter) { | 216 | for(; filter; ++filter) { | ||
207 | const IndexedDeclaration iDecl = *filter; | 217 | const IndexedDeclaration iDecl = *filter; | ||
208 | 218 | | |||
209 | Declaration* aliasDecl = iDecl.data(); | 219 | Declaration* aliasDecl = iDecl.data(); | ||
210 | 220 | | |||
211 | #ifdef DEBUG_SEARCH2 | 221 | #ifdef DEBUG_SEARCH2 | ||
212 | kDebug() << "Found declaration" << aliasDecl; | 222 | qDebug() << "Found declaration" << aliasDecl; | ||
213 | #endif | 223 | #endif | ||
214 | 224 | | |||
215 | if(!aliasDecl) | 225 | if(!aliasDecl) | ||
216 | continue; | 226 | continue; | ||
217 | 227 | | |||
218 | if(aliasDecl->identifier() != id.last()) { //Since we have retrieved the aliases by hash only, we still need to compare the name | 228 | if(aliasDecl->identifier() != id.last()) { //Since we have retrieved the aliases by hash only, we still need to compare the name | ||
219 | #ifdef DEBUG_SEARCH2 | 229 | #ifdef DEBUG_SEARCH2 | ||
220 | kDebug() << "Dumped as not the same identifier" << aliasDecl->identifier().toString() << id.last().toString(); | 230 | qDebug() << "Dumped as not the same identifier" << aliasDecl->identifier().toString() << id.last().toString(); | ||
221 | #endif | 231 | #endif | ||
222 | continue; | 232 | continue; | ||
223 | } | 233 | } | ||
224 | 234 | | |||
225 | ClassMemberDeclaration* classMemberDecl = dynamic_cast<ClassMemberDeclaration*>(aliasDecl); | 235 | ClassMemberDeclaration* classMemberDecl = dynamic_cast<ClassMemberDeclaration*>(aliasDecl); | ||
226 | 236 | | |||
227 | // TODO check logic here | 237 | // TODO check logic here | ||
228 | if (staticOnly && (!classMemberDecl || !classMemberDecl->isStatic())) { | 238 | if (staticOnly && (!classMemberDecl || !classMemberDecl->isStatic())) { | ||
229 | #ifdef DEBUG_SEARCH2 | 239 | #ifdef DEBUG_SEARCH2 | ||
230 | kDebug() << "Dumped as not static where search requested static only" << aliasDecl->identifier().toString(); | 240 | qDebug() << "Dumped as not static where search requested static only" << aliasDecl->identifier().toString(); | ||
231 | #endif | 241 | #endif | ||
232 | continue; | 242 | continue; | ||
233 | } | 243 | } | ||
234 | 244 | | |||
235 | #ifdef DEBUG_SEARCH2 | 245 | #ifdef DEBUG_SEARCH2 | ||
236 | kDebug() << "Trying to accept" << aliasDecl->identifier().toString(); | 246 | qDebug() << "Trying to accept" << aliasDecl->identifier().toString(); | ||
237 | #endif | 247 | #endif | ||
238 | accept(aliasDecl); | 248 | accept(aliasDecl); | ||
239 | } | 249 | } | ||
240 | } | 250 | } | ||
241 | } | 251 | } | ||
242 | 252 | | |||
243 | #ifdef DEBUG_SEARCH2 | 253 | #ifdef DEBUG_SEARCH2 | ||
244 | kDebug() << "Finished" << id.toString(); | 254 | qDebug() << "Finished" << id.toString(); | ||
245 | #endif | 255 | #endif | ||
246 | } | 256 | } | ||
247 | } | 257 | } | ||
248 | 258 | | |||
249 | } | 259 | } |