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/compiler | |
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/compiler')
-rw-r--r-- | src/qml/compiler/qqmlcodegenerator.cpp | 23 | ||||
-rw-r--r-- | src/qml/compiler/qqmlcodegenerator_p.h | 6 | ||||
-rw-r--r-- | src/qml/compiler/qv4compileddata_p.h | 12 |
3 files changed, 41 insertions, 0 deletions
diff --git a/src/qml/compiler/qqmlcodegenerator.cpp b/src/qml/compiler/qqmlcodegenerator.cpp index 5d60c64639..6ca7078e69 100644 --- a/src/qml/compiler/qqmlcodegenerator.cpp +++ b/src/qml/compiler/qqmlcodegenerator.cpp @@ -109,6 +109,7 @@ bool QQmlCodeGenerator::generateFromQml(const QString &code, const QUrl &url, co qSwap(_imports, output->imports); qSwap(_objects, output->objects); qSwap(_functions, output->functions); + qSwap(_typeReferences, output->typeReferences); this->pool = output->jsParserEngine.pool(); this->jsGenerator = &output->jsGenerator; @@ -128,9 +129,13 @@ bool QQmlCodeGenerator::generateFromQml(const QString &code, const QUrl &url, co AST::UiObjectDefinition *rootObject = AST::cast<AST::UiObjectDefinition*>(program->members->member); Q_ASSERT(rootObject); output->indexOfRootObject = defineQMLObject(rootObject); + + collectTypeReferences(); + qSwap(_imports, output->imports); qSwap(_objects, output->objects); qSwap(_functions, output->functions); + qSwap(_typeReferences, output->typeReferences); return true; } @@ -440,6 +445,8 @@ bool QQmlCodeGenerator::visit(AST::UiPublicMember *node) } param->nameIndex = registerString(p->name.toString()); + param->location.line = p->identifierToken.startLine; + param->location.column = p->identifierToken.startColumn; signal->parameters->append(param); p = p->next; } @@ -710,6 +717,22 @@ void QQmlCodeGenerator::recordError(const AST::SourceLocation &location, const Q errors << error; } +void QQmlCodeGenerator::collectTypeReferences() +{ + foreach (QmlObject *obj, _objects) { + _typeReferences.add(obj->inheritedTypeNameIndex, obj->location); + + for (QmlProperty *prop = obj->properties->first; prop; prop = prop->next) { + if (prop->type >= QV4::CompiledData::Property::Custom) + _typeReferences.add(prop->customTypeNameIndex, prop->location); + } + + for (Signal *sig = obj->qmlSignals->first; sig; sig = sig->next) + for (SignalParameter *param = sig->parameters->first; param; param = param->next) + _typeReferences.add(param->customTypeNameIndex, param->location); + } +} + QQmlScript::LocationSpan QQmlCodeGenerator::location(AST::SourceLocation start, AST::SourceLocation end) { QQmlScript::LocationSpan rv; diff --git a/src/qml/compiler/qqmlcodegenerator_p.h b/src/qml/compiler/qqmlcodegenerator_p.h index 100c1df1a4..97ba3ef075 100644 --- a/src/qml/compiler/qqmlcodegenerator_p.h +++ b/src/qml/compiler/qqmlcodegenerator_p.h @@ -163,6 +163,8 @@ struct ParsedQML QList<AST::Node*> functions; // FunctionDeclaration, Statement or Expression QV4::Compiler::JSUnitGenerator jsGenerator; + QV4::CompiledData::TypeReferenceMap typeReferences; + QString stringAt(int index) const { return jsGenerator.strings.value(index); } }; @@ -220,6 +222,8 @@ public: void recordError(const AST::SourceLocation &location, const QString &description); + void collectTypeReferences(); + static QQmlScript::LocationSpan location(AST::SourceLocation start, AST::SourceLocation end); int registerString(const QString &str) const { return jsGenerator->registerString(str); } @@ -231,6 +235,8 @@ public: QList<QmlObject*> _objects; QList<AST::Node*> _functions; + QV4::CompiledData::TypeReferenceMap _typeReferences; + QmlObject *_object; QSet<QString> _propertyNames; QSet<QString> _signalNames; diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h index 7833097325..c98d53a1fa 100644 --- a/src/qml/compiler/qv4compileddata_p.h +++ b/src/qml/compiler/qv4compileddata_p.h @@ -44,6 +44,7 @@ #include <QtCore/qstring.h> #include <QVector> #include <QStringList> +#include <QHash> #include <private/qv4value_def_p.h> #include <private/qv4executableallocator_p.h> @@ -73,6 +74,16 @@ struct Location int column; }; +// map from name index to location of first use +struct TypeReferenceMap : QHash<int, Location> +{ + void add(int nameIndex, const Location &loc) { + if (contains(nameIndex)) + return; + insert(nameIndex, loc); + } +}; + struct RegExp { enum Flags { @@ -263,6 +274,7 @@ struct Parameter quint32 type; quint32 customTypeNameIndex; quint32 reserved; + Location location; }; struct Signal |