| 284 | }; |
| 285 | |
| 286 | ItemUnderCursorInternal itemUnderCursorInternal(const CursorInRevision& c, DUContext* ctx, RangeInRevision::ContainsBehavior behavior) |
| 287 | { |
| 288 | //Search all collapsed sub-contexts. In C++, those can contain declarations that have ranges out of the context |
| 289 | const auto childContexts = ctx->childContexts(); |
| 290 | for (DUContext* subCtx : childContexts) { |
| 291 | //This is a little hacky, but we need it in case of foreach macros and similar stuff |
| 292 | if(subCtx->range().contains(c, behavior) || subCtx->range().isEmpty() || subCtx->range().start.line == c.line || subCtx->range().end.line == c.line) { |
| 293 | ItemUnderCursorInternal sub = itemUnderCursorInternal(c, subCtx, behavior); |
| 294 | if(sub.declaration) { |
| 295 | return sub; |
| 296 | } |
| 297 | } |
| 298 | } |
| 299 | |
| 300 | const auto localDeclarations = ctx->localDeclarations(); |
| 301 | for (Declaration* decl : localDeclarations) { |
| 302 | if(decl->range().contains(c, behavior)) { |
| 303 | return {decl, ctx, decl->range()}; |
| 304 | } |
| 305 | } |
| 306 | |
| 307 | //Try finding a use under the cursor |
| 308 | for(int a = 0; a < ctx->usesCount(); ++a) { |
| 309 | if(ctx->uses()[a].m_range.contains(c, behavior)) { |
| 310 | return {ctx->topContext()->usedDeclarationForIndex(ctx->uses()[a].m_declarationIndex), ctx, ctx->uses()[a].m_range}; |
| 311 | } |
| 312 | } |
| 313 | |
| 314 | return {nullptr, nullptr, RangeInRevision()}; |
| 315 | } |
| 316 | |
| 317 | DUChainUtils::ItemUnderCursor DUChainUtils::itemUnderCursor(const QUrl& url, const KTextEditor::Cursor& cursor) |
| 318 | { |
no test coverage detected