From 036aa822455b4d831076a1ba364fa1ef304dee84 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Tue, 29 May 2018 13:55:38 +0200 Subject: Show error message when type qmlRegisterType and friends fail When a type is registered through qmlRegisterType or similar functions, no error was shown. Task-number: QTBUG-68323 Change-Id: Iff44bf8744c67dba2fdd12c43aaee44a8e15364a Reviewed-by: Simon Hausmann --- src/qml/qml/qqmlimport.cpp | 14 +++++++------- src/qml/qml/qqmlmetatype.cpp | 42 +++++++++++++++++++++++++++++------------- src/qml/qml/qqmlmetatype_p.h | 13 ++++++++++++- 3 files changed, 48 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp index 005db4248e..80ebab5ca3 100644 --- a/src/qml/qml/qqmlimport.cpp +++ b/src/qml/qml/qqmlimport.cpp @@ -158,6 +158,8 @@ QQmlType fetchOrCreateTypeForUrl(const QString &urlString, const QHashedStringRe // can guarentee it will live long enough to reach qmlregister. QByteArray buf(unqualifiedtype.toString().toUtf8()); + QQmlMetaTypeRegistrationFailureRecorder failureRecorder; + // Register the type. Note that the URI parameters here are empty; for // file type imports, we do not place them in a URI as we don't // necessarily have a good and unique one (picture a library import, @@ -200,9 +202,9 @@ QQmlType fetchOrCreateTypeForUrl(const QString &urlString, const QHashedStringRe // data. if (!ret.isValid()) { if (!errors) // Cannot list errors properly, just quit - qFatal("%s", QQmlMetaType::typeRegistrationFailures().join('\n').toLatin1().constData()); + qFatal("%s", failureRecorder.failures().join('\n').toLatin1().constData()); QQmlError error; - error.setDescription(QQmlMetaType::typeRegistrationFailures().join('\n')); + error.setDescription(failureRecorder.failures().join('\n')); errors->prepend(error); } return ret; @@ -2010,7 +2012,7 @@ bool QQmlImportDatabase::registerPluginTypes(QObject *instance, const QString &b const QByteArray bytes = uri.toUtf8(); const char *moduleId = bytes.constData(); - QStringList registrationFailures; + QQmlMetaTypeRegistrationFailureRecorder failureRecorder; { // Create a scope for QWriteLocker to keep it as narrow as possible, and // to ensure that we release it before the call to initalizeEngine below @@ -2052,14 +2054,12 @@ bool QQmlImportDatabase::registerPluginTypes(QObject *instance, const QString &b } iface->registerTypes(moduleId); - - registrationFailures = QQmlMetaType::typeRegistrationFailures(); QQmlMetaType::setTypeRegistrationNamespace(QString()); } // QWriteLocker lock(QQmlMetaType::typeRegistrationLock()) - if (!registrationFailures.isEmpty()) { + if (!failureRecorder.failures().isEmpty()) { if (errors) { - for (const QString &failure : qAsConst(registrationFailures)) { + for (const QString &failure : failureRecorder.failures()) { QQmlError error; error.setDescription(failure); errors->prepend(error); diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index d842a7795f..2705321e77 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -114,13 +114,27 @@ struct QQmlMetaTypeData QSet protectedNamespaces; QString typeRegistrationNamespace; - QStringList typeRegistrationFailures; QHash qmlLists; QHash propertyCaches; QQmlPropertyCache *propertyCache(const QMetaObject *metaObject); QQmlPropertyCache *propertyCache(const QQmlType &type, int minorVersion); + + void startRecordingTypeRegFailures(QStringList *storage) + { typeRegistrationFailures = storage; } + void stopRecordingTypeRegFailures() + { startRecordingTypeRegFailures(nullptr); } + void recordTypeRegFailure(const QString &message) + { + if (typeRegistrationFailures) + typeRegistrationFailures->append(message); + else + qWarning("%s", message.toUtf8().constData()); + } + +private: + QStringList *typeRegistrationFailures = nullptr; }; class QQmlTypeModulePrivate @@ -152,6 +166,16 @@ static uint qHash(const QQmlMetaTypeData::VersionedUri &v) return v.uri.hash() ^ qHash(v.majorVersion); } +QQmlMetaTypeRegistrationFailureRecorder::QQmlMetaTypeRegistrationFailureRecorder() +{ + metaTypeData()->startRecordingTypeRegFailures(&_failures); +} + +QQmlMetaTypeRegistrationFailureRecorder::~QQmlMetaTypeRegistrationFailureRecorder() +{ + metaTypeData()->stopRecordingTypeRegFailures(); +} + QQmlMetaTypeData::QQmlMetaTypeData() { } @@ -1571,7 +1595,7 @@ bool checkRegistration(QQmlType::RegistrationType typeType, QQmlMetaTypeData *da if (!typeName.isEmpty()) { if (typeName.at(0).isLower()) { QString failure(QCoreApplication::translate("qmlRegisterType", "Invalid QML %1 name \"%2\"; type names must begin with an uppercase letter")); - data->typeRegistrationFailures.append(failure.arg(registrationTypeString(typeType)).arg(typeName)); + data->recordTypeRegFailure(failure.arg(registrationTypeString(typeType)).arg(typeName)); return false; } @@ -1579,7 +1603,7 @@ bool checkRegistration(QQmlType::RegistrationType typeType, QQmlMetaTypeData *da for (int ii = 0; ii < typeNameLen; ++ii) { if (!(typeName.at(ii).isLetterOrNumber() || typeName.at(ii) == '_')) { QString failure(QCoreApplication::translate("qmlRegisterType", "Invalid QML %1 name \"%2\"")); - data->typeRegistrationFailures.append(failure.arg(registrationTypeString(typeType)).arg(typeName)); + data->recordTypeRegFailure(failure.arg(registrationTypeString(typeType)).arg(typeName)); return false; } } @@ -1593,7 +1617,7 @@ bool checkRegistration(QQmlType::RegistrationType typeType, QQmlMetaTypeData *da if (data->protectedNamespaces.contains(nameSpace)) { QString failure(QCoreApplication::translate("qmlRegisterType", "Cannot install %1 '%2' into protected namespace '%3'")); - data->typeRegistrationFailures.append(failure.arg(registrationTypeString(typeType)).arg(typeName).arg(nameSpace)); + data->recordTypeRegFailure(failure.arg(registrationTypeString(typeType)).arg(typeName).arg(nameSpace)); return false; } } else if (majorVersion >= 0) { @@ -1604,7 +1628,7 @@ bool checkRegistration(QQmlType::RegistrationType typeType, QQmlMetaTypeData *da if (QQmlTypeModulePrivate::get(qqtm)->locked){ QString failure(QCoreApplication::translate("qmlRegisterType", "Cannot install %1 '%2' into protected module '%3' version '%4'")); - data->typeRegistrationFailures.append(failure.arg(registrationTypeString(typeType)).arg(typeName).arg(nameSpace).arg(majorVersion)); + data->recordTypeRegFailure(failure.arg(registrationTypeString(typeType)).arg(typeName).arg(nameSpace).arg(majorVersion)); return false; } } @@ -1878,14 +1902,6 @@ void QQmlMetaType::setTypeRegistrationNamespace(const QString &uri) QQmlMetaTypeData *data = metaTypeData(); data->typeRegistrationNamespace = uri; - data->typeRegistrationFailures.clear(); -} - -QStringList QQmlMetaType::typeRegistrationFailures() -{ - QQmlMetaTypeData *data = metaTypeData(); - - return data->typeRegistrationFailures; } QMutex *QQmlMetaType::typeRegistrationLock() diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h index 51bf485a3e..bcaf62d6ba 100644 --- a/src/qml/qml/qqmlmetatype_p.h +++ b/src/qml/qml/qqmlmetatype_p.h @@ -150,7 +150,6 @@ public: static void protectNamespace(const QString &); static void setTypeRegistrationNamespace(const QString &); - static QStringList typeRegistrationFailures(); static QMutex *typeRegistrationLock(); @@ -356,6 +355,18 @@ private: int m_minor; }; +class Q_AUTOTEST_EXPORT QQmlMetaTypeRegistrationFailureRecorder +{ + QStringList _failures; + +public: + QQmlMetaTypeRegistrationFailureRecorder(); + ~QQmlMetaTypeRegistrationFailureRecorder(); + + QStringList failures() const + { return _failures; } +}; + QT_END_NAMESPACE #endif // QQMLMETATYPE_P_H -- cgit v1.2.3