QML: Take care of QVariant when converting function arguments
We cannot convert to QVariant using QMetaType::convert(). But we can just construct a QVariant with the desired type and data. This will become an issue once we automatically convert argument types to match the desired type inside the function. As a side effect, also allow declaring "var" arguments to functions. Change-Id: Idc14021d8d85d3d09ee7b7f286de91b56ea02bfd Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
parent
6b5aa14596
commit
c8e756e560
|
@ -271,9 +271,9 @@ Notice the parameter and return type specified after the colon. You can use \l
|
|||
{QML Value Types}{value types} and \l {QML Object Types}{object types} as type
|
||||
names.
|
||||
|
||||
If the type is omitted in QML, then you must specify QVariant as type with
|
||||
Q_RETURN_ARG() and Q_ARG() when calling QMetaObject::invokeMethod.
|
||||
|
||||
If the type is omitted or specified as \c var in QML, then you must pass
|
||||
QVariant as type with Q_RETURN_ARG() and Q_ARG() when calling
|
||||
QMetaObject::invokeMethod.
|
||||
|
||||
\section2 Connecting to QML Signals
|
||||
|
||||
|
|
|
@ -461,9 +461,17 @@ void VME::exec(MetaTypesStackFrame *frame, ExecutionEngine *engine)
|
|||
|
||||
Q_ASSERT(argumentType.sizeOf() > 0);
|
||||
Q_ALLOCA_VAR(void, arg, argumentType.sizeOf());
|
||||
|
||||
if (argumentType == QMetaType::fromType<QVariant>()) {
|
||||
if (frame->argc() > i)
|
||||
new (arg) QVariant(frame->argTypes()[i], frame->argv()[i]);
|
||||
else
|
||||
new (arg) QVariant();
|
||||
} else {
|
||||
argumentType.construct(arg);
|
||||
if (frame->argc() > i)
|
||||
QMetaType::convert(frame->argTypes()[i], frame->argv()[i], argumentType, arg);
|
||||
}
|
||||
|
||||
transformedArguments[i] = arg;
|
||||
}
|
||||
|
|
|
@ -1680,6 +1680,9 @@ Type: UiQualifiedId;
|
|||
} break;
|
||||
./
|
||||
|
||||
Type: T_VAR;
|
||||
/. case $rule_number: Q_FALLTHROUGH(); ./
|
||||
|
||||
Type: T_VOID;
|
||||
/.
|
||||
case $rule_number: {
|
||||
|
|
|
@ -4,7 +4,7 @@ qt_internal_add_test(tst_qmlcppcodegen
|
|||
SOURCES
|
||||
tst_qmlcppcodegen.cpp
|
||||
LIBRARIES
|
||||
Qt::Qml
|
||||
Qt::QmlPrivate
|
||||
Qt::Gui
|
||||
codegen_test_module
|
||||
codegen_test_moduleplugin
|
||||
|
|
|
@ -65,6 +65,7 @@ set(qml_files
|
|||
functionLookup.qml
|
||||
funcWithParams.qml
|
||||
functionReturningVoid.qml
|
||||
functionTakingVar.qml
|
||||
globals.qml
|
||||
idAccess.qml
|
||||
immediateQuit.qml
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
pragma Strict
|
||||
import QtQml
|
||||
|
||||
QtObject {
|
||||
property var c;
|
||||
|
||||
function a(b: var) {
|
||||
c = b;
|
||||
}
|
||||
|
||||
}
|
|
@ -23,6 +23,8 @@
|
|||
#include <data/cppbaseclass.h>
|
||||
#include <data/objectwithmethod.h>
|
||||
|
||||
#include <QtQml/private/qqmlengine_p.h>
|
||||
|
||||
#include <QtTest>
|
||||
#include <QtQml>
|
||||
#include <QtGui/qcolor.h>
|
||||
|
@ -121,6 +123,7 @@ private slots:
|
|||
void blockComments();
|
||||
void functionLookup();
|
||||
void objectInVar();
|
||||
void functionTakingVar();
|
||||
};
|
||||
|
||||
void tst_QmlCppCodegen::simpleBinding()
|
||||
|
@ -1824,6 +1827,26 @@ void tst_QmlCppCodegen::objectInVar()
|
|||
QVERIFY(!result);
|
||||
}
|
||||
|
||||
void tst_QmlCppCodegen::functionTakingVar()
|
||||
{
|
||||
QQmlEngine engine;
|
||||
const QUrl document(u"qrc:/TestTypes/functionTakingVar.qml"_qs);
|
||||
QQmlComponent c(&engine, document);
|
||||
QVERIFY2(c.isReady(), qPrintable(c.errorString()));
|
||||
QScopedPointer<QObject> o(c.create());
|
||||
QVERIFY(o);
|
||||
|
||||
QVERIFY(!o->property("c").isValid());
|
||||
|
||||
int value = 11;
|
||||
QQmlEnginePrivate *e = QQmlEnginePrivate::get(&engine);
|
||||
void *args[] = { nullptr, reinterpret_cast<void *>(std::addressof(value)) };
|
||||
QMetaType types[] = { QMetaType::fromType<void>(), QMetaType::fromType<std::decay_t<int>>() };
|
||||
e->executeRuntimeFunction(document, 0, o.data(), 1, args, types);
|
||||
|
||||
QCOMPARE(o->property("c"), QVariant::fromValue<int>(11));
|
||||
}
|
||||
|
||||
void tst_QmlCppCodegen::runInterpreted()
|
||||
{
|
||||
if (qEnvironmentVariableIsSet("QV4_FORCE_INTERPRETER"))
|
||||
|
|
Loading…
Reference in New Issue