[new compiler] Avoid uncreatable type errors for types that aren't created
authorSimon Hausmann <simon.hausmann@digia.com>
Mon, 27 Jan 2014 15:55:49 +0000 (16:55 +0100)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Wed, 29 Jan 2014 09:08:50 +0000 (10:08 +0100)
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 <lars.knoll@digia.com>
src/qml/compiler/qqmlcodegenerator.cpp
src/qml/compiler/qqmltypecompiler.cpp
src/qml/compiler/qv4compileddata_p.h
src/qml/qml/qqmltypeloader.cpp
src/qml/qml/qqmltypeloader_p.h

index 344c38bf54fdf42effb8d098c96c71721e6f92c7..6776c1e91b145f30a9963499f0b17e68c21412c4 100644 (file)
@@ -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;
             }
         }
 
index 6fe3567031dd329643bc5a326dad66810d17b58b..1dc10fbf0ac09ce6ea7d8d43b69e5530428b927d 100644 (file)
@@ -84,7 +84,7 @@ bool QQmlTypeCompiler::compile()
         QScopedPointer<QQmlCompiledData::TypeReference> 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())
index 06361fbf85b2f041dcc38cc34fa654b066016f5f..29b6fd564ea2d2802f35819f3ff04a30b2c890fc 100644 (file)
@@ -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<int, Location>
+struct TypeReferenceMap : QHash<int, TypeReference>
 {
-    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);
     }
 };
 
index f734b77eecc8022d720ad3e6dfa563e2625e3914..7c32d4f19ccfb99e3cfc072c674d34623dc0431c 100644 (file)
@@ -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);
     }
index 976f5a5ffb4b3e172e3bb13b610f669e0ea98c06..02797220c59bbf3d1d36b35fb97e3e96262c5a6d 100644 (file)
@@ -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