forked from qt-creator/qt-creator
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>
This commit is contained in:
@@ -41,6 +41,29 @@
|
|||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
namespace {
|
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 createComponentReferences(const QMultiHash<QString, QmlDirParser::Component> &components)
|
||||||
{
|
{
|
||||||
ComponentReferences componentReferences;
|
ComponentReferences componentReferences;
|
||||||
@@ -198,21 +221,22 @@ void ProjectStorageUpdater::updateQmldirs(const QStringList &qmlDirs,
|
|||||||
Utils::PathString moduleName{parser.typeNamespace()};
|
Utils::PathString moduleName{parser.typeNamespace()};
|
||||||
ModuleId moduleId = m_projectStorage.moduleId(moduleName);
|
ModuleId moduleId = m_projectStorage.moduleId(moduleName);
|
||||||
|
|
||||||
addModuleExportedImports(package.moduleExportedImports,
|
auto imports = filterMultipleEntries(parser.imports());
|
||||||
moduleId,
|
|
||||||
parser.imports(),
|
addModuleExportedImports(package.moduleExportedImports, moduleId, imports, m_projectStorage);
|
||||||
m_projectStorage);
|
|
||||||
package.updatedModuleIds.push_back(moduleId);
|
package.updatedModuleIds.push_back(moduleId);
|
||||||
|
|
||||||
const auto qmlProjectDatas = m_projectStorage.fetchProjectDatas(qmlDirSourceId);
|
const auto qmlProjectDatas = m_projectStorage.fetchProjectDatas(qmlDirSourceId);
|
||||||
addSourceIds(package.updatedSourceIds, qmlProjectDatas);
|
addSourceIds(package.updatedSourceIds, qmlProjectDatas);
|
||||||
addSourceIds(package.updatedFileStatusSourceIds, qmlProjectDatas);
|
addSourceIds(package.updatedFileStatusSourceIds, qmlProjectDatas);
|
||||||
|
|
||||||
if (!parser.typeInfos().isEmpty()) {
|
auto qmlTypes = filterMultipleEntries(parser.typeInfos());
|
||||||
|
|
||||||
|
if (!qmlTypes.isEmpty()) {
|
||||||
ModuleId cppModuleId = m_projectStorage.moduleId(moduleName + "-cppnative");
|
ModuleId cppModuleId = m_projectStorage.moduleId(moduleName + "-cppnative");
|
||||||
parseTypeInfos(parser.typeInfos(),
|
parseTypeInfos(qmlTypes,
|
||||||
parser.dependencies(),
|
filterMultipleEntries(parser.dependencies()),
|
||||||
parser.imports(),
|
imports,
|
||||||
qmlDirSourceId,
|
qmlDirSourceId,
|
||||||
directoryId,
|
directoryId,
|
||||||
cppModuleId,
|
cppModuleId,
|
||||||
|
@@ -1076,6 +1076,32 @@ TEST_F(ProjectStorageUpdater, SynchronizeQmldirDependencies)
|
|||||||
updater.update(qmlDirs, {});
|
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)
|
TEST_F(ProjectStorageUpdater, SynchronizeQmldirWithNoDependencies)
|
||||||
{
|
{
|
||||||
QString qmldir{R"(module Example
|
QString qmldir{R"(module Example
|
||||||
@@ -1149,4 +1175,47 @@ TEST_F(ProjectStorageUpdater, SynchronizeQmldirWithNoImports)
|
|||||||
updater.update(qmlDirs, {});
|
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
|
} // namespace
|
||||||
|
Reference in New Issue
Block a user