Clean up pragma singleton handling in the type loader

Get rid of the m_isSingleton boolean by checking the
CompiledData::Unit::flags after the type compilation. This is more
compact and makes the singleton type checks independent from the IR.

Change-Id: I04189d284e6ea275ac8540918836b641914e7588
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
Simon Hausmann 2016-06-17 14:11:22 +02:00
parent e88500ff25
commit 7c8441fece
4 changed files with 29 additions and 66 deletions

View File

@ -1284,7 +1284,7 @@ void QQmlTypeLoader::shutdownThread()
} }
QQmlTypeLoader::Blob::Blob(const QUrl &url, QQmlDataBlob::Type type, QQmlTypeLoader *loader) QQmlTypeLoader::Blob::Blob(const QUrl &url, QQmlDataBlob::Type type, QQmlTypeLoader *loader)
: QQmlDataBlob(url, type, loader), m_importCache(loader), m_isSingleton(false) : QQmlDataBlob(url, type, loader), m_importCache(loader)
{ {
} }
@ -1448,51 +1448,6 @@ bool QQmlTypeLoader::Blob::addImport(const QV4::CompiledData::Import *import, QL
return true; return true;
} }
bool QQmlTypeLoader::Blob::addPragma(const QmlIR::Pragma &pragma, QList<QQmlError> *errors)
{
Q_ASSERT(errors);
if (pragma.type == QmlIR::Pragma::PragmaSingleton) {
QUrl myUrl = finalUrl();
QQmlType *ret = QQmlMetaType::qmlType(myUrl, true);
if (!ret) {
QQmlError error;
error.setDescription(QQmlTypeLoader::tr("No matching type found, pragma Singleton files cannot be used by QQmlComponent."));
error.setUrl(myUrl);
error.setLine(pragma.location.line);
error.setColumn(pragma.location.column);
errors->prepend(error);
return false;
}
if (!ret->isCompositeSingleton()) {
QQmlError error;
error.setDescription(QQmlTypeLoader::tr("pragma Singleton used with a non composite singleton type %1").arg(ret->qmlTypeName()));
error.setUrl(myUrl);
error.setLine(pragma.location.line);
error.setColumn(pragma.location.column);
errors->prepend(error);
return false;
}
// This flag is used for error checking when a qmldir file marks a type as
// composite singleton, but there is no pragma Singleton defined in QML.
m_isSingleton = true;
} else {
QQmlError error;
error.setDescription(QLatin1String("Invalid pragma"));
error.setUrl(finalUrl());
error.setLine(pragma.location.line);
error.setColumn(pragma.location.column);
errors->prepend(error);
return false;
}
return true;
}
void QQmlTypeLoader::Blob::dependencyError(QQmlDataBlob *blob) void QQmlTypeLoader::Blob::dependencyError(QQmlDataBlob *blob)
{ {
if (blob->type() == QQmlDataBlob::QmldirFile) { if (blob->type() == QQmlDataBlob::QmldirFile) {
@ -2121,18 +2076,36 @@ void QQmlTypeData::done()
} }
} }
// If the type is CompositeSingleton but there was no pragma Singleton in the
// QML file, lets report an error.
QQmlType *type = QQmlMetaType::qmlType(url(), true);
if (!isError() && type && type->isCompositeSingleton() && !m_isSingleton) {
QString typeName = type->qmlTypeName();
setError(QQmlTypeLoader::tr("qmldir defines type as singleton, but no pragma Singleton found in type %1.").arg(typeName));
}
// Compile component // Compile component
if (!isError()) if (!isError())
compile(); compile();
if (!isError()) {
QQmlType *type = QQmlMetaType::qmlType(finalUrl(), true);
if (m_compiledData && m_compiledData->data->flags & QV4::CompiledData::Unit::IsSingleton) {
if (!type) {
QQmlError error;
error.setDescription(QQmlTypeLoader::tr("No matching type found, pragma Singleton files cannot be used by QQmlComponent."));
setError(error);
} else if (!type->isCompositeSingleton()) {
QQmlError error;
error.setDescription(QQmlTypeLoader::tr("pragma Singleton used with a non composite singleton type %1").arg(type->qmlTypeName()));
setError(error);
}
} else {
// If the type is CompositeSingleton but there was no pragma Singleton in the
// QML file, lets report an error.
if (type && type->isCompositeSingleton()) {
QString typeName = type->qmlTypeName();
setError(QQmlTypeLoader::tr("qmldir defines type as singleton, but no pragma Singleton found in type %1.").arg(typeName));
}
}
}
if (isError()) {
m_compiledData = nullptr;
}
m_document.reset(); m_document.reset();
m_typeReferences.clear(); m_typeReferences.clear();
m_implicitImport = 0; m_implicitImport = 0;
@ -2248,14 +2221,6 @@ void QQmlTypeData::continueLoadFromIR()
return; return;
} }
} }
foreach (QmlIR::Pragma *pragma, m_document->pragmas) {
if (!addPragma(*pragma, &errors)) {
Q_ASSERT(errors.size());
setError(errors);
return;
}
}
} }
void QQmlTypeData::allDependenciesDone() void QQmlTypeData::allDependenciesDone()

View File

@ -232,7 +232,6 @@ public:
protected: protected:
bool addImport(const QV4::CompiledData::Import *import, QList<QQmlError> *errors); bool addImport(const QV4::CompiledData::Import *import, QList<QQmlError> *errors);
bool addPragma(const QmlIR::Pragma &pragma, QList<QQmlError> *errors);
bool fetchQmldir(const QUrl &url, const QV4::CompiledData::Import *import, int priority, QList<QQmlError> *errors); bool fetchQmldir(const QUrl &url, const QV4::CompiledData::Import *import, int priority, QList<QQmlError> *errors);
bool updateQmldir(QQmlQmldirData *data, const QV4::CompiledData::Import *import, QList<QQmlError> *errors); bool updateQmldir(QQmlQmldirData *data, const QV4::CompiledData::Import *import, QList<QQmlError> *errors);
@ -249,7 +248,6 @@ public:
virtual QString stringAt(int) const { return QString(); } virtual QString stringAt(int) const { return QString(); }
QQmlImports m_importCache; QQmlImports m_importCache;
bool m_isSingleton;
QHash<const QV4::CompiledData::Import*, int> m_unresolvedImports; QHash<const QV4::CompiledData::Import*, int> m_unresolvedImports;
QList<QQmlQmldirData *> m_qmldirs; QList<QQmlQmldirData *> m_qmldirs;
}; };

View File

@ -1,2 +1,2 @@
5:5:Type RegisteredCompositeType unavailable 5:5:Type RegisteredCompositeType unavailable
2:1:pragma Singleton used with a non composite singleton type CompositeSingletonTest/RegisteredCompositeType -1:-1:pragma Singleton used with a non composite singleton type CompositeSingletonTest/RegisteredCompositeType

View File

@ -1 +1 @@
2:1:No matching type found, pragma Singleton files cannot be used by QQmlComponent. -1:-1:No matching type found, pragma Singleton files cannot be used by QQmlComponent.