forked from qt-creator/qt-creator
QmlDesigner: Remove duplicate exports in qmldir
Fixes: QDS-13909 Change-Id: I9f369024d832d210c2efaed6410c462ef8af8bd7 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -1167,6 +1167,32 @@ void rangeForTheSameFileName(const ProjectStorageUpdater::Components &components
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void removeDuplicates(Storage::Synchronization::ExportedTypes &exportedTypes)
|
||||
{
|
||||
using Storage::Synchronization::ExportedType;
|
||||
|
||||
auto factory = [](auto... projections) {
|
||||
return [=](auto compare) {
|
||||
return [=](const auto &first, const auto &second) {
|
||||
return compare(std::forward_as_tuple(std::invoke(projections, first)...),
|
||||
std::forward_as_tuple(std::invoke(projections, second)...));
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
auto compare = factory(&ExportedType::name, &ExportedType::version);
|
||||
auto less = compare(std::ranges::less{});
|
||||
auto equal = compare(std::ranges::equal_to{});
|
||||
|
||||
std::ranges::sort(exportedTypes, less);
|
||||
|
||||
auto duplicateExportedTypes = std::ranges::unique(exportedTypes, equal);
|
||||
exportedTypes.erase(duplicateExportedTypes.begin(), duplicateExportedTypes.end());
|
||||
}
|
||||
} // namespace
|
||||
|
||||
Storage::Synchronization::ExportedTypes createExportedTypes(ProjectStorageUpdater::ComponentRange components)
|
||||
{
|
||||
Storage::Synchronization::ExportedTypes exportedTypes;
|
||||
@@ -1178,6 +1204,8 @@ Storage::Synchronization::ExportedTypes createExportedTypes(ProjectStorageUpdate
|
||||
Storage::Version{component.majorVersion, component.minorVersion});
|
||||
}
|
||||
|
||||
removeDuplicates(exportedTypes);
|
||||
|
||||
return exportedTypes;
|
||||
}
|
||||
|
||||
@@ -1197,9 +1225,8 @@ void ProjectStorageUpdater::parseQmlComponents(Components components,
|
||||
keyValue("directory id", directoryId),
|
||||
keyValue("qmldir state", qmldirState)};
|
||||
|
||||
std::sort(components.begin(), components.end(), [](auto &&first, auto &&second) {
|
||||
return first.fileName < second.fileName;
|
||||
});
|
||||
std::ranges::sort(components,
|
||||
[](auto &&first, auto &&second) { return first.fileName < second.fileName; });
|
||||
|
||||
auto directoryPath = m_pathCache.sourceContextPath(directoryId);
|
||||
|
||||
|
@@ -830,6 +830,82 @@ TEST_F(ProjectStorageUpdater, synchronize_qml_documents)
|
||||
updater.update({.directories = directories});
|
||||
}
|
||||
|
||||
TEST_F(ProjectStorageUpdater, skip_duplicate_qmldir_entries)
|
||||
{
|
||||
QString qmldir{R"(module Example
|
||||
FirstType 1.0 First.qml
|
||||
FirstType 1.0 First.qml
|
||||
FirstType 2.0 First.qml
|
||||
FirstType 2.2 First2.qml
|
||||
SecondType 2.2 Second.qml)"};
|
||||
setContent(u"/path/qmldir", qmldir);
|
||||
|
||||
EXPECT_CALL(
|
||||
projectStorageMock,
|
||||
synchronize(AllOf(
|
||||
Field(&SynchronizationPackage::imports, UnorderedElementsAre(import1, import2, import3)),
|
||||
Field(
|
||||
&SynchronizationPackage::types,
|
||||
UnorderedElementsAre(
|
||||
AllOf(IsStorageType("First.qml",
|
||||
Storage::Synchronization::ImportedType{"Object"},
|
||||
TypeTraitsKind::Reference,
|
||||
qmlDocumentSourceId1,
|
||||
Storage::Synchronization::ChangeLevel::Full),
|
||||
Field(&Storage::Synchronization::Type::exportedTypes,
|
||||
UnorderedElementsAre(IsExportedType(exampleModuleId, "FirstType", 1, 0),
|
||||
IsExportedType(exampleModuleId, "FirstType", 2, 0),
|
||||
IsExportedType(pathModuleId, "First", -1, -1)))),
|
||||
AllOf(IsStorageType("First2.qml",
|
||||
Storage::Synchronization::ImportedType{"Object2"},
|
||||
TypeTraitsKind::Reference,
|
||||
qmlDocumentSourceId2,
|
||||
Storage::Synchronization::ChangeLevel::Full),
|
||||
Field(&Storage::Synchronization::Type::exportedTypes,
|
||||
UnorderedElementsAre(IsExportedType(exampleModuleId, "FirstType", 2, 2),
|
||||
IsExportedType(pathModuleId, "First2", -1, -1)))),
|
||||
AllOf(IsStorageType("Second.qml",
|
||||
Storage::Synchronization::ImportedType{"Object3"},
|
||||
TypeTraitsKind::Reference,
|
||||
qmlDocumentSourceId3,
|
||||
Storage::Synchronization::ChangeLevel::Full),
|
||||
Field(&Storage::Synchronization::Type::exportedTypes,
|
||||
UnorderedElementsAre(IsExportedType(exampleModuleId, "SecondType", 2, 2),
|
||||
IsExportedType(pathModuleId, "Second", -1, -1)))))),
|
||||
Field(&SynchronizationPackage::updatedSourceIds,
|
||||
UnorderedElementsAre(qmlDirPathSourceId,
|
||||
qmlDocumentSourceId1,
|
||||
qmlDocumentSourceId2,
|
||||
qmlDocumentSourceId3)),
|
||||
Field(&SynchronizationPackage::updatedFileStatusSourceIds,
|
||||
UnorderedElementsAre(qmlDirPathSourceId,
|
||||
qmlDocumentSourceId1,
|
||||
qmlDocumentSourceId2,
|
||||
qmlDocumentSourceId3)),
|
||||
Field(&SynchronizationPackage::fileStatuses,
|
||||
UnorderedElementsAre(IsFileStatus(qmlDirPathSourceId, 1, 21),
|
||||
IsFileStatus(qmlDocumentSourceId1, 1, 21),
|
||||
IsFileStatus(qmlDocumentSourceId2, 1, 21),
|
||||
IsFileStatus(qmlDocumentSourceId3, 1, 21))),
|
||||
Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds,
|
||||
UnorderedElementsAre(directoryPathSourceId)),
|
||||
Field(&SynchronizationPackage::directoryInfos,
|
||||
UnorderedElementsAre(IsDirectoryInfo(directoryPathSourceId,
|
||||
qmlDocumentSourceId1,
|
||||
ModuleId{},
|
||||
FileType::QmlDocument),
|
||||
IsDirectoryInfo(directoryPathSourceId,
|
||||
qmlDocumentSourceId2,
|
||||
ModuleId{},
|
||||
FileType::QmlDocument),
|
||||
IsDirectoryInfo(directoryPathSourceId,
|
||||
qmlDocumentSourceId3,
|
||||
ModuleId{},
|
||||
FileType::QmlDocument))))));
|
||||
|
||||
updater.update({.directories = directories});
|
||||
}
|
||||
|
||||
TEST_F(ProjectStorageUpdater, synchronize_add_only_qml_document_in_directory)
|
||||
{
|
||||
QString qmldir{R"(module Example
|
||||
|
Reference in New Issue
Block a user