aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2022-06-10 11:23:20 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2022-06-10 20:40:56 +0000
commit2b8b69edc13d8abf49b68509b7a379f7ca1b7cb2 (patch)
treec83885c4784203febc173426feafdeee2cc1a94b
parent538c36af0a175451ea5a4f6f3d05ac68a7fc09a3 (diff)
qmltyperegistrar: Parse value type lists
We need to generate isList properties for those, so that qmlcachegen and qmllint can handle them. Fixes: QTBUG-104129 Change-Id: I7e632279a605694c2fd5f583c8a6dcf9968eb634 Reviewed-by: Maximilian Goldstein <max.goldstein@qt.io> (cherry picked from commit 8e69558f2f7d44f83779f7e1f60f811dfab0c275) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/qmltyperegistrar/qmltypescreator.cpp31
-rw-r--r--tests/auto/qml/qmlcppcodegen/data/Test.qml7
-rw-r--r--tests/auto/qml/qmlcppcodegen/data/cppbaseclass.h11
-rw-r--r--tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp12
4 files changed, 52 insertions, 9 deletions
diff --git a/src/qmltyperegistrar/qmltypescreator.cpp b/src/qmltyperegistrar/qmltypescreator.cpp
index d2a4ad9fd8..836eb0c10b 100644
--- a/src/qmltyperegistrar/qmltypescreator.cpp
+++ b/src/qmltyperegistrar/qmltypescreator.cpp
@@ -182,17 +182,30 @@ void QmlTypesCreator::writeType(const QJsonObject &property, const QString &key)
} else if (type == QLatin1String("quint64")) {
type = QLatin1String("qulonglong");
} else {
+ auto handleList = [&](QLatin1String list) {
+ if (!type.startsWith(list) || !type.endsWith(QLatin1Char('>')))
+ return false;
- const QLatin1String listProperty("QQmlListProperty<");
- if (type.startsWith(listProperty)) {
- isList = true;
- const int listPropertySize = listProperty.size();
- type = type.mid(listPropertySize, type.size() - listPropertySize - 1);
- }
+ const int listSize = list.size();
+ const QString elementType = type.mid(listSize, type.size() - listSize - 1).trimmed();
+
+ // QQmlListProperty internally constructs the pointer. Passing an explicit '*' will
+ // produce double pointers. QList is only for value types. We can't handle QLists
+ // of pointers (unless specially registered, but then they're not isList).
+ if (elementType.endsWith(QLatin1Char('*')))
+ return false;
- if (type.endsWith(QLatin1Char('*'))) {
- isPointer = true;
- type = type.left(type.size() - 1);
+ isList = true;
+ type = elementType;
+ return true;
+ };
+
+ if (!handleList(QLatin1String("QQmlListProperty<"))
+ && !handleList(QLatin1String("QList<"))) {
+ if (type.endsWith(QLatin1Char('*'))) {
+ isPointer = true;
+ type = type.left(type.size() - 1);
+ }
}
}
diff --git a/tests/auto/qml/qmlcppcodegen/data/Test.qml b/tests/auto/qml/qmlcppcodegen/data/Test.qml
index d7263a2bff..391360face 100644
--- a/tests/auto/qml/qmlcppcodegen/data/Test.qml
+++ b/tests/auto/qml/qmlcppcodegen/data/Test.qml
@@ -2,6 +2,8 @@ pragma Strict
import TestTypes 1.0
CppBaseClass {
+ id: self
+
enum EE {
AA, BB, CC
}
@@ -14,4 +16,9 @@ CppBaseClass {
// An actual binding. Can't be removed because cppProp may be manually set.
cppProp2: cppProp * 2
+
+ property int a: boo[0]
+ function incA() : void {
+ self.a = self.boo[1];
+ }
}
diff --git a/tests/auto/qml/qmlcppcodegen/data/cppbaseclass.h b/tests/auto/qml/qmlcppcodegen/data/cppbaseclass.h
index 1346ea272b..2b52196298 100644
--- a/tests/auto/qml/qmlcppcodegen/data/cppbaseclass.h
+++ b/tests/auto/qml/qmlcppcodegen/data/cppbaseclass.h
@@ -38,8 +38,16 @@ class CppBaseClass : public QObject
Q_OBJECT
Q_PROPERTY(int cppProp MEMBER cppProp BINDABLE cppPropBindable FINAL)
Q_PROPERTY(int cppProp2 MEMBER cppProp2 BINDABLE cppProp2Bindable FINAL)
+ Q_PROPERTY(QList<int> boo MEMBER boo FINAL CONSTANT)
QML_ELEMENT
public:
+ CppBaseClass(QObject *parent = nullptr)
+ : QObject(parent)
+ {
+ boo.append(16);
+ boo.append(17);
+ }
+
QProperty<int> cppProp;
QBindable<int> cppPropBindable() { return QBindable<int>(&cppProp); }
@@ -47,6 +55,9 @@ public:
QBindable<int> cppProp2Bindable() { return QBindable<int>(&cppProp2); }
Q_INVOKABLE void doCall(QObject *foo);
+
+private:
+ QList<int> boo;
};
inline void CppBaseClass::doCall(QObject *foo)
diff --git a/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp b/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp
index 54be586e24..8733bf6b96 100644
--- a/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp
+++ b/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp
@@ -42,6 +42,7 @@ class tst_QmlCppCodegen : public QObject
Q_OBJECT
private slots:
void simpleBinding();
+ void cppValueTypeList();
void anchorsFill();
void signalHandler();
void idAccess();
@@ -160,6 +161,17 @@ void tst_QmlCppCodegen::simpleBinding()
}
}
+void tst_QmlCppCodegen::cppValueTypeList()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine, QUrl(u"qrc:/TestTypes/Test.qml"_s));
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY2(!object.isNull(), component.errorString().toUtf8().constData());
+ QCOMPARE(object->property("a").toInt(), 16);
+ QMetaObject::invokeMethod(object.data(), "incA");
+ QCOMPARE(object->property("a").toInt(), 17);
+}
+
void tst_QmlCppCodegen::anchorsFill()
{
QQmlEngine engine;