aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/CMakeLists.txt1
-rw-r--r--src/qml/doc/snippets/qmltc/special/HelloWorld.qml.cpp2
-rw-r--r--src/qml/qmltc/supportlibrary/qqmlcpptypehelpers_p.h28
-rw-r--r--src/qmlcompiler/qqmljsimportvisitor.cpp65
-rw-r--r--src/qmlcompiler/qqmljsmetatypes_p.h3
-rw-r--r--src/qmlcompiler/qqmljsscope.cpp2
-rw-r--r--src/qmlcompiler/qqmljsscope_p.h1
-rw-r--r--src/qmlcompiler/qqmljstypedescriptionreader.cpp6
-rw-r--r--tests/auto/qml/qmltc/QmltcTests/CMakeLists.txt2
-rw-r--r--tests/auto/qml/qmltc/QmltcTests/cpptypes/typewithsignal.h34
-rw-r--r--tests/auto/qml/qmltc/QmltcTests/mySignals.qml27
-rw-r--r--tests/auto/qml/qmltc/tst_qmltc.cpp58
-rw-r--r--tests/auto/qml/qmltc/tst_qmltc.h1
-rw-r--r--tests/auto/qml/qmltc_qprocess/CMakeLists.txt3
-rw-r--r--tests/auto/qml/qmltc_qprocess/cpptypes/testtype.h14
-rw-r--r--tests/auto/qml/qmltc_qprocess/data/invalidSignalHandlers.qml10
-rw-r--r--tests/auto/qml/qmltc_qprocess/tst_qmltc_qprocess.cpp20
-rw-r--r--tools/qmltc/qmltccodewriter.cpp1
-rw-r--r--tools/qmltc/qmltccompiler.cpp28
19 files changed, 294 insertions, 12 deletions
diff --git a/src/qml/CMakeLists.txt b/src/qml/CMakeLists.txt
index 5781b03573..686c9dfb24 100644
--- a/src/qml/CMakeLists.txt
+++ b/src/qml/CMakeLists.txt
@@ -359,6 +359,7 @@ qt_internal_add_qml_module(Qml
qmltc/supportlibrary/qqmlcppbinding.cpp
qmltc/supportlibrary/qqmlcpponassignment_p.h
qmltc/supportlibrary/qqmlcpponassignment.cpp
+ qmltc/supportlibrary/qqmlcpptypehelpers_p.h
DEFINES
BUILDING_QT__
ENABLE_ASSEMBLER_WX_EXCLUSIVE=1
diff --git a/src/qml/doc/snippets/qmltc/special/HelloWorld.qml.cpp b/src/qml/doc/snippets/qmltc/special/HelloWorld.qml.cpp
index 732d915b99..eda9009bb7 100644
--- a/src/qml/doc/snippets/qmltc/special/HelloWorld.qml.cpp
+++ b/src/qml/doc/snippets/qmltc/special/HelloWorld.qml.cpp
@@ -31,7 +31,7 @@ public:
void setHello(const QString& hello_);
QString hello();
QBindable<QString> bindableHello();
- Q_INVOKABLE void printHello(QString prefix, QString suffix);
+ Q_INVOKABLE void printHello(passByConstRefOrValue<QString> prefix, passByConstRefOrValue<QString> suffix);
// ...
};
diff --git a/src/qml/qmltc/supportlibrary/qqmlcpptypehelpers_p.h b/src/qml/qmltc/supportlibrary/qqmlcpptypehelpers_p.h
new file mode 100644
index 0000000000..2470d87efe
--- /dev/null
+++ b/src/qml/qmltc/supportlibrary/qqmlcpptypehelpers_p.h
@@ -0,0 +1,28 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QQMLCPPTYPEHELPERS_H
+#define QQMLCPPTYPEHELPERS_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <type_traits>
+
+/*! \internal
+ Used by Qmltc to decide when value types should be passed by value or reference.
+ */
+template<typename T>
+using passByConstRefOrValue =
+ std::conditional_t<((sizeof(T) > 3 * sizeof(void *)) || !std::is_trivial_v<T>), const T &,
+ T>;
+
+#endif // QQMLCPPTYPEHELPERS_H
diff --git a/src/qmlcompiler/qqmljsimportvisitor.cpp b/src/qmlcompiler/qqmljsimportvisitor.cpp
index 8ce58cdcca..b44550cade 100644
--- a/src/qmlcompiler/qqmljsimportvisitor.cpp
+++ b/src/qmlcompiler/qqmljsimportvisitor.cpp
@@ -986,8 +986,69 @@ void QQmlJSImportVisitor::checkSignals()
const auto signalParameters = signalMethod->parameters();
QHash<QString, qsizetype> parameterNameIndexes;
- for (int i = 0; i < signalParameters.size(); i++)
- parameterNameIndexes[signalParameters[i].name()] = i;
+ // check parameter positions and also if signal is suitable for onSignal handler
+ for (int i = 0, end = signalParameters.size(); i < end; ++i) {
+ auto &p = signalParameters[i];
+ parameterNameIndexes[p.name()] = i;
+
+ auto signalName = [&]() {
+ if (signal)
+ return u" called %1"_s.arg(*signal);
+ return QString();
+ };
+ auto type = p.type();
+ if (!type) {
+ m_logger->log(
+ QStringLiteral(
+ "Type %1 of parameter %2 in signal%3 was not found, but is "
+ "required to compile %4. Did you add all import paths?")
+ .arg(p.typeName(), p.name(), signalName(), pair.first),
+ qmlSignalParameters, location);
+ continue;
+ }
+
+ if (type->isComposite())
+ continue;
+
+ // only accept following parameters for non-composite types:
+ // * QObjects by pointer (nonconst*, const*, const*const,*const)
+ // * Value types by value (QFont, int)
+ // * Value types by const ref (const QFont&, const int&)
+
+ auto parameterName = [&]() {
+ if (p.name().isEmpty())
+ return QString();
+ return u" called %1"_s.arg(p.name());
+ };
+ switch (type->accessSemantics()) {
+ case QQmlJSScope::AccessSemantics::Reference:
+ if (!p.isPointer())
+ m_logger->log(QStringLiteral("Type %1 of parameter%2 in signal%3 should be "
+ "passed by pointer to be able to compile %4. ")
+ .arg(p.typeName(), parameterName(), signalName(),
+ pair.first),
+ qmlSignalParameters, location);
+ break;
+ case QQmlJSScope::AccessSemantics::Value:
+ case QQmlJSScope::AccessSemantics::Sequence:
+ if (p.isPointer())
+ m_logger->log(
+ QStringLiteral(
+ "Type %1 of parameter%2 in signal%3 should be passed by "
+ "value or const reference to be able to compile %4. ")
+ .arg(p.typeName(), parameterName(), signalName(),
+ pair.first),
+ qmlSignalParameters, location);
+ break;
+ case QQmlJSScope::AccessSemantics::None:
+ m_logger->log(
+ QStringLiteral("Type %1 of parameter%2 in signal%3 required by the "
+ "compilation of %4 cannot be used. ")
+ .arg(p.typeName(), parameterName(), signalName(), pair.first),
+ qmlSignalParameters, location);
+ break;
+ }
+ }
if (pair.second.size() > signalParameters.size()) {
m_logger->log(QStringLiteral("Signal handler for \"%2\" has more formal"
diff --git a/src/qmlcompiler/qqmljsmetatypes_p.h b/src/qmlcompiler/qqmljsmetatypes_p.h
index 593a16b0c4..823a1849e5 100644
--- a/src/qmlcompiler/qqmljsmetatypes_p.h
+++ b/src/qmlcompiler/qqmljsmetatypes_p.h
@@ -135,6 +135,8 @@ public:
void setType(QWeakPointer<const QQmlJSScope> type) { m_type = type; }
Constness typeQualifier() const { return m_typeQualifier; }
void setTypeQualifier(Constness typeQualifier) { m_typeQualifier = typeQualifier; }
+ bool isPointer() const { return m_isPointer; }
+ void setIsPointer(bool isPointer) { m_isPointer = isPointer; }
friend bool operator==(const QQmlJSMetaParameter &a, const QQmlJSMetaParameter &b)
{
@@ -159,6 +161,7 @@ private:
QString m_typeName;
QWeakPointer<const QQmlJSScope> m_type;
Constness m_typeQualifier = NonConst;
+ bool m_isPointer = false;
};
class QQmlJSMetaMethod
diff --git a/src/qmlcompiler/qqmljsscope.cpp b/src/qmlcompiler/qqmljsscope.cpp
index ec0a90643d..e3d8bafeb3 100644
--- a/src/qmlcompiler/qqmljsscope.cpp
+++ b/src/qmlcompiler/qqmljsscope.cpp
@@ -508,6 +508,8 @@ QTypeRevision QQmlJSScope::resolveType(
if (const QString typeName = parameter.typeName();
!parameter.type() && !typeName.isEmpty()) {
const auto type = findType(typeName, context, usedTypes);
+ if (type.scope && type.scope->isReferenceType())
+ parameter.setIsPointer(true);
parameter.setType({ type.scope });
}
}
diff --git a/src/qmlcompiler/qqmljsscope_p.h b/src/qmlcompiler/qqmljsscope_p.h
index 9586d1c333..127d58abcc 100644
--- a/src/qmlcompiler/qqmljsscope_p.h
+++ b/src/qmlcompiler/qqmljsscope_p.h
@@ -561,6 +561,7 @@ public:
void setAccessSemantics(AccessSemantics semantics) { m_semantics = semantics; }
AccessSemantics accessSemantics() const { return m_semantics; }
bool isReferenceType() const { return m_semantics == QQmlJSScope::AccessSemantics::Reference; }
+ bool isValueType() const { return m_semantics == QQmlJSScope::AccessSemantics::Value; }
bool isIdInCurrentQmlScopes(const QString &id) const;
bool isIdInCurrentJSScopes(const QString &id) const;
diff --git a/src/qmlcompiler/qqmljstypedescriptionreader.cpp b/src/qmlcompiler/qqmljstypedescriptionreader.cpp
index 6f40b1d42f..8528d39f0f 100644
--- a/src/qmlcompiler/qqmljstypedescriptionreader.cpp
+++ b/src/qmlcompiler/qqmljstypedescriptionreader.cpp
@@ -428,6 +428,7 @@ void QQmlJSTypeDescriptionReader::readParameter(UiObjectDefinition *ast, QQmlJSM
QString name;
QString type;
bool isConstant = false;
+ bool isPointer = false;
for (UiObjectMemberList *it = ast->initializer->members; it; it = it->next) {
UiObjectMember *member = it->member;
@@ -443,9 +444,9 @@ void QQmlJSTypeDescriptionReader::readParameter(UiObjectDefinition *ast, QQmlJSM
} else if (id == QLatin1String("type")) {
type = readStringBinding(script);
} else if (id == QLatin1String("isPointer")) {
- // ### unhandled
+ isPointer = readBoolBinding(script);
} else if (id == QLatin1String("isConstant")) {
- isConstant = true;
+ isConstant = readBoolBinding(script);
} else if (id == QLatin1String("isReadonly")) {
// ### unhandled
} else if (id == QLatin1String("isList")) {
@@ -458,6 +459,7 @@ void QQmlJSTypeDescriptionReader::readParameter(UiObjectDefinition *ast, QQmlJSM
QQmlJSMetaParameter p(name, type);
p.setTypeQualifier(isConstant ? QQmlJSMetaParameter::Const : QQmlJSMetaParameter::NonConst);
+ p.setIsPointer(isPointer);
metaMethod->addParameter(std::move(p));
}
diff --git a/tests/auto/qml/qmltc/QmltcTests/CMakeLists.txt b/tests/auto/qml/qmltc/QmltcTests/CMakeLists.txt
index e81364d3e5..dc9a25a33a 100644
--- a/tests/auto/qml/qmltc/QmltcTests/CMakeLists.txt
+++ b/tests/auto/qml/qmltc/QmltcTests/CMakeLists.txt
@@ -20,6 +20,7 @@ set(cpp_sources
cpptypes/typewithmanyproperties.h
cpptypes/singletontype.h cpptypes/singletontype.cpp
+ cpptypes/typewithsignal.h
)
set(qml_sources
@@ -105,6 +106,7 @@ set(qml_sources
aliases.qml
inlineComponentsFromDifferentFiles.qml
singletons.qml
+ mySignals.qml
# support types:
DefaultPropertySingleChild.qml
diff --git a/tests/auto/qml/qmltc/QmltcTests/cpptypes/typewithsignal.h b/tests/auto/qml/qmltc/QmltcTests/cpptypes/typewithsignal.h
new file mode 100644
index 0000000000..139b431a40
--- /dev/null
+++ b/tests/auto/qml/qmltc/QmltcTests/cpptypes/typewithsignal.h
@@ -0,0 +1,34 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef TYPEWITHSIGNAL_H
+#define TYPEWITHSIGNAL_H
+
+#include <QtCore/qobject.h>
+#include <QtQml/qqmlregistration.h>
+#include <QtGui/qfont.h>
+
+class TypeWithSignal : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+
+Q_SIGNALS:
+ // value types by value
+ void signalWithPrimitive(int);
+ void signalWithGadget(QFont);
+
+ // value types by const reference
+ void signalWithConstReferenceToGadget(const QFont &);
+ void signalWithConstReferenceToPrimitive(const int &);
+
+ // object by pointers
+ void signalWithPointer(QObject *);
+ void signalWithPointerToConst(const QObject *);
+ void signalWithPointerToConst2(QObject const *);
+ void signalWithConstPointer(QObject *const);
+ void signalWithConstPointerToConst(const QObject *const);
+ void signalWithConstPointerToConst2(QObject const *const);
+};
+
+#endif // TYPEWITHSIGNAL_H
diff --git a/tests/auto/qml/qmltc/QmltcTests/mySignals.qml b/tests/auto/qml/qmltc/QmltcTests/mySignals.qml
new file mode 100644
index 0000000000..c79a0518c2
--- /dev/null
+++ b/tests/auto/qml/qmltc/QmltcTests/mySignals.qml
@@ -0,0 +1,27 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QmltcTests
+import QtQuick
+
+
+TypeWithSignal {
+ property int primitive
+ property font gadget
+ property QtObject object
+
+ // value types by value
+ onSignalWithPrimitive: (x) => { primitive = x; }
+ onSignalWithGadget: (x) => { gadget = x; }
+
+ // value types by const reference
+ onSignalWithConstReferenceToGadget: (x) => { gadget = x; }
+
+ // object by pointers
+ onSignalWithPointer: (x) => { object = x; }
+ onSignalWithPointerToConst: (x) => { object = x; }
+ onSignalWithPointerToConst2: (x) => { object = x; }
+ onSignalWithConstPointer: (x) => { object = x; }
+ onSignalWithConstPointerToConst: (x) => { object = x; }
+ onSignalWithConstPointerToConst2: (x) => { object = x; }
+}
diff --git a/tests/auto/qml/qmltc/tst_qmltc.cpp b/tests/auto/qml/qmltc/tst_qmltc.cpp
index af03af264c..06d63333fc 100644
--- a/tests/auto/qml/qmltc/tst_qmltc.cpp
+++ b/tests/auto/qml/qmltc/tst_qmltc.cpp
@@ -80,6 +80,7 @@
#include "testprivateproperty.h"
#include "singletons.h"
+#include "mysignals.h"
// Qt:
#include <QtCore/qstring.h>
@@ -3124,4 +3125,61 @@ void tst_qmltc::singletons()
QCOMPARE(createdByComponent->property("qmlSingleton2"), 100);
}
}
+
+void tst_qmltc::constSignalParameters()
+{
+ QQmlEngine e;
+ PREPEND_NAMESPACE(mySignals) fromQmltc(&e);
+
+ int primitive = 123;
+ QFont defaultGadget;
+ QFont gadget;
+ gadget.setBold(true);
+ QQuickItem myItem;
+ myItem.setObjectName("New Name");
+
+ // by value
+ fromQmltc.setPrimitive(123);
+ emit fromQmltc.signalWithPrimitive(primitive);
+ QCOMPARE(fromQmltc.primitive(), primitive);
+
+ fromQmltc.setGadget(defaultGadget);
+ emit fromQmltc.signalWithGadget(gadget);
+ QCOMPARE(fromQmltc.gadget(), gadget);
+
+ // by const ref
+ fromQmltc.setPrimitive(123);
+ emit fromQmltc.signalWithConstReferenceToPrimitive(primitive);
+ QCOMPARE(fromQmltc.primitive(), primitive);
+
+ fromQmltc.setGadget(defaultGadget);
+ emit fromQmltc.signalWithConstReferenceToGadget(gadget);
+ QCOMPARE(fromQmltc.gadget(), gadget);
+
+ // by pointer
+ fromQmltc.setObject(nullptr);
+ emit fromQmltc.signalWithPointer(&myItem);
+ QCOMPARE(fromQmltc.object(), &myItem);
+
+ fromQmltc.setObject(nullptr);
+ emit fromQmltc.signalWithPointerToConst(&myItem);
+ QCOMPARE(fromQmltc.object(), &myItem);
+
+ fromQmltc.setObject(nullptr);
+ emit fromQmltc.signalWithPointerToConst2(&myItem);
+ QCOMPARE(fromQmltc.object(), &myItem);
+
+ fromQmltc.setObject(nullptr);
+ emit fromQmltc.signalWithConstPointer(&myItem);
+ QCOMPARE(fromQmltc.object(), &myItem);
+
+ fromQmltc.setObject(nullptr);
+ emit fromQmltc.signalWithConstPointerToConst(&myItem);
+ QCOMPARE(fromQmltc.object(), &myItem);
+
+ fromQmltc.setObject(nullptr);
+ emit fromQmltc.signalWithConstPointerToConst2(&myItem);
+ QCOMPARE(fromQmltc.object(), &myItem);
+}
+
QTEST_MAIN(tst_qmltc)
diff --git a/tests/auto/qml/qmltc/tst_qmltc.h b/tests/auto/qml/qmltc/tst_qmltc.h
index ff55401c14..05a05bf9b6 100644
--- a/tests/auto/qml/qmltc/tst_qmltc.h
+++ b/tests/auto/qml/qmltc/tst_qmltc.h
@@ -90,4 +90,5 @@ private slots:
void aliases();
void inlineComponentsFromDifferentFiles();
void singletons();
+ void constSignalParameters();
};
diff --git a/tests/auto/qml/qmltc_qprocess/CMakeLists.txt b/tests/auto/qml/qmltc_qprocess/CMakeLists.txt
index 04d2084d4f..d936e2c757 100644
--- a/tests/auto/qml/qmltc_qprocess/CMakeLists.txt
+++ b/tests/auto/qml/qmltc_qprocess/CMakeLists.txt
@@ -20,6 +20,8 @@ qt6_add_qml_module(tst_qmltc_qprocess
AUTO_RESOURCE_PREFIX
SOURCES
cpptypes/testtype.h
+ DEPENDENCIES
+ QtQuick/auto
QML_FILES
data/dummy.qml
data/inlineComponentInvalidAlias.qml
@@ -30,6 +32,7 @@ qt6_add_qml_module(tst_qmltc_qprocess
data/inlineComponentWithEnum.qml
data/singletonUncreatable.qml
data/uncreatable.qml
+ data/invalidSignalHandlers.qml
)
set(common_libraries
diff --git a/tests/auto/qml/qmltc_qprocess/cpptypes/testtype.h b/tests/auto/qml/qmltc_qprocess/cpptypes/testtype.h
index 6082870c76..2130004def 100644
--- a/tests/auto/qml/qmltc_qprocess/cpptypes/testtype.h
+++ b/tests/auto/qml/qmltc_qprocess/cpptypes/testtype.h
@@ -7,6 +7,7 @@
#include <QtQmlIntegration/qqmlintegration.h>
#include <QtCore/qobject.h>
#include <QtQml/qqmlregistration.h>
+#include <QtGui/qfont.h>
class TypeWithVersionedAlias : public QObject
{
@@ -67,6 +68,19 @@ class NormalType : public QObject
}
};
+class TypeWithSignals : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+public:
+Q_SIGNALS:
+ void signalWithConstPointerToGadget(const QFont *); // not allowed
+ void signalWithConstPointerToGadgetConst(const QFont *const); // not allowed
+ void signalWithPointerToGadgetConst(QFont *const); // not allowed
+ void signalWithPointerToGadget(QFont *); // not allowed
+ void signalWithPrimitivePointer(int *);
+ void signalWithConstPrimitivePointer(const int *);
+};
#endif // TESTTYPE_H
diff --git a/tests/auto/qml/qmltc_qprocess/data/invalidSignalHandlers.qml b/tests/auto/qml/qmltc_qprocess/data/invalidSignalHandlers.qml
new file mode 100644
index 0000000000..a2a100ab3b
--- /dev/null
+++ b/tests/auto/qml/qmltc_qprocess/data/invalidSignalHandlers.qml
@@ -0,0 +1,10 @@
+
+TypeWithSignals
+{
+ onSignalWithConstPointerToGadget: (x) => { console.log(x); }
+ onSignalWithConstPointerToGadgetConst: (x) => { console.log(x); }
+ onSignalWithPointerToGadgetConst: (x) => { console.log(x); }
+ onSignalWithPointerToGadget: (x) => { console.log(x); }
+ onSignalWithPrimitivePointer: (x) => { console.log(x); }
+ onSignalWithConstPrimitivePointer: (x) => { console.log(x); }
+}
diff --git a/tests/auto/qml/qmltc_qprocess/tst_qmltc_qprocess.cpp b/tests/auto/qml/qmltc_qprocess/tst_qmltc_qprocess.cpp
index 04b3426298..1cea44206f 100644
--- a/tests/auto/qml/qmltc_qprocess/tst_qmltc_qprocess.cpp
+++ b/tests/auto/qml/qmltc_qprocess/tst_qmltc_qprocess.cpp
@@ -50,6 +50,7 @@ private slots:
void invalidAliasRevision();
void topLevelComponent();
void dashesInFilename();
+ void invalidSignalHandlers();
};
#ifndef TST_QMLTC_QPROCESS_RESOURCES
@@ -241,5 +242,24 @@ void tst_qmltc_qprocess::dashesInFilename()
}
}
+void tst_qmltc_qprocess::invalidSignalHandlers()
+{
+ {
+ const auto errors = runQmltc(u"invalidSignalHandlers.qml"_s, false);
+ QVERIFY(errors.contains(
+ u"invalidSignalHandlers.qml:4:5: Type QFont of parameter in signal called signalWithConstPointerToGadget should be passed by value or const reference to be able to compile onSignalWithConstPointerToGadget. [signal-handler-parameters]"_s));
+ QVERIFY(errors.contains(
+ u"invalidSignalHandlers.qml:5:5: Type QFont of parameter in signal called signalWithConstPointerToGadgetConst should be passed by value or const reference to be able to compile onSignalWithConstPointerToGadgetConst. [signal-handler-parameters]"_s));
+ QVERIFY(errors.contains(
+ u"invalidSignalHandlers.qml:6:5: Type QFont of parameter in signal called signalWithPointerToGadgetConst should be passed by value or const reference to be able to compile onSignalWithPointerToGadgetConst. [signal-handler-parameters]"_s));
+ QVERIFY(errors.contains(
+ u"invalidSignalHandlers.qml:7:5: Type QFont of parameter in signal called signalWithPointerToGadget should be passed by value or const reference to be able to compile onSignalWithPointerToGadget. [signal-handler-parameters]"_s));
+ QVERIFY(errors.contains(
+ u"invalidSignalHandlers.qml:8:5: Type int of parameter in signal called signalWithPrimitivePointer should be passed by value or const reference to be able to compile onSignalWithPrimitivePointer. [signal-handler-parameters]"_s));
+ QVERIFY(errors.contains(
+ u"invalidSignalHandlers.qml:9:5: Type int of parameter in signal called signalWithConstPrimitivePointer should be passed by value or const reference to be able to compile onSignalWithConstPrimitivePointer. [signal-handler-parameters]"_s));
+ }
+}
+
QTEST_MAIN(tst_qmltc_qprocess)
#include "tst_qmltc_qprocess.moc"
diff --git a/tools/qmltc/qmltccodewriter.cpp b/tools/qmltc/qmltccodewriter.cpp
index 68bd803b15..c4c5c30f83 100644
--- a/tools/qmltc/qmltccodewriter.cpp
+++ b/tools/qmltc/qmltccodewriter.cpp
@@ -137,6 +137,7 @@ void QmltcCodeWriter::writeGlobalHeader(QmltcOutputWrapper &code, const QString
code.rawAppendToCpp(u"// qmltc support library:");
code.rawAppendToCpp(u"#include <private/qqmlcppbinding_p.h>"); // QmltcSupportLib
code.rawAppendToCpp(u"#include <private/qqmlcpponassignment_p.h>"); // QmltcSupportLib
+ code.rawAppendToHeader(u"#include <private/qqmlcpptypehelpers_p.h> "); // QmltcSupportLib
code.rawAppendToCpp(u"#include <private/qqmlobjectcreator_p.h>"); // createComponent()
code.rawAppendToCpp(u"#include <private/qqmlcomponent_p.h>"); // QQmlComponentPrivate::get()
diff --git a/tools/qmltc/qmltccompiler.cpp b/tools/qmltc/qmltccompiler.cpp
index a69f8619e9..4050136ef2 100644
--- a/tools/qmltc/qmltccompiler.cpp
+++ b/tools/qmltc/qmltccompiler.cpp
@@ -425,7 +425,24 @@ compileMethodParameters(const QList<QQmlJSMetaParameter> &parameterInfos, bool a
Q_ASSERT(allowUnnamed || !name.isEmpty()); // assume verified
if (name.isEmpty() && allowUnnamed)
name = u"unnamed_" + QString::number(i);
- parameters.emplaceBack(p.type()->augmentedInternalName(), name, QString());
+
+ QString internalName;
+ const QQmlJSScope::AccessSemantics semantics = p.type()->accessSemantics();
+
+ switch (semantics) {
+ case QQmlJSScope::AccessSemantics::Reference:
+ if (p.typeQualifier() == QQmlJSMetaParameter::Const)
+ internalName = u"const "_s;
+ internalName += u"%1*"_s.arg(p.type()->internalName());
+ break;
+ case QQmlJSScope::AccessSemantics::Value:
+ case QQmlJSScope::AccessSemantics::Sequence:
+ internalName = u"passByConstRefOrValue<%1>"_s.arg(p.type()->internalName());
+ break;
+ case QQmlJSScope::AccessSemantics::None:
+ Q_ASSERT(false); // or maybe print an error message
+ }
+ parameters.emplaceBack(internalName, name, QString());
}
return parameters;
}
@@ -1658,12 +1675,9 @@ void QmltcCompiler::compileScriptBinding(QmltcType &current,
slotMethod.type = QQmlJSMetaMethod::Slot;
current.functions << std::move(slotMethod);
- current.setComplexBindings.body
- << u"QObject::connect(" + This_signal + u", "
- + QmltcCodeGenerator::wrap_qOverload(
- slotParameters, u"&" + objectClassName_signal + u"::" + signalName)
- + u", " + This_slot + u", &" + objectClassName_slot + u"::" + slotName
- + u");";
+ current.setComplexBindings.body << u"QObject::connect(" + This_signal + u", " + u"&"
+ + objectClassName_signal + u"::" + signalName + u", " + This_slot + u", &"
+ + objectClassName_slot + u"::" + slotName + u");";
};
switch (binding.scriptKind()) {