From 3d3429f55bca1b09c1d2184ef719abae0e762a09 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 27 Jan 2014 16:55:49 +0100 Subject: [PATCH] [new compiler] Avoid uncreatable type errors for types that aren't created QtQuick.Keys for example is not creatable, but it's also never created but only used as attached properties. Therefore types used as attached properties create the needCreation = false flag in the referenced types. Change-Id: I6ca3a3ff677858bf3c55d3e08a0f0fc8ee9160fe Reviewed-by: Lars Knoll --- src/qml/compiler/qqmlcodegenerator.cpp | 9 ++++++--- src/qml/compiler/qqmltypecompiler.cpp | 4 ++-- src/qml/compiler/qv4compileddata_p.h | 21 ++++++++++++++++----- src/qml/qml/qqmltypeloader.cpp | 10 ++++++---- src/qml/qml/qqmltypeloader_p.h | 3 ++- 5 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/qml/compiler/qqmlcodegenerator.cpp b/src/qml/compiler/qqmlcodegenerator.cpp index 344c38bf5..6776c1e91 100644 --- a/src/qml/compiler/qqmlcodegenerator.cpp +++ b/src/qml/compiler/qqmlcodegenerator.cpp @@ -1056,14 +1056,17 @@ void QQmlCodeGenerator::recordError(const AST::SourceLocation &location, const Q void QQmlCodeGenerator::collectTypeReferences() { foreach (QmlObject *obj, _objects) { - if (!stringAt(obj->inheritedTypeNameIndex).isEmpty()) - _typeReferences.add(obj->inheritedTypeNameIndex, obj->location); + if (!stringAt(obj->inheritedTypeNameIndex).isEmpty()) { + QV4::CompiledData::TypeReference &r = _typeReferences.add(obj->inheritedTypeNameIndex, obj->location); + r.needsCreation = true; + } for (QmlProperty *prop = obj->properties->first; prop; prop = prop->next) { if (prop->type >= QV4::CompiledData::Property::Custom) { // ### FIXME: We could report the more accurate location here by using prop->location, but the old // compiler can't and the tests expect it to be the object location right now. - _typeReferences.add(prop->customTypeNameIndex, obj->location); + QV4::CompiledData::TypeReference &r = _typeReferences.add(prop->customTypeNameIndex, obj->location); + r.needsCreation = true; } } diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp index 6fe356703..1dc10fbf0 100644 --- a/src/qml/compiler/qqmltypecompiler.cpp +++ b/src/qml/compiler/qqmltypecompiler.cpp @@ -84,7 +84,7 @@ bool QQmlTypeCompiler::compile() QScopedPointer ref(new QQmlCompiledData::TypeReference); QQmlType *qmlType = resolvedType->type; if (resolvedType->typeData) { - if (qmlType->isCompositeSingleton()) { + if (resolvedType->needsCreation && qmlType->isCompositeSingleton()) { QQmlError error; QString reason = tr("Composite Singleton Type %1 is not creatable.").arg(qmlType->qmlTypeName()); error.setDescription(reason); @@ -99,7 +99,7 @@ bool QQmlTypeCompiler::compile() ref->type = qmlType; Q_ASSERT(ref->type); - if (!ref->type->isCreatable()) { + if (resolvedType->needsCreation && !ref->type->isCreatable()) { QQmlError error; QString reason = ref->type->noCreationReason(); if (reason.isEmpty()) diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h index 06361fbf8..29b6fd564 100644 --- a/src/qml/compiler/qv4compileddata_p.h +++ b/src/qml/compiler/qv4compileddata_p.h @@ -74,13 +74,24 @@ struct Location qint32 column; }; +struct TypeReference +{ + TypeReference(const Location &loc) + : location(loc) + , needsCreation(false) + {} + Location location; // first use + bool needsCreation; // whether the type needs to be creatable or not +}; + // map from name index to location of first use -struct TypeReferenceMap : QHash +struct TypeReferenceMap : QHash { - void add(int nameIndex, const Location &loc) { - if (contains(nameIndex)) - return; - insert(nameIndex, loc); + TypeReference &add(int nameIndex, const Location &loc) { + Iterator it = find(nameIndex); + if (it != end()) + return *it; + return *insert(nameIndex, loc); } }; diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index f734b77ee..7c32d4f19 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -2453,8 +2453,8 @@ void QQmlTypeData::resolveTypes() error.setDescription(QQmlTypeLoader::tr("%1 %2").arg(name).arg(error.description())); } - error.setLine(unresolvedRef->line); - error.setColumn(unresolvedRef->column); + error.setLine(unresolvedRef->location.line); + error.setColumn(unresolvedRef->location.column); errors.prepend(error); setError(errors); @@ -2468,8 +2468,10 @@ void QQmlTypeData::resolveTypes() ref.majorVersion = majorVersion; ref.minorVersion = minorVersion; - ref.location.line = unresolvedRef->line; - ref.location.column = unresolvedRef->column; + ref.location.line = unresolvedRef->location.line; + ref.location.column = unresolvedRef->location.column; + + ref.needsCreation = unresolvedRef->needsCreation; m_resolvedTypes.insert(unresolvedRef.key(), ref); } diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h index 976f5a5ff..02797220c 100644 --- a/src/qml/qml/qqmltypeloader_p.h +++ b/src/qml/qml/qqmltypeloader_p.h @@ -396,7 +396,7 @@ class Q_AUTOTEST_EXPORT QQmlTypeData : public QQmlTypeLoader::Blob public: struct TypeReference { - TypeReference() : type(0), majorVersion(0), minorVersion(0), typeData(0) {} + TypeReference() : type(0), majorVersion(0), minorVersion(0), typeData(0), needsCreation(true) {} QQmlScript::Location location; QQmlType *type; @@ -404,6 +404,7 @@ public: int minorVersion; QQmlTypeData *typeData; QString prefix; // used by CompositeSingleton types + bool needsCreation; }; struct ScriptReference -- 2.34.1