aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmltypeloader.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2013-09-12 10:53:20 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-13 10:29:22 +0200
commit4b5a7b15fc6d3650c8e9b7bf619804a0a953eeba (patch)
treedc0e6952e2e6ee26118bcc14dc1f573fa9216593 /src/qml/qml/qqmltypeloader.cpp
parent8c2201e2e51e9a6c09b4f91c4b4fc09b2c82f4af (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.cpp87
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*/)