diff options
author | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2022-06-20 15:58:11 +0200 |
---|---|---|
committer | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2022-06-21 07:49:09 +0200 |
commit | a4e0ae01fdd7e9686445d9db3d62103dbbfafa91 (patch) | |
tree | 98c8ad2d622119f6c083ba3f7452a9ed6807cb34 | |
parent | 99c59f82575695163e45e3848a5338f2d4fadaae (diff) | |
download | qtactiveqt-a4e0ae01fdd7e9686445d9db3d62103dbbfafa91.tar.gz |
Postprocess moc output to fully qualify types
If a property is declared with a type that is also the name of a member
function, then the generated code will result in conflicts and compile
errors. For instance, a property "AddressEntry" might be of type
"AddressEntry*" and have a getter "AddressEntry", where the type lives
in the same namespace as the current class. This is reproducible with
the qutlook example, which doesn't build.
This issue can also be provoked by valid C++ code, but since moc has
no information about which types are classes or enums, or in which
namespace they live in, we cannot do anything about that problem (yet).
However, dumpcpp has information about which namespace a type live in,
so we can postprocess the moc output and fix the problematic code by
fully qualifying the types used with the namespace they were generated
in.
This slows down dumpcpp runs quite a bit, but those are infrequent as
the type library typically doesn't change.
Fixes: QTBUG-100145
Pick-to: 6.4 6.3
Change-Id: Id9b4656cb1ff2c319e0b87bd22b7e9399e7c410d
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
-rw-r--r-- | tools/dumpcpp/main.cpp | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/tools/dumpcpp/main.cpp b/tools/dumpcpp/main.cpp index 9471fcf..c2120b7 100644 --- a/tools/dumpcpp/main.cpp +++ b/tools/dumpcpp/main.cpp @@ -544,13 +544,37 @@ bool generateClassImpl(QTextStream &out, const QMetaObject *mo, const QByteArray qualifiedClassName = nameSpace + "::"; qualifiedClassName += className; - const QString moCode = mocCode(mo, QLatin1String(qualifiedClassName), - errorString); + QString moCode = mocCode(mo, QLatin1String(qualifiedClassName), errorString); if (moCode.isEmpty()) { out << "#error moc error\n"; return false; } + // Postprocess the moc output to fully qualify types. This works around moc + // not having any semantic type information, and a fix for QTBUG-100145. + constexpr QStringView typeAndForceComplete(u"QtPrivate::TypeAndForceComplete<"); + qsizetype nextTypeAndForceComplete = 0; + do { + nextTypeAndForceComplete = moCode.indexOf(typeAndForceComplete, nextTypeAndForceComplete); + if (nextTypeAndForceComplete == -1) + break; + const auto startType = nextTypeAndForceComplete + typeAndForceComplete.length(); + const auto lengthType = moCode.indexOf(u',', startType) - startType; + if (lengthType == -1) + break; + + QString type = moCode.sliced(startType, lengthType); + if (type.endsWith(u'*')) + type.chop(1); + type = type.trimmed(); + const auto namespaceForTypeEntry = namespaceForType.constFind(type.toUtf8()); + if (namespaceForTypeEntry != namespaceForType.constEnd()) { + const auto ns = QString::fromUtf8(namespaceForTypeEntry.value()); + moCode.insert(startType, ns + QStringView(u"::")); + } + nextTypeAndForceComplete = startType + lengthType; + } while (true); + out << moCode << "\n\n"; formatConstructorBody(out, nameSpace, className, controlID, category, useControlName); |