aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qmltc
diff options
context:
space:
mode:
authorAndrei Golubev <[email protected]>2022-04-28 11:03:09 +0200
committerAndrei Golubev <[email protected]>2022-06-02 10:07:39 +0200
commit26179e693717535eeff2e7b2a6ee99dc02dcd8f9 (patch)
treed546e470e6047165bff96209e5a8d913bc3abf75 /src/qml/qmltc
parentb85ac05e4ab3ef356ef59f6c57f44855edf15c5c (diff)
Address extension types in qmltc
Whenever working with properties (reading, writing, aliasing, etc.) of the type that has extensions, prefer the same-named properties from extension objects over type-owned properties (this is the internal QML mechanism) To achieve that, we need to query the extension object: * for Q_GADGETs use a dummy model of assuming we can cast the object to the extension type and use that * for Q_OBJECTs use a qmlExtendedObject() with additional logic of figuring out which extension should be picked in each specific case Create QQmlProxyMetaObject via a custom dynamic meta object API for qmltc-compiled objects that are derived from base types with extensions Task-number: QTBUG-91956 Change-Id: I5e783768ae2abdb9dddf894de7e79960244352bd Reviewed-by: Ulf Hermann <[email protected]>
Diffstat (limited to 'src/qml/qmltc')
-rw-r--r--src/qml/qmltc/qqmltcobjectcreationhelper.cpp98
-rw-r--r--src/qml/qmltc/qqmltcobjectcreationhelper_p.h23
2 files changed, 120 insertions, 1 deletions
diff --git a/src/qml/qmltc/qqmltcobjectcreationhelper.cpp b/src/qml/qmltc/qqmltcobjectcreationhelper.cpp
new file mode 100644
index 0000000000..b88b43d7be
--- /dev/null
+++ b/src/qml/qmltc/qqmltcobjectcreationhelper.cpp
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qqmltcobjectcreationhelper_p.h"
+
+#include <private/qqmlmetatype_p.h>
+#include <private/qmetaobjectbuilder_p.h>
+#include <private/qobject_p.h>
+#include <private/qqmltype_p_p.h>
+
+QT_BEGIN_NAMESPACE
+
+void qmltcCreateDynamicMetaObject(QObject *object, const QMetaObject *staticMetaObject,
+ const QmltcTypeData &data)
+{
+ // TODO: when/if qmltc-compiled types would be registered via
+ // qmltyperegistrar, instead of creating a dummy QQmlTypePrivate, fetch the
+ // good QQmlType via QQmlMetaType::qmlType(). to do it correctly, one needs,
+ // along with the meta object, module name and revision. all that should be
+ // available ahead-of-time to qmltc.
+ auto qmlTypePrivate = new QQmlTypePrivate(data.regType);
+ // place the newly created QQmlTypePrivate into the qml meta data storage so
+ // that it is properly deleted
+ QQmlMetaType::registerMetaObjectForType(staticMetaObject, qmlTypePrivate);
+
+ // initialize QQmlType::QQmlCppTypeData
+ Q_ASSERT(data.regType == QQmlType::CppType);
+ qmlTypePrivate->extraData.cd->allocationSize = data.allocationSize;
+ qmlTypePrivate->extraData.cd->newFunc = nullptr;
+ qmlTypePrivate->extraData.cd->userdata = nullptr;
+ qmlTypePrivate->extraData.cd->noCreationReason =
+ QStringLiteral("Qmltc-compiled type is not creatable via QQmlType");
+ qmlTypePrivate->extraData.cd->createValueTypeFunc = nullptr;
+ qmlTypePrivate->extraData.cd->parserStatusCast = -1;
+ qmlTypePrivate->extraData.cd->extFunc = nullptr;
+ qmlTypePrivate->extraData.cd->extMetaObject = nullptr;
+ qmlTypePrivate->extraData.cd->customParser = nullptr;
+ qmlTypePrivate->extraData.cd->attachedPropertiesFunc = nullptr;
+ qmlTypePrivate->extraData.cd->attachedPropertiesType = nullptr;
+ qmlTypePrivate->extraData.cd->propertyValueSourceCast = -1;
+ qmlTypePrivate->extraData.cd->propertyValueInterceptorCast = -1;
+ qmlTypePrivate->extraData.cd->finalizerCast = -1;
+ qmlTypePrivate->extraData.cd->registerEnumClassesUnscoped = false;
+ qmlTypePrivate->extraData.cd->registerEnumsFromRelatedTypes = false;
+
+ qmlTypePrivate->baseMetaObject = data.metaObject;
+ qmlTypePrivate->init();
+
+ QQmlType qmlType(qmlTypePrivate);
+ Q_ASSERT(qmlType.isValid());
+
+ QObjectPrivate *op = QObjectPrivate::get(object);
+ // ### inefficient - rather, call this function only once for the leaf type
+ if (op->metaObject) {
+ delete op->metaObject;
+ op->metaObject = nullptr;
+ }
+
+ qmlType.createProxy(object);
+}
+
+QT_END_NAMESPACE
diff --git a/src/qml/qmltc/qqmltcobjectcreationhelper_p.h b/src/qml/qmltc/qqmltcobjectcreationhelper_p.h
index 6aa37b1e53..56b89925da 100644
--- a/src/qml/qmltc/qqmltcobjectcreationhelper_p.h
+++ b/src/qml/qmltc/qqmltcobjectcreationhelper_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2021 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQml module of the Qt Toolkit.
@@ -53,6 +53,9 @@
#include <QtQml/qqml.h>
#include <QtCore/private/qglobal_p.h>
+#include <QtCore/qversionnumber.h>
+#include <private/qtqmlglobal_p.h>
+#include <private/qqmltype_p.h>
#include <array>
@@ -137,6 +140,24 @@ public:
}
};
+struct QmltcTypeData
+{
+ QQmlType::RegistrationType regType = QQmlType::CppType;
+ int allocationSize = 0;
+ const QMetaObject *metaObject = nullptr;
+
+ template<typename QmltcGeneratedType>
+ QmltcTypeData(QmltcGeneratedType *)
+ : allocationSize(sizeof(QmltcGeneratedType)),
+ metaObject(&QmltcGeneratedType::staticMetaObject)
+ {
+ }
+};
+
+Q_QML_PRIVATE_EXPORT void qmltcCreateDynamicMetaObject(QObject *object,
+ const QMetaObject *staticMetaObject,
+ const QmltcTypeData &data);
+
QT_END_NAMESPACE
#endif // QQMLTCOBJECTCREATIONHELPER_P_H