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 createExportedTypes(ProjectStorageUpdater::ComponentRange components)
|
||||||
{
|
{
|
||||||
Storage::Synchronization::ExportedTypes exportedTypes;
|
Storage::Synchronization::ExportedTypes exportedTypes;
|
||||||
@@ -1178,6 +1204,8 @@ Storage::Synchronization::ExportedTypes createExportedTypes(ProjectStorageUpdate
|
|||||||
Storage::Version{component.majorVersion, component.minorVersion});
|
Storage::Version{component.majorVersion, component.minorVersion});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
removeDuplicates(exportedTypes);
|
||||||
|
|
||||||
return exportedTypes;
|
return exportedTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1197,9 +1225,8 @@ void ProjectStorageUpdater::parseQmlComponents(Components components,
|
|||||||
keyValue("directory id", directoryId),
|
keyValue("directory id", directoryId),
|
||||||
keyValue("qmldir state", qmldirState)};
|
keyValue("qmldir state", qmldirState)};
|
||||||
|
|
||||||
std::sort(components.begin(), components.end(), [](auto &&first, auto &&second) {
|
std::ranges::sort(components,
|
||||||
return first.fileName < second.fileName;
|
[](auto &&first, auto &&second) { return first.fileName < second.fileName; });
|
||||||
});
|
|
||||||
|
|
||||||
auto directoryPath = m_pathCache.sourceContextPath(directoryId);
|
auto directoryPath = m_pathCache.sourceContextPath(directoryId);
|
||||||
|
|
||||||
|
@@ -830,6 +830,82 @@ TEST_F(ProjectStorageUpdater, synchronize_qml_documents)
|
|||||||
updater.update({.directories = directories});
|
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)
|
TEST_F(ProjectStorageUpdater, synchronize_add_only_qml_document_in_directory)
|
||||||
{
|
{
|
||||||
QString qmldir{R"(module Example
|
QString qmldir{R"(module Example
|
||||||
|
Reference in New Issue
Block a user