forked from qt-creator/qt-creator
QmlDesigner: Adapt project storage changes in updater
Task-number: QDS-5123 Task-number: QDS-4923 Task-number: QDS-4925 Change-Id: I79acbbdb11bf7a0529c1ef005e6b5e1fd0d12aa7 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -130,6 +130,11 @@ public:
|
|||||||
, sourceId{sourceId}
|
, sourceId{sourceId}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
explicit Module(QStringView name, SourceId sourceId = SourceId{})
|
||||||
|
: name{name}
|
||||||
|
, sourceId{sourceId}
|
||||||
|
{}
|
||||||
|
|
||||||
explicit Module(Utils::SmallStringView name, int sourceId)
|
explicit Module(Utils::SmallStringView name, int sourceId)
|
||||||
: name{name}
|
: name{name}
|
||||||
, sourceId{sourceId}
|
, sourceId{sourceId}
|
||||||
|
@@ -62,28 +62,31 @@ void ProjectUpdater::update()
|
|||||||
SourcePath qmldirSourcePath{qmldirPath};
|
SourcePath qmldirSourcePath{qmldirPath};
|
||||||
SourceId qmlDirSourceId = m_pathCache.sourceId(qmldirSourcePath);
|
SourceId qmlDirSourceId = m_pathCache.sourceId(qmldirSourcePath);
|
||||||
|
|
||||||
switch (fileState(qmlDirSourceId)) {
|
switch (fileState(qmlDirSourceId, fileStatuses)) {
|
||||||
case FileState::Changed: {
|
case FileState::Changed: {
|
||||||
QmlDirParser parser;
|
QmlDirParser parser;
|
||||||
parser.parse(m_fileSystem.contentAsQString(qmldirPath));
|
parser.parse(m_fileSystem.contentAsQString(qmldirPath));
|
||||||
|
|
||||||
|
modules.emplace_back(parser.typeNamespace(), qmlDirSourceId);
|
||||||
|
|
||||||
sourceIds.push_back(qmlDirSourceId);
|
sourceIds.push_back(qmlDirSourceId);
|
||||||
|
|
||||||
Utils::SmallString moduleName{parser.typeNamespace()};
|
Utils::SmallString moduleName{parser.typeNamespace()};
|
||||||
SourceContextId directoryId = m_pathCache.sourceContextId(qmlDirSourceId);
|
SourceContextId directoryId = m_pathCache.sourceContextId(qmlDirSourceId);
|
||||||
|
|
||||||
parseTypeInfos(parser.typeInfos(), directoryId, modules, types, sourceIds);
|
parseTypeInfos(parser.typeInfos(), directoryId, imports, types, sourceIds, fileStatuses);
|
||||||
parseQmlComponents(createComponentReferences(parser.components()),
|
parseQmlComponents(createComponentReferences(parser.components()),
|
||||||
directoryId,
|
directoryId,
|
||||||
moduleName,
|
moduleName,
|
||||||
modules,
|
imports,
|
||||||
types,
|
types,
|
||||||
sourceIds);
|
sourceIds,
|
||||||
|
fileStatuses);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FileState::NotChanged: {
|
case FileState::NotChanged: {
|
||||||
SourceIds qmltypesSourceIds = m_projectStorage.fetchSourceDependencieIds(qmlDirSourceId);
|
SourceIds qmltypesSourceIds = m_projectStorage.fetchSourceDependencieIds(qmlDirSourceId);
|
||||||
parseTypeInfos(qmltypesSourceIds, modules, types, sourceIds);
|
parseTypeInfos(qmltypesSourceIds, imports, types, sourceIds, fileStatuses);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FileState::NotExists: {
|
case FileState::NotExists: {
|
||||||
@@ -102,9 +105,10 @@ void ProjectUpdater::update()
|
|||||||
|
|
||||||
void ProjectUpdater::parseTypeInfos(const QStringList &typeInfos,
|
void ProjectUpdater::parseTypeInfos(const QStringList &typeInfos,
|
||||||
SourceContextId directoryId,
|
SourceContextId directoryId,
|
||||||
Storage::Modules &modules,
|
Storage::Imports &imports,
|
||||||
Storage::Types &types,
|
Storage::Types &types,
|
||||||
SourceIds &sourceIds)
|
SourceIds &sourceIds,
|
||||||
|
FileStatuses &fileStatuses)
|
||||||
{
|
{
|
||||||
QString directory{m_pathCache.sourceContextPath(directoryId)};
|
QString directory{m_pathCache.sourceContextPath(directoryId)};
|
||||||
|
|
||||||
@@ -112,41 +116,44 @@ void ProjectUpdater::parseTypeInfos(const QStringList &typeInfos,
|
|||||||
SourceId sourceId = m_pathCache.sourceId(directoryId, Utils::SmallString{typeInfo});
|
SourceId sourceId = m_pathCache.sourceId(directoryId, Utils::SmallString{typeInfo});
|
||||||
QString qmltypesPath = directory + "/" + typeInfo;
|
QString qmltypesPath = directory + "/" + typeInfo;
|
||||||
|
|
||||||
parseTypeInfo(sourceId, qmltypesPath, modules, types, sourceIds);
|
parseTypeInfo(sourceId, qmltypesPath, imports, types, sourceIds, fileStatuses);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectUpdater::parseTypeInfos(const SourceIds &qmltypesSourceIds,
|
void ProjectUpdater::parseTypeInfos(const SourceIds &qmltypesSourceIds,
|
||||||
Storage::Modules &modules,
|
Storage::Imports &imports,
|
||||||
Storage::Types &types,
|
Storage::Types &types,
|
||||||
SourceIds &sourceIds)
|
SourceIds &sourceIds,
|
||||||
|
FileStatuses &fileStatuses)
|
||||||
{
|
{
|
||||||
for (SourceId sourceId : qmltypesSourceIds) {
|
for (SourceId sourceId : qmltypesSourceIds) {
|
||||||
QString qmltypesPath = m_pathCache.sourcePath(sourceId).toQString();
|
QString qmltypesPath = m_pathCache.sourcePath(sourceId).toQString();
|
||||||
|
|
||||||
parseTypeInfo(sourceId, qmltypesPath, modules, types, sourceIds);
|
parseTypeInfo(sourceId, qmltypesPath, imports, types, sourceIds, fileStatuses);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectUpdater::parseTypeInfo(SourceId sourceId,
|
void ProjectUpdater::parseTypeInfo(SourceId sourceId,
|
||||||
const QString &qmltypesPath,
|
const QString &qmltypesPath,
|
||||||
Storage::Modules &modules,
|
Storage::Imports &imports,
|
||||||
Storage::Types &types,
|
Storage::Types &types,
|
||||||
SourceIds &sourceIds)
|
SourceIds &sourceIds,
|
||||||
|
FileStatuses &fileStatuses)
|
||||||
{
|
{
|
||||||
if (fileState(sourceId) == FileState::Changed) {
|
if (fileState(sourceId, fileStatuses) == FileState::Changed) {
|
||||||
sourceIds.push_back(sourceId);
|
sourceIds.push_back(sourceId);
|
||||||
const auto content = m_fileSystem.contentAsQString(qmltypesPath);
|
const auto content = m_fileSystem.contentAsQString(qmltypesPath);
|
||||||
m_qmlTypesParser.parse(content, modules, types, sourceIds);
|
m_qmlTypesParser.parse(content, imports, types, sourceIds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectUpdater::parseQmlComponents(ComponentReferences components,
|
void ProjectUpdater::parseQmlComponents(ComponentReferences components,
|
||||||
SourceContextId directoryId,
|
SourceContextId directoryId,
|
||||||
Utils::SmallStringView moduleName,
|
Utils::SmallStringView moduleName,
|
||||||
Storage::Modules &modules,
|
Storage::Imports &imports,
|
||||||
Storage::Types &types,
|
Storage::Types &types,
|
||||||
SourceIds &sourceIds)
|
SourceIds &sourceIds,
|
||||||
|
FileStatuses &fileStatuses)
|
||||||
{
|
{
|
||||||
std::sort(components.begin(), components.end(), [](auto &&first, auto &&second) {
|
std::sort(components.begin(), components.end(), [](auto &&first, auto &&second) {
|
||||||
return std::tie(first.get().typeName, first.get().majorVersion, first.get().minorVersion)
|
return std::tie(first.get().typeName, first.get().majorVersion, first.get().minorVersion)
|
||||||
@@ -166,22 +173,27 @@ void ProjectUpdater::parseQmlComponents(ComponentReferences components,
|
|||||||
Utils::SmallString fileName{component.fileName};
|
Utils::SmallString fileName{component.fileName};
|
||||||
SourceId sourceId = m_pathCache.sourceId(directoryId, fileName);
|
SourceId sourceId = m_pathCache.sourceId(directoryId, fileName);
|
||||||
|
|
||||||
|
if (fileState(sourceId, fileStatuses) != FileState::Changed)
|
||||||
|
continue;
|
||||||
|
|
||||||
sourceIds.push_back(sourceId);
|
sourceIds.push_back(sourceId);
|
||||||
|
|
||||||
const auto content = m_fileSystem.contentAsQString(directory + "/" + component.fileName);
|
const auto content = m_fileSystem.contentAsQString(directory + "/" + component.fileName);
|
||||||
auto type = m_qmlDocumentParser.parse(content);
|
auto type = m_qmlDocumentParser.parse(content, imports);
|
||||||
|
|
||||||
type.typeName = fileName;
|
type.typeName = fileName;
|
||||||
type.module.name = moduleName;
|
type.module.name = moduleName;
|
||||||
type.accessSemantics = Storage::TypeAccessSemantics::Reference;
|
type.accessSemantics = Storage::TypeAccessSemantics::Reference;
|
||||||
type.sourceId = sourceId;
|
type.sourceId = sourceId;
|
||||||
type.exportedTypes.push_back(Storage::ExportedType{Utils::SmallString{component.typeName}});
|
type.exportedTypes.push_back(
|
||||||
|
Storage::ExportedType{Utils::SmallString{component.typeName},
|
||||||
|
Storage::Version{component.majorVersion, component.minorVersion}});
|
||||||
|
|
||||||
types.push_back(std::move(type));
|
types.push_back(std::move(type));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ProjectUpdater::FileState ProjectUpdater::fileState(SourceId sourceId) const
|
ProjectUpdater::FileState ProjectUpdater::fileState(SourceId sourceId, FileStatuses &fileStatuses) const
|
||||||
{
|
{
|
||||||
auto currentFileStatus = m_fileStatusCache.find(sourceId);
|
auto currentFileStatus = m_fileStatusCache.find(sourceId);
|
||||||
|
|
||||||
@@ -190,8 +202,10 @@ ProjectUpdater::FileState ProjectUpdater::fileState(SourceId sourceId) const
|
|||||||
|
|
||||||
auto projectStorageFileStatus = m_projectStorage.fetchFileStatus(sourceId);
|
auto projectStorageFileStatus = m_projectStorage.fetchFileStatus(sourceId);
|
||||||
|
|
||||||
if (!projectStorageFileStatus.isValid() || projectStorageFileStatus != currentFileStatus)
|
if (!projectStorageFileStatus.isValid() || projectStorageFileStatus != currentFileStatus) {
|
||||||
|
fileStatuses.push_back(currentFileStatus);
|
||||||
return FileState::Changed;
|
return FileState::Changed;
|
||||||
|
}
|
||||||
|
|
||||||
return FileState::NotChanged;
|
return FileState::NotChanged;
|
||||||
}
|
}
|
||||||
|
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "filestatus.h"
|
||||||
#include "nonlockingmutex.h"
|
#include "nonlockingmutex.h"
|
||||||
#include "projectstorageids.h"
|
#include "projectstorageids.h"
|
||||||
#include "projectstoragetypes.h"
|
#include "projectstoragetypes.h"
|
||||||
@@ -85,26 +86,30 @@ private:
|
|||||||
|
|
||||||
void parseTypeInfos(const QStringList &typeInfos,
|
void parseTypeInfos(const QStringList &typeInfos,
|
||||||
SourceContextId directoryId,
|
SourceContextId directoryId,
|
||||||
Storage::Modules &modules,
|
Storage::Imports &imports,
|
||||||
Storage::Types &types,
|
Storage::Types &types,
|
||||||
SourceIds &sourceIds);
|
SourceIds &sourceIds,
|
||||||
|
FileStatuses &fileStatuses);
|
||||||
void parseTypeInfos(const SourceIds &qmltypesSourceIds,
|
void parseTypeInfos(const SourceIds &qmltypesSourceIds,
|
||||||
Storage::Modules &modules,
|
Storage::Imports &imports,
|
||||||
Storage::Types &types,
|
Storage::Types &types,
|
||||||
SourceIds &sourceIds);
|
SourceIds &sourceIds,
|
||||||
|
FileStatuses &fileStatuses);
|
||||||
void parseTypeInfo(SourceId sourceId,
|
void parseTypeInfo(SourceId sourceId,
|
||||||
const QString &qmltypesPath,
|
const QString &qmltypesPath,
|
||||||
Storage::Modules &modules,
|
Storage::Imports &imports,
|
||||||
Storage::Types &types,
|
Storage::Types &types,
|
||||||
SourceIds &sourceIds);
|
SourceIds &sourceIds,
|
||||||
|
FileStatuses &fileStatuses);
|
||||||
void parseQmlComponents(ComponentReferences components,
|
void parseQmlComponents(ComponentReferences components,
|
||||||
SourceContextId directoryId,
|
SourceContextId directoryId,
|
||||||
Utils::SmallStringView moduleName,
|
Utils::SmallStringView moduleName,
|
||||||
Storage::Modules &modules,
|
Storage::Imports &imports,
|
||||||
Storage::Types &types,
|
Storage::Types &types,
|
||||||
SourceIds &sourceIds);
|
SourceIds &sourceIds,
|
||||||
|
FileStatuses &fileStatuses);
|
||||||
|
|
||||||
FileState fileState(SourceId sourceId) const;
|
FileState fileState(SourceId sourceId, FileStatuses &fileStatuses) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ProjectManagerInterface &m_projectManager;
|
ProjectManagerInterface &m_projectManager;
|
||||||
|
@@ -34,7 +34,7 @@ namespace QmlDesigner {
|
|||||||
class QmlDocumentParserInterface
|
class QmlDocumentParserInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual Storage::Type parse(const QString &sourceContent) = 0;
|
virtual Storage::Type parse(const QString &sourceContent, Storage::Imports &imports) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
~QmlDocumentParserInterface() = default;
|
~QmlDocumentParserInterface() = default;
|
||||||
|
@@ -35,7 +35,7 @@ class QmlTypesParserInterface
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void parse(const QString &sourceContent,
|
virtual void parse(const QString &sourceContent,
|
||||||
Storage::Modules &modules,
|
Storage::Imports &imports,
|
||||||
Storage::Types &types,
|
Storage::Types &types,
|
||||||
SourceIds &sourceIds)
|
SourceIds &sourceIds)
|
||||||
= 0;
|
= 0;
|
||||||
|
@@ -1080,7 +1080,8 @@ std::ostream &operator<<(std::ostream &out, Version version)
|
|||||||
|
|
||||||
std::ostream &operator<<(std::ostream &out, const ExportedType &exportedType)
|
std::ostream &operator<<(std::ostream &out, const ExportedType &exportedType)
|
||||||
{
|
{
|
||||||
return out << "(\"" << exportedType.name << "\")";
|
return out << "(\"" << exportedType.name << "\""
|
||||||
|
<< ", " << exportedType.version << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream &operator<<(std::ostream &out, const NativeType &nativeType)
|
std::ostream &operator<<(std::ostream &out, const NativeType &nativeType)
|
||||||
|
@@ -77,13 +77,40 @@ MATCHER_P3(IsPropertyDeclaration,
|
|||||||
&& propertyDeclaration.traits == traits;
|
&& propertyDeclaration.traits == traits;
|
||||||
}
|
}
|
||||||
|
|
||||||
MATCHER_P(IsExportedType,
|
MATCHER_P3(IsExportedType,
|
||||||
name,
|
name,
|
||||||
std::string(negation ? "isn't " : "is ") + PrintToString(Storage::ExportedType{name}))
|
majorVersion,
|
||||||
|
minorVersion,
|
||||||
|
std::string(negation ? "isn't " : "is ")
|
||||||
|
+ PrintToString(Storage::ExportedType{name,
|
||||||
|
Storage::Version{majorVersion, minorVersion}}))
|
||||||
{
|
{
|
||||||
const Storage::ExportedType &type = arg;
|
const Storage::ExportedType &type = arg;
|
||||||
|
|
||||||
return type.name == name;
|
return type.name == name && type.version == Storage::Version{majorVersion, minorVersion};
|
||||||
|
}
|
||||||
|
|
||||||
|
MATCHER_P2(IsModule,
|
||||||
|
name,
|
||||||
|
sourceId,
|
||||||
|
std::string(negation ? "isn't " : "is ") + PrintToString(Storage::Module{name, sourceId}))
|
||||||
|
{
|
||||||
|
const Storage::Module &module = arg;
|
||||||
|
|
||||||
|
return module.name == name && module.sourceId == sourceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
MATCHER_P3(IsFileStatus,
|
||||||
|
sourceId,
|
||||||
|
size,
|
||||||
|
lastModified,
|
||||||
|
std::string(negation ? "isn't " : "is ")
|
||||||
|
+ PrintToString(FileStatus{sourceId, size, lastModified}))
|
||||||
|
{
|
||||||
|
const FileStatus &fileStatus = arg;
|
||||||
|
|
||||||
|
return fileStatus.sourceId == sourceId && fileStatus.size == size
|
||||||
|
&& fileStatus.lastModified == lastModified;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ProjectStorageUpdater : public testing::Test
|
class ProjectStorageUpdater : public testing::Test
|
||||||
@@ -113,6 +140,19 @@ public:
|
|||||||
ON_CALL(projectManagerMock, qtQmlDirs()).WillByDefault(Return(QStringList{"/path/qmldir"}));
|
ON_CALL(projectManagerMock, qtQmlDirs()).WillByDefault(Return(QStringList{"/path/qmldir"}));
|
||||||
ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/qmldir"))))
|
ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/qmldir"))))
|
||||||
.WillByDefault(Return(qmldir));
|
.WillByDefault(Return(qmldir));
|
||||||
|
|
||||||
|
ON_CALL(fileSystemMock, fileStatus(Eq(qmlDocumentSourceId1)))
|
||||||
|
.WillByDefault(Return(FileStatus{qmlDocumentSourceId1, 22, 12}));
|
||||||
|
ON_CALL(projectStorageMock, fetchFileStatus(Eq(qmlDocumentSourceId1)))
|
||||||
|
.WillByDefault(Return(FileStatus{qmlDocumentSourceId1, 22, 2}));
|
||||||
|
ON_CALL(fileSystemMock, fileStatus(Eq(qmlDocumentSourceId2)))
|
||||||
|
.WillByDefault(Return(FileStatus{qmlDocumentSourceId2, 22, 13}));
|
||||||
|
ON_CALL(projectStorageMock, fetchFileStatus(Eq(qmlDocumentSourceId2)))
|
||||||
|
.WillByDefault(Return(FileStatus{qmlDocumentSourceId2, 22, 2}));
|
||||||
|
ON_CALL(fileSystemMock, fileStatus(Eq(qmlDocumentSourceId3)))
|
||||||
|
.WillByDefault(Return(FileStatus{qmlDocumentSourceId3, 22, 14}));
|
||||||
|
ON_CALL(projectStorageMock, fetchFileStatus(Eq(qmlDocumentSourceId3)))
|
||||||
|
.WillByDefault(Return(FileStatus{qmlDocumentSourceId3, 22, 2}));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -143,6 +183,9 @@ protected:
|
|||||||
SourceId qmltypesPathSourceId = sourcePathCache.sourceId("/path/example.qmltypes");
|
SourceId qmltypesPathSourceId = sourcePathCache.sourceId("/path/example.qmltypes");
|
||||||
SourceId qmltypes2PathSourceId = sourcePathCache.sourceId("/path/example2.qmltypes");
|
SourceId qmltypes2PathSourceId = sourcePathCache.sourceId("/path/example2.qmltypes");
|
||||||
SourceId qmlDirPathSourceId = sourcePathCache.sourceId("/path/qmldir");
|
SourceId qmlDirPathSourceId = sourcePathCache.sourceId("/path/qmldir");
|
||||||
|
SourceId qmlDocumentSourceId1 = sourcePathCache.sourceId("/path/First.qml");
|
||||||
|
SourceId qmlDocumentSourceId2 = sourcePathCache.sourceId("/path/First.2.qml");
|
||||||
|
SourceId qmlDocumentSourceId3 = sourcePathCache.sourceId("/path/Second.qml");
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(ProjectStorageUpdater, GetContentForQmlDirPathsIfFileStatusIsDifferent)
|
TEST_F(ProjectStorageUpdater, GetContentForQmlDirPathsIfFileStatusIsDifferent)
|
||||||
@@ -232,8 +275,15 @@ TEST_F(ProjectStorageUpdater, ParseQmlTypes)
|
|||||||
updater.update();
|
updater.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ProjectStorageUpdater, DISABLED_SynchronizeIsEmptyForNoChange)
|
TEST_F(ProjectStorageUpdater, SynchronizeIsEmptyForNoChange)
|
||||||
{
|
{
|
||||||
|
ON_CALL(projectStorageMock, fetchFileStatus(Eq(qmltypesPathSourceId)))
|
||||||
|
.WillByDefault(Return(FileStatus{qmltypesPathSourceId, 21, 421}));
|
||||||
|
ON_CALL(projectStorageMock, fetchFileStatus(Eq(qmltypes2PathSourceId)))
|
||||||
|
.WillByDefault(Return(FileStatus{qmltypes2PathSourceId, 21, 421}));
|
||||||
|
ON_CALL(projectStorageMock, fetchFileStatus(Eq(qmlDirPathSourceId)))
|
||||||
|
.WillByDefault(Return(FileStatus{qmlDirPathSourceId, 21, 421}));
|
||||||
|
|
||||||
EXPECT_CALL(projectStorageMock,
|
EXPECT_CALL(projectStorageMock,
|
||||||
synchronize(IsEmpty(), IsEmpty(), IsEmpty(), IsEmpty(), IsEmpty()));
|
synchronize(IsEmpty(), IsEmpty(), IsEmpty(), IsEmpty(), IsEmpty()));
|
||||||
|
|
||||||
@@ -244,20 +294,23 @@ TEST_F(ProjectStorageUpdater, SynchronizeQmlTypes)
|
|||||||
{
|
{
|
||||||
auto qmlDirPathSourceId = sourcePathCache.sourceId("/path/qmldir");
|
auto qmlDirPathSourceId = sourcePathCache.sourceId("/path/qmldir");
|
||||||
auto qmltypesPathSourceId = sourcePathCache.sourceId("/path/example.qmltypes");
|
auto qmltypesPathSourceId = sourcePathCache.sourceId("/path/example.qmltypes");
|
||||||
|
Storage::Import import{"Qml", Storage::Version{2, 3}, qmltypesPathSourceId};
|
||||||
QString qmltypes{"Module {\ndependencies: []}"};
|
QString qmltypes{"Module {\ndependencies: []}"};
|
||||||
ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/example.qmltypes"))))
|
ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/example.qmltypes"))))
|
||||||
.WillByDefault(Return(qmltypes));
|
.WillByDefault(Return(qmltypes));
|
||||||
ON_CALL(qmlTypesParserMock, parse(qmltypes, _, _, _))
|
ON_CALL(qmlTypesParserMock, parse(qmltypes, _, _, _))
|
||||||
.WillByDefault([&](auto, auto &moduleDependencies, auto &types, auto &sourceIds) {
|
.WillByDefault([&](auto, auto &imports, auto &types, auto &sourceIds) {
|
||||||
types.push_back(objectType);
|
types.push_back(objectType);
|
||||||
|
imports.push_back(import);
|
||||||
});
|
});
|
||||||
|
|
||||||
EXPECT_CALL(projectStorageMock,
|
EXPECT_CALL(projectStorageMock,
|
||||||
synchronize(_,
|
synchronize(ElementsAre(IsModule("Example", qmlDirPathSourceId)),
|
||||||
_,
|
ElementsAre(import),
|
||||||
ElementsAre(Eq(objectType)),
|
ElementsAre(Eq(objectType)),
|
||||||
UnorderedElementsAre(qmlDirPathSourceId, qmltypesPathSourceId),
|
UnorderedElementsAre(qmlDirPathSourceId, qmltypesPathSourceId),
|
||||||
_));
|
UnorderedElementsAre(IsFileStatus(qmlDirPathSourceId, 21, 421),
|
||||||
|
IsFileStatus(qmltypesPathSourceId, 21, 421))));
|
||||||
|
|
||||||
updater.update();
|
updater.update();
|
||||||
}
|
}
|
||||||
@@ -268,7 +321,7 @@ TEST_F(ProjectStorageUpdater, SynchronizeQmlTypesAreEmptyIfFileDoesNotChanged)
|
|||||||
ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/example.qmltypes"))))
|
ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/example.qmltypes"))))
|
||||||
.WillByDefault(Return(qmltypes));
|
.WillByDefault(Return(qmltypes));
|
||||||
ON_CALL(qmlTypesParserMock, parse(qmltypes, _, _, _))
|
ON_CALL(qmlTypesParserMock, parse(qmltypes, _, _, _))
|
||||||
.WillByDefault([&](auto, auto &moduleDependencies, auto &types, auto &sourceIds) {
|
.WillByDefault([&](auto, auto &imports, auto &types, auto &sourceIds) {
|
||||||
types.push_back(objectType);
|
types.push_back(objectType);
|
||||||
});
|
});
|
||||||
ON_CALL(fileSystemMock, fileStatus(Eq(qmltypesPathSourceId)))
|
ON_CALL(fileSystemMock, fileStatus(Eq(qmltypesPathSourceId)))
|
||||||
@@ -313,30 +366,30 @@ TEST_F(ProjectStorageUpdater, ParseQmlDocuments)
|
|||||||
ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/Second.qml"))))
|
ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/Second.qml"))))
|
||||||
.WillByDefault(Return(qmlDocument3));
|
.WillByDefault(Return(qmlDocument3));
|
||||||
|
|
||||||
EXPECT_CALL(qmlDocumentParserMock, parse(qmlDocument1));
|
EXPECT_CALL(qmlDocumentParserMock, parse(qmlDocument1, _));
|
||||||
EXPECT_CALL(qmlDocumentParserMock, parse(qmlDocument2));
|
EXPECT_CALL(qmlDocumentParserMock, parse(qmlDocument2, _));
|
||||||
EXPECT_CALL(qmlDocumentParserMock, parse(qmlDocument3));
|
EXPECT_CALL(qmlDocumentParserMock, parse(qmlDocument3, _));
|
||||||
|
|
||||||
updater.update();
|
updater.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ProjectStorageUpdater, SynchronizeQmlDocuments)
|
TEST_F(ProjectStorageUpdater, SynchronizeQmlDocuments)
|
||||||
{
|
{
|
||||||
QString qmldir{"module Example\nFirstType 1.0 First.qml\nFirstTypeV2 2.2 "
|
Storage::Module exampleModule{"Example"};
|
||||||
|
QString qmldir{"module Example\nFirstType 1.0 First.qml\nFirstType 2.2 "
|
||||||
"First.2.qml\nSecondType 2.1 OldSecond.qml\nSecondType 2.2 Second.qml\n"};
|
"First.2.qml\nSecondType 2.1 OldSecond.qml\nSecondType 2.2 Second.qml\n"};
|
||||||
QString qmlDocument1{"First{}"};
|
QString qmlDocument1{"First{}"};
|
||||||
QString qmlDocument2{"Second{}"};
|
QString qmlDocument2{"Second{}"};
|
||||||
QString qmlDocument3{"Third{}"};
|
QString qmlDocument3{"Third{}"};
|
||||||
auto qmlDocumentSourceId1 = sourcePathCache.sourceId("/path/First.qml");
|
|
||||||
auto qmlDocumentSourceId2 = sourcePathCache.sourceId("/path/First.2.qml");
|
|
||||||
auto qmlDocumentSourceId3 = sourcePathCache.sourceId("/path/Second.qml");
|
|
||||||
Storage::Type firstType;
|
Storage::Type firstType;
|
||||||
firstType.prototype = Storage::ImportedType{"Object"};
|
firstType.prototype = Storage::ImportedType{"Object"};
|
||||||
Storage::Type secondType;
|
Storage::Type secondType;
|
||||||
secondType.prototype = Storage::ImportedType{"Object2"};
|
secondType.prototype = Storage::ImportedType{"Object2"};
|
||||||
Storage::Type thirdType;
|
Storage::Type thirdType;
|
||||||
thirdType.prototype = Storage::ImportedType{"Object3"};
|
thirdType.prototype = Storage::ImportedType{"Object3"};
|
||||||
auto firstQmlDocumentSourceId = sourcePathCache.sourceId("/path/First.qml");
|
Storage::Import import1{"Qml", Storage::Version{2, 3}, qmlDocumentSourceId1};
|
||||||
|
Storage::Import import2{"Qml", Storage::Version{}, qmlDocumentSourceId2};
|
||||||
|
Storage::Import import3{"Qml", Storage::Version{2}, qmlDocumentSourceId3};
|
||||||
ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/qmldir")))).WillByDefault(Return(qmldir));
|
ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/qmldir")))).WillByDefault(Return(qmldir));
|
||||||
ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/First.qml"))))
|
ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/First.qml"))))
|
||||||
.WillByDefault(Return(qmlDocument1));
|
.WillByDefault(Return(qmlDocument1));
|
||||||
@@ -344,25 +397,77 @@ TEST_F(ProjectStorageUpdater, SynchronizeQmlDocuments)
|
|||||||
.WillByDefault(Return(qmlDocument2));
|
.WillByDefault(Return(qmlDocument2));
|
||||||
ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/Second.qml"))))
|
ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/Second.qml"))))
|
||||||
.WillByDefault(Return(qmlDocument3));
|
.WillByDefault(Return(qmlDocument3));
|
||||||
ON_CALL(qmlDocumentParserMock, parse(qmlDocument1)).WillByDefault(Return(firstType));
|
ON_CALL(qmlDocumentParserMock, parse(qmlDocument1, _)).WillByDefault([&](auto, auto &imports) {
|
||||||
ON_CALL(qmlDocumentParserMock, parse(qmlDocument2)).WillByDefault(Return(secondType));
|
imports.push_back(import1);
|
||||||
ON_CALL(qmlDocumentParserMock, parse(qmlDocument3)).WillByDefault(Return(thirdType));
|
return firstType;
|
||||||
|
});
|
||||||
|
ON_CALL(qmlDocumentParserMock, parse(qmlDocument2, _)).WillByDefault([&](auto, auto &imports) {
|
||||||
|
imports.push_back(import2);
|
||||||
|
return secondType;
|
||||||
|
});
|
||||||
|
ON_CALL(qmlDocumentParserMock, parse(qmlDocument3, _)).WillByDefault([&](auto, auto &imports) {
|
||||||
|
imports.push_back(import3);
|
||||||
|
return thirdType;
|
||||||
|
});
|
||||||
|
|
||||||
EXPECT_CALL(projectStorageMock,
|
EXPECT_CALL(projectStorageMock,
|
||||||
synchronize(_,
|
synchronize(ElementsAre(IsModule("Example", qmlDirPathSourceId)),
|
||||||
_,
|
UnorderedElementsAre(import1, import2, import3),
|
||||||
Contains(AllOf(IsStorageType(Storage::Module{"Example"},
|
UnorderedElementsAre(
|
||||||
"First.qml",
|
AllOf(IsStorageType(Storage::Module{"Example"},
|
||||||
Storage::ImportedType{"Object"},
|
"First.qml",
|
||||||
TypeAccessSemantics::Reference,
|
Storage::ImportedType{"Object"},
|
||||||
firstQmlDocumentSourceId),
|
TypeAccessSemantics::Reference,
|
||||||
Field(&Storage::Type::exportedTypes,
|
qmlDocumentSourceId1),
|
||||||
ElementsAre(IsExportedType("FirstType"))))),
|
Field(&Storage::Type::exportedTypes,
|
||||||
|
ElementsAre(IsExportedType("FirstType", 1, 0)))),
|
||||||
|
AllOf(IsStorageType(Storage::Module{"Example"},
|
||||||
|
"First.2.qml",
|
||||||
|
Storage::ImportedType{"Object2"},
|
||||||
|
TypeAccessSemantics::Reference,
|
||||||
|
qmlDocumentSourceId2),
|
||||||
|
Field(&Storage::Type::exportedTypes,
|
||||||
|
ElementsAre(IsExportedType("FirstType", 2, 2)))),
|
||||||
|
AllOf(IsStorageType(Storage::Module{"Example"},
|
||||||
|
"Second.qml",
|
||||||
|
Storage::ImportedType{"Object3"},
|
||||||
|
TypeAccessSemantics::Reference,
|
||||||
|
qmlDocumentSourceId3),
|
||||||
|
Field(&Storage::Type::exportedTypes,
|
||||||
|
ElementsAre(IsExportedType("SecondType", 2, 2))))),
|
||||||
UnorderedElementsAre(qmlDirPathSourceId,
|
UnorderedElementsAre(qmlDirPathSourceId,
|
||||||
qmlDocumentSourceId1,
|
qmlDocumentSourceId1,
|
||||||
qmlDocumentSourceId2,
|
qmlDocumentSourceId2,
|
||||||
qmlDocumentSourceId3),
|
qmlDocumentSourceId3),
|
||||||
_));
|
UnorderedElementsAre(IsFileStatus(qmlDirPathSourceId, 21, 421),
|
||||||
|
IsFileStatus(qmlDocumentSourceId1, 22, 12),
|
||||||
|
IsFileStatus(qmlDocumentSourceId2, 22, 13),
|
||||||
|
IsFileStatus(qmlDocumentSourceId3, 22, 14))));
|
||||||
|
|
||||||
|
updater.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ProjectStorageUpdater, SynchronizeModules)
|
||||||
|
{
|
||||||
|
SourceId qmlDirPathSourceId2 = sourcePathCache.sourceId("/path2/qmldir");
|
||||||
|
ON_CALL(fileSystemMock, fileStatus(Eq(qmlDirPathSourceId2)))
|
||||||
|
.WillByDefault(Return(FileStatus{qmlDirPathSourceId2, 22, 423}));
|
||||||
|
ON_CALL(projectStorageMock, fetchFileStatus(Eq(qmlDirPathSourceId2)))
|
||||||
|
.WillByDefault(Return(FileStatus{qmlDirPathSourceId2, 2, 421}));
|
||||||
|
QString qmldir2{"module Example2\n"};
|
||||||
|
ON_CALL(projectManagerMock, qtQmlDirs())
|
||||||
|
.WillByDefault(Return(QStringList{"/path/qmldir", "/path2/qmldir"}));
|
||||||
|
ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path2/qmldir")))).WillByDefault(Return(qmldir2));
|
||||||
|
|
||||||
|
EXPECT_CALL(projectStorageMock,
|
||||||
|
synchronize(UnorderedElementsAre(IsModule("Example", qmlDirPathSourceId),
|
||||||
|
IsModule("Example2", qmlDirPathSourceId2)),
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
UnorderedElementsAre(IsFileStatus(qmlDirPathSourceId, 21, 421),
|
||||||
|
IsFileStatus(qmltypesPathSourceId, 21, 421),
|
||||||
|
IsFileStatus(qmlDirPathSourceId2, 22, 423))));
|
||||||
|
|
||||||
updater.update();
|
updater.update();
|
||||||
}
|
}
|
||||||
|
@@ -32,5 +32,8 @@
|
|||||||
class QmlDocumentParserMock : public QmlDesigner::QmlDocumentParserInterface
|
class QmlDocumentParserMock : public QmlDesigner::QmlDocumentParserInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MOCK_METHOD(QmlDesigner::Storage::Type, parse, (const QString &), (override));
|
MOCK_METHOD(QmlDesigner::Storage::Type,
|
||||||
|
parse,
|
||||||
|
(const QString &, QmlDesigner::Storage::Imports &),
|
||||||
|
(override));
|
||||||
};
|
};
|
||||||
|
@@ -35,7 +35,7 @@ public:
|
|||||||
MOCK_METHOD(void,
|
MOCK_METHOD(void,
|
||||||
parse,
|
parse,
|
||||||
(const QString &sourceContent,
|
(const QString &sourceContent,
|
||||||
QmlDesigner::Storage::Modules &modules,
|
QmlDesigner::Storage::Imports &imports,
|
||||||
QmlDesigner::Storage::Types &types,
|
QmlDesigner::Storage::Types &types,
|
||||||
QmlDesigner::SourceIds &sourceIds),
|
QmlDesigner::SourceIds &sourceIds),
|
||||||
(override));
|
(override));
|
||||||
|
Reference in New Issue
Block a user