QmlDesigner: Support multiple module ids per type

The type will be use source id and name instead of module id and name as
key.

Task-number: QDS-5236
Task-number: QDS-5238
Change-Id: Ibc9c298dc0a6363b630173ec4981d574cecd02ff
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-11 11:15:47 +02:00
committed by Tim Jenssen
parent 3871e40f43
commit cb946ec307
16 changed files with 1835 additions and 2206 deletions

View File

@@ -99,6 +99,24 @@ bool set_intersection_compare(
return false; return false;
} }
template<class InputIt1, class InputIt2, class Callable, class Compare>
void set_greedy_difference(
InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, Callable call, Compare comp)
{
while (first1 != last1 && first2 != last2) {
if (comp(*first1, *first2)) {
call(*first1++);
} else if (comp(*first2, *first1)) {
++first2;
} else {
++first1;
}
}
while (first1 != last1)
call(*first1++);
}
template<typename InputIt1, typename InputIt2, typename BinaryPredicate, typename Callable, typename Value> template<typename InputIt1, typename InputIt2, typename BinaryPredicate, typename Callable, typename Value>
Value mismatch_collect(InputIt1 first1, Value mismatch_collect(InputIt1 first1,
InputIt1 last1, InputIt1 last1,

View File

@@ -33,13 +33,14 @@ namespace QmlDesigner {
class ProjectStorageInterface class ProjectStorageInterface
{ {
public: public:
virtual void synchronize(Storage::Modules modules, virtual void synchronize(Storage::Imports imports,
Storage::Imports imports,
Storage::Types types, Storage::Types types,
SourceIds sourceIds, SourceIds sourceIds,
FileStatuses fileStatuses) FileStatuses fileStatuses)
= 0; = 0;
virtual ModuleId moduleId(Utils::SmallStringView name) = 0;
virtual FileStatus fetchFileStatus(SourceId sourceId) const = 0; virtual FileStatus fetchFileStatus(SourceId sourceId) const = 0;
virtual SourceIds fetchSourceDependencieIds(SourceId sourceId) const = 0; virtual SourceIds fetchSourceDependencieIds(SourceId sourceId) const = 0;

View File

@@ -121,38 +121,6 @@ public:
VersionNumber minor; VersionNumber minor;
}; };
class Module
{
public:
explicit Module() = default;
explicit Module(Utils::SmallStringView name, SourceId sourceId = SourceId{})
: name{name}
, sourceId{sourceId}
{}
explicit Module(QStringView name, SourceId sourceId = SourceId{})
: name{name}
, sourceId{sourceId}
{}
explicit Module(Utils::SmallStringView name, int sourceId)
: name{name}
, sourceId{sourceId}
{}
friend bool operator==(const Module &first, const Module &second)
{
return first.name == second.name;
}
public:
Utils::PathString name;
SourceId sourceId;
};
using Modules = std::vector<Module>;
enum class IsQualified : int { No, Yes }; enum class IsQualified : int { No, Yes };
inline int operator-(IsQualified first, IsQualified second) inline int operator-(IsQualified first, IsQualified second)
@@ -172,41 +140,29 @@ class Import
public: public:
explicit Import() = default; explicit Import() = default;
explicit Import(Utils::SmallStringView name, explicit Import(ModuleId moduleId, Version version, SourceId sourceId)
Version version,
SourceId sourceId,
ImportKind kind = ImportKind::Module)
: name{name}
, version{version}
, sourceId{sourceId}
, kind{kind}
{}
explicit Import(Version version, ModuleId moduleId, SourceId sourceId)
: version{version} : version{version}
, moduleId{moduleId} , moduleId{moduleId}
, sourceId{sourceId} , sourceId{sourceId}
{} {}
explicit Import(Utils::SmallStringView name, int majorVersion, int minorVersion, int sourceId) explicit Import(int moduleId, int majorVersion, int minorVersion, int sourceId)
: name{name} : moduleId{moduleId}
, version{majorVersion, minorVersion} , version{majorVersion, minorVersion}
, sourceId{sourceId} , sourceId{sourceId}
{} {}
friend bool operator==(const Import &first, const Import &second) friend bool operator==(const Import &first, const Import &second)
{ {
return first.name == second.name && first.version == second.version return first.moduleId == second.moduleId && first.version == second.version
&& first.sourceId == second.sourceId && first.moduleId.id == second.moduleId.id; && first.sourceId == second.sourceId;
} }
public: public:
Utils::SmallString name;
Version version; Version version;
ModuleId moduleId; ModuleId moduleId;
SourceId sourceId; SourceId sourceId;
Utils::SmallString aliasName; Utils::SmallString aliasName;
ImportKind kind = ImportKind::Module;
}; };
using Imports = std::vector<Import>; using Imports = std::vector<Import>;
@@ -296,9 +252,10 @@ public:
, moduleId{moduleId} , moduleId{moduleId}
{} {}
explicit ExportedType(Utils::SmallStringView name, int majorVersion, int minorVersion) explicit ExportedType(int moduleId, Utils::SmallStringView name, int majorVersion, int minorVersion)
: name{name} : name{name}
, version{majorVersion, minorVersion} , version{majorVersion, minorVersion}
, moduleId{moduleId}
{} {}
friend bool operator==(const ExportedType &first, const ExportedType &second) friend bool operator==(const ExportedType &first, const ExportedType &second)
@@ -576,6 +533,15 @@ public:
, kind{PropertyKind::Property} , kind{PropertyKind::Property}
{} {}
explicit PropertyDeclaration(Utils::SmallStringView name,
TypeId propertyTypeId,
PropertyDeclarationTraits traits)
: name{name}
, traits{traits}
, propertyTypeId{propertyTypeId}
, kind{PropertyKind::Property}
{}
explicit PropertyDeclaration(Utils::SmallStringView name, explicit PropertyDeclaration(Utils::SmallStringView name,
ImportedTypeName typeName, ImportedTypeName typeName,
PropertyDeclarationTraits traits, PropertyDeclarationTraits traits,
@@ -588,13 +554,24 @@ public:
{} {}
explicit PropertyDeclaration(Utils::SmallStringView name, explicit PropertyDeclaration(Utils::SmallStringView name,
Utils::SmallStringView typeName, TypeId propetyTypeId,
PropertyDeclarationTraits traits,
Utils::SmallStringView aliasPropertyName)
: name{name}
, aliasPropertyName{aliasPropertyName}
, traits{traits}
, propertyTypeId{propertyTypeId}
, kind{PropertyKind::Property}
{}
explicit PropertyDeclaration(Utils::SmallStringView name,
long long propertyTypeId,
int traits, int traits,
Utils::SmallStringView aliasPropertyName) Utils::SmallStringView aliasPropertyName)
: name{name} : name{name}
, typeName{NativeType{typeName}}
, aliasPropertyName{aliasPropertyName} , aliasPropertyName{aliasPropertyName}
, traits{static_cast<PropertyDeclarationTraits>(traits)} , traits{static_cast<PropertyDeclarationTraits>(traits)}
, propertyTypeId{propertyTypeId}
, kind{PropertyKind::Property} , kind{PropertyKind::Property}
{} {}
@@ -619,6 +596,7 @@ public:
ImportedTypeName typeName; ImportedTypeName typeName;
Utils::SmallString aliasPropertyName; Utils::SmallString aliasPropertyName;
PropertyDeclarationTraits traits = {}; PropertyDeclarationTraits traits = {};
TypeId propertyTypeId;
TypeId typeId; TypeId typeId;
PropertyKind kind = PropertyKind::Property; PropertyKind kind = PropertyKind::Property;
}; };
@@ -657,8 +635,7 @@ class Type
{ {
public: public:
explicit Type() = default; explicit Type() = default;
explicit Type(ModuleId moduleId, explicit Type(Utils::SmallStringView typeName,
Utils::SmallStringView typeName,
ImportedTypeName prototype, ImportedTypeName prototype,
TypeAccessSemantics accessSemantics, TypeAccessSemantics accessSemantics,
SourceId sourceId, SourceId sourceId,
@@ -677,12 +654,20 @@ public:
, enumerationDeclarations{std::move(enumerationDeclarations)} , enumerationDeclarations{std::move(enumerationDeclarations)}
, accessSemantics{accessSemantics} , accessSemantics{accessSemantics}
, sourceId{sourceId} , sourceId{sourceId}
, moduleId{moduleId}
, changeLevel{changeLevel} , changeLevel{changeLevel}
{} {}
explicit Type(ModuleId moduleId, explicit Type(Utils::SmallStringView typeName,
Utils::SmallStringView typeName, TypeId prototypeId,
TypeAccessSemantics accessSemantics,
SourceId sourceId)
: typeName{typeName}
, accessSemantics{accessSemantics}
, sourceId{sourceId}
, prototypeId{prototypeId}
{}
explicit Type(Utils::SmallStringView typeName,
Utils::SmallStringView prototype, Utils::SmallStringView prototype,
int accessSemantics, int accessSemantics,
int sourceId) int sourceId)
@@ -690,22 +675,19 @@ public:
, prototype{NativeType{prototype}} , prototype{NativeType{prototype}}
, accessSemantics{static_cast<TypeAccessSemantics>(accessSemantics)} , accessSemantics{static_cast<TypeAccessSemantics>(accessSemantics)}
, sourceId{sourceId} , sourceId{sourceId}
, moduleId{moduleId}
{} {}
explicit Type(int moduleId, explicit Type(int sourceId,
Utils::SmallStringView typeName, Utils::SmallStringView typeName,
long long typeId, long long typeId,
Utils::SmallStringView prototype, long long prototypeId,
int accessSemantics, int accessSemantics)
int sourceId)
: typeName{typeName} : typeName{typeName}
, prototype{NativeType{prototype}}
, accessSemantics{static_cast<TypeAccessSemantics>(accessSemantics)} , accessSemantics{static_cast<TypeAccessSemantics>(accessSemantics)}
, sourceId{sourceId} , sourceId{sourceId}
, typeId{typeId} , typeId{typeId}
, moduleId{moduleId} , prototypeId{prototypeId}
{} {}
friend bool operator==(const Type &first, const Type &second) noexcept friend bool operator==(const Type &first, const Type &second) noexcept
@@ -715,7 +697,6 @@ public:
&& first.propertyDeclarations == second.propertyDeclarations && first.propertyDeclarations == second.propertyDeclarations
&& first.functionDeclarations == second.functionDeclarations && first.functionDeclarations == second.functionDeclarations
&& first.signalDeclarations == second.signalDeclarations && first.signalDeclarations == second.signalDeclarations
&& first.moduleId == second.moduleId && first.sourceId == second.sourceId
&& first.sourceId == second.sourceId; && first.sourceId == second.sourceId;
} }
@@ -730,28 +711,10 @@ public:
TypeAccessSemantics accessSemantics = TypeAccessSemantics::None; TypeAccessSemantics accessSemantics = TypeAccessSemantics::None;
SourceId sourceId; SourceId sourceId;
TypeId typeId; TypeId typeId;
ModuleId moduleId; TypeId prototypeId;
ChangeLevel changeLevel = ChangeLevel::Full; ChangeLevel changeLevel = ChangeLevel::Full;
}; };
using Types = std::vector<Type>; using Types = std::vector<Type>;
class ModuleView
{
public:
explicit ModuleView(Utils::SmallStringView name, int sourceId)
: name{name}
, sourceId{sourceId}
{}
friend bool operator==(const ModuleView &first, const ModuleView &second)
{
return first.name == second.name && first.sourceId == second.sourceId;
}
public:
Utils::SmallStringView name;
SourceId sourceId;
};
} // namespace QmlDesigner::Storage } // namespace QmlDesigner::Storage

