From 28a88b5986e8a1d1b2f8968cc9f9d7af9b381656 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 13 Dec 2023 11:45:38 +0100 Subject: [PATCH] moc: store the FQN in JSON superClass objects Tooling can then use this information to find the correct base class, even absent C++ scoping information. Pick-to: 6.6 6.5 Task-number: QTBUG-101141 Change-Id: I5350da8d2d9aaf5ec86027357131ebac1eb50372 Reviewed-by: Fabian Kosmale Reviewed-by: Qt CI Bot (cherry picked from commit 672a824639a927e7e3061e84dfa35e06eb26a7fa) Reviewed-by: Qt Cherry-pick Bot --- src/tools/moc/moc.cpp | 15 ++++++++-- src/tools/moc/moc.h | 3 ++ tests/auto/tools/moc/CMakeLists.txt | 1 + tests/auto/tools/moc/allmocs_baseline_in.json | 29 +++++++++++++++++++ tests/auto/tools/moc/namespaced-base-class.h | 20 +++++++++++++ 5 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 tests/auto/tools/moc/namespaced-base-class.h diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp index b471418a274..d39ee7018a5 100644 --- a/src/tools/moc/moc.cpp +++ b/src/tools/moc/moc.cpp @@ -26,6 +26,15 @@ static QByteArray normalizeType(const QByteArray &ba) return ba.size() ? normalizeTypeInternal(ba.constBegin(), ba.constEnd()) : ba; } +const QByteArray &Moc::toFullyQualified(const QByteArray &name) const noexcept +{ + if (auto it = knownQObjectClasses.find(name); it != knownQObjectClasses.end()) + return it.value(); + if (auto it = knownGadgets.find(name); it != knownGadgets.end()) + return it.value(); + return name; +} + bool Moc::parseClassHead(ClassDef *def) { // figure out whether this is a class declaration, or only a @@ -87,12 +96,12 @@ bool Moc::parseClassHead(ClassDef *def) else test(PUBLIC); test(VIRTUAL); - const QByteArray type = parseType().name; + const Type type = parseType(); // ignore the 'class Foo : BAR(Baz)' case if (test(LPAREN)) { until(RPAREN); } else { - def->superclassList += SuperClass{type, access}; + def->superclassList.push_back({type.name, toFullyQualified(type.name), access}); } } while (test(COMMA)); @@ -2041,6 +2050,8 @@ QJsonObject ClassDef::toJson() const for (const auto &super: std::as_const(superclassList)) { QJsonObject superCls; superCls["name"_L1] = QString::fromUtf8(super.classname); + if (super.classname != super.qualified) + superCls["fullyQualifiedName"_L1] = QString::fromUtf8(super.qualified); FunctionDef::accessToJson(&superCls, super.access); superClasses.append(superCls); } diff --git a/src/tools/moc/moc.h b/src/tools/moc/moc.h index d425351e136..c1759fb0a3e 100644 --- a/src/tools/moc/moc.h +++ b/src/tools/moc/moc.h @@ -157,6 +157,7 @@ struct BaseDef { struct SuperClass { QByteArray classname; + QByteArray qualified; FunctionDef::Access access; }; Q_DECLARE_TYPEINFO(SuperClass, Q_RELOCATABLE_TYPE); @@ -240,6 +241,8 @@ public: return index > def->begin && index < def->end - 1; } + const QByteArray &toFullyQualified(const QByteArray &name) const noexcept; + void prependNamespaces(BaseDef &def, const QList &namespaceList) const; Type parseType(); diff --git a/tests/auto/tools/moc/CMakeLists.txt b/tests/auto/tools/moc/CMakeLists.txt index f2a5a1dbe81..1377c48306a 100644 --- a/tests/auto/tools/moc/CMakeLists.txt +++ b/tests/auto/tools/moc/CMakeLists.txt @@ -30,6 +30,7 @@ set(JSON_HEADERS moc_include.h namespace.h namespaced-flags.h + namespaced-base-class.h no-keywords.h non-gadget-parent-class.h oldstyle-casts.h diff --git a/tests/auto/tools/moc/allmocs_baseline_in.json b/tests/auto/tools/moc/allmocs_baseline_in.json index 50dbb200d2d..5cbcb99e68f 100644 --- a/tests/auto/tools/moc/allmocs_baseline_in.json +++ b/tests/auto/tools/moc/allmocs_baseline_in.json @@ -1319,6 +1319,35 @@ "inputFile": "namespace.h", "outputRevision": 68 }, + { + "classes": [ + { + "className": "Base", + "object": true, + "qualifiedClassName": "QTBUG_101141::Base", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + }, + { + "className": "Derived", + "object": true, + "qualifiedClassName": "QTBUG_101141::Derived", + "superClasses": [ + { + "access": "public", + "fullyQualifiedName": "QTBUG_101141::Base", + "name": "Base" + } + ] + } + ], + "inputFile": "namespaced-base-class.h", + "outputRevision": 68 + }, { "classes": [ { diff --git a/tests/auto/tools/moc/namespaced-base-class.h b/tests/auto/tools/moc/namespaced-base-class.h new file mode 100644 index 00000000000..6d76db9b542 --- /dev/null +++ b/tests/auto/tools/moc/namespaced-base-class.h @@ -0,0 +1,20 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#ifndef TST_MOC_NAMESPACED_BASE_CLASS_H +#define TST_MOC_NAMESPACED_BASE_CLASS_H + +#include + +namespace QTBUG_101141 { + class Base : public QObject { + Q_OBJECT + }; + + class Derived : public Base + { + Q_OBJECT + }; +} + +#endif // TST_MOC_NAMESPACED_BASE_CLASS_H