diff --git a/src/plugins/clangcodemodel/clangdast.cpp b/src/plugins/clangcodemodel/clangdast.cpp index 6b97146dd56..01f12d1177e 100644 --- a/src/plugins/clangcodemodel/clangdast.cpp +++ b/src/plugins/clangcodemodel/clangdast.cpp @@ -172,6 +172,20 @@ bool ClangdAstNode::hasChildWithRole(const QString &role) const [&role](const ClangdAstNode &c) { return c.role() == role; }); } +bool ClangdAstNode::hasChild(const std::function &predicate, + bool recursive) const +{ + std::function fullPredicate = predicate; + if (recursive) { + fullPredicate = [&predicate](const ClangdAstNode &n) { + if (predicate(n)) + return true; + return n.hasChild(predicate, true); + }; + } + return Utils::contains(children().value_or(QList()), fullPredicate); +} + QString ClangdAstNode::operatorString() const { if (kind() == "BinaryOperator") diff --git a/src/plugins/clangcodemodel/clangdast.h b/src/plugins/clangcodemodel/clangdast.h index 7eb24e9f21f..cdb87c7be07 100644 --- a/src/plugins/clangcodemodel/clangdast.h +++ b/src/plugins/clangcodemodel/clangdast.h @@ -77,6 +77,7 @@ public: bool childContainsRange(int index, const LanguageServerProtocol::Range &range) const; bool hasChildWithRole(const QString &role) const; + bool hasChild(const std::function &predicate, bool recursive) const; QString operatorString() const; enum class FileStatus { Ours, Foreign, Mixed, Unknown }; diff --git a/src/plugins/clangcodemodel/clangdfindreferences.cpp b/src/plugins/clangcodemodel/clangdfindreferences.cpp index 2130587a2d5..12f860c87c1 100644 --- a/src/plugins/clangcodemodel/clangdfindreferences.cpp +++ b/src/plugins/clangcodemodel/clangdfindreferences.cpp @@ -595,6 +595,19 @@ static Usage::Tags getUsageType(const ClangdAstPath &path, const QString &search tags |= Usage::Tag::Operator; } } + if (pathIt->kind() == "CXXMethod") { + const ClangdAstNode &classNode = *std::next(pathIt); + if (classNode.hasChild([&](const ClangdAstNode &n) { + if (n.kind() != "StaticAssert") + return false; + return n.hasChild([&](const ClangdAstNode &n) { + return n.arcanaContains("Q_PROPERTY"); }, true) + && n.hasChild([&](const ClangdAstNode &n) { + return n.arcanaContains(" " + searchTerm); }, true); + }, false)) { + tags |= Usage::Tag::MocInvokable; + } + } return tags; } if (pathIt->kind() == "MemberInitializer")