QML: Fix conflicts between QML_ANONYMOUS, QML_UNCREATABLE and namespaces
Even though it makes no sense, we have to allow QML_ANONYMOUS and
QML_UNCREATABLE in the same class since we've documented it. You
cannot trigger the custom message because you'd need a name to attempt
to create an instance of the type. Therefore, the documentation
suggesting this is nonsensical.
In theory you could indeed provide a custom message for namespaces, but
in order to continue supporting this, we would either have to drop the
QmlIsUncreatable mechanism, or we would need a different macro. So,
let's drop this for now. If we really need it, we can introduce a
different macro later.
[ChangeLog][QtQml][Important Behavior Changes] You can no longer
override the "uncreatable" message for QML-exposed namespaces using
QML_UNCREATABLE. This would be incompatible with making the
QML_UNCREATABLE macro safe from unintended inheritance. The latter is
much more important.
Fixes: QTBUG-111470
Change-Id: Ib736a2411128d58d939fa2a57d28a0b31c0777e6
Reviewed-by: Robert Griebl <robert.griebl@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
(cherry picked from commit a60968283b
)
This commit is contained in:
parent
064fd7e6e5
commit
2acf4db153
|
@ -153,8 +153,7 @@
|
|||
|
||||
Some QML types are implicitly uncreatable, in particular types exposed with
|
||||
\l QML_ANONYMOUS or namespaces exposed with \l QML_ELEMENT or
|
||||
\l QML_NAMED_ELEMENT(). For such types, \l QML_UNCREATABLE() can be used to
|
||||
provide a custom error message.
|
||||
\l QML_NAMED_ELEMENT().
|
||||
|
||||
Since Qt 6.0 you can use "" instead of a reason to use a standard message instead.
|
||||
|
||||
|
|
|
@ -891,7 +891,7 @@ void qmlRegisterTypesAndRevisions(const char *uri, int versionMajor, QList<int>
|
|||
QQmlPrivate::QmlSingleton<T>::Value,
|
||||
QQmlPrivate::QmlInterface<T>::Value,
|
||||
QQmlPrivate::QmlSequence<T>::Value,
|
||||
QQmlPrivate::QmlUncreatable<T>::Value>
|
||||
QQmlPrivate::QmlUncreatable<T>::Value || QQmlPrivate::QmlAnonymous<T>::Value>
|
||||
::registerTypeAndRevisions(uri, versionMajor, qmlTypeIds,
|
||||
QQmlPrivate::QmlExtendedNamespace<T>::metaObject()), ...);
|
||||
}
|
||||
|
|
|
@ -897,6 +897,20 @@ namespace QQmlPrivate
|
|||
&& bool(T::QmlIsUncreatable::yes);
|
||||
};
|
||||
|
||||
template<class T, class = std::void_t<>>
|
||||
struct QmlAnonymous
|
||||
{
|
||||
static constexpr bool Value = false;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct QmlAnonymous<T, std::void_t<typename T::QmlIsAnonymous>>
|
||||
{
|
||||
static constexpr bool Value =
|
||||
QmlTypeHasMarker<T, decltype(&T::qt_qmlMarker_anonymous)>::value
|
||||
&& bool(T::QmlIsAnonymous::yes);
|
||||
};
|
||||
|
||||
|
||||
template<class T, class = std::void_t<>>
|
||||
struct QmlSingleton
|
||||
|
|
|
@ -18,6 +18,8 @@ namespace QQmlPrivate {
|
|||
struct QmlExtendedNamespace;
|
||||
template<class, class>
|
||||
struct QmlUncreatable;
|
||||
template<class, class>
|
||||
struct QmlAnonymous;
|
||||
}
|
||||
|
||||
template <typename T> class QList;
|
||||
|
@ -41,11 +43,11 @@ QT_END_NAMESPACE
|
|||
|
||||
#define QML_ANONYMOUS \
|
||||
Q_CLASSINFO("QML.Element", "anonymous") \
|
||||
enum class QmlIsUncreatable {yes = true}; \
|
||||
template<typename, typename> friend struct QML_PRIVATE_NAMESPACE::QmlUncreatable; \
|
||||
enum class QmlIsAnonymous{yes = true}; \
|
||||
template<typename, typename> friend struct QML_PRIVATE_NAMESPACE::QmlAnonymous; \
|
||||
template<typename... Args> \
|
||||
friend void QML_REGISTER_TYPES_AND_REVISIONS(const char *uri, int versionMajor, QList<int> *); \
|
||||
inline constexpr void qt_qmlMarker_uncreatable() {}
|
||||
inline constexpr void qt_qmlMarker_anonymous() {}
|
||||
|
||||
#define QML_NAMED_ELEMENT(NAME) \
|
||||
Q_CLASSINFO("QML.Element", #NAME)
|
||||
|
|
|
@ -573,4 +573,15 @@ void tst_qmltyperegistrar::baseVersionInQmltypes()
|
|||
QVERIFY(qmltypesData.contains("exports: [\"QmlTypeRegistrarTest/WithMethod 1.0\"]"));
|
||||
}
|
||||
|
||||
void tst_qmltyperegistrar::anonymousAndUncreatable()
|
||||
{
|
||||
QVERIFY(qmltypesData.contains(
|
||||
R"(Component {
|
||||
file: "tst_qmltyperegistrar.h"
|
||||
name: "AnonymousAndUncreatable"
|
||||
accessSemantics: "reference"
|
||||
prototype: "QObject"
|
||||
})"));
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_qmltyperegistrar)
|
||||
|
|
|
@ -501,6 +501,13 @@ signals:
|
|||
void clonedSignal(int i = 7);
|
||||
};
|
||||
|
||||
class AnonymousAndUncreatable : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
QML_UNCREATABLE("Pointless uncreatable message")
|
||||
};
|
||||
|
||||
class tst_qmltyperegistrar : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -549,6 +556,7 @@ private slots:
|
|||
void duplicateExportWarnings();
|
||||
void clonedSignal();
|
||||
void baseVersionInQmltypes();
|
||||
void anonymousAndUncreatable();
|
||||
|
||||
private:
|
||||
QByteArray qmltypesData;
|
||||
|
|
Loading…
Reference in New Issue