diff options
Diffstat (limited to 'src/qml/qml/qqmltypeloader.cpp')
-rw-r--r-- | src/qml/qml/qqmltypeloader.cpp | 59 |
1 files changed, 43 insertions, 16 deletions
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index 9547204760..e800eb815d 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -1902,7 +1902,7 @@ QQmlTypeData::TypeDataCallback::~TypeDataCallback() QQmlTypeData::QQmlTypeData(const QUrl &url, QQmlTypeLoader::Options options, QQmlTypeLoader *manager) : QQmlTypeLoader::Blob(url, QmlFile, manager), m_options(options), - m_typesResolved(false), m_compiledData(0), m_implicitImport(0) + m_typesResolved(false), m_compiledData(0), m_implicitImport(0), m_implicitImportLoaded(false) { } @@ -2008,23 +2008,14 @@ void QQmlTypeData::completed() } } -void QQmlTypeData::dataReceived(const Data &data) +bool QQmlTypeData::loadImplicitImport() { - QString code = QString::fromUtf8(data.data(), data.size()); - QByteArray preparseData; - - if (data.isFile()) preparseData = data.asFile()->metaData(QLatin1String("qml:preparse")); - - if (!scriptParser.parse(code, preparseData, finalUrl(), finalUrlString())) { - setError(scriptParser.errors()); - return; - } + m_implicitImportLoaded = true; // Even if we hit an error, count as loaded (we'd just keep hitting the error) m_imports.setBaseUrl(finalUrl(), finalUrlString()); QQmlImportDatabase *importDatabase = typeLoader()->importDatabase(); - - // For local urls, add an implicit import "." as first (most overridden) lookup. + // For local urls, add an implicit import "." as most overridden lookup. // This will also trigger the loading of the qmldir and the import of any native // types from available plugins. QList<QQmlError> implicitImportErrors; @@ -2032,20 +2023,41 @@ void QQmlTypeData::dataReceived(const Data &data) if (!implicitImportErrors.isEmpty()) { setError(implicitImportErrors); + return false; + } + + return true; +} + +void QQmlTypeData::dataReceived(const Data &data) +{ + QString code = QString::fromUtf8(data.data(), data.size()); + QByteArray preparseData; + + if (data.isFile()) preparseData = data.asFile()->metaData(QLatin1String("qml:preparse")); + + if (!scriptParser.parse(code, preparseData, finalUrl(), finalUrlString())) { + setError(scriptParser.errors()); return; } - QList<QQmlError> errors; + m_imports.setBaseUrl(finalUrl(), finalUrlString()); + // For remote URLs, we don't delay the loading of the implicit import + // because the loading probably requires an asynchronous fetch of the + // qmldir (so we can't load it just in time). if (!finalUrl().scheme().isEmpty()) { QUrl qmldirUrl = finalUrl().resolved(QUrl(QLatin1String("qmldir"))); if (!QQmlImports::isLocal(qmldirUrl)) { + if (!loadImplicitImport()) + return; // This qmldir is for the implicit import m_implicitImport = new QQmlScript::Import; m_implicitImport->uri = QLatin1String("."); m_implicitImport->qualifier = QString(); m_implicitImport->majorVersion = -1; m_implicitImport->minorVersion = -1; + QList<QQmlError> errors; if (!fetchQmldir(qmldirUrl, m_implicitImport, 1, &errors)) { setError(errors); @@ -2054,6 +2066,8 @@ void QQmlTypeData::dataReceived(const Data &data) } } + QList<QQmlError> errors; + foreach (const QQmlScript::Import &import, scriptParser.imports()) { if (!addImport(import, &errors)) { Q_ASSERT(errors.size()); @@ -2155,8 +2169,21 @@ void QQmlTypeData::resolveTypes() QQmlImportNamespace *typeNamespace = 0; QList<QQmlError> errors; - if (!m_imports.resolveType(parserRef->name, &ref.type, &majorVersion, &minorVersion, - &typeNamespace, &errors) || typeNamespace) { + bool typeFound = m_imports.resolveType(parserRef->name, &ref.type, + &majorVersion, &minorVersion, &typeNamespace, &errors); + if (!typeNamespace && !typeFound && !m_implicitImportLoaded) { + // Lazy loading of implicit import + if (loadImplicitImport()) { + // Try again to find the type + errors.clear(); + typeFound = m_imports.resolveType(parserRef->name, &ref.type, + &majorVersion, &minorVersion, &typeNamespace, &errors); + } else { + return; //loadImplicitImport() hit an error, and called setError already + } + } + + if (!typeFound || typeNamespace) { // Known to not be a type: // - known to be a namespace (Namespace {}) // - type with unknown namespace (UnknownNamespace.SomeType {}) |