diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2023-03-17 11:42:50 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2023-03-21 12:45:26 +0100 |
commit | c10c513b6fa596e7e94bad6c31c160b06b0daccd (patch) | |
tree | d2d5c12123c88d84cb50767a2627542feec4f191 | |
parent | 07a8850933a049c1a2931c2ac358517a6fb88038 (diff) |
qmltyperegistrar: Do not guess types with upper case names
We generally need to guess value types since there are value types
without metaobjects of their own, such as QRectF and QSizeF. However, if
they have upper case element names, they are clearly not in that
category. Guessing those as value types will make further tools produce
follow-up mistakes.
Fixes: QTBUG-111986
Change-Id: Ic15ef8c726eb3913c87eb4a300794f321f59fafa
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
(cherry picked from commit c2fd73b516f6021f0ebb9f5cfd4de79f3f437f51)
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
-rw-r--r-- | src/qmltyperegistrar/qmltypesclassdescription.cpp | 28 | ||||
-rw-r--r-- | tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp | 7 | ||||
-rw-r--r-- | tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h | 12 |
3 files changed, 42 insertions, 5 deletions
diff --git a/src/qmltyperegistrar/qmltypesclassdescription.cpp b/src/qmltyperegistrar/qmltypesclassdescription.cpp index 28f50db3bc..6385f9cbe8 100644 --- a/src/qmltyperegistrar/qmltypesclassdescription.cpp +++ b/src/qmltyperegistrar/qmltypesclassdescription.cpp @@ -261,11 +261,29 @@ void QmlTypesClassDescription::collect( accessSemantics = QLatin1String("reference"); } else { isCreatable = false; - // If no classDef, we assume it's a value type defined by the foreign/extended trick. - // Objects and namespaces always have metaobjects and therefore classDefs. - accessSemantics = (!classDef || classDef->value(QLatin1String("gadget")).toBool()) - ? QLatin1String("value") - : QLatin1String("none"); + + if (!classDef) { + if (elementName.isEmpty() || elementName[0].isLower()) { + // If no classDef, we generally assume it's a value type defined by the + // foreign/extended trick. + accessSemantics = QLatin1String("value"); + } else { + // Objects and namespaces always have metaobjects and therefore classDefs. + // However, we may not be able to resolve the metaobject at compile time. See + // the "Invisible" test case. In that case, we must not assume anything about + // access semantics. + qWarning() << "Warning: Refusing to generate non-lowercase name" + << elementName << "for unknown foreign type"; + elementName.clear(); + // Make it completely inaccessible. + // We cannot get enums from anonymous types after all. + accessSemantics = QLatin1String("none"); + } + } else if (classDef->value(QLatin1String("gadget")).toBool()) { + accessSemantics = QLatin1String("value"); + } else { + accessSemantics = QLatin1String("none"); + } } } diff --git a/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp b/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp index aeb46a8274..27f83ca22f 100644 --- a/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp +++ b/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp @@ -300,4 +300,11 @@ void tst_qmltyperegistrar::methodReturnType() QVERIFY(qmltypesData.contains("type: \"QQmlComponent\"")); } +void tst_qmltyperegistrar::omitInvisible() +{ + // If it cannot resolve the type a QML_FOREIGN refers to, it should not generate anything. + QVERIFY(qmltypesData.contains( + R"(Component { file: "tst_qmltyperegistrar.h"; name: "Invisible"; accessSemantics: "none" })")); +} + QTEST_MAIN(tst_qmltyperegistrar) diff --git a/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h b/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h index 7cfce1c2be..1372c32d02 100644 --- a/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h +++ b/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h @@ -398,6 +398,17 @@ public: Q_INVOKABLE QQmlComponent *createAThing(int) { return nullptr; } }; +class Invisible : public QObject +{ +}; + +struct InvisibleForeign +{ + Q_GADGET + QML_FOREIGN(Invisible) + QML_NAMED_ELEMENT(Invisible) +}; + class tst_qmltyperegistrar : public QObject { Q_OBJECT @@ -429,6 +440,7 @@ private slots: void namespacesAndValueTypes(); void derivedFromForeignPrivate(); void methodReturnType(); + void omitInvisible(); private: QByteArray qmltypesData; |