Changeset View
Changeset View
Standalone View
Standalone View
duchain/helpers.cpp
Show First 20 Lines • Show All 170 Lines • ▼ Show 20 Line(s) | 162 | { | |||
---|---|---|---|---|---|
171 | 171 | | |||
172 | // Otherwise look for a `__call__()` method. | 172 | // Otherwise look for a `__call__()` method. | ||
173 | static const IndexedIdentifier callId(KDevelop::Identifier("__call__")); | 173 | static const IndexedIdentifier callId(KDevelop::Identifier("__call__")); | ||
174 | 174 | | |||
175 | auto attr = accessAttribute(called->abstractType(), (isAlias ? initId : callId), called->topContext()); | 175 | auto attr = accessAttribute(called->abstractType(), (isAlias ? initId : callId), called->topContext()); | ||
176 | return { dynamic_cast<FunctionDeclaration*>(attr), isAlias }; | 176 | return { dynamic_cast<FunctionDeclaration*>(attr), isAlias }; | ||
177 | } | 177 | } | ||
178 | 178 | | |||
179 | Declaration* Helper::declarationForName(const QualifiedIdentifier& identifier, const RangeInRevision& nodeRange, | 179 | Declaration* Helper::declarationForName(const QString& name, const CursorInRevision& location, | ||
180 | KDevelop::DUChainPointer<const DUContext> context) | 180 | KDevelop::DUChainPointer<const DUContext> context) | ||
181 | { | 181 | { | ||
182 | DUChainReadLocker lock(DUChain::lock()); | 182 | DUChainReadLocker lock(DUChain::lock()); | ||
183 | auto localDeclarations = context->findLocalDeclarations(identifier.last(), nodeRange.end, 0, | 183 | auto identifier = KDevelop::Identifier(name); | ||
184 | auto localDeclarations = context->findLocalDeclarations(identifier, location, 0, | ||||
184 | AbstractType::Ptr(0), DUContext::DontResolveAliases); | 185 | AbstractType::Ptr(0), DUContext::DontResolveAliases); | ||
185 | if ( !localDeclarations.isEmpty() ) { | 186 | if ( !localDeclarations.isEmpty() ) { | ||
186 | return localDeclarations.last(); | 187 | return localDeclarations.last(); | ||
187 | } | 188 | } | ||
188 | 189 | | |||
189 | QList<Declaration*> declarations; | 190 | QList<Declaration*> declarations; | ||
190 | const DUContext* currentContext = context.data(); | 191 | const DUContext* currentContext = context.data(); | ||
191 | bool findInNext = true, findBeyondUse = false; | 192 | bool findInNext = true, findBeyondUse = false; | ||
192 | do { | 193 | do { | ||
193 | if (findInNext) { | 194 | if (findInNext) { | ||
194 | CursorInRevision findUntil = findBeyondUse ? currentContext->topContext()->range().end : nodeRange.end; | 195 | CursorInRevision findUntil = findBeyondUse ? currentContext->topContext()->range().end : location; | ||
195 | declarations = currentContext->findDeclarations(identifier.last(), findUntil); | 196 | declarations = currentContext->findDeclarations(identifier, findUntil); | ||
196 | 197 | | |||
197 | for (Declaration* declaration: declarations) { | 198 | for (Declaration* declaration: declarations) { | ||
198 | if (declaration->context()->type() != DUContext::Class || | 199 | if (declaration->context()->type() != DUContext::Class || | ||
199 | (currentContext->type() == DUContext::Function && declaration->context() == currentContext->parentContext())) { | 200 | (currentContext->type() == DUContext::Function && declaration->context() == currentContext->parentContext())) { | ||
200 | // Declarations from class decls must be referenced through `self.<foo>`, except | 201 | // Declarations from class decls must be referenced through `self.<foo>`, except | ||
201 | // in their local scope (handled above) or when used as default arguments for methods of the same class. | 202 | // in their local scope (handled above) or when used as default arguments for methods of the same class. | ||
202 | // Otherwise, we're done! | 203 | // Otherwise, we're done! | ||
203 | return declaration; | 204 | return declaration; | ||
Show All 11 Lines | 214 | if (!findBeyondUse && currentContext->owner() && currentContext->owner()->isFunctionDeclaration()) { | |||
215 | // Note: only the parameter list has type DUContext::Function, so we have to do this instead. | 216 | // Note: only the parameter list has type DUContext::Function, so we have to do this instead. | ||
216 | findBeyondUse = findInNext = true; | 217 | findBeyondUse = findInNext = true; | ||
217 | } | 218 | } | ||
218 | } while ((currentContext = currentContext->parentContext())); | 219 | } while ((currentContext = currentContext->parentContext())); | ||
219 | 220 | | |||
220 | return nullptr; | 221 | return nullptr; | ||
221 | } | 222 | } | ||
222 | 223 | | |||
224 | | ||||
225 | Declaration* Helper::declarationForName(const Python::NameAst* name, CursorInRevision location, | ||||
226 | KDevelop::DUChainPointer<const DUContext> context) | ||||
227 | { | ||||
228 | const Ast* checkNode = name; | ||||
229 | while ((checkNode = checkNode->parent)) { | ||||
230 | switch (checkNode->astType) { | ||||
231 | default: | ||||
232 | continue; | ||||
233 | case Ast::ListComprehensionAstType: | ||||
234 | case Ast::SetComprehensionAstType: | ||||
235 | case Ast::DictionaryComprehensionAstType: | ||||
236 | case Ast::GeneratorExpressionAstType: | ||||
237 | // Variables in comprehensions are used before their definition. `[foo for foo in bar]` | ||||
238 | auto cmpEnd = CursorInRevision(checkNode->endLine, checkNode->endCol); | ||||
239 | if (cmpEnd > location) { | ||||
240 | location = cmpEnd; | ||||
241 | } | ||||
242 | } | ||||
243 | } | ||||
244 | return declarationForName(name->identifier->value, location, context); | ||||
245 | } | ||||
246 | | ||||
223 | QVector<DUContext*> Helper::internalContextsForClass(const StructureType::Ptr classType, | 247 | QVector<DUContext*> Helper::internalContextsForClass(const StructureType::Ptr classType, | ||
224 | const TopDUContext* context, ContextSearchFlags flags, int depth) | 248 | const TopDUContext* context, ContextSearchFlags flags, int depth) | ||
225 | { | 249 | { | ||
226 | QVector<DUContext*> searchContexts; | 250 | QVector<DUContext*> searchContexts; | ||
227 | if ( ! classType ) { | 251 | if ( ! classType ) { | ||
228 | return searchContexts; | 252 | return searchContexts; | ||
229 | } | 253 | } | ||
230 | if ( auto c = classType->internalContext(context) ) { | 254 | if ( auto c = classType->internalContext(context) ) { | ||
▲ Show 20 Lines • Show All 304 Lines • Show Last 20 Lines |