View File

@@ -52,7 +52,6 @@ ComponentReferences createComponentReferences(const QMultiHash<QString, QmlDirPa
void ProjectUpdater::update() void ProjectUpdater::update()
{ {
Storage::Modules modules;
Storage::Imports imports; Storage::Imports imports;
Storage::Types types; Storage::Types types;
SourceIds sourceIds; SourceIds sourceIds;
@@ -67,22 +66,17 @@ void ProjectUpdater::update()
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);
SourceContextId directoryId = m_pathCache.sourceContextId(qmlDirSourceId); SourceContextId directoryId = m_pathCache.sourceContextId(qmlDirSourceId);
parseTypeInfos(parser.typeInfos(), ModuleId moduleId = m_projectStorage.moduleId(Utils::PathString{parser.typeNamespace()});
directoryId,
ModuleId{&qmlDirSourceId}, parseTypeInfos(
imports, parser.typeInfos(), directoryId, moduleId, imports, types, sourceIds, fileStatuses);
types,
sourceIds,
fileStatuses);
parseQmlComponents(createComponentReferences(parser.components()), parseQmlComponents(createComponentReferences(parser.components()),
directoryId, directoryId,
ModuleId{&qmlDirSourceId}, moduleId,
imports, imports,
types, types,
sourceIds, sourceIds,
@@ -106,8 +100,7 @@ void ProjectUpdater::update()
} }
} }
m_projectStorage.synchronize(std::move(modules), m_projectStorage.synchronize(std::move(imports),
std::move(imports),
std::move(types), std::move(types),
std::move(sourceIds), std::move(sourceIds),
std::move(fileStatuses)); std::move(fileStatuses));
@@ -197,11 +190,11 @@ void ProjectUpdater::parseQmlComponents(ComponentReferences components,
auto type = m_qmlDocumentParser.parse(content, imports); auto type = m_qmlDocumentParser.parse(content, imports);
type.typeName = fileName; type.typeName = fileName;
type.moduleId = moduleId;
type.accessSemantics = Storage::TypeAccessSemantics::Reference; type.accessSemantics = Storage::TypeAccessSemantics::Reference;
type.sourceId = sourceId; type.sourceId = sourceId;
type.exportedTypes.push_back( type.exportedTypes.push_back(
Storage::ExportedType{Utils::SmallString{component.typeName}, Storage::ExportedType{moduleId,
Utils::SmallString{component.typeName},
Storage::Version{component.majorVersion, component.minorVersion}}); Storage::Version{component.majorVersion, component.minorVersion}});
types.push_back(std::move(type)); types.push_back(std::move(type));

View File

@@ -69,19 +69,19 @@ void addImports(Storage::Imports &imports,
const QList<QmlDom::Import> &qmlImports, const QList<QmlDom::Import> &qmlImports,
SourceId sourceId, SourceId sourceId,
SourceContextId sourceContextId, SourceContextId sourceContextId,
QmlDocumentParser::PathCache &pathCache) QmlDocumentParser::PathCache &pathCache,
QmlDocumentParser::ProjectStorage &storage)
{ {
for (const QmlDom::Import &qmlImport : qmlImports) { for (const QmlDom::Import &qmlImport : qmlImports) {
if (qmlImport.uri == u"file://.") { if (qmlImport.uri == u"file://.") {
SourceId directorySourceId = pathCache.sourceId(sourceContextId, "."); auto moduleId = storage.moduleId(pathCache.sourceContextPath(sourceContextId));
imports.emplace_back(Storage::Version{}, ModuleId{&directorySourceId}, sourceId); imports.emplace_back(moduleId, Storage::Version{}, sourceId);
} else if (qmlImport.uri.startsWith(u"file://")) { } else if (qmlImport.uri.startsWith(u"file://")) {
SourceId uriSourceId = pathCache.sourceId(sourceContextId, convertUri(qmlImport.uri)); auto moduleId = storage.moduleId(convertUri(qmlImport.uri));
imports.emplace_back(Storage::Version{}, ModuleId{&uriSourceId}, sourceId); imports.emplace_back(moduleId, Storage::Version{}, sourceId);
} else { } else {
imports.emplace_back(Utils::SmallString{qmlImport.uri}, auto moduleId = storage.moduleId(Utils::SmallString{qmlImport.uri});
convertVersion(qmlImport.version), imports.emplace_back(moduleId, convertVersion(qmlImport.version), sourceId);
sourceId);
} }
} }
} }
@@ -185,7 +185,7 @@ Storage::Type QmlDocumentParser::parse(const QString &sourceContent,
type.prototype = Storage::ImportedType{Utils::SmallString{qmlObject.name()}}; type.prototype = Storage::ImportedType{Utils::SmallString{qmlObject.name()}};
addImports(imports, qmlFile->imports(), sourceId, sourceContextId, m_pathCache); addImports(imports, qmlFile->imports(), sourceId, sourceContextId, m_pathCache, m_storage);
addPropertyDeclarations(type, qmlObject); addPropertyDeclarations(type, qmlObject);
addFunctionAndSignalDeclarations(type, qmlObject); addFunctionAndSignalDeclarations(type, qmlObject);

View File

@@ -43,11 +43,12 @@ class SourcePathCache;
class QmlDocumentParser class QmlDocumentParser
{ {
public: public:
using PathCache = QmlDesigner::SourcePathCache<QmlDesigner::ProjectStorage<Sqlite::Database>, using ProjectStorage = QmlDesigner::ProjectStorage<Sqlite::Database>;
NonLockingMutex>; using PathCache = QmlDesigner::SourcePathCache<ProjectStorage, NonLockingMutex>;
QmlDocumentParser(PathCache &pathCache) QmlDocumentParser(PathCache &pathCache, ProjectStorage &storage)
: m_pathCache{pathCache} : m_pathCache{pathCache}
, m_storage{storage}
{} {}
virtual Storage::Type parse(const QString &sourceContent, virtual Storage::Type parse(const QString &sourceContent,
@@ -57,5 +58,6 @@ public:
private: private:
PathCache &m_pathCache; PathCache &m_pathCache;
ProjectStorage &m_storage;
}; };
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -45,15 +45,20 @@ namespace QmlDom = QQmlJS::Dom;
namespace { namespace {
void addType(const QQmlJSScope::Ptr &object, Storage::Types &types) {} void addType(const QQmlJSScope::Ptr &object, Storage::Types &types) {}
Storage::Import createImport(const QString &dependency, SourceId sourceId) void appendImports(Storage::Imports &imports,
const QString &dependency,
SourceId sourceId,
QmlTypesParser::ProjectStorage &storage)
{ {
Storage::Import import;
import.kind = Storage::ImportKind::QmlTypesDependency;
import.sourceId = sourceId;
auto spaceFound = std::find_if(dependency.begin(), dependency.end(), [](QChar c) { auto spaceFound = std::find_if(dependency.begin(), dependency.end(), [](QChar c) {
return c.isSpace(); return c.isSpace();
}); });
import.name = Utils::SmallString{QStringView(dependency.begin(), spaceFound)};
Utils::PathString moduleName{QStringView(dependency.begin(), spaceFound)};
ModuleId moduleId = storage.moduleId(moduleName);
moduleName.append("-cppnative");
ModuleId cppModuleId = storage.moduleId(moduleName);
auto majorVersionFound = std::find_if(spaceFound, dependency.end(), [](QChar c) { auto majorVersionFound = std::find_if(spaceFound, dependency.end(), [](QChar c) {
return c.isDigit(); return c.isDigit();
@@ -61,33 +66,39 @@ Storage::Import createImport(const QString &dependency, SourceId sourceId)
auto majorVersionEnd = std::find_if(majorVersionFound, dependency.end(), [](QChar c) { auto majorVersionEnd = std::find_if(majorVersionFound, dependency.end(), [](QChar c) {
return !c.isDigit(); return !c.isDigit();
}); });
Storage::Version version;
QStringView majorVersionString(majorVersionFound, majorVersionEnd); QStringView majorVersionString(majorVersionFound, majorVersionEnd);
if (majorVersionString.isEmpty()) if (!majorVersionString.isEmpty()) {
return import; version.major.value = majorVersionString.toInt();
import.version.major.value = majorVersionString.toInt();
auto minorVersionFound = std::find_if(majorVersionEnd, dependency.end(), [](QChar c) { auto minorVersionFound = std::find_if(majorVersionEnd, dependency.end(), [](QChar c) {
return c.isDigit(); return c.isDigit();
}); });
auto minorVersionEnd = std::find_if(minorVersionFound, dependency.end(), [](QChar c) { auto minorVersionEnd = std::find_if(minorVersionFound, dependency.end(), [](QChar c) {
return !c.isDigit(); return !c.isDigit();
}); });
QStringView minorVersionString(minorVersionFound, minorVersionEnd); QStringView minorVersionString(minorVersionFound, minorVersionEnd);
if (minorVersionString.isEmpty()) if (!minorVersionString.isEmpty())
return import; version.minor.value = QStringView(minorVersionFound, minorVersionEnd).toInt();
import.version.minor.value = QStringView(minorVersionFound, minorVersionEnd).toInt();
return import;
}
void addImports(Storage::Imports &imports, SourceId sourceId, const QStringList &dependencies)
{
for (const QString &dependency : dependencies) {
imports.push_back(createImport(dependency, sourceId));
} }
imports.emplace_back("QML", Storage::Version{}, sourceId, Storage::ImportKind::QmlTypesDependency); imports.emplace_back(moduleId, version, sourceId);
imports.emplace_back("QtQml", Storage::Version{}, sourceId, Storage::ImportKind::QmlTypesDependency); imports.emplace_back(cppModuleId, version, sourceId);
}
void addImports(Storage::Imports &imports,
SourceId sourceId,
const QStringList &dependencies,
QmlTypesParser::ProjectStorage &storage)
{
for (const QString &dependency : dependencies)
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);
} }
Storage::TypeAccessSemantics createTypeAccessSemantics(QQmlJSScope::AccessSemantics accessSematics) Storage::TypeAccessSemantics createTypeAccessSemantics(QQmlJSScope::AccessSemantics accessSematics)
@@ -249,8 +260,7 @@ Storage::EnumerationDeclarations createEnumeration(const QHash<QString, QQmlJSMe
void addType(Storage::Types &types, SourceId sourceId, ModuleId moduleId, const QQmlJSScope &component) void addType(Storage::Types &types, SourceId sourceId, ModuleId moduleId, const QQmlJSScope &component)
{ {
auto [functionsDeclarations, signalDeclarations] = createFunctionAndSignals(component.ownMethods()); auto [functionsDeclarations, signalDeclarations] = createFunctionAndSignals(component.ownMethods());
types.emplace_back(moduleId, types.emplace_back(Utils::SmallString{component.internalName()},
Utils::SmallString{component.internalName()},
Storage::NativeType{Utils::SmallString{component.baseTypeName()}}, Storage::NativeType{Utils::SmallString{component.baseTypeName()}},
createTypeAccessSemantics(component.accessSemantics()), createTypeAccessSemantics(component.accessSemantics()),
sourceId, sourceId,
@@ -287,7 +297,7 @@ void QmlTypesParser::parse(const QString &sourceContent,
if (!isValid) if (!isValid)
throw CannotParseQmlTypesFile{}; throw CannotParseQmlTypesFile{};
addImports(imports, sourceId, dependencies); addImports(imports, sourceId, dependencies, m_storage);
addTypes(types, sourceId, moduleId, components); addTypes(types, sourceId, moduleId, components);
} }

View File

@@ -43,11 +43,12 @@ class SourcePathCache;
class QmlTypesParser : public QmlTypesParserInterface class QmlTypesParser : public QmlTypesParserInterface
{ {
public: public:
using PathCache = QmlDesigner::SourcePathCache<QmlDesigner::ProjectStorage<Sqlite::Database>, using ProjectStorage = QmlDesigner::ProjectStorage<Sqlite::Database>;
NonLockingMutex>; using PathCache = QmlDesigner::SourcePathCache<ProjectStorage, NonLockingMutex>;
QmlTypesParser(PathCache &pathCache) QmlTypesParser(PathCache &pathCache, ProjectStorage &storage)
: m_pathCache{pathCache} : m_pathCache{pathCache}
, m_storage{storage}
{} {}
void parse(const QString &sourceContent, void parse(const QString &sourceContent,
@@ -58,5 +59,6 @@ public:
private: private:
PathCache &m_pathCache; PathCache &m_pathCache;
ProjectStorage &m_storage;
}; };
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -1095,8 +1095,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.moduleId << ", "
<< ", " << exportedType.version << ")"; << exportedType.version << ")";
} }
std::ostream &operator<<(std::ostream &out, const NativeType &nativeType) std::ostream &operator<<(std::ostream &out, const NativeType &nativeType)
@@ -1116,10 +1116,9 @@ std::ostream &operator<<(std::ostream &out, const QualifiedImportedType &importe
std::ostream &operator<<(std::ostream &out, const Type &type) std::ostream &operator<<(std::ostream &out, const Type &type)
{ {
using Utils::operator<<; using Utils::operator<<;
return out << "(moduleId: " << type.moduleId << ", typename: \"" << type.typeName return out << "( typename: \"" << type.typeName << "\", prototype: " << type.prototype << ", "
<< "\", prototype: " << type.prototype << ", " << type.accessSemantics << type.prototypeId << ", " << type.accessSemantics << ", source: " << type.sourceId
<< ", source: " << type.sourceId << ", exports: " << type.exportedTypes << ", exports: " << type.exportedTypes << ", properties: " << type.propertyDeclarations
<< ", properties: " << type.propertyDeclarations
<< ", functions: " << type.functionDeclarations << ", functions: " << type.functionDeclarations
<< ", signals: " << type.signalDeclarations << ")"; << ", signals: " << type.signalDeclarations << ")";
} }
@@ -1127,9 +1126,10 @@ std::ostream &operator<<(std::ostream &out, const Type &type)
std::ostream &operator<<(std::ostream &out, const PropertyDeclaration &propertyDeclaration) std::ostream &operator<<(std::ostream &out, const PropertyDeclaration &propertyDeclaration)
{ {
using Utils::operator<<; using Utils::operator<<;
return out << "(\"" << propertyDeclaration.name << "\", \"" << propertyDeclaration.typeName return out << "(\"" << propertyDeclaration.name << "\", " << propertyDeclaration.typeName
<< "\", " << propertyDeclaration.traits << ", " << propertyDeclaration.typeId << ", " << propertyDeclaration.typeId << ", " << propertyDeclaration.traits << ", "
<< ", \"" << propertyDeclaration.aliasPropertyName << "\")"; << propertyDeclaration.typeId << ", \"" << propertyDeclaration.aliasPropertyName
<< "\")";
} }
std::ostream &operator<<(std::ostream &out, PropertyDeclarationTraits traits) std::ostream &operator<<(std::ostream &out, PropertyDeclarationTraits traits)
@@ -1186,11 +1186,6 @@ std::ostream &operator<<(std::ostream &out, const EnumerationDeclaration &enumer
<< enumerationDeclaration.enumeratorDeclarations << ")"; << enumerationDeclaration.enumeratorDeclarations << ")";
} }
std::ostream &operator<<(std::ostream &out, const Module &module)
{
return out << "(" << module.name << ", " << module.sourceId << ")";
}
std::ostream &operator<<(std::ostream &out, const ImportKind &importKind) std::ostream &operator<<(std::ostream &out, const ImportKind &importKind)
{ {
return out << importKindToText(importKind); return out << importKindToText(importKind);
@@ -1198,8 +1193,7 @@ std::ostream &operator<<(std::ostream &out, const ImportKind &importKind)
std::ostream &operator<<(std::ostream &out, const Import &import) std::ostream &operator<<(std::ostream &out, const Import &import)
{ {
return out << "(" << import.name << ", " << import.version << ", " << import.sourceId << ", " return out << "(" << import.moduleId << ", " << import.version << ", " << import.sourceId << ")";
<< import.moduleId << ", " << import.kind << ")";
} }
} // namespace Storage } // namespace Storage

View File

@@ -260,8 +260,6 @@ class ParameterDeclaration;
class SignalDeclaration; class SignalDeclaration;
class EnumerationDeclaration; class EnumerationDeclaration;
class EnumeratorDeclaration; class EnumeratorDeclaration;
class Module;
class ModuleDependency;
enum class ImportKind : char; enum class ImportKind : char;
class Import; class Import;
enum class IsQualified : int; enum class IsQualified : int;
@@ -281,8 +279,6 @@ std::ostream &operator<<(std::ostream &out, const ParameterDeclaration &paramete
std::ostream &operator<<(std::ostream &out, const SignalDeclaration &signalDeclaration); std::ostream &operator<<(std::ostream &out, const SignalDeclaration &signalDeclaration);
std::ostream &operator<<(std::ostream &out, const EnumerationDeclaration &enumerationDeclaration); std::ostream &operator<<(std::ostream &out, const EnumerationDeclaration &enumerationDeclaration);
std::ostream &operator<<(std::ostream &out, const EnumeratorDeclaration &enumeratorDeclaration); std::ostream &operator<<(std::ostream &out, const EnumeratorDeclaration &enumeratorDeclaration);
std::ostream &operator<<(std::ostream &out, const Module &module);
std::ostream &operator<<(std::ostream &out, const ModuleDependency &module);
std::ostream &operator<<(std::ostream &out, const ImportKind &importKind); std::ostream &operator<<(std::ostream &out, const ImportKind &importKind);
std::ostream &operator<<(std::ostream &out, const Import &import); std::ostream &operator<<(std::ostream &out, const Import &import);
std::ostream &operator<<(std::ostream &out, IsQualified isQualified); std::ostream &operator<<(std::ostream &out, IsQualified isQualified);

File diff suppressed because it is too large Load Diff

View File

@@ -38,13 +38,14 @@ class ProjectStorageMock : public QmlDesigner::ProjectStorageInterface
public: public:
MOCK_METHOD(void, MOCK_METHOD(void,
synchronize, synchronize,
(QmlDesigner::Storage::Modules modules, (QmlDesigner::Storage::Imports imports,
QmlDesigner::Storage::Imports imports,
QmlDesigner::Storage::Types types, QmlDesigner::Storage::Types types,
QmlDesigner::SourceIds sourceIds, QmlDesigner::SourceIds sourceIds,
QmlDesigner::FileStatuses fileStatuses), QmlDesigner::FileStatuses fileStatuses),
(override)); (override));
MOCK_METHOD(QmlDesigner::ModuleId, moduleId, (Utils::SmallStringView), (override));
MOCK_METHOD(QmlDesigner::FileStatus, MOCK_METHOD(QmlDesigner::FileStatus,
fetchFileStatus, fetchFileStatus,
(QmlDesigner::SourceId sourceId), (QmlDesigner::SourceId sourceId),

View File

@@ -42,26 +42,25 @@ namespace {
namespace Storage = QmlDesigner::Storage; namespace Storage = QmlDesigner::Storage;
using QmlDesigner::FileStatus; using QmlDesigner::FileStatus;
using QmlDesigner::ModuleId;
using QmlDesigner::SourceId; using QmlDesigner::SourceId;
using QmlDesigner::Storage::TypeAccessSemantics; using QmlDesigner::Storage::TypeAccessSemantics;
namespace Storage = QmlDesigner::Storage; namespace Storage = QmlDesigner::Storage;
using QmlDesigner::IdPaths; using QmlDesigner::IdPaths;
using QmlDesigner::Storage::Version; using QmlDesigner::Storage::Version;
MATCHER_P5(IsStorageType, MATCHER_P4(IsStorageType,
moduleId,
typeName, typeName,
prototype, prototype,
accessSemantics, accessSemantics,
sourceId, sourceId,
std::string(negation ? "isn't " : "is ") std::string(negation ? "isn't " : "is ")
+ PrintToString(Storage::Type{moduleId, typeName, prototype, accessSemantics, sourceId})) + PrintToString(Storage::Type{typeName, prototype, accessSemantics, sourceId}))
{ {
const Storage::Type &type = arg; const Storage::Type &type = arg;
return type.moduleId == moduleId && type.typeName == typeName return type.typeName == typeName && type.accessSemantics == accessSemantics
&& type.accessSemantics == accessSemantics && type.sourceId == sourceId && type.sourceId == sourceId && Storage::ImportedTypeName{prototype} == type.prototype;
&& Storage::ImportedTypeName{prototype} == type.prototype;
} }
MATCHER_P3(IsPropertyDeclaration, MATCHER_P3(IsPropertyDeclaration,
@@ -78,27 +77,20 @@ MATCHER_P3(IsPropertyDeclaration,
&& propertyDeclaration.traits == traits; && propertyDeclaration.traits == traits;
} }
MATCHER_P3(IsExportedType, MATCHER_P4(IsExportedType,
moduleId,
name, name,
majorVersion, majorVersion,
minorVersion, minorVersion,
std::string(negation ? "isn't " : "is ") std::string(negation ? "isn't " : "is ")
+ PrintToString(Storage::ExportedType{name, + PrintToString(Storage::ExportedType{moduleId,
name,
Storage::Version{majorVersion, minorVersion}})) Storage::Version{majorVersion, minorVersion}}))
{ {
const Storage::ExportedType &type = arg; const Storage::ExportedType &type = arg;
return type.name == name && type.version == Storage::Version{majorVersion, minorVersion}; return type.moduleId == moduleId && 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, MATCHER_P3(IsFileStatus,
@@ -154,6 +146,8 @@ public:
.WillByDefault(Return(FileStatus{qmlDocumentSourceId3, 22, 14})); .WillByDefault(Return(FileStatus{qmlDocumentSourceId3, 22, 14}));
ON_CALL(projectStorageMock, fetchFileStatus(Eq(qmlDocumentSourceId3))) ON_CALL(projectStorageMock, fetchFileStatus(Eq(qmlDocumentSourceId3)))
.WillByDefault(Return(FileStatus{qmlDocumentSourceId3, 22, 2})); .WillByDefault(Return(FileStatus{qmlDocumentSourceId3, 22, 2}));
ON_CALL(projectStorageMock, moduleId(Eq("Example"))).WillByDefault(Return(exampleModuleId));
ON_CALL(projectStorageMock, moduleId(Eq("Qml"))).WillByDefault(Return(qmlModuleId));
firstType.prototype = Storage::ImportedType{"Object"}; firstType.prototype = Storage::ImportedType{"Object"};
secondType.prototype = Storage::ImportedType{"Object2"}; secondType.prototype = Storage::ImportedType{"Object2"};
@@ -203,25 +197,26 @@ 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");
QmlDesigner::ModuleId exampleModuleId{&qmlDirPathSourceId};
SourceId qmlDocumentSourceId1 = sourcePathCache.sourceId("/path/First.qml"); SourceId qmlDocumentSourceId1 = sourcePathCache.sourceId("/path/First.qml");
SourceId qmlDocumentSourceId2 = sourcePathCache.sourceId("/path/First.2.qml"); SourceId qmlDocumentSourceId2 = sourcePathCache.sourceId("/path/First.2.qml");
SourceId qmlDocumentSourceId3 = sourcePathCache.sourceId("/path/Second.qml"); SourceId qmlDocumentSourceId3 = sourcePathCache.sourceId("/path/Second.qml");
Storage::Type objectType{exampleModuleId, ModuleId qmlModuleId{storage.moduleId("Qml")};
"QObject", ModuleId exampleModuleId{storage.moduleId("Example")};
Storage::Type objectType{"QObject",
Storage::NativeType{}, Storage::NativeType{},
Storage::TypeAccessSemantics::Reference, Storage::TypeAccessSemantics::Reference,
objectTypeSourceId, objectTypeSourceId,
{Storage::ExportedType{"Object"}, Storage::ExportedType{"Obj"}}}; {Storage::ExportedType{exampleModuleId, "Object"},
Storage::ExportedType{exampleModuleId, "Obj"}}};
QString qmlDocument1{"First{}"}; QString qmlDocument1{"First{}"};
QString qmlDocument2{"Second{}"}; QString qmlDocument2{"Second{}"};
QString qmlDocument3{"Third{}"}; QString qmlDocument3{"Third{}"};
Storage::Type firstType; Storage::Type firstType;
Storage::Type secondType; Storage::Type secondType;
Storage::Type thirdType; Storage::Type thirdType;
Storage::Import import1{"Qml", Storage::Version{2, 3}, qmlDocumentSourceId1}; Storage::Import import1{qmlModuleId, Storage::Version{2, 3}, qmlDocumentSourceId1};
Storage::Import import2{"Qml", Storage::Version{}, qmlDocumentSourceId2}; Storage::Import import2{qmlModuleId, Storage::Version{}, qmlDocumentSourceId2};
Storage::Import import3{"Qml", Storage::Version{2}, qmlDocumentSourceId3}; Storage::Import import3{qmlModuleId, Storage::Version{2}, qmlDocumentSourceId3};
}; };
TEST_F(ProjectStorageUpdater, GetContentForQmlDirPathsIfFileStatusIsDifferent) TEST_F(ProjectStorageUpdater, GetContentForQmlDirPathsIfFileStatusIsDifferent)
@@ -320,8 +315,7 @@ TEST_F(ProjectStorageUpdater, SynchronizeIsEmptyForNoChange)
ON_CALL(projectStorageMock, fetchFileStatus(Eq(qmlDirPathSourceId))) ON_CALL(projectStorageMock, fetchFileStatus(Eq(qmlDirPathSourceId)))
.WillByDefault(Return(FileStatus{qmlDirPathSourceId, 21, 421})); .WillByDefault(Return(FileStatus{qmlDirPathSourceId, 21, 421}));
EXPECT_CALL(projectStorageMock, EXPECT_CALL(projectStorageMock, synchronize(IsEmpty(), IsEmpty(), IsEmpty(), IsEmpty()));
synchronize(IsEmpty(), IsEmpty(), IsEmpty(), IsEmpty(), IsEmpty()));
updater.update(); updater.update();
} }
@@ -330,7 +324,7 @@ 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}; Storage::Import import{qmlModuleId, 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));
@@ -340,9 +334,9 @@ TEST_F(ProjectStorageUpdater, SynchronizeQmlTypes)
imports.push_back(import); imports.push_back(import);
}); });
EXPECT_CALL(projectStorageMock, moduleId(Eq("Example")));
EXPECT_CALL(projectStorageMock, EXPECT_CALL(projectStorageMock,
synchronize(ElementsAre(IsModule("Example", qmlDirPathSourceId)), synchronize(ElementsAre(import),
ElementsAre(import),
ElementsAre(Eq(objectType)), ElementsAre(Eq(objectType)),
UnorderedElementsAre(qmlDirPathSourceId, qmltypesPathSourceId), UnorderedElementsAre(qmlDirPathSourceId, qmltypesPathSourceId),
UnorderedElementsAre(IsFileStatus(qmlDirPathSourceId, 21, 421), UnorderedElementsAre(IsFileStatus(qmlDirPathSourceId, 21, 421),
@@ -366,8 +360,7 @@ TEST_F(ProjectStorageUpdater, SynchronizeQmlTypesAreEmptyIfFileDoesNotChanged)
ON_CALL(fileSystemMock, fileStatus(Eq(qmlDirPathSourceId))) ON_CALL(fileSystemMock, fileStatus(Eq(qmlDirPathSourceId)))
.WillByDefault(Return(FileStatus{qmlDirPathSourceId, 2, 421})); .WillByDefault(Return(FileStatus{qmlDirPathSourceId, 2, 421}));
EXPECT_CALL(projectStorageMock, EXPECT_CALL(projectStorageMock, synchronize(IsEmpty(), IsEmpty(), IsEmpty(), IsEmpty()));
synchronize(IsEmpty(), IsEmpty(), IsEmpty(), IsEmpty(), IsEmpty()));
updater.update(); updater.update();
} }
@@ -414,39 +407,36 @@ TEST_F(ProjectStorageUpdater, SynchronizeQmlDocuments)
"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"};
ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/qmldir")))).WillByDefault(Return(qmldir)); ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/qmldir")))).WillByDefault(Return(qmldir));
EXPECT_CALL(projectStorageMock, EXPECT_CALL(
synchronize(ElementsAre(IsModule("Example", qmlDirPathSourceId)), projectStorageMock,
UnorderedElementsAre(import1, import2, import3), synchronize(UnorderedElementsAre(import1, import2, import3),
UnorderedElementsAre( UnorderedElementsAre(
AllOf(IsStorageType(exampleModuleId, AllOf(IsStorageType("First.qml",
"First.qml", Storage::ImportedType{"Object"},
Storage::ImportedType{"Object"}, TypeAccessSemantics::Reference,
TypeAccessSemantics::Reference, qmlDocumentSourceId1),
qmlDocumentSourceId1), Field(&Storage::Type::exportedTypes,
Field(&Storage::Type::exportedTypes, ElementsAre(IsExportedType(exampleModuleId, "FirstType", 1, 0)))),
ElementsAre(IsExportedType("FirstType", 1, 0)))), AllOf(IsStorageType("First.2.qml",
AllOf(IsStorageType(exampleModuleId, Storage::ImportedType{"Object2"},
"First.2.qml", TypeAccessSemantics::Reference,
Storage::ImportedType{"Object2"}, qmlDocumentSourceId2),
TypeAccessSemantics::Reference, Field(&Storage::Type::exportedTypes,
qmlDocumentSourceId2), ElementsAre(IsExportedType(exampleModuleId, "FirstType", 2, 2)))),
Field(&Storage::Type::exportedTypes, AllOf(IsStorageType("Second.qml",
ElementsAre(IsExportedType("FirstType", 2, 2)))), Storage::ImportedType{"Object3"},
AllOf(IsStorageType(exampleModuleId, TypeAccessSemantics::Reference,
"Second.qml", qmlDocumentSourceId3),
Storage::ImportedType{"Object3"}, Field(&Storage::Type::exportedTypes,
TypeAccessSemantics::Reference, ElementsAre(IsExportedType(exampleModuleId, "SecondType", 2, 2))))),
qmlDocumentSourceId3), UnorderedElementsAre(qmlDirPathSourceId,
Field(&Storage::Type::exportedTypes, qmlDocumentSourceId1,
ElementsAre(IsExportedType("SecondType", 2, 2))))), qmlDocumentSourceId2,
UnorderedElementsAre(qmlDirPathSourceId, qmlDocumentSourceId3),
qmlDocumentSourceId1, UnorderedElementsAre(IsFileStatus(qmlDirPathSourceId, 21, 421),
qmlDocumentSourceId2, IsFileStatus(qmlDocumentSourceId1, 22, 12),
qmlDocumentSourceId3), IsFileStatus(qmlDocumentSourceId2, 22, 13),
UnorderedElementsAre(IsFileStatus(qmlDirPathSourceId, 21, 421), IsFileStatus(qmlDocumentSourceId3, 22, 14))));
IsFileStatus(qmlDocumentSourceId1, 22, 12),
IsFileStatus(qmlDocumentSourceId2, 22, 13),
IsFileStatus(qmlDocumentSourceId3, 22, 14))));
updater.update(); updater.update();
} }
@@ -461,22 +451,20 @@ TEST_F(ProjectStorageUpdater, SynchronizeQmlDocumentsDontUpdateIfUpToDate)
EXPECT_CALL( EXPECT_CALL(
projectStorageMock, projectStorageMock,
synchronize(ElementsAre(IsModule("Example", qmlDirPathSourceId)), synchronize(UnorderedElementsAre(import1, import2),
UnorderedElementsAre(import1, import2), UnorderedElementsAre(
UnorderedElementsAre(AllOf(IsStorageType(exampleModuleId, AllOf(IsStorageType("First.qml",
"First.qml", Storage::ImportedType{"Object"},
Storage::ImportedType{"Object"}, TypeAccessSemantics::Reference,
TypeAccessSemantics::Reference, qmlDocumentSourceId1),
qmlDocumentSourceId1), Field(&Storage::Type::exportedTypes,
Field(&Storage::Type::exportedTypes, ElementsAre(IsExportedType(exampleModuleId, "FirstType", 1, 0)))),
ElementsAre(IsExportedType("FirstType", 1, 0)))), AllOf(IsStorageType("First.2.qml",
AllOf(IsStorageType(exampleModuleId, Storage::ImportedType{"Object2"},
"First.2.qml", TypeAccessSemantics::Reference,
Storage::ImportedType{"Object2"}, qmlDocumentSourceId2),
TypeAccessSemantics::Reference, Field(&Storage::Type::exportedTypes,
qmlDocumentSourceId2), ElementsAre(IsExportedType(exampleModuleId, "FirstType", 2, 2))))),
Field(&Storage::Type::exportedTypes,
ElementsAre(IsExportedType("FirstType", 2, 2))))),
UnorderedElementsAre(qmlDirPathSourceId, qmlDocumentSourceId1, qmlDocumentSourceId2), UnorderedElementsAre(qmlDirPathSourceId, qmlDocumentSourceId1, qmlDocumentSourceId2),
UnorderedElementsAre(IsFileStatus(qmlDirPathSourceId, 21, 421), UnorderedElementsAre(IsFileStatus(qmlDirPathSourceId, 21, 421),
IsFileStatus(qmlDocumentSourceId1, 22, 12), IsFileStatus(qmlDocumentSourceId1, 22, 12),
@@ -485,31 +473,6 @@ TEST_F(ProjectStorageUpdater, SynchronizeQmlDocumentsDontUpdateIfUpToDate)
updater.update(); 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();
}
TEST_F(ProjectStorageUpdater, UpdateQmldirDocuments) TEST_F(ProjectStorageUpdater, UpdateQmldirDocuments)
{ {
QString qmldir{"module Example\nFirstType 1.1 First.qml\nFirstType 2.2 " QString qmldir{"module Example\nFirstType 1.1 First.qml\nFirstType 2.2 "

View File

@@ -129,7 +129,7 @@ protected:
QmlDesigner::ProjectStorage<Sqlite::Database> storage{database, database.isInitialized()}; QmlDesigner::ProjectStorage<Sqlite::Database> storage{database, database.isInitialized()};
QmlDesigner::SourcePathCache<QmlDesigner::ProjectStorage<Sqlite::Database>> sourcePathCache{ QmlDesigner::SourcePathCache<QmlDesigner::ProjectStorage<Sqlite::Database>> sourcePathCache{
storage}; storage};
QmlDesigner::QmlDocumentParser parser{sourcePathCache}; QmlDesigner::QmlDocumentParser parser{sourcePathCache, storage};
Storage::Imports imports; Storage::Imports imports;
SourceId qmlFileSourceId{sourcePathCache.sourceId("path/to/qmlfile.qml")}; SourceId qmlFileSourceId{sourcePathCache.sourceId("path/to/qmlfile.qml")};
SourceContextId qmlFileSourceContextId{sourcePathCache.sourceContextId(qmlFileSourceId)}; SourceContextId qmlFileSourceContextId{sourcePathCache.sourceContextId(qmlFileSourceId)};
@@ -146,6 +146,7 @@ TEST_F(QmlDocumentParser, Prototype)
TEST_F(QmlDocumentParser, DISABLED_QualifiedPrototype) TEST_F(QmlDocumentParser, DISABLED_QualifiedPrototype)
{ {
auto exampleModuleId = storage.moduleId("Example");
auto type = parser.parse("import Example as Example\n Example.Item{}", auto type = parser.parse("import Example as Example\n Example.Item{}",
imports, imports,
qmlFileSourceId, qmlFileSourceId,
@@ -153,7 +154,7 @@ TEST_F(QmlDocumentParser, DISABLED_QualifiedPrototype)
ASSERT_THAT(type, ASSERT_THAT(type,
HasPrototype(Storage::QualifiedImportedType( HasPrototype(Storage::QualifiedImportedType(
"Item", Storage::Import{"Example", Storage::Version{}, qmlFileSourceId}))); "Item", Storage::Import{exampleModuleId, Storage::Version{}, qmlFileSourceId})));
} }
TEST_F(QmlDocumentParser, Properties) TEST_F(QmlDocumentParser, Properties)
@@ -171,7 +172,10 @@ TEST_F(QmlDocumentParser, Properties)
TEST_F(QmlDocumentParser, DISABLED_Imports) TEST_F(QmlDocumentParser, DISABLED_Imports)
{ {
ModuleId fooDirectoryModuleId{&sourcePathCache.sourceId("path/to/foo/.")}; ModuleId fooDirectoryModuleId = storage.moduleId("path/to/foo/.");
ModuleId qmlModuleId = storage.moduleId("QML");
ModuleId qtQmlModuleId = storage.moduleId("QtQml");
ModuleId qtQuickModuleId = storage.moduleId("QtQuick");
auto type = parser.parse("import QtQuick\n import \"../foo\"\nExample{}", auto type = parser.parse("import QtQuick\n import \"../foo\"\nExample{}",
imports, imports,
qmlFileSourceId, qmlFileSourceId,
@@ -179,11 +183,11 @@ TEST_F(QmlDocumentParser, DISABLED_Imports)
ASSERT_THAT(imports, ASSERT_THAT(imports,
UnorderedElementsAre( UnorderedElementsAre(
Storage::Import{Storage::Version{}, directoryModuleId, qmlFileSourceId}, Storage::Import{directoryModuleId, Storage::Version{}, qmlFileSourceId},
Storage::Import{Storage::Version{}, fooDirectoryModuleId, qmlFileSourceId}, Storage::Import{fooDirectoryModuleId, Storage::Version{}, qmlFileSourceId},
Storage::Import{"QML", Storage::Version{1, 0}, qmlFileSourceId}, Storage::Import{qmlModuleId, Storage::Version{1, 0}, qmlFileSourceId},
Storage::Import{"QtQml", Storage::Version{6, 0}, qmlFileSourceId}, Storage::Import{qtQmlModuleId, Storage::Version{6, 0}, qmlFileSourceId},
Storage::Import{"QtQuick", Storage::Version{}, qmlFileSourceId})); Storage::Import{qtQuickModuleId, Storage::Version{}, qmlFileSourceId}));
} }
TEST_F(QmlDocumentParser, Functions) TEST_F(QmlDocumentParser, Functions)

View File

@@ -39,18 +39,16 @@ using QmlDesigner::ModuleId;
using QmlDesigner::SourceContextId; using QmlDesigner::SourceContextId;
using QmlDesigner::SourceId; using QmlDesigner::SourceId;
MATCHER_P4(IsImport, MATCHER_P3(IsImport,
name, moduleId,
version, version,
sourceId, sourceId,
kind,
std::string(negation ? "isn't " : "is ") std::string(negation ? "isn't " : "is ")
+ PrintToString(Storage::Import{name, version, sourceId, kind})) + PrintToString(Storage::Import{moduleId, version, sourceId}))
{ {
const Storage::Import &import = arg; const Storage::Import &import = arg;
return import.name == name && import.version == version && import.sourceId == sourceId return import.moduleId == moduleId && import.version == version && import.sourceId == sourceId;
&& import.kind == kind;
} }
MATCHER_P(HasPrototype, prototype, std::string(negation ? "isn't " : "is ") + PrintToString(prototype)) MATCHER_P(HasPrototype, prototype, std::string(negation ? "isn't " : "is ") + PrintToString(prototype))
@@ -60,19 +58,17 @@ MATCHER_P(HasPrototype, prototype, std::string(negation ? "isn't " : "is ") + Pr
return Storage::ImportedTypeName{prototype} == type.prototype; return Storage::ImportedTypeName{prototype} == type.prototype;
} }
MATCHER_P5(IsType, MATCHER_P4(IsType,
moduleId,
typeName, typeName,
prototype, prototype,
accessSemantics, accessSemantics,
sourceId, sourceId,
std::string(negation ? "isn't " : "is ") std::string(negation ? "isn't " : "is ")
+ PrintToString(Storage::Type{moduleId, typeName, prototype, accessSemantics, sourceId})) + PrintToString(Storage::Type{typeName, prototype, accessSemantics, sourceId}))
{ {
const Storage::Type &type = arg; const Storage::Type &type = arg;
return type.moduleId == moduleId && type.typeName == typeName return type.typeName == typeName && type.prototype == Storage::ImportedTypeName{prototype}
&& type.prototype == Storage::ImportedTypeName{prototype}
&& type.accessSemantics == accessSemantics && type.sourceId == sourceId; && type.accessSemantics == accessSemantics && type.sourceId == sourceId;
} }
@@ -173,13 +169,12 @@ protected:
QmlDesigner::ProjectStorage<Sqlite::Database> storage{database, database.isInitialized()}; QmlDesigner::ProjectStorage<Sqlite::Database> storage{database, database.isInitialized()};
QmlDesigner::SourcePathCache<QmlDesigner::ProjectStorage<Sqlite::Database>> sourcePathCache{ QmlDesigner::SourcePathCache<QmlDesigner::ProjectStorage<Sqlite::Database>> sourcePathCache{
storage}; storage};
QmlDesigner::QmlTypesParser parser{sourcePathCache}; QmlDesigner::QmlTypesParser parser{sourcePathCache, storage};
Storage::Imports imports; Storage::Imports imports;
Storage::Types types; Storage::Types types;
SourceId qmltypesFileSourceId{sourcePathCache.sourceId("path/to/types.qmltypes")}; SourceId qmltypesFileSourceId{sourcePathCache.sourceId("path/to/types.qmltypes")};
SourceContextId qmltypesFileSourceContextId{sourcePathCache.sourceContextId(qmltypesFileSourceId)}; SourceContextId qmltypesFileSourceContextId{sourcePathCache.sourceContextId(qmltypesFileSourceId)};
SourceId directorySourceId{sourcePathCache.sourceId("path/to/.")}; ModuleId directoryModuleId{storage.moduleId("path/to/")};
ModuleId directoryModuleId{&directorySourceId};
}; };
TEST_F(QmlTypesParser, Imports) TEST_F(QmlTypesParser, Imports)
@@ -191,27 +186,20 @@ TEST_F(QmlTypesParser, Imports)
parser.parse(source, imports, types, qmltypesFileSourceId, directoryModuleId); parser.parse(source, imports, types, qmltypesFileSourceId, directoryModuleId);
ASSERT_THAT(imports, ASSERT_THAT(
UnorderedElementsAre(IsImport("QtQuick", imports,
Storage::Version{2, 15}, UnorderedElementsAre(
qmltypesFileSourceId, IsImport(storage.moduleId("QML"), Storage::Version{}, qmltypesFileSourceId),
Storage::ImportKind::QmlTypesDependency), IsImport(storage.moduleId("QtQml"), Storage::Version{}, qmltypesFileSourceId),
IsImport("QtQuick.Window", IsImport(storage.moduleId("QtQml-cppnative"), Storage::Version{}, qmltypesFileSourceId),
Storage::Version{2, 1}, IsImport(storage.moduleId("QtQuick"), Storage::Version{2, 15}, qmltypesFileSourceId),
qmltypesFileSourceId, IsImport(storage.moduleId("QtQuick-cppnative"), Storage::Version{2, 15}, qmltypesFileSourceId),
Storage::ImportKind::QmlTypesDependency), IsImport(storage.moduleId("QtQuick.Window"), Storage::Version{2, 1}, qmltypesFileSourceId),
IsImport("QML", IsImport(storage.moduleId("QtQuick.Window-cppnative"),
Storage::Version{}, Storage::Version{2, 1},
qmltypesFileSourceId, qmltypesFileSourceId),
Storage::ImportKind::QmlTypesDependency), IsImport(storage.moduleId("QtFoo"), Storage::Version{6}, qmltypesFileSourceId),
IsImport("QtQml", IsImport(storage.moduleId("QtFoo-cppnative"), Storage::Version{6}, qmltypesFileSourceId)));
Storage::Version{},
qmltypesFileSourceId,
Storage::ImportKind::QmlTypesDependency),
IsImport("QtFoo",
Storage::Version{6},
qmltypesFileSourceId,
Storage::ImportKind::QmlTypesDependency)));
} }
TEST_F(QmlTypesParser, Types) TEST_F(QmlTypesParser, Types)
@@ -225,13 +213,11 @@ TEST_F(QmlTypesParser, Types)
parser.parse(source, imports, types, qmltypesFileSourceId, directoryModuleId); parser.parse(source, imports, types, qmltypesFileSourceId, directoryModuleId);
ASSERT_THAT(types, ASSERT_THAT(types,
UnorderedElementsAre(IsType(directoryModuleId, UnorderedElementsAre(IsType("QObject",
"QObject",
Storage::NativeType{}, Storage::NativeType{},
Storage::TypeAccessSemantics::Reference, Storage::TypeAccessSemantics::Reference,
qmltypesFileSourceId), qmltypesFileSourceId),
IsType(directoryModuleId, IsType("QQmlComponent",
"QQmlComponent",
Storage::NativeType{"QObject"}, Storage::NativeType{"QObject"},
Storage::TypeAccessSemantics::Reference, Storage::TypeAccessSemantics::Reference,
qmltypesFileSourceId))); qmltypesFileSourceId)));