diff options
author | Marco Bubke <marco.bubke@qt.io> | 2022-02-16 16:06:06 +0100 |
---|---|---|
committer | Marco Bubke <marco.bubke@qt.io> | 2022-02-16 18:10:46 +0000 |
commit | 3225cd92eba6eacbb64c089796b9ae4bbc86e78e (patch) | |
tree | 8bf769dea221707653518f454a5a2409b4c3d718 | |
parent | 7084ee0eab51edc16c2e79755f451d21697ed895 (diff) |
QmlDesigner: Handle double entries in qmldir files
There can be double entries for dependencies or imports.
Change-Id: Id2ef9b1bd17ca6f179208215bb782b8b9931e66b
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
-rw-r--r-- | src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.cpp | 40 | ||||
-rw-r--r-- | tests/unit/unittest/projectstorageupdater-test.cpp | 69 |
2 files changed, 101 insertions, 8 deletions
diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.cpp b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.cpp index d628b3191c..d144647fd2 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.cpp +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.cpp @@ -41,6 +41,29 @@ namespace QmlDesigner { namespace { +QStringList filterMultipleEntries(QStringList qmlTypes) +{ + std::sort(qmlTypes.begin(), qmlTypes.end()); + qmlTypes.erase(std::unique(qmlTypes.begin(), qmlTypes.end()), qmlTypes.end()); + + return qmlTypes; +} + +QList<QmlDirParser::Import> filterMultipleEntries(QList<QmlDirParser::Import> imports) +{ + std::stable_sort(imports.begin(), imports.end(), [](auto &&first, auto &&second) { + return first.module < second.module; + }); + imports.erase(std::unique(imports.begin(), + imports.end(), + [](auto &&first, auto &&second) { + return first.module == second.module; + }), + imports.end()); + + return imports; +} + ComponentReferences createComponentReferences(const QMultiHash<QString, QmlDirParser::Component> &components) { ComponentReferences componentReferences; @@ -198,21 +221,22 @@ void ProjectStorageUpdater::updateQmldirs(const QStringList &qmlDirs, Utils::PathString moduleName{parser.typeNamespace()}; ModuleId moduleId = m_projectStorage.moduleId(moduleName); - addModuleExportedImports(package.moduleExportedImports, - moduleId, - parser.imports(), - m_projectStorage); + auto imports = filterMultipleEntries(parser.imports()); + + addModuleExportedImports(package.moduleExportedImports, moduleId, imports, m_projectStorage); package.updatedModuleIds.push_back(moduleId); const auto qmlProjectDatas = m_projectStorage.fetchProjectDatas(qmlDirSourceId); addSourceIds(package.updatedSourceIds, qmlProjectDatas); addSourceIds(package.updatedFileStatusSourceIds, qmlProjectDatas); - if (!parser.typeInfos().isEmpty()) { + auto qmlTypes = filterMultipleEntries(parser.typeInfos()); + + if (!qmlTypes.isEmpty()) { ModuleId cppModuleId = m_projectStorage.moduleId(moduleName + "-cppnative"); - parseTypeInfos(parser.typeInfos(), - parser.dependencies(), - parser.imports(), + parseTypeInfos(qmlTypes, + filterMultipleEntries(parser.dependencies()), + imports, qmlDirSourceId, directoryId, cppModuleId, diff --git a/tests/unit/unittest/projectstorageupdater-test.cpp b/tests/unit/unittest/projectstorageupdater-test.cpp index 69ed54ef9b..b33c1a89e5 100644 --- a/tests/unit/unittest/projectstorageupdater-test.cpp +++ b/tests/unit/unittest/projectstorageupdater-test.cpp @@ -1076,6 +1076,32 @@ TEST_F(ProjectStorageUpdater, SynchronizeQmldirDependencies) updater.update(qmlDirs, {}); } +TEST_F(ProjectStorageUpdater, SynchronizeQmldirDependenciesWithDoubleEntries) +{ + QString qmldir{R"(module Example + depends Qml + depends QML + depends Qml + typeinfo example.qmltypes + typeinfo types/example2.qmltypes + )"}; + ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/qmldir")))).WillByDefault(Return(qmldir)); + + EXPECT_CALL( + projectStorageMock, + synchronize(AllOf( + Field(&SynchronizationPackage::moduleDependencies, + UnorderedElementsAre( + Import{qmlCppNativeModuleId, Storage::Version{}, qmltypesPathSourceId}, + Import{builtinCppNativeModuleId, Storage::Version{}, qmltypesPathSourceId}, + Import{qmlCppNativeModuleId, Storage::Version{}, qmltypes2PathSourceId}, + Import{builtinCppNativeModuleId, Storage::Version{}, qmltypes2PathSourceId})), + Field(&SynchronizationPackage::updatedModuleDependencySourceIds, + UnorderedElementsAre(qmltypesPathSourceId, qmltypes2PathSourceId))))); + + updater.update(qmlDirs, {}); +} + TEST_F(ProjectStorageUpdater, SynchronizeQmldirWithNoDependencies) { QString qmldir{R"(module Example @@ -1149,4 +1175,47 @@ TEST_F(ProjectStorageUpdater, SynchronizeQmldirWithNoImports) updater.update(qmlDirs, {}); } +TEST_F(ProjectStorageUpdater, SynchronizeQmldirImportsWithDoubleEntries) +{ + QString qmldir{R"(module Example + import Qml auto + import QML 2.1 + import Quick + import Qml + )"}; + ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/qmldir")))).WillByDefault(Return(qmldir)); + + EXPECT_CALL(projectStorageMock, + synchronize( + AllOf(Field(&SynchronizationPackage::moduleExportedImports, + UnorderedElementsAre(ModuleExportedImport{exampleModuleId, + qmlModuleId, + Storage::Version{}, + IsAutoVersion::Yes}, + ModuleExportedImport{exampleModuleId, + qmlCppNativeModuleId, + Storage::Version{}, + IsAutoVersion::No}, + ModuleExportedImport{exampleModuleId, + builtinModuleId, + Storage::Version{2, 1}, + IsAutoVersion::No}, + ModuleExportedImport{exampleModuleId, + builtinCppNativeModuleId, + Storage::Version{}, + IsAutoVersion::No}, + ModuleExportedImport{exampleModuleId, + quickModuleId, + Storage::Version{}, + IsAutoVersion::No}, + ModuleExportedImport{exampleModuleId, + quickCppNativeModuleId, + Storage::Version{}, + IsAutoVersion::No})), + Field(&SynchronizationPackage::updatedModuleIds, + ElementsAre(exampleModuleId))))); + + updater.update(qmlDirs, {}); +} + } // namespace |