QmlDesigner: Prevent prototype chains cycles

A cycle would lead to an endless loop. So we throw an exception for
synchronization. Maybe we can add later more information to user so
he can easily resolve the error.

Task-number: QDS-4457
Change-Id: I83092ccdff030a610942c155571a0bfa899e808c
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
Marco Bubke
2021-07-06 15:45:10 +02:00
parent a8d6bb06df
commit a30775a19e
3 changed files with 76 additions and 8 deletions

View File

@@ -912,8 +912,15 @@ TEST_F(ProjectStorageSlowTest, SynchronizeTypesAddsNewTypesThrowsWithWrongExport
TEST_F(ProjectStorageSlowTest, SynchronizeTypesAddsNewTypesWithMissingImportAndExportedPrototypeName)
{
Storage::Types types{createTypes()};
types.push_back(Storage::Type{importId3,
"QObject2",
Storage::NativeType{},
TypeAccessSemantics::Reference,
sourceId4,
importIds,
{Storage::ExportedType{"Object2"}, Storage::ExportedType{"Obj2"}}});
storage.synchronizeDocuments({Storage::Document{sourceId1, {importId1}}});
types[1].prototype = Storage::ExportedType{"Object"};
types[1].prototype = Storage::ExportedType{"Object2"};
ASSERT_THROW(storage.synchronizeTypes(types, {sourceId1, sourceId2}),
QmlDesigner::TypeNameDoesNotExists);
@@ -3070,4 +3077,40 @@ TEST_F(ProjectStorageSlowTest, ChangePrototypeTypeNameThrowsForWrongNativeProtot
QmlDesigner::TypeNameDoesNotExists);
}
TEST_F(ProjectStorageSlowTest, ThrowForPrototypeChainCycles)
{
Storage::Types types{createTypes()};
types[1].prototype = Storage::ExportedType{"Object2"};
types.push_back(Storage::Type{importId3,
"QObject2",
Storage::ExportedType{"Item"},
TypeAccessSemantics::Reference,
sourceId3,
importIds,
{Storage::ExportedType{"Object2"}, Storage::ExportedType{"Obj2"}}});
ASSERT_THROW(storage.synchronizeTypes(types, {sourceId1, sourceId2, sourceId3}),
QmlDesigner::PrototypeChainCycle);
}
TEST_F(ProjectStorageSlowTest, ThrowForTypeIdAndPrototypeIdAreTheSame)
{
Storage::Types types{createTypes()};
types[1].prototype = Storage::ExportedType{"Object"};
ASSERT_THROW(storage.synchronizeTypes(types, {sourceId1, sourceId2}),
QmlDesigner::PrototypeChainCycle);
}
TEST_F(ProjectStorageSlowTest, ThrowForTypeIdAndPrototypeIdAreTheSameForRelinking)
{
Storage::Types types{createTypes()};
types[0].propertyDeclarations[0].typeName = Storage::ExportedType{"Object"};
types[0].prototype = Storage::ExportedType{"Object"};
storage.synchronizeTypes(types, {sourceId1, sourceId2});
types[1].prototype = Storage::ExportedType{"Item"};
types[1].typeName = "QObject2";
ASSERT_THROW(storage.synchronizeTypes({types[1]}, {sourceId2}), QmlDesigner::PrototypeChainCycle);
}
} // namespace