aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler
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/compiler
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/compiler')
-rw-r--r--src/qml/compiler/qqmlcodegenerator.cpp23
-rw-r--r--src/qml/compiler/qqmlcodegenerator_p.h6
-rw-r--r--src/qml/compiler/qv4compileddata_p.h12
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