aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/qml/qqmlcompiler.cpp31
-rw-r--r--src/qml/qml/qqmlcompiler_p.h3
-rw-r--r--src/qml/qml/qqmlcustomparser.cpp3
-rw-r--r--src/qml/qml/qqmlimport.cpp96
-rw-r--r--src/qml/qml/qqmlimport_p.h1
-rw-r--r--src/qml/qml/qqmlinstruction.cpp4
-rw-r--r--src/qml/qml/qqmlscript.cpp58
-rw-r--r--src/qml/qml/qqmlscript_p.h16
-rw-r--r--src/qml/qml/qqmltypeloader.cpp18
-rw-r--r--src/qml/qml/qqmlvme.cpp3
-rw-r--r--tests/auto/qml/qqmlinstruction/tst_qqmlinstruction.cpp6
11 files changed, 108 insertions, 131 deletions
diff --git a/src/qml/qml/qqmlcompiler.cpp b/src/qml/qml/qqmlcompiler.cpp
index 5708a84fd9..7d06ff359c 100644
--- a/src/qml/qml/qqmlcompiler.cpp
+++ b/src/qml/qml/qqmlcompiler.cpp
@@ -90,7 +90,6 @@ using namespace QQmlCompilerTypes;
static QString id_string(QLatin1String("id"));
static QString on_string(QLatin1String("on"));
static QString Changed_string(QLatin1String("Changed"));
-static QString Component_string(QLatin1String("Component"));
static QString Component_import_string(QLatin1String("QML/Component"));
static QString qsTr_string(QLatin1String("qsTr"));
static QString qsTrId_string(QLatin1String("qsTrId"));
@@ -793,22 +792,22 @@ bool QQmlCompiler::compile(QQmlEngine *engine,
QString err = ref.type->noCreationReason();
if (err.isEmpty())
err = tr( "Element is not creatable.");
- COMPILE_EXCEPTION(parserRef->refObjects.first(), err);
+ COMPILE_EXCEPTION(parserRef->firstUse, err);
}
if (ref.type->containsRevisionedAttributes()) {
QQmlError cacheError;
- ref.typePropertyCache = enginePrivate->cache(ref.type, resolvedTypes.at(ii).minorVersion,
+ ref.typePropertyCache = enginePrivate->cache(ref.type,
+ resolvedTypes.at(ii).minorVersion,
cacheError);
if (!ref.typePropertyCache)
- COMPILE_EXCEPTION(parserRef->refObjects.first(), cacheError.description());
+ COMPILE_EXCEPTION(parserRef->firstUse, cacheError.description());
ref.typePropertyCache->addref();
}
} else if (tref.typeData) {
ref.component = tref.typeData->compiledData();
}
- ref.className = parserRef->name;
out->types << ref;
}
@@ -943,9 +942,6 @@ bool QQmlCompiler::buildObject(QQmlScript::Object *obj, const BindingContext &ct
const QQmlCompiledData::TypeReference &tr = output->types.at(obj->type);
obj->metatype = tr.metaObject();
- if (tr.type)
- obj->typeName = tr.type->qmlTypeName();
-
// This object is a "Component" element
if (tr.type && obj->metatype == &QQmlComponent::staticMetaObject) {
COMPILE_CHECK(buildComponent(obj, ctxt));
@@ -1614,7 +1610,6 @@ int QQmlCompiler::componentTypeRef()
}
}
QQmlCompiledData::TypeReference ref;
- ref.className = Component_string;
ref.type = t;
output->types << ref;
cachedComponentTypeRef = output->types.count() - 1;
@@ -2399,7 +2394,6 @@ bool QQmlCompiler::buildPropertyObjectAssignment(QQmlScript::Property *prop,
QQmlScript::Object *root = v->object;
QQmlScript::Object *component = pool->New<Object>();
component->type = componentTypeRef();
- component->typeName = QStringLiteral("Qt/Component");
component->metatype = &QQmlComponent::staticMetaObject;
component->location = root->location;
QQmlScript::Value *componentValue = pool->New<Value>();
@@ -2460,7 +2454,7 @@ bool QQmlCompiler::buildPropertyOnAssignment(QQmlScript::Property *prop,
buildDynamicMeta(baseObj, ForceCreation);
v->type = isPropertyValue ? Value::ValueSource : Value::ValueInterceptor;
} else {
- COMPILE_EXCEPTION(v, tr("\"%1\" cannot operate on \"%2\"").arg(v->object->typeName).arg(prop->name().toString()));
+ COMPILE_EXCEPTION(v, tr("\"%1\" cannot operate on \"%2\"").arg(elementName(v->object)).arg(prop->name().toString()));
}
return true;
@@ -2540,14 +2534,6 @@ bool QQmlCompiler::testQualifiedEnumAssignment(QQmlScript::Property *prop,
QQmlType *type = 0;
unit->imports().resolveType(typeName, &type, 0, 0, 0, 0);
- //handle enums on value types (where obj->typeName is empty)
- QString objTypeName = obj->typeName;
- if (objTypeName.isEmpty()) {
- QQmlType *objType = toQmlType(obj);
- if (objType)
- objTypeName = objType->qmlTypeName();
- }
-
if (!type)
return true;
@@ -2555,7 +2541,7 @@ bool QQmlCompiler::testQualifiedEnumAssignment(QQmlScript::Property *prop,
int value;
bool ok;
- if (objTypeName == type->qmlTypeName()) {
+ if (toQmlType(obj) == type) {
// When these two match, we can short cut the search
if (mprop.isFlagType()) {
value = mprop.enumerator().keysToValue(enumValue.toUtf8().constData(), &ok);
@@ -3736,7 +3722,7 @@ QString QQmlCompiler::elementName(QQmlScript::Object *o)
{
Q_ASSERT(o);
if (o->type != -1) {
- return output->types.at(o->type).className;
+ return unit->parser().referencedTypes().at(o->type)->name;
} else {
return QString();
}
@@ -3744,6 +3730,9 @@ QString QQmlCompiler::elementName(QQmlScript::Object *o)
QQmlType *QQmlCompiler::toQmlType(QQmlScript::Object *from)
{
+ if (from->type != -1 && output->types.at(from->type).type)
+ return output->types.at(from->type).type;
+
// ### Optimize
const QMetaObject *mo = from->metatype;
QQmlType *type = 0;
diff --git a/src/qml/qml/qqmlcompiler_p.h b/src/qml/qml/qqmlcompiler_p.h
index 5a52dcf403..f2e2376c7a 100644
--- a/src/qml/qml/qqmlcompiler_p.h
+++ b/src/qml/qml/qqmlcompiler_p.h
@@ -94,7 +94,6 @@ public:
TypeReference()
: type(0), typePropertyCache(0), component(0) {}
- QString className;
QQmlType *type;
QQmlPropertyCache *typePropertyCache;
QQmlCompiledData *component;
@@ -403,7 +402,7 @@ private:
int componentTypeRef();
int translationContextIndex();
- static QQmlType *toQmlType(QQmlScript::Object *from);
+ QQmlType *toQmlType(QQmlScript::Object *from);
bool canCoerce(int to, QQmlScript::Object *from);
QString elementName(QQmlScript::Object *);
diff --git a/src/qml/qml/qqmlcustomparser.cpp b/src/qml/qml/qqmlcustomparser.cpp
index f888b61e7d..67e580ccc4 100644
--- a/src/qml/qml/qqmlcustomparser.cpp
+++ b/src/qml/qml/qqmlcustomparser.cpp
@@ -97,7 +97,8 @@ QQmlCustomParserNode
QQmlCustomParserNodePrivate::fromObject(QQmlScript::Object *root)
{
QQmlCustomParserNode rootNode;
- rootNode.d->name = root->typeName;
+ if (root->typeReference)
+ rootNode.d->name = root->typeReference->name;
rootNode.d->location = root->location.start;
for (Property *p = root->properties.first(); p; p = root->properties.next(p)) {
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index 1417e3dff7..2f17137140 100644
--- a/src/qml/qml/qqmlimport.cpp
+++ b/src/qml/qml/qqmlimport.cpp
@@ -51,12 +51,15 @@
#include <private/qqmlglobal_p.h>
#include <private/qqmltypenamecache_p.h>
#include <private/qqmlengine_p.h>
+#include <private/qfieldlist_p.h>
QT_BEGIN_NAMESPACE
DEFINE_BOOL_CONFIG_OPTION(qmlImportTrace, QML_IMPORT_TRACE)
DEFINE_BOOL_CONFIG_OPTION(qmlCheckTypes, QML_CHECK_TYPES)
+static QString dotqml_string(QLatin1String(".qml"));
+
QString resolveLocalUrl(const QString &url, const QString &relative)
{
if (relative.contains(QLatin1Char(':'))) {
@@ -111,6 +114,8 @@ Q_GLOBAL_STATIC(StringStringMap, qmlEnginePluginsWithRegisteredTypes); // stores
class QQmlImportNamespace
{
public:
+ QQmlImportNamespace() : nextNamespace(0) {}
+
struct Import {
QString uri;
QString url;
@@ -131,6 +136,12 @@ public:
int *vmajor, int *vminor,
QQmlType** type_return, QString* url_return,
QString *base = 0, QList<QQmlError> *errors = 0);
+
+ // Prefix when used as a qualified import. Otherwise empty.
+ QString prefix;
+
+ // Used by QQmlImportsPrivate::qualifiedSets
+ QQmlImportNamespace *nextNamespace;
};
class QQmlImportsPrivate
@@ -153,9 +164,11 @@ public:
QString base;
int ref;
- QSet<QString> qmlDirFilesForWhichPluginsHaveBeenLoaded;
QQmlImportNamespace unqualifiedset;
- QHash<QString, QQmlImportNamespace *> set;
+
+ QQmlImportNamespace *findQualifiedNamespace(const QString &);
+ QFieldList<QQmlImportNamespace, &QQmlImportNamespace::nextNamespace> qualifiedSets;
+
QQmlTypeLoader *typeLoader;
static inline QString tr(const char *str) {
@@ -239,23 +252,22 @@ void QQmlImports::populateCache(QQmlTypeNameCache *cache, QQmlEngine *engine) co
cache->m_anonymousImports.append(QQmlTypeModuleVersion(module, import.minversion));
}
- for (QHash<QString, QQmlImportNamespace* >::ConstIterator iter = d->set.begin();
- iter != d->set.end();
- ++iter) {
+ for (QQmlImportNamespace *ns = d->qualifiedSets.first(); ns; ns = d->qualifiedSets.next(ns)) {
+
+ const QQmlImportNamespace &set = *ns;
- const QQmlImportNamespace &set = *iter.value();
for (int ii = set.imports.count() - 1; ii >= 0; --ii) {
const QQmlImportNamespace::Import &import = set.imports.at(ii);
QQmlTypeModule *module = QQmlMetaType::typeModule(import.uri, import.majversion);
if (module) {
- QQmlTypeNameCache::Import &typeimport = cache->m_namedImports[iter.key()];
+ QQmlTypeNameCache::Import &typeimport = cache->m_namedImports[set.prefix];
typeimport.modules.append(QQmlTypeModuleVersion(module, import.minversion));
}
QQmlMetaType::ModuleApi moduleApi = QQmlMetaType::moduleApi(import.uri, import.majversion,
import.minversion);
if (moduleApi.script || moduleApi.qobject) {
- QQmlTypeNameCache::Import &import = cache->m_namedImports[iter.key()];
+ QQmlTypeNameCache::Import &import = cache->m_namedImports[set.prefix];
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
import.moduleApi = ep->moduleApiInstance(moduleApi);
}
@@ -280,10 +292,8 @@ QList<QQmlImports::ScriptReference> QQmlImports::resolvedScripts() const
}
}
- for (QHash<QString, QQmlImportNamespace* >::ConstIterator iter = d->set.constBegin();
- iter != d->set.constEnd();
- ++iter) {
- const QQmlImportNamespace &set = *iter.value();
+ for (QQmlImportNamespace *ns = d->qualifiedSets.first(); ns; ns = d->qualifiedSets.next(ns)) {
+ const QQmlImportNamespace &set = *ns;
for (int ii = set.imports.count() - 1; ii >= 0; --ii) {
const QQmlImportNamespace::Import &import = set.imports.at(ii);
@@ -291,7 +301,7 @@ QList<QQmlImports::ScriptReference> QQmlImports::resolvedScripts() const
foreach (const QQmlDirParser::Script &script, import.qmlDirScripts) {
ScriptReference ref;
ref.nameSpace = script.nameSpace;
- ref.qualifier = iter.key();
+ ref.qualifier = set.prefix;
ref.location = QUrl(import.url).resolved(QUrl(script.fileName));
scripts.append(ref);
}
@@ -319,7 +329,7 @@ bool QQmlImports::resolveType(const QString& type,
QQmlType** type_return, QString* url_return, int *vmaj, int *vmin,
QQmlImportNamespace** ns_return, QList<QQmlError> *errors) const
{
- QQmlImportNamespace* ns = d->set.value(type);
+ QQmlImportNamespace* ns = d->findQualifiedNamespace(type);
if (ns) {
if (ns_return)
*ns_return = ns;
@@ -383,13 +393,13 @@ bool QQmlImportNamespace::Import::resolveType(QQmlTypeLoader *typeLoader,
bool typeWasDeclaredInQmldir = false;
if (!qmlDirComponents.isEmpty()) {
foreach (const QQmlDirParser::Component &c, qmlDirComponents) {
- if (c.typeName == type) {
+ if (type == c.typeName) {
typeWasDeclaredInQmldir = true;
// importing version -1 means import ALL versions
if ((majversion == -1) || (c.majorVersion == majversion &&
minversion >= c.minorVersion)) {
- QString candidate = resolveLocalUrl(QString(url + type + QLatin1String(".qml")),
- c.fileName);
+
+ QString candidate = resolveLocalUrl(QString(url + type + dotqml_string), c.fileName);
if (c.internal && base) {
if (resolveLocalUrl(*base, c.fileName) != candidate)
continue; // failed attempt to access an internal type
@@ -408,7 +418,7 @@ bool QQmlImportNamespace::Import::resolveType(QQmlTypeLoader *typeLoader,
}
if (!typeWasDeclaredInQmldir && !isLibrary) {
- QString qmlUrl(url + type + QLatin1String(".qml"));
+ QString qmlUrl = url + type + dotqml_string;
bool exists = false;
@@ -439,10 +449,10 @@ bool QQmlImportsPrivate::resolveType(const QString& type, int *vmajor, int *vmin
QList<QQmlError> *errors)
{
QQmlImportNamespace *s = 0;
- int slash = type.indexOf(QLatin1Char('/'));
- if (slash >= 0) {
- QString namespaceName = type.left(slash);
- s = set.value(namespaceName);
+ int dot = type.indexOf(QLatin1Char('.'));
+ if (dot >= 0) {
+ QString namespaceName = type.left(dot);
+ s = findQualifiedNamespace(namespaceName);
if (!s) {
if (errors) {
QQmlError error;
@@ -451,8 +461,8 @@ bool QQmlImportsPrivate::resolveType(const QString& type, int *vmajor, int *vmin
}
return false;
}
- int nslash = type.indexOf(QLatin1Char('/'),slash+1);
- if (nslash > 0) {
+ int ndot = type.indexOf(QLatin1Char('.'),dot+1);
+ if (ndot > 0) {
if (errors) {
QQmlError error;
error.setDescription(QQmlImportDatabase::tr("- nested namespaces not allowed"));
@@ -463,7 +473,7 @@ bool QQmlImportsPrivate::resolveType(const QString& type, int *vmajor, int *vmin
} else {
s = &unqualifiedset;
}
- QString unqualifiedtype = slash < 0 ? type : type.mid(slash+1); // common-case opt (QString::mid works fine, but slower)
+ QString unqualifiedtype = dot < 0 ? type : type.mid(dot+1, -1);
if (s) {
if (s->resolveType(typeLoader,unqualifiedtype,vmajor,vminor,type_return,url_return, &base, errors))
return true;
@@ -477,8 +487,8 @@ bool QQmlImportsPrivate::resolveType(const QString& type, int *vmajor, int *vmin
return false;
}
-bool QQmlImportNamespace::resolveType(QQmlTypeLoader *typeLoader, const QString& type, int *vmajor,
- int *vminor, QQmlType** type_return,
+bool QQmlImportNamespace::resolveType(QQmlTypeLoader *typeLoader, const QString& type,
+ int *vmajor, int *vminor, QQmlType** type_return,
QString* url_return, QString *base, QList<QQmlError> *errors)
{
bool typeRecursionDetected = false;
@@ -496,10 +506,10 @@ bool QQmlImportNamespace::resolveType(QQmlTypeLoader *typeLoader, const QString&
QString u2 = imports.at(j).url;
if (base) {
QString b = *base;
- int slash = b.lastIndexOf(QLatin1Char('/'));
- if (slash >= 0) {
- b = b.left(slash+1);
- QString l = b.left(slash);
+ int dot = b.lastIndexOf(QLatin1Char('.'));
+ if (dot >= 0) {
+ b = b.left(dot+1);
+ QString l = b.left(dot);
if (u1.startsWith(b))
u1 = u1.mid(b.count());
else if (u1 == l)
@@ -546,8 +556,17 @@ QQmlImportsPrivate::QQmlImportsPrivate(QQmlTypeLoader *loader)
QQmlImportsPrivate::~QQmlImportsPrivate()
{
- foreach (QQmlImportNamespace* s, set.values())
- delete s;
+ while (QQmlImportNamespace *ns = qualifiedSets.takeFirst())
+ delete ns;
+}
+
+QQmlImportNamespace *QQmlImportsPrivate::findQualifiedNamespace(const QString &prefix)
+{
+ for (QQmlImportNamespace *ns = qualifiedSets.first(); ns; ns = qualifiedSets.next(ns)) {
+ if (prefix == ns->prefix)
+ return ns;
+ }
+ return 0;
}
/*!
@@ -591,8 +610,7 @@ bool QQmlImportsPrivate::importExtension(const QString &qmldirFilePath,
qDebug().nospace() << "QQmlImports(" << qPrintable(base) << "::importExtension: "
<< "loaded " << qmldirFilePath;
- if (!qmlDirFilesForWhichPluginsHaveBeenLoaded.contains(qmldirFilePath)) {
- qmlDirFilesForWhichPluginsHaveBeenLoaded.insert(qmldirFilePath);
+ if (!database->qmlDirFilesForWhichPluginsHaveBeenLoaded.contains(qmldirFilePath)) {
QString qmldirPath = qmldirFilePath;
@@ -630,6 +648,8 @@ bool QQmlImportsPrivate::importExtension(const QString &qmldirFilePath,
return false;
}
}
+
+ database->qmlDirFilesForWhichPluginsHaveBeenLoaded.insert(qmldirFilePath);
}
if (components)
@@ -789,10 +809,12 @@ bool QQmlImportsPrivate::addImport(const QQmlDirComponents &qmldircomponentsnetw
if (prefix.isEmpty()) {
importSet = &unqualifiedset;
} else {
- importSet = set.value(prefix);
+ importSet = findQualifiedNamespace(prefix);
+
if (!importSet) {
importSet = new QQmlImportNamespace;
- set.insert(prefix, importSet);
+ importSet->prefix = prefix;
+ qualifiedSets.append(importSet);
}
}
diff --git a/src/qml/qml/qqmlimport_p.h b/src/qml/qml/qqmlimport_p.h
index d673b64766..ad0bbc6cc6 100644
--- a/src/qml/qml/qqmlimport_p.h
+++ b/src/qml/qml/qqmlimport_p.h
@@ -161,6 +161,7 @@ private:
QStringList filePluginPath;
QStringList fileImportPath;
+ QSet<QString> qmlDirFilesForWhichPluginsHaveBeenLoaded;
QSet<QString> initializedPlugins;
QQmlEngine *engine;
};
diff --git a/src/qml/qml/qqmlinstruction.cpp b/src/qml/qml/qqmlinstruction.cpp
index 82cf235712..96136ffee6 100644
--- a/src/qml/qml/qqmlinstruction.cpp
+++ b/src/qml/qml/qqmlinstruction.cpp
@@ -64,10 +64,10 @@ void QQmlCompiledData::dump(QQmlInstruction *instr, int idx)
qWarning().nospace() << idx << "\t\t" << "DONE";
break;
case QQmlInstruction::CreateCppObject:
- qWarning().nospace() << idx << "\t\t" << "CREATECPP\t\t\t" << instr->create.type << "\t\t\t" << types.at(instr->create.type).className;
+ qWarning().nospace() << idx << "\t\t" << "CREATECPP\t\t\t" << instr->create.type;
break;
case QQmlInstruction::CreateQMLObject:
- qWarning().nospace() << idx << "\t\t" << "CREATEQML\t\t\t" << instr->createQml.type << "\t" << instr->createQml.bindingBits << "\t\t" << types.at(instr->createQml.type).className;
+ qWarning().nospace() << idx << "\t\t" << "CREATEQML\t\t\t" << instr->createQml.type << "\t" << instr->createQml.bindingBits;
break;
case QQmlInstruction::CompleteQMLObject:
qWarning().nospace() << idx << "\t\t" << "COMPLETEQML";
diff --git a/src/qml/qml/qqmlscript.cpp b/src/qml/qml/qqmlscript.cpp
index b1a50a4f9a..704130d69b 100644
--- a/src/qml/qml/qqmlscript.cpp
+++ b/src/qml/qml/qqmlscript.cpp
@@ -63,8 +63,8 @@ using namespace QQmlScript;
// Parser IR classes
//
QQmlScript::Object::Object()
-: type(-1), idIndex(-1), metatype(0), synthCache(0), defaultProperty(0), parserStatusCast(-1),
- componentCompileState(0), nextAliasingObject(0), nextIdObject(0)
+: type(-1), typeReference(0), idIndex(-1), metatype(0), synthCache(0), defaultProperty(0),
+ parserStatusCast(-1), componentCompileState(0), nextAliasingObject(0), nextIdObject(0)
{
// initialize the members in the meta object
extObject.d.superdata = 0;
@@ -547,8 +547,6 @@ protected:
QQmlScript::Object *currentObject() const;
Property *currentProperty() const;
- QString qualifiedNameId() const;
-
QString textAt(const AST::SourceLocation &loc) const
{ return _contents->mid(loc.offset, loc.length); }
@@ -600,7 +598,6 @@ protected:
private:
QQmlScript::Parser *_parser;
StateStack _stateStack;
- QStringList _scope;
const QString *_contents;
};
@@ -642,11 +639,6 @@ Property *ProcessAST::currentProperty() const
return state().property;
}
-QString ProcessAST::qualifiedNameId() const
-{
- return _scope.join(QLatin1String("/"));
-}
-
void ProcessAST::extractVersion(QStringRef string, int *maj, int *min)
{
*maj = -1; *min = -1;
@@ -749,22 +741,10 @@ ProcessAST::defineObjectBinding(AST::UiQualifiedId *propertyName,
} else {
// Class
- QString resolvableObjectType = objectType;
- if (lastTypeDot >= 0)
- resolvableObjectType.replace(QLatin1Char('.'),QLatin1Char('/'));
-
QQmlScript::Object *obj = _parser->_pool.New<QQmlScript::Object>();
- QQmlScript::TypeReference *typeRef = _parser->findOrCreateType(resolvableObjectType);
- obj->type = typeRef->id;
-
- typeRef->refObjects.append(obj);
-
- // XXX this doesn't do anything (_scope never builds up)
- _scope.append(resolvableObjectType);
- obj->typeName = qualifiedNameId();
- _scope.removeLast();
-
+ obj->type = _parser->findOrCreateTypeId(objectType, obj);
+ obj->typeReference = _parser->_refTypes.at(obj->type);
obj->location = location;
if (propertyCount) {
@@ -1059,9 +1039,8 @@ bool ProcessAST::visit(AST::UiPublicMember *node)
property->nameLocation.line = node->identifierToken.startLine;
property->nameLocation.column = node->identifierToken.startColumn;
if (type >= Object::DynamicProperty::Custom) {
- QQmlScript::TypeReference *typeRef =
- _parser->findOrCreateType(memberType.toString());
- typeRef->refObjects.append(_stateStack.top().object);
+ // This forces the type to be added to the resolved types list
+ _parser->findOrCreateTypeId(memberType.toString(), _stateStack.top().object);
property->customType = memberType;
}
@@ -1301,7 +1280,7 @@ QByteArray QQmlScript::Parser::preparseData() const
return QByteArray();
}
-bool QQmlScript::Parser::parse(const QString &qmlcode, const QByteArray &preparseData,
+bool QQmlScript::Parser::parse(const QString &qmlcode, const QByteArray & /* preparseData */,
const QUrl &url, const QString &urlString)
{
clear();
@@ -1672,7 +1651,6 @@ QQmlScript::Parser::JavaScriptMetaData QQmlScript::Parser::extractMetaData(QStri
void QQmlScript::Parser::clear()
{
_imports.clear();
- qDeleteAll(_refTypes);
_refTypes.clear();
_errors.clear();
@@ -1684,22 +1662,18 @@ void QQmlScript::Parser::clear()
_pool.clear();
}
-QQmlScript::TypeReference *QQmlScript::Parser::findOrCreateType(const QString &name)
+int QQmlScript::Parser::findOrCreateTypeId(const QString &name, Object *object)
{
- TypeReference *type = 0;
- int i = 0;
- for (; i < _refTypes.size(); ++i) {
- if (_refTypes.at(i)->name == name) {
- type = _refTypes.at(i);
- break;
- }
- }
- if (!type) {
- type = new TypeReference(i, name);
- _refTypes.append(type);
+ for (int ii = 0; ii < _refTypes.size(); ++ii) {
+ if (_refTypes.at(ii)->name == name)
+ return ii;
}
- return type;
+ TypeReference *type = _pool.New<TypeReference>();
+ type->name = name;
+ type->firstUse = object;
+ _refTypes.append(type);
+ return _refTypes.size() - 1;
}
void QQmlScript::Parser::setTree(QQmlScript::Object *tree)
diff --git a/src/qml/qml/qqmlscript_p.h b/src/qml/qml/qqmlscript_p.h
index 1e46e6b655..0a762d457f 100644
--- a/src/qml/qml/qqmlscript_p.h
+++ b/src/qml/qml/qqmlscript_p.h
@@ -124,16 +124,13 @@ public:
};
class Object;
-class TypeReference
+class TypeReference : public QQmlPool::Class
{
public:
- TypeReference(int typeId, const QString &typeName) : id(typeId), name(typeName) {}
-
- int id;
// type as it has been referenced in Qml
QString name;
- // objects in parse tree referencing the type
- QList<QQmlScript::Object*> refObjects;
+ // The first use of this type in the parse tree. Useful for error locations.
+ QQmlScript::Object *firstUse;
};
class Object;
@@ -310,9 +307,10 @@ public:
// QQmlCompiledData::types array, or -1 if the object is a property
// group.
int type;
+ // A back pointer to the QQmlScript::TypeReference for this type, if any.
+ // Set by the parser.
+ TypeReference *typeReference;
- // The fully-qualified name of this type
- QString typeName;
// The id assigned to the object (if any). Set by the QQmlCompiler
QString id;
// The id index assigned to the object (if any). Set by the QQmlCompiler
@@ -503,7 +501,7 @@ public:
// ### private:
- TypeReference *findOrCreateType(const QString &name);
+ int findOrCreateTypeId(const QString &name, Object *);
void setTree(QQmlScript::Object *tree);
void setScriptFile(const QString &filename) {_scriptFile = filename; }
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index 2e8f17e6cd..4b5aa6cd32 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -1851,10 +1851,8 @@ void QQmlTypeData::resolveTypes()
// - known to be a namespace (Namespace {})
// - type with unknown namespace (UnknownNamespace.SomeType {})
QQmlError error;
- QString userTypeName = parserRef->name;
- userTypeName.replace(QLatin1Char('/'),QLatin1Char('.'));
if (typeNamespace) {
- error.setDescription(QQmlTypeLoader::tr("Namespace %1 cannot be used as a type").arg(userTypeName));
+ error.setDescription(QQmlTypeLoader::tr("Namespace %1 cannot be used as a type").arg(parserRef->name));
} else {
if (errors.size()) {
error = errors.takeFirst();
@@ -1864,14 +1862,12 @@ void QQmlTypeData::resolveTypes()
error.setDescription(QQmlTypeLoader::tr("Unreported error adding script import to import database"));
}
error.setUrl(m_imports.baseUrl());
- error.setDescription(QQmlTypeLoader::tr("%1 %2").arg(userTypeName).arg(error.description()));
+ error.setDescription(QQmlTypeLoader::tr("%1 %2").arg(parserRef->name).arg(error.description()));
}
- if (!parserRef->refObjects.isEmpty()) {
- QQmlScript::Object *obj = parserRef->refObjects.first();
- error.setLine(obj->location.start.line);
- error.setColumn(obj->location.start.column);
- }
+ Q_ASSERT(parserRef->firstUse);
+ error.setLine(parserRef->firstUse->location.start.line);
+ error.setColumn(parserRef->firstUse->location.start.column);
errors.prepend(error);
setError(errors);
@@ -1886,8 +1882,8 @@ void QQmlTypeData::resolveTypes()
addDependency(ref.typeData);
}
- if (parserRef->refObjects.count())
- ref.location = parserRef->refObjects.first()->location.start;
+ Q_ASSERT(parserRef->firstUse);
+ ref.location = parserRef->firstUse->location.start;
m_types << ref;
}
diff --git a/src/qml/qml/qqmlvme.cpp b/src/qml/qml/qqmlvme.cpp
index 6047688a95..357200d5a5 100644
--- a/src/qml/qml/qqmlvme.cpp
+++ b/src/qml/qml/qqmlvme.cpp
@@ -559,7 +559,8 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
}
if (!o)
- VME_EXCEPTION(tr("Unable to create object of type %1").arg(type.className), instr.line);
+ VME_EXCEPTION(tr("Unable to create object of type %1").arg(type.type->elementName()),
+ instr.line);
if (instr.isRoot) {
if (ddata->context) {
diff --git a/tests/auto/qml/qqmlinstruction/tst_qqmlinstruction.cpp b/tests/auto/qml/qqmlinstruction/tst_qqmlinstruction.cpp
index d0e818f076..18b3653607 100644
--- a/tests/auto/qml/qqmlinstruction/tst_qqmlinstruction.cpp
+++ b/tests/auto/qml/qqmlinstruction/tst_qqmlinstruction.cpp
@@ -86,10 +86,6 @@ void tst_qqmlinstruction::dump()
}
{
- QQmlCompiledData::TypeReference ref;
- ref.className = "Test";
- data->types << ref;
-
QQmlCompiledData::Instruction::CreateCppObject i;
i.type = 0;
i.data = -1;
@@ -476,7 +472,7 @@ void tst_qqmlinstruction::dump()
<< "Index\tOperation\t\tData1\tData2\tData3\tComments"
<< "-------------------------------------------------------------------------------"
<< "0\t\tINIT\t\t\t0\t3\t-1\t-1"
- << "1\t\tCREATECPP\t\t\t0\t\t\t\"Test\""
+ << "1\t\tCREATECPP\t\t\t0"
<< "2\t\tSETID\t\t\t0\t\t\t\"testId\""
<< "3\t\tSET_DEFAULT"
<< "4\t\tCREATE_COMPONENT\t3"