| 669 | } |
| 670 | |
| 671 | Declaration* findDeclaration(const QualifiedIdentifier& qid, const DUContextPointer& ctx, const CursorInRevision& position, QSet<Declaration*>& handled) |
| 672 | { |
| 673 | Declaration* ret = nullptr; |
| 674 | const auto& importedContexts = ctx->topContext()->importedParentContexts(); |
| 675 | auto visitor = [&](const IndexedDeclaration& indexedDeclaration) { |
| 676 | // if the context is not included, then this match is not correct for our consideration |
| 677 | // this fixes issues where we used to include matches from files that did not have |
| 678 | // anything to do with the current TU, e.g. the main from a different file or stuff like that |
| 679 | // it also reduces the chance of us picking up a function of the same name from somewhere else |
| 680 | // also, this makes sure the context has the correct language and we don't get confused by stuff |
| 681 | // from other language plugins |
| 682 | if (std::none_of(importedContexts.begin(), importedContexts.end(), |
| 683 | [indexedDeclaration](const DUContext::Import& import) { |
| 684 | return import.topContextIndex() == indexedDeclaration.indexedTopContext().index(); |
| 685 | })) { |
| 686 | return PersistentSymbolTable::VisitorState::Continue; |
| 687 | } |
| 688 | |
| 689 | auto declaration = indexedDeclaration.declaration(); |
| 690 | if (!declaration) { |
| 691 | // Mitigate problems such as: Cannot load a top-context from file "/home/kfunk/.cache/kdevduchain/kdevelop-{foo}/topcontexts/6085" |
| 692 | // - the required language-support for handling ID 55 is probably not loaded |
| 693 | qCWarning(KDEV_CLANG) << "Detected an invalid declaration for" << qid; |
| 694 | |
| 695 | return PersistentSymbolTable::VisitorState::Continue; |
| 696 | } |
| 697 | |
| 698 | if (declaration->kind() == Declaration::Instance && !declaration->isFunctionDeclaration()) { |
| 699 | return PersistentSymbolTable::VisitorState::Break; |
| 700 | } |
| 701 | if (Algorithm::insert(handled, declaration).inserted) { |
| 702 | ret = declaration; |
| 703 | return PersistentSymbolTable::VisitorState::Break; |
| 704 | } |
| 705 | |
| 706 | return PersistentSymbolTable::VisitorState::Continue; |
| 707 | }; |
| 708 | PersistentSymbolTable::self().visitDeclarations(qid, visitor); |
| 709 | if (ret) { |
| 710 | return ret; |
| 711 | } |
| 712 | |
| 713 | const auto foundDeclarations = ctx->findDeclarations(qid, position); |
| 714 | for (auto dec : foundDeclarations) { |
| 715 | if (Algorithm::insert(handled, dec).inserted) { |
| 716 | return dec; |
| 717 | } |
| 718 | } |
| 719 | |
| 720 | return nullptr; |
| 721 | } |
| 722 | |
| 723 | /// If any parent of this context is a class, the closest class declaration is returned, nullptr otherwise |
| 724 | Declaration* classDeclarationForContext(const DUContextPointer& context, const CursorInRevision& position) |
no test coverage detected