diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2023-05-04 15:54:56 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2023-05-09 21:28:06 +0200 |
commit | 9cead49c0ede00ffd42759a3897359d317f5a299 (patch) | |
tree | 932a114609a3ce33bc176b63778f26fc50aebc6a | |
parent | 406a9e1301e2597962ef0564348304be67d2c316 (diff) | |
download | qtdeclarative-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.cpp | 5 | ||||
-rw-r--r-- | src/qmlcompiler/qqmljsmetatypes_p.h | 3 | ||||
-rw-r--r-- | src/qmlcompiler/qqmljsscope.cpp | 10 | ||||
-rw-r--r-- | src/qmlcompiler/qqmljstypedescriptionreader.cpp | 7 | ||||
-rw-r--r-- | tests/auto/qml/qmlcppcodegen/data/person.h | 2 | ||||
-rw-r--r-- | tests/auto/qml/qmlcppcodegen/data/signalsWithLists.qml | 10 | ||||
-rw-r--r-- | tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp | 4 |
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 ¶meter = 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() |