summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2023-05-04 15:54:56 +0200
committerUlf Hermann <ulf.hermann@qt.io>2023-05-09 21:28:06 +0200
commit9cead49c0ede00ffd42759a3897359d317f5a299 (patch)
tree932a114609a3ce33bc176b63778f26fc50aebc6a
parent406a9e1301e2597962ef0564348304be67d2c316 (diff)
downloadqtdeclarative-9cead49c0ede00ffd42759a3897359d317f5a299.tar.gz
Properly support lists as method arguments
a, Teach QV4::QObjectWrapper how to convert QQmlListProperty to QObjectList. b, Parse the isList attribute from qmltypes. c, Resolve lists when resolving QQmlJSScope. Change-Id: I70c6d40507de990b45a87eb7d8c7bba279d550e8 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp5
-rw-r--r--src/qmlcompiler/qqmljsmetatypes_p.h3
-rw-r--r--src/qmlcompiler/qqmljsscope.cpp10
-rw-r--r--src/qmlcompiler/qqmljstypedescriptionreader.cpp7
-rw-r--r--tests/auto/qml/qmlcppcodegen/data/person.h2
-rw-r--r--tests/auto/qml/qmlcppcodegen/data/signalsWithLists.qml10
-rw-r--r--tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp4
7 files changed, 37 insertions, 4 deletions
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index df6f788247..ba94a7ad95 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -2147,6 +2147,11 @@ bool CallArgument::fromValue(QMetaType metaType, ExecutionEngine *engine, const
return true;
}
+ if (const QmlListWrapper *listWrapper = value.as<QmlListWrapper>()) {
+ *qlistPtr = listWrapper->d()->property().toList<QList<QObject *>>();
+ return true;
+ }
+
qlistPtr->append(nullptr);
return value.isNullOrUndefined();
}
diff --git a/src/qmlcompiler/qqmljsmetatypes_p.h b/src/qmlcompiler/qqmljsmetatypes_p.h
index 3153b63578..6d6f9fef36 100644
--- a/src/qmlcompiler/qqmljsmetatypes_p.h
+++ b/src/qmlcompiler/qqmljsmetatypes_p.h
@@ -139,6 +139,8 @@ public:
void setTypeQualifier(Constness typeQualifier) { m_typeQualifier = typeQualifier; }
bool isPointer() const { return m_isPointer; }
void setIsPointer(bool isPointer) { m_isPointer = isPointer; }
+ bool isList() const { return m_isList; }
+ void setIsList(bool isList) { m_isList = isList; }
friend bool operator==(const QQmlJSMetaParameter &a, const QQmlJSMetaParameter &b)
{
@@ -164,6 +166,7 @@ private:
QWeakPointer<const QQmlJSScope> m_type;
Constness m_typeQualifier = NonConst;
bool m_isPointer = false;
+ bool m_isList = false;
};
class QQmlJSMetaMethod
diff --git a/src/qmlcompiler/qqmljsscope.cpp b/src/qmlcompiler/qqmljsscope.cpp
index ca52d60dc1..98ab16b91c 100644
--- a/src/qmlcompiler/qqmljsscope.cpp
+++ b/src/qmlcompiler/qqmljsscope.cpp
@@ -516,9 +516,15 @@ QTypeRevision QQmlJSScope::resolveType(
auto &parameter = parameters[i];
if (const QString typeName = parameter.typeName();
!parameter.type() && !typeName.isEmpty()) {
- const auto type = findType(typeName, context, usedTypes);
- if (type.scope && type.scope->isReferenceType())
+ auto type = findType(typeName, context, usedTypes);
+ if (type.scope && parameter.isList()) {
+ type.scope = type.scope->listType();
+ parameter.setIsList(false);
+ parameter.setIsPointer(false);
+ parameter.setTypeName(type.scope ? type.scope->internalName() : QString());
+ } else if (type.scope && type.scope->isReferenceType()) {
parameter.setIsPointer(true);
+ }
parameter.setType({ type.scope });
}
}
diff --git a/src/qmlcompiler/qqmljstypedescriptionreader.cpp b/src/qmlcompiler/qqmljstypedescriptionreader.cpp
index 77a080f648..f33fb75ec6 100644
--- a/src/qmlcompiler/qqmljstypedescriptionreader.cpp
+++ b/src/qmlcompiler/qqmljstypedescriptionreader.cpp
@@ -439,6 +439,7 @@ void QQmlJSTypeDescriptionReader::readParameter(UiObjectDefinition *ast, QQmlJSM
QString type;
bool isConstant = false;
bool isPointer = false;
+ bool isList = false;
for (UiObjectMemberList *it = ast->initializer->members; it; it = it->next) {
UiObjectMember *member = it->member;
@@ -460,16 +461,18 @@ void QQmlJSTypeDescriptionReader::readParameter(UiObjectDefinition *ast, QQmlJSM
} else if (id == QLatin1String("isReadonly")) {
// ### unhandled
} else if (id == QLatin1String("isList")) {
- // ### unhandled
+ isList = readBoolBinding(script);
} else {
addWarning(script->firstSourceLocation(),
- tr("Expected only name and type script bindings."));
+ tr("Expected only name, type, isPointer, isConstant, isReadonly, "
+ "or IsList script bindings."));
}
}
QQmlJSMetaParameter p(name, type);
p.setTypeQualifier(isConstant ? QQmlJSMetaParameter::Const : QQmlJSMetaParameter::NonConst);
p.setIsPointer(isPointer);
+ p.setIsList(isList);
metaMethod->addParameter(std::move(p));
}
diff --git a/tests/auto/qml/qmlcppcodegen/data/person.h b/tests/auto/qml/qmlcppcodegen/data/person.h
index fba4a9e9a5..b30b7e024b 100644
--- a/tests/auto/qml/qmlcppcodegen/data/person.h
+++ b/tests/auto/qml/qmlcppcodegen/data/person.h
@@ -62,6 +62,8 @@ signals:
void ambiguous(int a = 9);
void cousinsChanged();
+ void objectListHappened(const QList<QObject *> &);
+ void variantListHappened(const QList<QVariant> &);
private:
QString m_name;
diff --git a/tests/auto/qml/qmlcppcodegen/data/signalsWithLists.qml b/tests/auto/qml/qmlcppcodegen/data/signalsWithLists.qml
index 91967e0bc0..9a07b206d4 100644
--- a/tests/auto/qml/qmlcppcodegen/data/signalsWithLists.qml
+++ b/tests/auto/qml/qmlcppcodegen/data/signalsWithLists.qml
@@ -5,4 +5,14 @@ import TestTypes
Person {
property list<var> varlist: [1, "foo", this, undefined, true]
property list<QtObject> objlist: [this, null, this]
+
+ function sendSignals() {
+ variantListHappened(varlist);
+ objectListHappened(objlist);
+ }
+
+ property int happening: 0
+
+ onObjectListHappened: (objects) => { happening += objects.length }
+ onVariantListHappened: (variants) => { happening += variants.length }
}
diff --git a/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp b/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp
index f3869e6e40..5c511ef10c 100644
--- a/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp
+++ b/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp
@@ -3359,6 +3359,10 @@ void tst_QmlCppCodegen::signalsWithLists()
QCOMPARE(objlist.at(&objlist, 0), o.data());
QCOMPARE(objlist.at(&objlist, 1), nullptr);
QCOMPARE(objlist.at(&objlist, 2), o.data());
+
+ QCOMPARE(o->property("happening").toInt(), 0);
+ o->metaObject()->invokeMethod(o.data(), "sendSignals");
+ QCOMPARE(o->property("happening").toInt(), 8);
}
void tst_QmlCppCodegen::signatureIgnored()