forked from qt-creator/qt-creator
QmlDesigner: Adapt to QmlDom changes
Task-number: QDS-6799 Change-Id: Ic37d8549c9a6fd8bca770b07b0dcb0f84892841b Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -97,7 +97,7 @@ private:
|
||||
const QList<QmlDirParser::Import> &qmldirDependencies,
|
||||
const QList<QmlDirParser::Import> &qmldirImports,
|
||||
SourceId qmldirSourceId,
|
||||
SourceContextId directoryId,
|
||||
Utils::SmallStringView directoryPath,
|
||||
ModuleId moduleId,
|
||||
Storage::SynchronizationPackage &package,
|
||||
SourceIds ¬UpdatedFileStatusSourceIds,
|
||||
@@ -115,11 +115,13 @@ private:
|
||||
SourceId qmldirSourceId,
|
||||
SourceContextId directoryId,
|
||||
ModuleId moduleId,
|
||||
ModuleId pathModuleId,
|
||||
Storage::SynchronizationPackage &package,
|
||||
SourceIds ¬UpdatedFileStatusSourceIds);
|
||||
void parseQmlComponents(const Storage::ProjectDatas &projectDatas,
|
||||
Storage::SynchronizationPackage &package,
|
||||
SourceIds ¬UpdatedFileStatusSourceIds);
|
||||
SourceIds ¬UpdatedFileStatusSourceIds,
|
||||
Utils::SmallStringView directoryPath);
|
||||
void parseQmlComponent(Utils::SmallStringView fileName,
|
||||
Utils::SmallStringView directory,
|
||||
Storage::ExportedTypes exportedTypes,
|
||||
@@ -129,6 +131,7 @@ private:
|
||||
SourceIds ¬UpdatedFileStatusSourceIds);
|
||||
void parseQmlComponent(Utils::SmallStringView fileName,
|
||||
Utils::SmallStringView filePath,
|
||||
Utils::SmallStringView directoryPath,
|
||||
SourceId sourceId,
|
||||
Storage::SynchronizationPackage &package,
|
||||
SourceIds ¬UpdatedFileStatusSourceIds);
|
||||
|
@@ -1,3 +1,4 @@
|
||||
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
@@ -54,16 +55,20 @@ Storage::Version convertVersion(QmlDom::Version version)
|
||||
convertVersionNumber(version.minorVersion)};
|
||||
}
|
||||
|
||||
Utils::PathString convertUri(const QString &uri)
|
||||
Utils::PathString createNormalizedPath(Utils::SmallStringView directoryPath,
|
||||
const QString &relativePath)
|
||||
{
|
||||
QStringView localPath{uri.begin() + 7, uri.end()};
|
||||
std::filesystem::path modulePath{std::string_view{directoryPath},
|
||||
std::filesystem::path::format::generic_format};
|
||||
|
||||
std::filesystem::path path{
|
||||
std::u16string_view{localPath.utf16(), static_cast<std::size_t>(localPath.size())}};
|
||||
modulePath /= relativePath.toStdString();
|
||||
|
||||
auto x = std::filesystem::weakly_canonical(path);
|
||||
Utils::PathString normalizedPath = modulePath.lexically_normal().generic_string();
|
||||
|
||||
return Utils::PathString{x.generic_string()};
|
||||
if (normalizedPath[normalizedPath.size() - 1] == '/')
|
||||
normalizedPath.resize(normalizedPath.size() - 1);
|
||||
|
||||
return normalizedPath;
|
||||
}
|
||||
|
||||
Storage::Import createImport(const QmlDom::Import &qmlImport,
|
||||
@@ -71,21 +76,26 @@ Storage::Import createImport(const QmlDom::Import &qmlImport,
|
||||
Utils::SmallStringView directoryPath,
|
||||
QmlDocumentParser::ProjectStorage &storage)
|
||||
{
|
||||
if (qmlImport.uri == u"file://.") {
|
||||
auto moduleId = storage.moduleId(directoryPath);
|
||||
using QmlUriKind = QQmlJS::Dom::QmlUri::Kind;
|
||||
|
||||
auto &&uri = qmlImport.uri;
|
||||
|
||||
if (uri.kind() == QmlUriKind::RelativePath) {
|
||||
auto path = createNormalizedPath(directoryPath, uri.localPath());
|
||||
auto moduleId = storage.moduleId(createNormalizedPath(directoryPath, uri.localPath()));
|
||||
return Storage::Import(moduleId, Storage::Version{}, sourceId);
|
||||
}
|
||||
|
||||
if (qmlImport.uri.startsWith(u"file://")) {
|
||||
auto moduleId = storage.moduleId(convertUri(qmlImport.uri));
|
||||
return Storage::Import(moduleId, Storage::Version{}, sourceId);
|
||||
if (uri.kind() == QmlUriKind::ModuleUri) {
|
||||
auto moduleId = storage.moduleId(Utils::PathString{uri.moduleUri()});
|
||||
return Storage::Import(moduleId, convertVersion(qmlImport.version), sourceId);
|
||||
}
|
||||
|
||||
auto moduleId = storage.moduleId(Utils::SmallString{qmlImport.uri});
|
||||
auto moduleId = storage.moduleId(Utils::PathString{uri.toString()});
|
||||
return Storage::Import(moduleId, convertVersion(qmlImport.version), sourceId);
|
||||
}
|
||||
|
||||
QualifiedImports filterQualifiedImports(const QList<QmlDom::Import> &qmlImports,
|
||||
QualifiedImports createQualifiedImports(const QList<QmlDom::Import> &qmlImports,
|
||||
SourceId sourceId,
|
||||
Utils::SmallStringView directoryPath,
|
||||
QmlDocumentParser::ProjectStorage &storage)
|
||||
@@ -93,7 +103,7 @@ QualifiedImports filterQualifiedImports(const QList<QmlDom::Import> &qmlImports,
|
||||
QualifiedImports qualifiedImports;
|
||||
|
||||
for (const QmlDom::Import &qmlImport : qmlImports) {
|
||||
if (!qmlImport.importId.isEmpty())
|
||||
if (!qmlImport.importId.isEmpty() && !qmlImport.implicit)
|
||||
qualifiedImports.try_emplace(qmlImport.importId,
|
||||
createImport(qmlImport, sourceId, directoryPath, storage));
|
||||
}
|
||||
@@ -107,11 +117,24 @@ void addImports(Storage::Imports &imports,
|
||||
Utils::SmallStringView directoryPath,
|
||||
QmlDocumentParser::ProjectStorage &storage)
|
||||
{
|
||||
for (const QmlDom::Import &qmlImport : qmlImports)
|
||||
int importCount = 0;
|
||||
for (const QmlDom::Import &qmlImport : qmlImports) {
|
||||
if (!qmlImport.implicit) {
|
||||
imports.push_back(createImport(qmlImport, sourceId, directoryPath, storage));
|
||||
++importCount;
|
||||
}
|
||||
}
|
||||
|
||||
auto localDirectoryModuleId = storage.moduleId(directoryPath);
|
||||
imports.emplace_back(localDirectoryModuleId, Storage::Version{}, sourceId);
|
||||
++importCount;
|
||||
|
||||
auto qmlModuleId = storage.moduleId("QML");
|
||||
imports.emplace_back(qmlModuleId, Storage::Version{}, sourceId);
|
||||
++importCount;
|
||||
|
||||
auto end = imports.end();
|
||||
auto begin = std::prev(end, qmlImports.size());
|
||||
auto begin = std::prev(end, importCount);
|
||||
|
||||
std::sort(begin, end);
|
||||
imports.erase(std::unique(begin, end), end);
|
||||
@@ -196,14 +219,17 @@ void addEnumeraton(Storage::Type &type, const QmlDom::Component &component)
|
||||
|
||||
Storage::Type QmlDocumentParser::parse(const QString &sourceContent,
|
||||
Storage::Imports &imports,
|
||||
SourceId sourceId)
|
||||
SourceId sourceId,
|
||||
Utils::SmallStringView directoryPath)
|
||||
{
|
||||
Storage::Type type;
|
||||
|
||||
QmlDom::DomItem environment = QmlDom::DomEnvironment::create(
|
||||
{},
|
||||
QmlDom::DomEnvironment::Option::SingleThreaded
|
||||
| QmlDom::DomEnvironment::Option::NoDependencies);
|
||||
using Option = QmlDom::DomEnvironment::Option;
|
||||
|
||||
QmlDom::DomItem environment = QmlDom::DomEnvironment::create({},
|
||||
Option::SingleThreaded
|
||||
| Option::NoDependencies
|
||||
| Option::WeakLoad);
|
||||
|
||||
QmlDom::DomItem items;
|
||||
|
||||
@@ -238,9 +264,11 @@ Storage::Type QmlDocumentParser::parse(const QString &sourceContent,
|
||||
const QmlDom::QmlObject &qmlObject = objects.front();
|
||||
|
||||
const auto qmlImports = qmlFile->imports();
|
||||
auto directoryPath{m_pathCache.sourceContextPath(m_pathCache.sourceContextId(sourceId))};
|
||||
|
||||
const auto qualifiedImports = filterQualifiedImports(qmlImports, sourceId, directoryPath, m_storage);
|
||||
const auto qualifiedImports = createQualifiedImports(qmlImports,
|
||||
sourceId,
|
||||
directoryPath,
|
||||
m_storage);
|
||||
|
||||
type.prototype = createImportedTypeName(qmlObject.name(), qualifiedImports);
|
||||
|
||||
|
@@ -53,7 +53,8 @@ public:
|
||||
|
||||
Storage::Type parse(const QString &sourceContent,
|
||||
Storage::Imports &imports,
|
||||
SourceId sourceId) override;
|
||||
SourceId sourceId,
|
||||
Utils::SmallStringView directoryPath) override;
|
||||
|
||||
private:
|
||||
ProjectStorage &m_storage;
|
||||
|
@@ -34,7 +34,11 @@ namespace QmlDesigner {
|
||||
class QmlDocumentParserInterface
|
||||
{
|
||||
public:
|
||||
virtual Storage::Type parse(const QString &sourceContent, Storage::Imports &imports, SourceId sourceId) = 0;
|
||||
virtual Storage::Type parse(const QString &sourceContent,
|
||||
Storage::Imports &imports,
|
||||
SourceId sourceId,
|
||||
Utils::SmallStringView directoryPath)
|
||||
= 0;
|
||||
|
||||
protected:
|
||||
~QmlDocumentParserInterface() = default;
|
||||
|
@@ -47,7 +47,7 @@ namespace {
|
||||
using ComponentWithoutNamespaces = QMap<QString, QString>;
|
||||
|
||||
ComponentWithoutNamespaces createComponentNameWithoutNamespaces(
|
||||
const QHash<QString, QQmlJSScope::Ptr> &objects)
|
||||
const QHash<QString, QQmlJSExportedScope> &objects)
|
||||
{
|
||||
ComponentWithoutNamespaces componentWithoutNamespaces;
|
||||
|
||||
@@ -409,15 +409,17 @@ EnumerationTypes addEnumerationTypes(Storage::Types &types,
|
||||
void addType(Storage::Types &types,
|
||||
SourceId sourceId,
|
||||
ModuleId cppModuleId,
|
||||
const QQmlJSScope &component,
|
||||
const QQmlJSExportedScope &exportScope,
|
||||
QmlTypesParser::ProjectStorage &storage,
|
||||
const ComponentWithoutNamespaces &componentNameWithoutNamespace)
|
||||
{
|
||||
const auto &component = *exportScope.scope;
|
||||
|
||||
auto [functionsDeclarations, signalDeclarations] = createFunctionAndSignals(
|
||||
component.ownMethods(), componentNameWithoutNamespace);
|
||||
TypeNameString typeName{component.internalName()};
|
||||
auto enumerations = component.ownEnumerations();
|
||||
auto exports = component.exports();
|
||||
auto exports = exportScope.exports;
|
||||
|
||||
auto enumerationTypes = addEnumerationTypes(types, typeName, sourceId, cppModuleId, enumerations);
|
||||
types.emplace_back(Utils::SmallStringView{typeName},
|
||||
@@ -435,7 +437,7 @@ void addType(Storage::Types &types,
|
||||
|
||||
void addTypes(Storage::Types &types,
|
||||
const Storage::ProjectData &projectData,
|
||||
const QHash<QString, QQmlJSScope::Ptr> &objects,
|
||||
const QHash<QString, QQmlJSExportedScope> &objects,
|
||||
QmlTypesParser::ProjectStorage &storage,
|
||||
const ComponentWithoutNamespaces &componentNameWithoutNamespaces)
|
||||
{
|
||||
@@ -445,7 +447,7 @@ void addTypes(Storage::Types &types,
|
||||
addType(types,
|
||||
projectData.sourceId,
|
||||
projectData.moduleId,
|
||||
*object.get(),
|
||||
object,
|
||||
storage,
|
||||
componentNameWithoutNamespaces);
|
||||
}
|
||||
@@ -458,7 +460,7 @@ void QmlTypesParser::parse(const QString &sourceContent,
|
||||
const Storage::ProjectData &projectData)
|
||||
{
|
||||
QQmlJSTypeDescriptionReader reader({}, sourceContent);
|
||||
QHash<QString, QQmlJSScope::Ptr> components;
|
||||
QHash<QString, QQmlJSExportedScope> components;
|
||||
QStringList dependencies;
|
||||
bool isValid = reader(&components, &dependencies);
|
||||
if (!isValid)
|
||||
|
@@ -183,7 +183,7 @@ public:
|
||||
|
||||
ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/First.qml"))))
|
||||
.WillByDefault(Return(qmlDocument1));
|
||||
ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/First.2.qml"))))
|
||||
ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/First2.qml"))))
|
||||
.WillByDefault(Return(qmlDocument2));
|
||||
ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/Second.qml"))))
|
||||
.WillByDefault(Return(qmlDocument3));
|
||||
@@ -192,18 +192,18 @@ public:
|
||||
ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/types/example2.qmltypes"))))
|
||||
.WillByDefault(Return(qmltypes2));
|
||||
|
||||
ON_CALL(qmlDocumentParserMock, parse(qmlDocument1, _, _))
|
||||
.WillByDefault([&](auto, auto &imports, auto) {
|
||||
ON_CALL(qmlDocumentParserMock, parse(qmlDocument1, _, _, _))
|
||||
.WillByDefault([&](auto, auto &imports, auto, auto) {
|
||||
imports.push_back(import1);
|
||||
return firstType;
|
||||
});
|
||||
ON_CALL(qmlDocumentParserMock, parse(qmlDocument2, _, _))
|
||||
.WillByDefault([&](auto, auto &imports, auto) {
|
||||
ON_CALL(qmlDocumentParserMock, parse(qmlDocument2, _, _, _))
|
||||
.WillByDefault([&](auto, auto &imports, auto, auto) {
|
||||
imports.push_back(import2);
|
||||
return secondType;
|
||||
});
|
||||
ON_CALL(qmlDocumentParserMock, parse(qmlDocument3, _, _))
|
||||
.WillByDefault([&](auto, auto &imports, auto) {
|
||||
ON_CALL(qmlDocumentParserMock, parse(qmlDocument3, _, _, _))
|
||||
.WillByDefault([&](auto, auto &imports, auto, auto) {
|
||||
imports.push_back(import3);
|
||||
return thirdType;
|
||||
});
|
||||
@@ -239,7 +239,7 @@ protected:
|
||||
SourceId qmltypes2PathSourceId = sourcePathCache.sourceId("/path/types/example2.qmltypes");
|
||||
SourceId qmlDirPathSourceId = sourcePathCache.sourceId("/path/qmldir");
|
||||
SourceId qmlDocumentSourceId1 = sourcePathCache.sourceId("/path/First.qml");
|
||||
SourceId qmlDocumentSourceId2 = sourcePathCache.sourceId("/path/First.2.qml");
|
||||
SourceId qmlDocumentSourceId2 = sourcePathCache.sourceId("/path/First2.qml");
|
||||
SourceId qmlDocumentSourceId3 = sourcePathCache.sourceId("/path/Second.qml");
|
||||
ModuleId qmlModuleId{storage.moduleId("Qml")};
|
||||
ModuleId qmlCppNativeModuleId{storage.moduleId("Qml-cppnative")};
|
||||
@@ -249,6 +249,8 @@ protected:
|
||||
ModuleId builtinCppNativeModuleId{storage.moduleId("QML-cppnative")};
|
||||
ModuleId quickModuleId{storage.moduleId("Quick")};
|
||||
ModuleId quickCppNativeModuleId{storage.moduleId("Quick-cppnative")};
|
||||
ModuleId pathModuleId{storage.moduleId("/path")};
|
||||
ModuleId subPathQmlModuleId{storage.moduleId("/path/qml")};
|
||||
Storage::Type objectType{"QObject",
|
||||
Storage::ImportedType{},
|
||||
Storage::TypeAccessSemantics::Reference,
|
||||
@@ -397,6 +399,7 @@ TEST_F(ProjectStorageUpdater, SynchronizeQmlTypes)
|
||||
|
||||
EXPECT_CALL(projectStorageMock, moduleId(Eq("Example")));
|
||||
EXPECT_CALL(projectStorageMock, moduleId(Eq("Example-cppnative")));
|
||||
EXPECT_CALL(projectStorageMock, moduleId(Eq("/path")));
|
||||
EXPECT_CALL(projectStorageMock,
|
||||
synchronize(
|
||||
AllOf(Field(&SynchronizationPackage::imports, ElementsAre(import)),
|
||||
@@ -445,14 +448,14 @@ TEST_F(ProjectStorageUpdater, GetContentForQmlDocuments)
|
||||
.WillByDefault(Return(qmlDocument3));
|
||||
QString qmldir{R"(module Example
|
||||
FirstType 1.0 First.qml
|
||||
FirstTypeV2 2.2 First.2.qml
|
||||
FirstTypeV2 2.2 First2.qml
|
||||
SecondType 2.1 OldSecond.qml
|
||||
SecondType 2.2 Second.qml)"};
|
||||
EXPECT_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/qmldir"))))
|
||||
.WillRepeatedly(Return(qmldir));
|
||||
|
||||
EXPECT_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/First.qml"))));
|
||||
EXPECT_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/First.2.qml"))));
|
||||
EXPECT_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/First2.qml"))));
|
||||
EXPECT_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/OldSecond.qml"))));
|
||||
EXPECT_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/Second.qml"))));
|
||||
|
||||
@@ -463,7 +466,7 @@ TEST_F(ProjectStorageUpdater, ParseQmlDocuments)
|
||||
{
|
||||
QString qmldir{R"(module Example
|
||||
FirstType 1.0 First.qml
|
||||
FirstTypeV2 2.2 First.2.qml
|
||||
FirstTypeV2 2.2 First2.qml
|
||||
SecondType 2.2 Second.qml)"};
|
||||
QString qmlDocument1{"First{}"};
|
||||
QString qmlDocument2{"Second{}"};
|
||||
@@ -471,14 +474,14 @@ TEST_F(ProjectStorageUpdater, ParseQmlDocuments)
|
||||
ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/qmldir")))).WillByDefault(Return(qmldir));
|
||||
ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/First.qml"))))
|
||||
.WillByDefault(Return(qmlDocument1));
|
||||
ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/First.2.qml"))))
|
||||
ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/First2.qml"))))
|
||||
.WillByDefault(Return(qmlDocument2));
|
||||
ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/Second.qml"))))
|
||||
.WillByDefault(Return(qmlDocument3));
|
||||
|
||||
EXPECT_CALL(qmlDocumentParserMock, parse(qmlDocument1, _, _));
|
||||
EXPECT_CALL(qmlDocumentParserMock, parse(qmlDocument2, _, _));
|
||||
EXPECT_CALL(qmlDocumentParserMock, parse(qmlDocument3, _, _));
|
||||
EXPECT_CALL(qmlDocumentParserMock, parse(qmlDocument1, _, _, _));
|
||||
EXPECT_CALL(qmlDocumentParserMock, parse(qmlDocument2, _, _, _));
|
||||
EXPECT_CALL(qmlDocumentParserMock, parse(qmlDocument3, _, _, _));
|
||||
|
||||
updater.update(qmlDirs, {});
|
||||
}
|
||||
@@ -496,7 +499,7 @@ TEST_F(ProjectStorageUpdater, SynchronizeQmlDocuments)
|
||||
{
|
||||
QString qmldir{R"(module Example
|
||||
FirstType 1.0 First.qml
|
||||
FirstType 2.2 First.2.qml
|
||||
FirstType 2.2 First2.qml
|
||||
SecondType 2.2 Second.qml)"};
|
||||
ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/qmldir")))).WillByDefault(Return(qmldir));
|
||||
|
||||
@@ -512,21 +515,24 @@ TEST_F(ProjectStorageUpdater, SynchronizeQmlDocuments)
|
||||
qmlDocumentSourceId1,
|
||||
Storage::ChangeLevel::Full),
|
||||
Field(&Storage::Type::exportedTypes,
|
||||
ElementsAre(IsExportedType(exampleModuleId, "FirstType", 1, 0)))),
|
||||
AllOf(IsStorageType("First.2.qml",
|
||||
ElementsAre(IsExportedType(exampleModuleId, "FirstType", 1, 0),
|
||||
IsExportedType(pathModuleId, "First", -1, -1)))),
|
||||
AllOf(IsStorageType("First2.qml",
|
||||
Storage::ImportedType{"Object2"},
|
||||
TypeAccessSemantics::Reference,
|
||||
qmlDocumentSourceId2,
|
||||
Storage::ChangeLevel::Full),
|
||||
Field(&Storage::Type::exportedTypes,
|
||||
ElementsAre(IsExportedType(exampleModuleId, "FirstType", 2, 2)))),
|
||||
ElementsAre(IsExportedType(exampleModuleId, "FirstType", 2, 2),
|
||||
IsExportedType(pathModuleId, "First2", -1, -1)))),
|
||||
AllOf(IsStorageType("Second.qml",
|
||||
Storage::ImportedType{"Object3"},
|
||||
TypeAccessSemantics::Reference,
|
||||
qmlDocumentSourceId3,
|
||||
Storage::ChangeLevel::Full),
|
||||
Field(&Storage::Type::exportedTypes,
|
||||
ElementsAre(IsExportedType(exampleModuleId, "SecondType", 2, 2)))))),
|
||||
ElementsAre(IsExportedType(exampleModuleId, "SecondType", 2, 2),
|
||||
IsExportedType(pathModuleId, "Second", -1, -1)))))),
|
||||
Field(&SynchronizationPackage::updatedSourceIds,
|
||||
UnorderedElementsAre(qmlDirPathSourceId,
|
||||
qmlDocumentSourceId1,
|
||||
@@ -565,7 +571,7 @@ TEST_F(ProjectStorageUpdater, SynchronizeRemoved)
|
||||
{
|
||||
QString qmldir{R"(module Example
|
||||
FirstType 1.0 First.qml
|
||||
FirstType 2.2 First.2.qml
|
||||
FirstType 2.2 First2.qml
|
||||
typeinfo example.qmltypes
|
||||
typeinfo types/example2.qmltypes
|
||||
)"};
|
||||
@@ -595,14 +601,16 @@ TEST_F(ProjectStorageUpdater, SynchronizeRemoved)
|
||||
qmlDocumentSourceId1,
|
||||
Storage::ChangeLevel::Full),
|
||||
Field(&Storage::Type::exportedTypes,
|
||||
ElementsAre(IsExportedType(exampleModuleId, "FirstType", 1, 0)))),
|
||||
AllOf(IsStorageType("First.2.qml",
|
||||
ElementsAre(IsExportedType(exampleModuleId, "FirstType", 1, 0),
|
||||
IsExportedType(pathModuleId, "First", -1, -1)))),
|
||||
AllOf(IsStorageType("First2.qml",
|
||||
Storage::ImportedType{},
|
||||
TypeAccessSemantics::Reference,
|
||||
qmlDocumentSourceId2,
|
||||
Storage::ChangeLevel::Minimal),
|
||||
Field(&Storage::Type::exportedTypes,
|
||||
ElementsAre(IsExportedType(exampleModuleId, "FirstType", 2, 2)))))),
|
||||
ElementsAre(IsExportedType(exampleModuleId, "FirstType", 2, 2),
|
||||
IsExportedType(pathModuleId, "First2", -1, -1)))))),
|
||||
Field(&SynchronizationPackage::updatedSourceIds,
|
||||
UnorderedElementsAre(qmlDirPathSourceId,
|
||||
qmltypesPathSourceId,
|
||||
@@ -645,7 +653,7 @@ TEST_F(ProjectStorageUpdater, SynchronizeQmlDocumentsDontUpdateIfUpToDate)
|
||||
{
|
||||
QString qmldir{R"(module Example
|
||||
FirstType 1.0 First.qml
|
||||
FirstType 2.2 First.2.qml
|
||||
FirstType 2.2 First2.qml
|
||||
SecondType 2.2 Second.qml)"};
|
||||
ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/qmldir")))).WillByDefault(Return(qmldir));
|
||||
ON_CALL(projectStorageMock, fetchFileStatus(Eq(qmlDocumentSourceId3)))
|
||||
@@ -663,21 +671,24 @@ TEST_F(ProjectStorageUpdater, SynchronizeQmlDocumentsDontUpdateIfUpToDate)
|
||||
qmlDocumentSourceId1,
|
||||
Storage::ChangeLevel::Full),
|
||||
Field(&Storage::Type::exportedTypes,
|
||||
ElementsAre(IsExportedType(exampleModuleId, "FirstType", 1, 0)))),
|
||||
AllOf(IsStorageType("First.2.qml",
|
||||
ElementsAre(IsExportedType(exampleModuleId, "FirstType", 1, 0),
|
||||
IsExportedType(pathModuleId, "First", -1, -1)))),
|
||||
AllOf(IsStorageType("First2.qml",
|
||||
Storage::ImportedType{"Object2"},
|
||||
TypeAccessSemantics::Reference,
|
||||
qmlDocumentSourceId2,
|
||||
Storage::ChangeLevel::Full),
|
||||
Field(&Storage::Type::exportedTypes,
|
||||
ElementsAre(IsExportedType(exampleModuleId, "FirstType", 2, 2)))),
|
||||
ElementsAre(IsExportedType(exampleModuleId, "FirstType", 2, 2),
|
||||
IsExportedType(pathModuleId, "First2", -1, -1)))),
|
||||
AllOf(IsStorageType("Second.qml",
|
||||
Storage::ImportedType{},
|
||||
TypeAccessSemantics::Reference,
|
||||
qmlDocumentSourceId3,
|
||||
Storage::ChangeLevel::Minimal),
|
||||
Field(&Storage::Type::exportedTypes,
|
||||
ElementsAre(IsExportedType(exampleModuleId, "SecondType", 2, 2)))))),
|
||||
ElementsAre(IsExportedType(exampleModuleId, "SecondType", 2, 2),
|
||||
IsExportedType(pathModuleId, "Second", -1, -1)))))),
|
||||
Field(&SynchronizationPackage::updatedSourceIds,
|
||||
UnorderedElementsAre(qmlDirPathSourceId,
|
||||
qmlDocumentSourceId1,
|
||||
@@ -712,7 +723,7 @@ TEST_F(ProjectStorageUpdater, UpdateQmldirDocuments)
|
||||
{
|
||||
QString qmldir{R"(module Example
|
||||
FirstType 1.1 First.qml
|
||||
FirstType 2.2 First.2.qml
|
||||
FirstType 2.2 First2.qml
|
||||
SecondType 2.2 Second.qml)"};
|
||||
ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/qmldir")))).WillByDefault(Return(qmldir));
|
||||
ON_CALL(projectStorageMock, fetchFileStatus(Eq(qmlDocumentSourceId3)))
|
||||
@@ -767,7 +778,7 @@ TEST_F(ProjectStorageUpdater, SynchronizIfQmldirFileHasNotChanged)
|
||||
qmlDocumentSourceId1,
|
||||
Storage::ChangeLevel::ExcludeExportedTypes),
|
||||
Field(&Storage::Type::exportedTypes, IsEmpty())),
|
||||
AllOf(IsStorageType("First.2.qml",
|
||||
AllOf(IsStorageType("First2.qml",
|
||||
Storage::ImportedType{"Object2"},
|
||||
TypeAccessSemantics::Reference,
|
||||
qmlDocumentSourceId2,
|
||||
@@ -921,7 +932,8 @@ TEST_F(ProjectStorageUpdater, SynchronizeQmlDocumentsWithDifferentVersionButSame
|
||||
UnorderedElementsAre(
|
||||
IsExportedType(exampleModuleId, "FirstType", 1, 0),
|
||||
IsExportedType(exampleModuleId, "FirstType", 1, 1),
|
||||
IsExportedType(exampleModuleId, "FirstType", 6, 0)))))),
|
||||
IsExportedType(exampleModuleId, "FirstType", 6, 0),
|
||||
IsExportedType(pathModuleId, "First", -1, -1)))))),
|
||||
Field(&SynchronizationPackage::updatedSourceIds,
|
||||
UnorderedElementsAre(qmlDirPathSourceId, qmlDocumentSourceId1)),
|
||||
Field(&SynchronizationPackage::updatedFileStatusSourceIds,
|
||||
@@ -951,8 +963,8 @@ TEST_F(ProjectStorageUpdater, SynchronizeQmlDocumentsWithDifferentTypeNameButSam
|
||||
synchronize(
|
||||
AllOf(Field(&SynchronizationPackage::imports, UnorderedElementsAre(import1)),
|
||||
Field(&SynchronizationPackage::types,
|
||||
UnorderedElementsAre(AllOf(
|
||||
IsStorageType("First.qml",
|
||||
UnorderedElementsAre(
|
||||
AllOf(IsStorageType("First.qml",
|
||||
Storage::ImportedType{"Object"},
|
||||
TypeAccessSemantics::Reference,
|
||||
qmlDocumentSourceId1,
|
||||
@@ -960,7 +972,8 @@ TEST_F(ProjectStorageUpdater, SynchronizeQmlDocumentsWithDifferentTypeNameButSam
|
||||
Field(&Storage::Type::exportedTypes,
|
||||
UnorderedElementsAre(
|
||||
IsExportedType(exampleModuleId, "FirstType", 1, 0),
|
||||
IsExportedType(exampleModuleId, "FirstType2", 1, 0)))))),
|
||||
IsExportedType(exampleModuleId, "FirstType2", 1, 0),
|
||||
IsExportedType(pathModuleId, "First", -1, -1)))))),
|
||||
Field(&SynchronizationPackage::updatedSourceIds,
|
||||
UnorderedElementsAre(qmlDirPathSourceId, qmlDocumentSourceId1)),
|
||||
Field(&SynchronizationPackage::updatedFileStatusSourceIds,
|
||||
@@ -1032,7 +1045,8 @@ TEST_F(ProjectStorageUpdater, SynchronizeQmlDocumentsWithRelativeFilePath)
|
||||
Field(&Storage::Type::exportedTypes,
|
||||
UnorderedElementsAre(
|
||||
IsExportedType(exampleModuleId, "FirstType", 1, 0),
|
||||
IsExportedType(exampleModuleId, "FirstType2", 1, 0)))))),
|
||||
IsExportedType(exampleModuleId, "FirstType2", 1, 0),
|
||||
IsExportedType(subPathQmlModuleId, "First", -1, -1)))))),
|
||||
Field(&SynchronizationPackage::updatedSourceIds,
|
||||
UnorderedElementsAre(qmlDirPathSourceId, qmlDocumentSourceId)),
|
||||
Field(&SynchronizationPackage::updatedFileStatusSourceIds,
|
||||
|
@@ -133,12 +133,13 @@ protected:
|
||||
Storage::Imports imports;
|
||||
SourceId qmlFileSourceId{sourcePathCache.sourceId("/path/to/qmlfile.qml")};
|
||||
SourceContextId qmlFileSourceContextId{sourcePathCache.sourceContextId(qmlFileSourceId)};
|
||||
ModuleId directoryModuleId{storage.moduleId("/path/to")};
|
||||
Utils::PathString directoryPath{sourcePathCache.sourceContextPath(qmlFileSourceContextId)};
|
||||
ModuleId directoryModuleId{storage.moduleId(directoryPath)};
|
||||
};
|
||||
|
||||
TEST_F(QmlDocumentParser, Prototype)
|
||||
{
|
||||
auto type = parser.parse("Example{}", imports, qmlFileSourceId);
|
||||
auto type = parser.parse("Example{}", imports, qmlFileSourceId, directoryPath);
|
||||
|
||||
ASSERT_THAT(type, HasPrototype(Storage::ImportedType("Example")));
|
||||
}
|
||||
@@ -149,7 +150,7 @@ TEST_F(QmlDocumentParser, QualifiedPrototype)
|
||||
QString text = R"(import Example 2.1 as Example
|
||||
Example.Item{})";
|
||||
|
||||
auto type = parser.parse(text, imports, qmlFileSourceId);
|
||||
auto type = parser.parse(text, imports, qmlFileSourceId, directoryPath);
|
||||
|
||||
ASSERT_THAT(type,
|
||||
HasPrototype(Storage::QualifiedImportedType("Item",
|
||||
@@ -160,7 +161,7 @@ TEST_F(QmlDocumentParser, QualifiedPrototype)
|
||||
|
||||
TEST_F(QmlDocumentParser, Properties)
|
||||
{
|
||||
auto type = parser.parse(R"(Example{ property int foo })", imports, qmlFileSourceId);
|
||||
auto type = parser.parse(R"(Example{ property int foo })", imports, qmlFileSourceId, directoryPath);
|
||||
|
||||
ASSERT_THAT(type.propertyDeclarations,
|
||||
UnorderedElementsAre(IsPropertyDeclaration("foo",
|
||||
@@ -175,7 +176,8 @@ TEST_F(QmlDocumentParser, QualifiedProperties)
|
||||
auto type = parser.parse(R"(import Example 2.1 as Example
|
||||
Item{ property Example.Foo foo})",
|
||||
imports,
|
||||
qmlFileSourceId);
|
||||
qmlFileSourceId,
|
||||
directoryPath);
|
||||
|
||||
ASSERT_THAT(type.propertyDeclarations,
|
||||
UnorderedElementsAre(IsPropertyDeclaration(
|
||||
@@ -192,7 +194,8 @@ TEST_F(QmlDocumentParser, EnumerationInProperties)
|
||||
auto type = parser.parse(R"(import Example 2.1 as Example
|
||||
Item{ property Enumeration.Foo foo})",
|
||||
imports,
|
||||
qmlFileSourceId);
|
||||
qmlFileSourceId,
|
||||
directoryPath);
|
||||
|
||||
ASSERT_THAT(type.propertyDeclarations,
|
||||
UnorderedElementsAre(IsPropertyDeclaration("foo",
|
||||
@@ -207,7 +210,8 @@ TEST_F(QmlDocumentParser, QualifiedEnumerationInProperties)
|
||||
auto type = parser.parse(R"(import Example 2.1 as Example
|
||||
Item{ property Example.Enumeration.Foo foo})",
|
||||
imports,
|
||||
qmlFileSourceId);
|
||||
qmlFileSourceId,
|
||||
directoryPath);
|
||||
|
||||
ASSERT_THAT(type.propertyDeclarations,
|
||||
UnorderedElementsAre(IsPropertyDeclaration(
|
||||
@@ -223,21 +227,61 @@ TEST_F(QmlDocumentParser, Imports)
|
||||
{
|
||||
ModuleId fooDirectoryModuleId = storage.moduleId("/path/foo");
|
||||
ModuleId qmlModuleId = storage.moduleId("QML");
|
||||
ModuleId qtQmlModuleId = storage.moduleId("QtQml");
|
||||
ModuleId qtQuickModuleId = storage.moduleId("QtQuick");
|
||||
|
||||
auto type = parser.parse(R"(import QtQuick
|
||||
import "../foo"
|
||||
Example{})",
|
||||
imports,
|
||||
qmlFileSourceId);
|
||||
qmlFileSourceId,
|
||||
directoryPath);
|
||||
|
||||
ASSERT_THAT(imports,
|
||||
UnorderedElementsAre(
|
||||
Storage::Import{directoryModuleId, Storage::Version{}, qmlFileSourceId},
|
||||
Storage::Import{fooDirectoryModuleId, Storage::Version{}, qmlFileSourceId},
|
||||
Storage::Import{qmlModuleId, Storage::Version{1, 0}, qmlFileSourceId},
|
||||
Storage::Import{qtQmlModuleId, Storage::Version{6, 0}, qmlFileSourceId},
|
||||
Storage::Import{qmlModuleId, Storage::Version{}, qmlFileSourceId},
|
||||
Storage::Import{qtQuickModuleId, Storage::Version{}, qmlFileSourceId}));
|
||||
}
|
||||
|
||||
TEST_F(QmlDocumentParser, ImportsWithVersion)
|
||||
{
|
||||
ModuleId fooDirectoryModuleId = storage.moduleId("/path/foo");
|
||||
ModuleId qmlModuleId = storage.moduleId("QML");
|
||||
ModuleId qtQuickModuleId = storage.moduleId("QtQuick");
|
||||
|
||||
auto type = parser.parse(R"(import QtQuick 2.1
|
||||
import "../foo"
|
||||
Example{})",
|
||||
imports,
|
||||
qmlFileSourceId,
|
||||
directoryPath);
|
||||
|
||||
ASSERT_THAT(imports,
|
||||
UnorderedElementsAre(
|
||||
Storage::Import{directoryModuleId, Storage::Version{}, qmlFileSourceId},
|
||||
Storage::Import{fooDirectoryModuleId, Storage::Version{}, qmlFileSourceId},
|
||||
Storage::Import{qmlModuleId, Storage::Version{}, qmlFileSourceId},
|
||||
Storage::Import{qtQuickModuleId, Storage::Version{2, 1}, qmlFileSourceId}));
|
||||
}
|
||||
|
||||
TEST_F(QmlDocumentParser, ImportsWithExplictDirectory)
|
||||
{
|
||||
ModuleId qmlModuleId = storage.moduleId("QML");
|
||||
ModuleId qtQuickModuleId = storage.moduleId("QtQuick");
|
||||
|
||||
auto type = parser.parse(R"(import QtQuick
|
||||
import "../to"
|
||||
import "."
|
||||
Example{})",
|
||||
imports,
|
||||
qmlFileSourceId,
|
||||
directoryPath);
|
||||
|
||||
ASSERT_THAT(
|
||||
imports,
|
||||
UnorderedElementsAre(Storage::Import{directoryModuleId, Storage::Version{}, qmlFileSourceId},
|
||||
Storage::Import{qmlModuleId, Storage::Version{}, qmlFileSourceId},
|
||||
Storage::Import{qtQuickModuleId, Storage::Version{}, qmlFileSourceId}));
|
||||
}
|
||||
|
||||
@@ -246,7 +290,8 @@ TEST_F(QmlDocumentParser, Functions)
|
||||
auto type = parser.parse(
|
||||
"Example{\n function someScript(x, y) {}\n function otherFunction() {}\n}",
|
||||
imports,
|
||||
qmlFileSourceId);
|
||||
qmlFileSourceId,
|
||||
directoryPath);
|
||||
|
||||
ASSERT_THAT(type.functionDeclarations,
|
||||
UnorderedElementsAre(AllOf(IsFunctionDeclaration("otherFunction", ""),
|
||||
@@ -261,7 +306,8 @@ TEST_F(QmlDocumentParser, Signals)
|
||||
{
|
||||
auto type = parser.parse("Example{\n signal someSignal(int x, real y)\n signal signal2()\n}",
|
||||
imports,
|
||||
qmlFileSourceId);
|
||||
qmlFileSourceId,
|
||||
directoryPath);
|
||||
|
||||
ASSERT_THAT(type.signalDeclarations,
|
||||
UnorderedElementsAre(AllOf(IsSignalDeclaration("someSignal"),
|
||||
@@ -277,7 +323,8 @@ TEST_F(QmlDocumentParser, Enumeration)
|
||||
auto type = parser.parse("Example{\n enum Color{red, green, blue=10, white}\n enum "
|
||||
"State{On,Off}\n}",
|
||||
imports,
|
||||
qmlFileSourceId);
|
||||
qmlFileSourceId,
|
||||
directoryPath);
|
||||
|
||||
ASSERT_THAT(type.enumerationDeclarations,
|
||||
UnorderedElementsAre(
|
||||
@@ -308,7 +355,8 @@ TEST_F(QmlDocumentParser, DISABLED_DuplicateImportsAreRemoved)
|
||||
|
||||
Example{})",
|
||||
imports,
|
||||
qmlFileSourceId);
|
||||
qmlFileSourceId,
|
||||
directoryPath);
|
||||
|
||||
ASSERT_THAT(imports,
|
||||
UnorderedElementsAre(
|
||||
|
@@ -36,6 +36,7 @@ public:
|
||||
parse,
|
||||
(const QString &sourceContent,
|
||||
QmlDesigner::Storage::Imports &imports,
|
||||
QmlDesigner::SourceId sourceId),
|
||||
QmlDesigner::SourceId sourceId,
|
||||
Utils::SmallStringView directoryPath),
|
||||
(override));
|
||||
};
|
||||
|
Reference in New Issue
Block a user