QmlDesigner: Introduce different modules for cpp, qml and directories

There are now different modules for qml, cpp and directory imports.
Cpp imports are qml import append by "-cppnative".

Task-number: QDS-5196
Change-Id: I599b224892c5ada0224a765d0bde8b32de20b061
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
Marco Bubke
2021-10-19 14:42:28 +02:00
committed by Tim Jenssen
parent cb946ec307
commit b4fcd05451
12 changed files with 86 additions and 81 deletions

View File

@@ -308,7 +308,10 @@ public:
&sourceId);
}
SourceIds fetchSourceDependencieIds(SourceId sourceId) const override { return {}; }
Storage::ProjectDatas fetchProjectDatas(SourceId sourceId) const override
{
return Storage::ProjectDatas{};
}
private:
class ModuleStorageAdapter

View File

@@ -42,7 +42,7 @@ public:
virtual ModuleId moduleId(Utils::SmallStringView name) = 0;
virtual FileStatus fetchFileStatus(SourceId sourceId) const = 0;
virtual SourceIds fetchSourceDependencieIds(SourceId sourceId) const = 0;
virtual Storage::ProjectDatas fetchProjectDatas(SourceId sourceId) const = 0;
protected:
~ProjectStorageInterface() = default;

View File

@@ -717,4 +717,13 @@ public:
using Types = std::vector<Type>;
class ProjectData
{
public:
ModuleId extraModuleId;
SourceId sourceId;
};
using ProjectDatas = std::vector<ProjectData>;
} // namespace QmlDesigner::Storage

View File

