aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2023-03-17 11:42:50 +0100
committerUlf Hermann <ulf.hermann@qt.io>2023-03-21 12:45:26 +0100
commitc10c513b6fa596e7e94bad6c31c160b06b0daccd (patch)
treed2d5c12123c88d84cb50767a2627542feec4f191
parent07a8850933a049c1a2931c2ac358517a6fb88038 (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.cpp28
-rw-r--r--tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp7
-rw-r--r--tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h12
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;