Split QML registration macros into their own module

This allows modules to mark objects to be registered with QML, without
depending on qtdeclarative. A library using that module can then be
passed to qt6_generate_foreign_qml_types to add its types to a dedicated
QML library.

Fixes: QTBUG-92258
Change-Id: I8f9071a974902186088e12c1e7848ea138f85716
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
This commit is contained in:
Fabian Kosmale 2021-11-25 14:54:08 +01:00
parent a9d571e847
commit fa1ba8ed8e
7 changed files with 167 additions and 95 deletions

View File

@ -6,6 +6,7 @@ if (NOT QT_FEATURE_commandlineparser)
endif()
add_subdirectory(qmltyperegistrar)
add_subdirectory(qmlintegration)
add_subdirectory(qml)
add_subdirectory(qmlmodels)

View File

@ -386,6 +386,7 @@ qt_internal_add_qml_module(Qml
Qt::CorePrivate
PUBLIC_LIBRARIES
Qt::Core
Qt::QmlIntegration
PRIVATE_MODULE_INTERFACE
Qt::CorePrivate
EXTRA_CMAKE_FILES

View File

@ -824,10 +824,6 @@ struct QmlTypeAndRevisionsRegistration<T, Resolved, void, false, true, false> {
}
};
template<typename T = void, typename... Args>
void qmlRegisterTypesAndRevisions(const char *uri, int versionMajor,
QList<int> *qmlTypeIds = nullptr);
template<typename T, typename... Args>
void qmlRegisterTypesAndRevisions(const char *uri, int versionMajor, QList<int> *qmlTypeIds)
{

View File

@ -41,86 +41,11 @@
#define QQMLREGISTRATION_H
#include <QtCore/qglobal.h>
#include <QtQmlIntegration/qqmlintegration.h>
// satisfy configure, which warns about public headers not using those
QT_BEGIN_NAMESPACE
#define QML_PRIVATE_NAMESPACE \
QT_PREPEND_NAMESPACE(QQmlPrivate)
#define QML_REGISTER_TYPES_AND_REVISIONS \
QT_PREPEND_NAMESPACE(qmlRegisterTypesAndRevisions)
#define QML_ELEMENT \
Q_CLASSINFO("QML.Element", "auto")
#define QML_ANONYMOUS \
Q_CLASSINFO("QML.Element", "anonymous")
#define QML_NAMED_ELEMENT(NAME) \
Q_CLASSINFO("QML.Element", #NAME)
#define QML_VALUE_TYPE(NAME) \
Q_CLASSINFO("QML.Element", #NAME) \
QML_UNCREATABLE("Value types cannot be created.")
#define QML_UNCREATABLE(REASON) \
Q_CLASSINFO("QML.Creatable", "false") \
Q_CLASSINFO("QML.UncreatableReason", REASON)
#define QML_SINGLETON \
Q_CLASSINFO("QML.Singleton", "true") \
enum class QmlIsSingleton {yes = true}; \
template<typename, typename> friend struct QML_PRIVATE_NAMESPACE::QmlSingleton; \
template<typename T, typename... Args> \
friend void QML_REGISTER_TYPES_AND_REVISIONS(const char *uri, int versionMajor, QList<int> *);
#define QML_SEQUENTIAL_CONTAINER(VALUE_TYPE) \
Q_CLASSINFO("QML.Sequence", #VALUE_TYPE) \
using QmlSequenceValueType = VALUE_TYPE; \
enum class QmlIsSequence {yes = true}; \
template<typename, typename> friend struct QML_PRIVATE_NAMESPACE::QmlSequence; \
template<typename T, typename... Args> \
friend void QML_REGISTER_TYPES_AND_REVISIONS(const char *uri, int versionMajor, QList<int> *);
#define QML_ADDED_IN_MINOR_VERSION(VERSION) \
Q_CLASSINFO("QML.AddedInVersion", Q_REVISION(VERSION))
#define QML_ADDED_IN_VERSION(MAJOR, MINOR) \
Q_CLASSINFO("QML.AddedInVersion", Q_REVISION(MAJOR, MINOR))
#define QML_EXTRA_VERSION(MAJOR, MINOR) \
Q_CLASSINFO("QML.ExtraVersion", Q_REVISION(MAJOR, MINOR))
#define QML_REMOVED_IN_MINOR_VERSION(VERSION) \
Q_CLASSINFO("QML.RemovedInVersion", Q_REVISION(VERSION))
#define QML_REMOVED_IN_VERSION(MAJOR, MINOR) \
Q_CLASSINFO("QML.RemovedInVersion", Q_REVISION(MAJOR, MINOR))
#define QML_ATTACHED(ATTACHED_TYPE) \
Q_CLASSINFO("QML.Attached", #ATTACHED_TYPE) \
using QmlAttachedType = ATTACHED_TYPE; \
template<class, class, bool> friend struct QML_PRIVATE_NAMESPACE::QmlAttached; \
template<class> friend struct QML_PRIVATE_NAMESPACE::QmlAttachedAccessor;
#define QML_EXTENDED(EXTENDED_TYPE) \
Q_CLASSINFO("QML.Extended", #EXTENDED_TYPE) \
using QmlExtendedType = EXTENDED_TYPE; \
template<class, class> friend struct QML_PRIVATE_NAMESPACE::QmlExtended; \
template<typename T, typename... Args> \
friend void QML_REGISTER_TYPES_AND_REVISIONS(const char *uri, int versionMajor, QList<int> *);
#define QML_EXTENDED_NAMESPACE(EXTENDED_NAMESPACE) \
Q_CLASSINFO("QML.Extended", #EXTENDED_NAMESPACE) \
static constexpr const QMetaObject *qmlExtendedNamespace() { return &EXTENDED_NAMESPACE::staticMetaObject; } \
template<class, class> friend struct QML_PRIVATE_NAMESPACE::QmlExtendedNamespace; \
template<typename T, typename... Args> \
friend void QML_REGISTER_TYPES_AND_REVISIONS(const char *uri, int versionMajor, QList<int> *);
#define QML_NAMESPACE_EXTENDED(EXTENDED_NAMESPACE) \
Q_CLASSINFO("QML.Extended", #EXTENDED_NAMESPACE)
#define QML_FOREIGN(FOREIGN_TYPE) \
Q_CLASSINFO("QML.Foreign", #FOREIGN_TYPE) \
using QmlForeignType = FOREIGN_TYPE; \
@ -131,21 +56,6 @@ QT_BEGIN_NAMESPACE
#define QML_FOREIGN_NAMESPACE(FOREIGN_NAMESPACE) \
Q_CLASSINFO("QML.Foreign", #FOREIGN_NAMESPACE)
#define QML_INTERFACE \
Q_CLASSINFO("QML.Element", "anonymous") \
enum class QmlIsInterface {yes = true}; \
template<typename, typename> friend struct QML_PRIVATE_NAMESPACE::QmlInterface; \
template<typename T, typename... Args> \
friend void QML_REGISTER_TYPES_AND_REVISIONS(const char *uri, int versionMajor, QList<int> *);
#define QML_IMPLEMENTS_INTERFACES(INTERFACES) \
Q_INTERFACES(INTERFACES) \
enum class QmlIsInterface {yes = false}; \
template<typename, typename> friend struct QML_PRIVATE_NAMESPACE::QmlInterface;
#define QML_UNAVAILABLE \
QML_FOREIGN(QQmlTypeNotAvailable)
#define QML_CUSTOMPARSER Q_CLASSINFO("QML.HasCustomParser", "true")
QT_END_NAMESPACE

View File

@ -0,0 +1,7 @@
qt_internal_add_module(QmlIntegration
HEADER_MODULE
SOURCES
qqmlintegration.h
LIBRARIES
Qt::Core
)

View File

@ -0,0 +1,156 @@
/****************************************************************************
**
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQmlIntegration 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$
**
****************************************************************************/
#ifndef QMLINTEGRATION_H
#define QMLINTEGRATION_H
#include <QtCore/qglobal.h>
// forward declarations of structs and functions defined in QtQml
QT_BEGIN_NAMESPACE
namespace QQmlPrivate {
template<typename, typename> struct QmlSingleton;
template<class, class, bool> struct QmlAttached;
template<class> struct QmlAttachedAccessor;
template<class, class> struct QmlExtended;
template<typename, typename> struct QmlInterface;
}
template <typename T> class QList;
template<typename T = void, typename... Args>
void qmlRegisterTypesAndRevisions(const char *uri, int versionMajor,
QList<int> *qmlTypeIds = nullptr);
QT_END_NAMESPACE
#define QML_PRIVATE_NAMESPACE \
QT_PREPEND_NAMESPACE(QQmlPrivate)
#define QML_REGISTER_TYPES_AND_REVISIONS \
QT_PREPEND_NAMESPACE(qmlRegisterTypesAndRevisions)
#define QML_ELEMENT \
Q_CLASSINFO("QML.Element", "auto")
#define QML_ANONYMOUS \
Q_CLASSINFO("QML.Element", "anonymous")
#define QML_NAMED_ELEMENT(NAME) \
Q_CLASSINFO("QML.Element", #NAME)
#define QML_UNCREATABLE(REASON) \
Q_CLASSINFO("QML.Creatable", "false") \
Q_CLASSINFO("QML.UncreatableReason", REASON)
#define QML_VALUE_TYPE(NAME) \
Q_CLASSINFO("QML.Element", #NAME) \
QML_UNCREATABLE("Value types cannot be created.")
#define QML_SINGLETON \
Q_CLASSINFO("QML.Singleton", "true") \
enum class QmlIsSingleton {yes = true}; \
template<typename, typename> friend struct QML_PRIVATE_NAMESPACE::QmlSingleton; \
template<typename T, typename... Args> \
friend void QML_REGISTER_TYPES_AND_REVISIONS(const char *uri, int versionMajor, QList<int> *);
#define QML_ADDED_IN_MINOR_VERSION(VERSION) \
Q_CLASSINFO("QML.AddedInVersion", Q_REVISION(VERSION))
#define QML_ADDED_IN_VERSION(MAJOR, MINOR) \
Q_CLASSINFO("QML.AddedInVersion", Q_REVISION(MAJOR, MINOR))
#define QML_EXTRA_VERSION(MAJOR, MINOR) \
Q_CLASSINFO("QML.ExtraVersion", Q_REVISION(MAJOR, MINOR))
#define QML_REMOVED_IN_MINOR_VERSION(VERSION) \
Q_CLASSINFO("QML.RemovedInVersion", Q_REVISION(VERSION))
#define QML_REMOVED_IN_VERSION(MAJOR, MINOR) \
Q_CLASSINFO("QML.RemovedInVersion", Q_REVISION(MAJOR, MINOR))
#define QML_ATTACHED(ATTACHED_TYPE) \
Q_CLASSINFO("QML.Attached", #ATTACHED_TYPE) \
using QmlAttachedType = ATTACHED_TYPE; \
template<class, class, bool> friend struct QML_PRIVATE_NAMESPACE::QmlAttached; \
template<class> friend struct QML_PRIVATE_NAMESPACE::QmlAttachedAccessor;
#define QML_EXTENDED(EXTENDED_TYPE) \
Q_CLASSINFO("QML.Extended", #EXTENDED_TYPE) \
using QmlExtendedType = EXTENDED_TYPE; \
template<class, class> friend struct QML_PRIVATE_NAMESPACE::QmlExtended; \
template<typename T, typename... Args> \
friend void QML_REGISTER_TYPES_AND_REVISIONS(const char *uri, int versionMajor, QList<int> *);
#define QML_EXTENDED_NAMESPACE(EXTENDED_NAMESPACE) \
Q_CLASSINFO("QML.Extended", #EXTENDED_NAMESPACE) \
static constexpr const QMetaObject *qmlExtendedNamespace() { return &EXTENDED_NAMESPACE::staticMetaObject; } \
template<class, class> friend struct QML_PRIVATE_NAMESPACE::QmlExtendedNamespace; \
template<typename T, typename... Args> \
friend void QML_REGISTER_TYPES_AND_REVISIONS(const char *uri, int versionMajor, QList<int> *);
#define QML_NAMESPACE_EXTENDED(EXTENDED_NAMESPACE) \
Q_CLASSINFO("QML.Extended", #EXTENDED_NAMESPACE)
#define QML_INTERFACE \
Q_CLASSINFO("QML.Element", "anonymous") \
enum class QmlIsInterface {yes = true}; \
template<typename, typename> friend struct QML_PRIVATE_NAMESPACE::QmlInterface; \
template<typename T, typename... Args> \
friend void QML_REGISTER_TYPES_AND_REVISIONS(const char *uri, int versionMajor, QList<int> *);
#define QML_IMPLEMENTS_INTERFACES(INTERFACES) \
Q_INTERFACES(INTERFACES) \
enum class QmlIsInterface {yes = false}; \
template<typename, typename> friend struct QML_PRIVATE_NAMESPACE::QmlInterface;
#define QML_SEQUENTIAL_CONTAINER(VALUE_TYPE) \
Q_CLASSINFO("QML.Sequence", #VALUE_TYPE) \
using QmlSequenceValueType = VALUE_TYPE; \
enum class QmlIsSequence {yes = true}; \
template<typename, typename> friend struct QML_PRIVATE_NAMESPACE::QmlSequence; \
template<typename T, typename... Args> \
friend void QML_REGISTER_TYPES_AND_REVISIONS(const char *uri, int versionMajor, QList<int> *);
#define QML_UNAVAILABLE \
QML_FOREIGN(QQmlTypeNotAvailable)
#endif

View File

@ -1,4 +1,5 @@
%modules = ( # path to module name map
"QtQmlIntegration" => "$basedir/src/qmlintegration",
"QtQml" => "$basedir/src/qml",
"QtQmlCore" => "$basedir/src/core",
"QtQuick" => "$basedir/src/quick",