diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2013-09-12 10:53:20 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-09-13 10:29:22 +0200 |
commit | 4b5a7b15fc6d3650c8e9b7bf619804a0a953eeba (patch) | |
tree | dc0e6952e2e6ee26118bcc14dc1f573fa9216593 /src/qml/qml/qqmltypeloader.cpp | |
parent | 8c2201e2e51e9a6c09b4f91c4b4fc09b2c82f4af (diff) |
[new compiler] Implement proper type resolution
Collect all references to unknown types after parsing, re-use the existing code
in QQmlTypeLoader to resolve them and finally use the resolved references map
in the QQmlObjectCreator instead of the type name cache directly.
Change-Id: I8b83af4f8852e79c33985457081c024358bb9622
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/qml/qml/qqmltypeloader.cpp')
-rw-r--r-- | src/qml/qml/qqmltypeloader.cpp | 87 |
1 files changed, 84 insertions, 3 deletions
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index 0f83da7b0a..e1f96442b1 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -2167,6 +2167,13 @@ void QQmlTypeData::compile() m_imports.populateCache(m_compiledData->importCache); m_compiledData->importCache->addref(); + for (QHash<int, TypeReference>::ConstIterator resolvedType = m_resolvedTypes.constBegin(), end = m_resolvedTypes.constEnd(); + resolvedType != end; ++resolvedType) { + QQmlCompiledData::TypeReference ref; + ref.type = resolvedType->type; + m_compiledData->resolvedTypes.insert(resolvedType.key(), ref); + } + JSCodeGen jsCodeGen; jsCodeGen.generateJSCodeForFunctionsAndBindings(finalUrlString(), parsedQML.data()); @@ -2196,8 +2203,8 @@ void QQmlTypeData::compile() m_compiledData->propertyCaches.reserve(qmlUnit->nObjects); QQmlPropertyCacheCreator propertyCacheBuilder(QQmlEnginePrivate::get(m_typeLoader->engine()), - qmlUnit, m_compiledData->url, m_compiledData->importCache, - &m_imports); + qmlUnit, m_compiledData->url, + &m_imports, &m_compiledData->resolvedTypes); for (quint32 i = 0; i < qmlUnit->nObjects; ++i) { const QV4::CompiledData::Object *obj = qmlUnit->objectAt(i); @@ -2255,10 +2262,10 @@ void QQmlTypeData::resolveTypes() m_scripts << ref; } + // --- old compiler: foreach (QQmlScript::TypeReference *parserRef, scriptParser.referencedTypes()) { TypeReference ref; - QString url; int majorVersion = -1; int minorVersion = -1; QQmlImportNamespace *typeNamespace = 0; @@ -2318,6 +2325,80 @@ void QQmlTypeData::resolveTypes() m_types << ref; } + + // --- new compiler: + QV4::CompiledData::TypeReferenceMap typeReferences; + QStringList names; + if (parsedQML) { + typeReferences = parsedQML->typeReferences; + names = parsedQML->jsGenerator.strings; + } else { + // ### collect from available QV4::CompiledData::QmlUnit + } + for (QV4::CompiledData::TypeReferenceMap::ConstIterator unresolvedRef = typeReferences.constBegin(), end = typeReferences.constEnd(); + unresolvedRef != end; ++unresolvedRef) { + + TypeReference ref; // resolved reference + + int majorVersion = -1; + int minorVersion = -1; + QQmlImportNamespace *typeNamespace = 0; + QList<QQmlError> errors; + + const QString name = names.at(unresolvedRef.key()); + bool typeFound = m_imports.resolveType(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(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 {}) + QQmlError error; + if (typeNamespace) { + error.setDescription(QQmlTypeLoader::tr("Namespace %1 cannot be used as a type").arg(name)); + } else { + if (errors.size()) { + error = errors.takeFirst(); + } else { + // this should not be possible! + // Description should come from error provided by addImport() function. + error.setDescription(QQmlTypeLoader::tr("Unreported error adding script import to import database")); + } + error.setUrl(m_imports.baseUrl()); + error.setDescription(QQmlTypeLoader::tr("%1 %2").arg(name).arg(error.description())); + } + + error.setLine(unresolvedRef->line); + error.setColumn(unresolvedRef->column); + + errors.prepend(error); + setError(errors); + return; + } + + if (ref.type->isComposite()) { + ref.typeData = typeLoader()->getType(ref.type->sourceUrl()); + addDependency(ref.typeData); + } + ref.majorVersion = majorVersion; + ref.minorVersion = minorVersion; + + ref.location.line = unresolvedRef->line; + ref.location.column = unresolvedRef->column; + + m_resolvedTypes.insert(unresolvedRef.key(), ref); + } } void QQmlTypeData::scriptImported(QQmlScriptBlob *blob, const QQmlScript::Location &location, const QString &qualifier, const QString &/*nameSpace*/) |