@@ -70,10 +70,10 @@ void ProjectUpdater::update()
SourceContextId directoryId = m_pathCache.sourceContextId(qmlDirSourceId);
ModuleId moduleId = m_projectStorage.moduleId(Utils::PathString{parser.typeNamespace()});
Utils::PathString moduleName{parser.typeNamespace()};
ModuleId moduleId = m_projectStorage.moduleId(moduleName);
parseTypeInfos(
parser.typeInfos(), directoryId, moduleId, imports, types, sourceIds, fileStatuses);
parseTypeInfos(parser.typeInfos(), directoryId, imports, types, sourceIds, fileStatuses);
parseQmlComponents(createComponentReferences(parser.components()),
directoryId,
moduleId,
@@ -84,13 +84,8 @@ void ProjectUpdater::update()
break;
}
case FileState::NotChanged: {
SourceIds qmltypesSourceIds = m_projectStorage.fetchSourceDependencieIds(qmlDirSourceId);
parseTypeInfos(ModuleId{&qmlDirSourceId},
qmltypesSourceIds,
imports,
types,
sourceIds,
fileStatuses);
auto qmlProjectDatas = m_projectStorage.fetchProjectDatas(qmlDirSourceId);
parseTypeInfos(qmlProjectDatas, imports, types, sourceIds, fileStatuses);
break;
}
case FileState::NotExists: {
@@ -110,7 +105,6 @@ void ProjectUpdater::pathsWithIdsChanged(const std::vector<IdPaths> &idPaths) {}
void ProjectUpdater::parseTypeInfos(const QStringList &typeInfos,
SourceContextId directoryId,
ModuleId moduleId,
Storage::Imports &imports,
Storage::Types &types,
SourceIds &sourceIds,
@@ -122,36 +116,36 @@ void ProjectUpdater::parseTypeInfos(const QStringList &typeInfos,
SourceId sourceId = m_pathCache.sourceId(directoryId, Utils::SmallString{typeInfo});
QString qmltypesPath = directory + "/" + typeInfo;
parseTypeInfo(sourceId, moduleId, qmltypesPath, imports, types, sourceIds, fileStatuses);
Storage::ProjectData projectData{ModuleId{}, sourceId};
parseTypeInfo(projectData, qmltypesPath, imports, types, sourceIds, fileStatuses);
}
}
void ProjectUpdater::parseTypeInfos(ModuleId moduleId,
const SourceIds &qmltypesSourceIds,
void ProjectUpdater::parseTypeInfos(const Storage::ProjectDatas &projectDatas,
Storage::Imports &imports,
Storage::Types &types,
SourceIds &sourceIds,
FileStatuses &fileStatuses)
{
for (SourceId sourceId : qmltypesSourceIds) {
QString qmltypesPath = m_pathCache.sourcePath(sourceId).toQString();
for (const Storage::ProjectData &projectData : projectDatas) {
QString qmltypesPath = m_pathCache.sourcePath(projectData.sourceId).toQString();
parseTypeInfo(sourceId, moduleId, qmltypesPath, imports, types, sourceIds, fileStatuses);
parseTypeInfo(projectData, qmltypesPath, imports, types, sourceIds, fileStatuses);
}
}
void ProjectUpdater::parseTypeInfo(SourceId sourceId,
ModuleId moduleId,
void ProjectUpdater::parseTypeInfo(const Storage::ProjectData &projectData,
const QString &qmltypesPath,
Storage::Imports &imports,
Storage::Types &types,
SourceIds &sourceIds,
FileStatuses &fileStatuses)
{
if (fileState(sourceId, fileStatuses) == FileState::Changed) {
sourceIds.push_back(sourceId);
if (fileState(projectData.sourceId, fileStatuses) == FileState::Changed) {
sourceIds.push_back(projectData.sourceId);
const auto content = m_fileSystem.contentAsQString(qmltypesPath);
m_qmlTypesParser.parse(content, imports, types, sourceId, moduleId);
m_qmlTypesParser.parse(content, imports, types, projectData);
}
}

View File

@@ -88,19 +88,16 @@ private:
void parseTypeInfos(const QStringList &typeInfos,
SourceContextId directoryId,
ModuleId moduleId,
Storage::Imports &imports,
Storage::Types &types,
SourceIds &sourceIds,
FileStatuses &fileStatuses);
void parseTypeInfos(ModuleId moduleId,
const SourceIds &qmltypesSourceIds,
void parseTypeInfos(const Storage::ProjectDatas &projectDatas,
Storage::Imports &imports,
Storage::Types &types,
SourceIds &sourceIds,
FileStatuses &fileStatuses);
void parseTypeInfo(SourceId sourceId,
ModuleId moduleId,
void parseTypeInfo(const Storage::ProjectData &projectData,
const QString &qmltypesPath,
Storage::Imports &imports,
Storage::Types &types,

View File

@@ -43,7 +43,6 @@ namespace QmlDesigner {
namespace QmlDom = QQmlJS::Dom;
namespace {
void addType(const QQmlJSScope::Ptr &object, Storage::Types &types) {}
void appendImports(Storage::Imports &imports,
const QString &dependency,
@@ -55,8 +54,6 @@ void appendImports(Storage::Imports &imports,
});
Utils::PathString moduleName{QStringView(dependency.begin(), spaceFound)};
ModuleId moduleId = storage.moduleId(moduleName);
moduleName.append("-cppnative");
ModuleId cppModuleId = storage.moduleId(moduleName);
@@ -84,7 +81,6 @@ void appendImports(Storage::Imports &imports,
version.minor.value = QStringView(minorVersionFound, minorVersionEnd).toInt();
}
imports.emplace_back(moduleId, version, sourceId);
imports.emplace_back(cppModuleId, version, sourceId);
}
@@ -97,7 +93,6 @@ void addImports(Storage::Imports &imports,
appendImports(imports, dependency, sourceId, storage);
imports.emplace_back(storage.moduleId("QML"), Storage::Version{}, sourceId);
imports.emplace_back(storage.moduleId("QtQml"), Storage::Version{}, sourceId);
imports.emplace_back(storage.moduleId("QtQml-cppnative"), Storage::Version{}, sourceId);
}
@@ -122,17 +117,22 @@ Storage::Version createVersion(QTypeRevision qmlVersion)
return Storage::Version{qmlVersion.majorVersion(), qmlVersion.minorVersion()};
}
Storage::ExportedTypes createExports(ModuleId moduleId, const QList<QQmlJSScope::Export> &qmlExports)
Storage::ExportedTypes createExports(const QList<QQmlJSScope::Export> &qmlExports,
const QQmlJSScope &component,
QmlTypesParser::ProjectStorage &storage,
ModuleId cppModuleId)
{
Storage::ExportedTypes exportedTypes;
exportedTypes.reserve(Utils::usize(qmlExports));
for (const QQmlJSScope::Export &qmlExport : qmlExports) {
exportedTypes.emplace_back(moduleId,
exportedTypes.emplace_back(storage.moduleId(Utils::SmallString{qmlExport.package()}),
Utils::SmallString{qmlExport.type()},
createVersion(qmlExport.version()));
}
exportedTypes.emplace_back(cppModuleId, Utils::SmallString{component.internalName()});
return exportedTypes;
}
@@ -257,14 +257,18 @@ Storage::EnumerationDeclarations createEnumeration(const QHash<QString, QQmlJSMe
return enumerationDeclarations;
}
void addType(Storage::Types &types, SourceId sourceId, ModuleId moduleId, const QQmlJSScope &component)
void addType(Storage::Types &types,
SourceId sourceId,
ModuleId cppModuleId,
const QQmlJSScope &component,
QmlTypesParser::ProjectStorage &storage)
{
auto [functionsDeclarations, signalDeclarations] = createFunctionAndSignals(component.ownMethods());
types.emplace_back(Utils::SmallString{component.internalName()},
Storage::NativeType{Utils::SmallString{component.baseTypeName()}},
createTypeAccessSemantics(component.accessSemantics()),
sourceId,
createExports(moduleId, component.exports()),
createExports(component.exports(), component, storage, cppModuleId),
createProperties(component.ownProperties()),
std::move(functionsDeclarations),
std::move(signalDeclarations),
@@ -272,14 +276,14 @@ void addType(Storage::Types &types, SourceId sourceId, ModuleId moduleId, const
}
void addTypes(Storage::Types &types,
SourceId sourceId,
ModuleId moduleId,
const QHash<QString, QQmlJSScope::Ptr> &objects)
const Storage::ProjectData &projectData,
const QHash<QString, QQmlJSScope::Ptr> &objects,
QmlTypesParser::ProjectStorage &storage)
{
types.reserve(Utils::usize(objects) + types.size());
for (const auto &object : objects)
addType(types, sourceId, moduleId, *object.get());
addType(types, projectData.sourceId, projectData.extraModuleId, *object.get(), storage);
}
} // namespace
@@ -287,8 +291,7 @@ void addTypes(Storage::Types &types,
void QmlTypesParser::parse(const QString &sourceContent,
Storage::Imports &imports,
Storage::Types &types,
SourceId sourceId,
ModuleId moduleId)
const Storage::ProjectData &projectData)
{
QQmlJSTypeDescriptionReader reader({}, sourceContent);
QHash<QString, QQmlJSScope::Ptr> components;
@@ -297,8 +300,8 @@ void QmlTypesParser::parse(const QString &sourceContent,
if (!isValid)
throw CannotParseQmlTypesFile{};
addImports(imports, sourceId, dependencies, m_storage);
addTypes(types, sourceId, moduleId, components);
addImports(imports, projectData.sourceId, dependencies, m_storage);
addTypes(types, projectData, components, m_storage);
}
} // namespace QmlDesigner

View File

@@ -54,8 +54,7 @@ public:
void parse(const QString &sourceContent,
Storage::Imports &imports,
Storage::Types &types,
SourceId sourceId,
ModuleId moduleId) override;
const Storage::ProjectData &projectData) override;
private:
PathCache &m_pathCache;

View File

@@ -37,8 +37,7 @@ public:
virtual void parse(const QString &sourceContent,
Storage::Imports &imports,
Storage::Types &types,
SourceId sourceId,
ModuleId moduleId)
const Storage::ProjectData &projectData)
= 0;
protected:

View File

@@ -51,8 +51,8 @@ public:
(QmlDesigner::SourceId sourceId),
(const, override));
MOCK_METHOD(QmlDesigner::SourceIds,
fetchSourceDependencieIds,
MOCK_METHOD(QmlDesigner::Storage::ProjectDatas,
fetchProjectDatas,
(QmlDesigner::SourceId sourceId),
(const, override));

View File

@@ -126,8 +126,10 @@ public:
ON_CALL(projectStorageMock, fetchFileStatus(Eq(qmlDirPathSourceId)))
.WillByDefault(Return(FileStatus{qmlDirPathSourceId, 2, 421}));
ON_CALL(projectStorageMock, fetchSourceDependencieIds(Eq(qmlDirPathSourceId)))
.WillByDefault(Return(QmlDesigner::SourceIds{qmltypesPathSourceId, qmltypes2PathSourceId}));
ON_CALL(projectStorageMock, fetchProjectDatas(Eq(qmlDirPathSourceId)))
.WillByDefault(
Return(QmlDesigner::Storage::ProjectDatas{{ModuleId{}, qmltypesPathSourceId},
{ModuleId{}, qmltypes2PathSourceId}}));
QString qmldir{"module Example\ntypeinfo example.qmltypes\n"};
ON_CALL(projectManagerMock, qtQmlDirs()).WillByDefault(Return(QStringList{"/path/qmldir"}));
@@ -300,8 +302,8 @@ TEST_F(ProjectStorageUpdater, ParseQmlTypes)
ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/example2.qmltypes"))))
.WillByDefault(Return(qmltypes2));
EXPECT_CALL(qmlTypesParserMock, parse(qmltypes, _, _, _, _));
EXPECT_CALL(qmlTypesParserMock, parse(qmltypes2, _, _, _, _));
EXPECT_CALL(qmlTypesParserMock, parse(qmltypes, _, _, _));
EXPECT_CALL(qmlTypesParserMock, parse(qmltypes2, _, _, _));
updater.update();
}
@@ -328,8 +330,8 @@ TEST_F(ProjectStorageUpdater, SynchronizeQmlTypes)
QString qmltypes{"Module {\ndependencies: []}"};
ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/example.qmltypes"))))
.WillByDefault(Return(qmltypes));
ON_CALL(qmlTypesParserMock, parse(qmltypes, _, _, _, _))
.WillByDefault([&](auto, auto &imports, auto &types, auto, auto) {
ON_CALL(qmlTypesParserMock, parse(qmltypes, _, _, _))
.WillByDefault([&](auto, auto &imports, auto &types, auto) {
types.push_back(objectType);
imports.push_back(import);
});
@@ -350,9 +352,8 @@ TEST_F(ProjectStorageUpdater, SynchronizeQmlTypesAreEmptyIfFileDoesNotChanged)
QString qmltypes{"Module {\ndependencies: []}"};
ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/example.qmltypes"))))
.WillByDefault(Return(qmltypes));
ON_CALL(qmlTypesParserMock, parse(qmltypes, _, _, _, _))
.WillByDefault(
[&](auto, auto &imports, auto &types, auto, auto) { types.push_back(objectType); });
ON_CALL(qmlTypesParserMock, parse(qmltypes, _, _, _))
.WillByDefault([&](auto, auto &, auto &types, auto) { types.push_back(objectType); });
ON_CALL(fileSystemMock, fileStatus(Eq(qmltypesPathSourceId)))
.WillByDefault(Return(FileStatus{qmltypesPathSourceId, 2, 421}));
ON_CALL(fileSystemMock, fileStatus(Eq(qmltypes2PathSourceId)))

View File

@@ -173,6 +173,8 @@ protected:
Storage::Imports imports;
Storage::Types types;
SourceId qmltypesFileSourceId{sourcePathCache.sourceId("path/to/types.qmltypes")};
QmlDesigner::Storage::ProjectData projectData{storage.moduleId("QtQml-cppnative"),
qmltypesFileSourceId};
SourceContextId qmltypesFileSourceContextId{sourcePathCache.sourceContextId(qmltypesFileSourceId)};
ModuleId directoryModuleId{storage.moduleId("path/to/")};
};
@@ -184,21 +186,17 @@ TEST_F(QmlTypesParser, Imports)
dependencies:
["QtQuick 2.15", "QtQuick.Window 2.1", "QtFoo 6"]})"};
parser.parse(source, imports, types, qmltypesFileSourceId, directoryModuleId);
parser.parse(source, imports, types, projectData);
ASSERT_THAT(
imports,
UnorderedElementsAre(
IsImport(storage.moduleId("QML"), Storage::Version{}, qmltypesFileSourceId),
IsImport(storage.moduleId("QtQml"), Storage::Version{}, qmltypesFileSourceId),
IsImport(storage.moduleId("QtQml-cppnative"), Storage::Version{}, qmltypesFileSourceId),
IsImport(storage.moduleId("QtQuick"), Storage::Version{2, 15}, qmltypesFileSourceId),
IsImport(storage.moduleId("QtQuick-cppnative"), Storage::Version{2, 15}, qmltypesFileSourceId),
IsImport(storage.moduleId("QtQuick.Window"), Storage::Version{2, 1}, qmltypesFileSourceId),
IsImport(storage.moduleId("QtQuick.Window-cppnative"),
Storage::Version{2, 1},
qmltypesFileSourceId),
IsImport(storage.moduleId("QtFoo"), Storage::Version{6}, qmltypesFileSourceId),
IsImport(storage.moduleId("QtFoo-cppnative"), Storage::Version{6}, qmltypesFileSourceId)));
}
@@ -210,7 +208,7 @@ TEST_F(QmlTypesParser, Types)
Component { name: "QQmlComponent"
prototype: "QObject"}})"};
parser.parse(source, imports, types, qmltypesFileSourceId, directoryModuleId);
parser.parse(source, imports, types, projectData);
ASSERT_THAT(types,
UnorderedElementsAre(IsType("QObject",
@@ -228,17 +226,20 @@ TEST_F(QmlTypesParser, ExportedTypes)
QString source{R"(import QtQuick.tooling 1.2
Module{
Component { name: "QObject"
exports: ["QtQml/QtObject 1.0", "QtQml/QtObject 2.1"]
exports: ["QML/QtObject 1.0", "QtQml/QtObject 2.1"]
}})"};
ModuleId qmlModuleId = storage.moduleId("QML");
ModuleId qtQmlModuleId = storage.moduleId("QtQml");
ModuleId qtQmlNativeModuleId = storage.moduleId("QtQml-cppnative");
parser.parse(source, imports, types, qmltypesFileSourceId, directoryModuleId);
parser.parse(source, imports, types, projectData);
ASSERT_THAT(
types,
ElementsAre(
Field(&Storage::Type::exportedTypes,
ElementsAre(IsExportedType(directoryModuleId, "QtObject", Storage::Version{1, 0}),
IsExportedType(directoryModuleId, "QtObject", Storage::Version{2, 1})))));
ASSERT_THAT(types,
ElementsAre(Field(
&Storage::Type::exportedTypes,
ElementsAre(IsExportedType(qmlModuleId, "QtObject", Storage::Version{1, 0}),
IsExportedType(qtQmlModuleId, "QtObject", Storage::Version{2, 1}),
IsExportedType(qtQmlNativeModuleId, "QObject", Storage::Version{})))));
}
TEST_F(QmlTypesParser, Properties)
@@ -252,7 +253,7 @@ TEST_F(QmlTypesParser, Properties)
Property { name: "targets"; type: "QQuickItem"; isList: true; isReadonly: true; isPointer: true }
}})"};
parser.parse(source, imports, types, qmltypesFileSourceId, directoryModuleId);
parser.parse(source, imports, types, projectData);
ASSERT_THAT(types,
ElementsAre(Field(
@@ -296,7 +297,7 @@ TEST_F(QmlTypesParser, Functions)
}
}})"};
parser.parse(source, imports, types, qmltypesFileSourceId, directoryModuleId);
parser.parse(source, imports, types, projectData);
ASSERT_THAT(types,
ElementsAre(
@@ -337,7 +338,7 @@ TEST_F(QmlTypesParser, Signals)
}
}})"};
parser.parse(source, imports, types, qmltypesFileSourceId, directoryModuleId);
parser.parse(source, imports, types, projectData);
ASSERT_THAT(types,
ElementsAre(Field(&Storage::Type::signalDeclarations,
@@ -375,7 +376,7 @@ TEST_F(QmlTypesParser, Enumerations)
}
}})"};
parser.parse(source, imports, types, qmltypesFileSourceId, directoryModuleId);
parser.parse(source, imports, types, projectData);
ASSERT_THAT(types,
ElementsAre(

View File

@@ -37,7 +37,6 @@ public:
(const QString &sourceContent,
QmlDesigner::Storage::Imports &imports,
QmlDesigner::Storage::Types &types,
QmlDesigner::SourceId sourceId,
QmlDesigner::ModuleId moduleId),
const QmlDesigner::Storage::ProjectData &projectData),
(override));
};