forked from qt-creator/qt-creator
QmlDesigner: Add minimal updates
Exported type names are synchronized so that old type names are removed. Task-number: QDS-5130 Task-number: QDS-5126 Change-Id: I6e6482170c8197f37f60a57bdfb7f1b450001b4b Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -86,7 +86,8 @@ enum class BasicIdType {
|
|||||||
Module,
|
Module,
|
||||||
ProjectPartId,
|
ProjectPartId,
|
||||||
Import,
|
Import,
|
||||||
ImportedTypeName
|
ImportedTypeName,
|
||||||
|
ExportedTypeName
|
||||||
};
|
};
|
||||||
|
|
||||||
using TypeId = BasicId<BasicIdType::Type>;
|
using TypeId = BasicId<BasicIdType::Type>;
|
||||||
@@ -122,4 +123,7 @@ using ImportIds = std::vector<ImportId>;
|
|||||||
using ImportedTypeNameId = BasicId<BasicIdType::ImportedTypeName>;
|
using ImportedTypeNameId = BasicId<BasicIdType::ImportedTypeName>;
|
||||||
using ImportedTypeNameIds = std::vector<ImportedTypeNameId>;
|
using ImportedTypeNameIds = std::vector<ImportedTypeNameId>;
|
||||||
|
|
||||||
|
using ExportedTypeNameId = BasicId<BasicIdType::ExportedTypeName>;
|
||||||
|
using ExportedTypeNameIds = std::vector<ExportedTypeNameId>;
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -369,14 +369,20 @@ private:
|
|||||||
std::vector<AliasPropertyDeclaration> &insertedAliasPropertyDeclarations,
|
std::vector<AliasPropertyDeclaration> &insertedAliasPropertyDeclarations,
|
||||||
std::vector<AliasPropertyDeclaration> &updatedAliasPropertyDeclarations)
|
std::vector<AliasPropertyDeclaration> &updatedAliasPropertyDeclarations)
|
||||||
{
|
{
|
||||||
|
Storage::ExportedTypes exportedTypes;
|
||||||
|
exportedTypes.reserve(types.size() * 3);
|
||||||
|
|
||||||
for (auto &&type : types) {
|
for (auto &&type : types) {
|
||||||
if (!type.sourceId)
|
if (!type.sourceId)
|
||||||
throw TypeHasInvalidSourceId{};
|
throw TypeHasInvalidSourceId{};
|
||||||
|
|
||||||
updatedTypeIds.push_back(declareType(type));
|
TypeId typeId = declareType(type);
|
||||||
|
updatedTypeIds.push_back(typeId);
|
||||||
|
extractExportedTypes(typeId, type, exportedTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
synchronizeExportedTypes(updatedTypeIds, exportedTypes);
|
||||||
|
|
||||||
for (auto &&type : types)
|
for (auto &&type : types)
|
||||||
syncPrototypes(type);
|
syncPrototypes(type);
|
||||||
|
|
||||||
@@ -745,37 +751,78 @@ private:
|
|||||||
updateAliasPropertyDeclarationValues(updatedAliasPropertyDeclarations);
|
updateAliasPropertyDeclarationValues(updatedAliasPropertyDeclarations);
|
||||||
}
|
}
|
||||||
|
|
||||||
void upsertExportedType(ModuleId moduleId,
|
void synchronizeExportedTypes(const TypeIds &typeIds, Storage::ExportedTypes &exportedTypes)
|
||||||
Utils::SmallStringView name,
|
|
||||||
TypeId typeId,
|
|
||||||
Storage::Version version)
|
|
||||||
{
|
{
|
||||||
if (version) {
|
std::sort(exportedTypes.begin(), exportedTypes.end(), [](auto &&first, auto &&second) {
|
||||||
upsertTypeNamesWithVersionStatement.write(&moduleId,
|
return std::tie(first.moduleId, first.name, first.version)
|
||||||
name,
|
< std::tie(second.moduleId, second.name, second.version);
|
||||||
static_cast<long long>(
|
});
|
||||||
Storage::TypeNameKind::Exported),
|
|
||||||
version.major.value,
|
|
||||||
version.minor.value,
|
|
||||||
&typeId);
|
|
||||||
|
|
||||||
} else if (version.major) {
|
auto range = selectExportedTypesForTypeIdStatement.template range<Storage::ExportedTypeView>(
|
||||||
upsertTypeNamesWithMajorVersionStatement.write(&moduleId,
|
const_cast<void *>(static_cast<const void *>(typeIds.data())),
|
||||||
name,
|
static_cast<long long>(typeIds.size()));
|
||||||
static_cast<long long>(
|
|
||||||
Storage::TypeNameKind::Exported),
|
auto compareKey = [](const Storage::ExportedTypeView &view,
|
||||||
version.major.value,
|
const Storage::ExportedType &type) -> long long {
|
||||||
&typeId);
|
auto moduleIdDifference = view.moduleId.id - type.moduleId.id;
|
||||||
} else {
|
if (moduleIdDifference != 0)
|
||||||
upsertTypeNamesWithoutVersionStatement.write(
|
return moduleIdDifference;
|
||||||
&moduleId, name, static_cast<long long>(Storage::TypeNameKind::Exported), &typeId);
|
|
||||||
}
|
auto nameDifference = Sqlite::compare(view.name, type.name);
|
||||||
|
if (nameDifference != 0)
|
||||||
|
return nameDifference;
|
||||||
|
|
||||||
|
auto versionDifference = view.version.major.value - type.version.major.value;
|
||||||
|
if (versionDifference != 0)
|
||||||
|
return versionDifference;
|
||||||
|
|
||||||
|
return view.version.minor.value - type.version.minor.value;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto insert = [&](const Storage::ExportedType &type) {
|
||||||
|
if (type.version) {
|
||||||
|
upsertExportedTypeNamesWithVersionStatement.write(&type.moduleId,
|
||||||
|
type.name,
|
||||||
|
static_cast<long long>(
|
||||||
|
Storage::TypeNameKind::Exported),
|
||||||
|
type.version.major.value,
|
||||||
|
type.version.minor.value,
|
||||||
|
&type.typeId);
|
||||||
|
|
||||||
|
} else if (type.version.major) {
|
||||||
|
upsertExportedTypeNamesWithMajorVersionStatement
|
||||||
|
.write(&type.moduleId,
|
||||||
|
type.name,
|
||||||
|
static_cast<long long>(Storage::TypeNameKind::Exported),
|
||||||
|
type.version.major.value,
|
||||||
|
&type.typeId);
|
||||||
|
} else {
|
||||||
|
upsertExportedTypeNamesWithoutVersionStatement
|
||||||
|
.write(&type.moduleId,
|
||||||
|
type.name,
|
||||||
|
static_cast<long long>(Storage::TypeNameKind::Exported),
|
||||||
|
&type.typeId);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto update = [&](const Storage::ExportedTypeView &view, const Storage::ExportedType &type) {
|
||||||
|
if (view.typeId != type.typeId)
|
||||||
|
updateExportedTypeNameTypeIdStatement.write(&view.exportedTypeNameId, &type.typeId);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto remove = [&](const Storage::ExportedTypeView &view) {
|
||||||
|
deleteExportedTypeNameStatement.write(&view.exportedTypeNameId);
|
||||||
|
};
|
||||||
|
|
||||||
|
Sqlite::insertUpdateDelete(range, exportedTypes, compareKey, insert, update, remove);
|
||||||
}
|
}
|
||||||
|
|
||||||
void upsertNativeType(ModuleId moduleId, Utils::SmallStringView name, TypeId typeId)
|
void upsertNativeType(ModuleId moduleId, Utils::SmallStringView name, TypeId typeId)
|
||||||
{
|
{
|
||||||
upsertTypeNamesWithoutVersionStatement
|
upsertExportedTypeNameStatement.write(&moduleId,
|
||||||
.write(&moduleId, name, static_cast<long long>(Storage::TypeNameKind::Native), &typeId);
|
name,
|
||||||
|
static_cast<long long>(Storage::TypeNameKind::Native),
|
||||||
|
&typeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void synchronizePropertyDeclarationsInsertAlias(
|
void synchronizePropertyDeclarationsInsertAlias(
|
||||||
@@ -1205,30 +1252,50 @@ private:
|
|||||||
Sqlite::insertUpdateDelete(range, enumerationDeclarations, compareKey, insert, update, remove);
|
Sqlite::insertUpdateDelete(range, enumerationDeclarations, compareKey, insert, update, remove);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void extractExportedTypes(TypeId typeId,
|
||||||
|
const Storage::Type &type,
|
||||||
|
Storage::ExportedTypes &exportedTypes)
|
||||||
|
{
|
||||||
|
for (const auto &exportedType : type.exportedTypes)
|
||||||
|
exportedTypes.emplace_back(exportedType.name, exportedType.version, typeId, type.moduleId);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ModuleAndTypeId
|
||||||
|
{
|
||||||
|
ModuleAndTypeId() = default;
|
||||||
|
ModuleAndTypeId(int moduleId, long long typeId)
|
||||||
|
: moduleId{moduleId}
|
||||||
|
, typeId{typeId}
|
||||||
|
{}
|
||||||
|
|
||||||
|
ModuleId moduleId;
|
||||||
|
TypeId typeId;
|
||||||
|
};
|
||||||
|
|
||||||
TypeId declareType(Storage::Type &type)
|
TypeId declareType(Storage::Type &type)
|
||||||
{
|
{
|
||||||
if (type.module.name.isEmpty() && type.typeName.isEmpty()) {
|
if (type.module.name.isEmpty() && type.typeName.isEmpty()) {
|
||||||
type.typeId = selectTypeIdBySourceIdStatement.template value<TypeId>(&type.sourceId);
|
auto [moduleId, typeId] = selectModuleAndTypeIdBySourceIdStatement
|
||||||
|
.template value<ModuleAndTypeId>(&type.sourceId);
|
||||||
|
type.typeId = typeId;
|
||||||
|
type.moduleId = moduleId;
|
||||||
return type.typeId;
|
return type.typeId;
|
||||||
}
|
}
|
||||||
|
|
||||||
ModuleId moduleId = fetchModuleIdUnguarded(type.module);
|
type.moduleId = fetchModuleIdUnguarded(type.module);
|
||||||
|
|
||||||
if (!moduleId)
|
if (!type.moduleId)
|
||||||
throw ModuleDoesNotExists{};
|
throw ModuleDoesNotExists{};
|
||||||
|
|
||||||
type.typeId = upsertTypeStatement.template value<TypeId>(&moduleId,
|
type.typeId = upsertTypeStatement.template value<TypeId>(&type.moduleId,
|
||||||
type.typeName,
|
type.typeName,
|
||||||
static_cast<int>(type.accessSemantics),
|
static_cast<int>(type.accessSemantics),
|
||||||
&type.sourceId);
|
&type.sourceId);
|
||||||
|
|
||||||
if (!type.typeId)
|
if (!type.typeId)
|
||||||
type.typeId = selectTypeIdByModuleIdAndNameStatement.template value<TypeId>(&moduleId,
|
type.typeId = selectTypeIdByModuleIdAndNameStatement.template value<TypeId>(&type.moduleId,
|
||||||
type.typeName);
|
type.typeName);
|
||||||
upsertNativeType(moduleId, type.typeName, type.typeId);
|
upsertNativeType(type.moduleId, type.typeName, type.typeId);
|
||||||
|
|
||||||
for (const auto &exportedType : type.exportedTypes)
|
|
||||||
upsertExportedType(moduleId, exportedType.name, type.typeId, exportedType.version);
|
|
||||||
|
|
||||||
return type.typeId;
|
return type.typeId;
|
||||||
}
|
}
|
||||||
@@ -1275,6 +1342,9 @@ private:
|
|||||||
|
|
||||||
void syncPrototypes(Storage::Type &type)
|
void syncPrototypes(Storage::Type &type)
|
||||||
{
|
{
|
||||||
|
if (type.changeLevel == Storage::ChangeLevel::Minimal)
|
||||||
|
return;
|
||||||
|
|
||||||
if (Utils::visit([](auto &&typeName) -> bool { return typeName.name.isEmpty(); },
|
if (Utils::visit([](auto &&typeName) -> bool { return typeName.name.isEmpty(); },
|
||||||
type.prototype)) {
|
type.prototype)) {
|
||||||
updatePrototypeStatement.write(&type.typeId, Sqlite::NullValue{}, Sqlite::NullValue{});
|
updatePrototypeStatement.write(&type.typeId, Sqlite::NullValue{}, Sqlite::NullValue{});
|
||||||
@@ -1642,7 +1712,7 @@ private:
|
|||||||
Sqlite::Enforment::Deferred);
|
Sqlite::Enforment::Deferred);
|
||||||
auto &nameColumn = table.addColumn("name");
|
auto &nameColumn = table.addColumn("name");
|
||||||
auto &kindColumn = table.addColumn("kind");
|
auto &kindColumn = table.addColumn("kind");
|
||||||
table.addColumn("typeId");
|
auto &typeIdColumn = table.addColumn("typeId");
|
||||||
auto &majorVersionColumn = table.addColumn("majorVersion");
|
auto &majorVersionColumn = table.addColumn("majorVersion");
|
||||||
auto &minorVersionColumn = table.addColumn("minorVersion");
|
auto &minorVersionColumn = table.addColumn("minorVersion");
|
||||||
|
|
||||||
@@ -1654,6 +1724,8 @@ private:
|
|||||||
{moduleIdColumn, nameColumn, kindColumn, majorVersionColumn, minorVersionColumn},
|
{moduleIdColumn, nameColumn, kindColumn, majorVersionColumn, minorVersionColumn},
|
||||||
"majorVersion IS NOT NULL AND minorVersion IS NOT NULL");
|
"majorVersion IS NOT NULL AND minorVersion IS NOT NULL");
|
||||||
|
|
||||||
|
table.addIndex({typeIdColumn}, "kind=1");
|
||||||
|
|
||||||
table.initialize(database);
|
table.initialize(database);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1828,23 +1900,6 @@ public:
|
|||||||
" FROM propertyDeclarations JOIN typeSelection USING(typeId) "
|
" FROM propertyDeclarations JOIN typeSelection USING(typeId) "
|
||||||
" WHERE name=?2 ORDER BY level LIMIT 1",
|
" WHERE name=?2 ORDER BY level LIMIT 1",
|
||||||
database};
|
database};
|
||||||
WriteStatement upsertTypeNamesWithVersionStatement{
|
|
||||||
"INSERT INTO exportedTypeNames(moduleId, name, kind, majorVersion, minorVersion, typeId) "
|
|
||||||
"VALUES(?1, ?2, ?3, ?4, ?5, ?6) ON CONFLICT DO UPDATE SET typeId=excluded.typeId, "
|
|
||||||
"majorVersion=excluded.majorVersion, minorVersion=excluded.minorVersion WHERE typeId IS "
|
|
||||||
"NOT excluded.typeId OR majorVersion IS NOT excluded.majorVersion OR minorVersion IS NOT "
|
|
||||||
"excluded.minorVersion",
|
|
||||||
database};
|
|
||||||
WriteStatement upsertTypeNamesWithMajorVersionStatement{
|
|
||||||
"INSERT INTO exportedTypeNames(moduleId, name, kind, majorVersion, typeId) "
|
|
||||||
"VALUES(?1, ?2, ?3, ?4, ?5) ON CONFLICT DO UPDATE SET typeId=excluded.typeId, "
|
|
||||||
"majorVersion=excluded.majorVersion WHERE typeId IS NOT excluded.typeId OR majorVersion IS "
|
|
||||||
"NOT excluded.majorVersion",
|
|
||||||
database};
|
|
||||||
WriteStatement upsertTypeNamesWithoutVersionStatement{
|
|
||||||
"INSERT INTO exportedTypeNames(moduleId, name, kind, typeId) VALUES(?1, ?2, ?3, ?4) ON "
|
|
||||||
"CONFLICT DO UPDATE SET typeId=excluded.typeId WHERE typeId IS NOT excluded.typeId",
|
|
||||||
database};
|
|
||||||
mutable ReadStatement<1> selectPrototypeIdsStatement{
|
mutable ReadStatement<1> selectPrototypeIdsStatement{
|
||||||
"WITH RECURSIVE "
|
"WITH RECURSIVE "
|
||||||
" typeSelection(typeId, level) AS ("
|
" typeSelection(typeId, level) AS ("
|
||||||
@@ -2188,8 +2243,8 @@ public:
|
|||||||
WriteStatement deleteFileStatusStatement{"DELETE FROM fileStatuses WHERE sourceId=?1", database};
|
WriteStatement deleteFileStatusStatement{"DELETE FROM fileStatuses WHERE sourceId=?1", database};
|
||||||
WriteStatement updateFileStatusStatement{
|
WriteStatement updateFileStatusStatement{
|
||||||
"UPDATE fileStatuses SET size=?2, lastModified=?3 WHERE sourceId=?1", database};
|
"UPDATE fileStatuses SET size=?2, lastModified=?3 WHERE sourceId=?1", database};
|
||||||
ReadStatement<1> selectTypeIdBySourceIdStatement{"SELECT typeId FROM types WHERE sourceId=?",
|
ReadStatement<2> selectModuleAndTypeIdBySourceIdStatement{
|
||||||
database};
|
"SELECT moduleId, typeId FROM types WHERE sourceId=?", database};
|
||||||
mutable ReadStatement<1> selectImportedTypeNameIdStatement{
|
mutable ReadStatement<1> selectImportedTypeNameIdStatement{
|
||||||
"SELECT importedTypeNameId FROM importedTypeNames WHERE kind=?1 AND importOrSourceId=?2 "
|
"SELECT importedTypeNameId FROM importedTypeNames WHERE kind=?1 AND importOrSourceId=?2 "
|
||||||
"AND name=?3 LIMIT 1",
|
"AND name=?3 LIMIT 1",
|
||||||
@@ -2235,6 +2290,31 @@ public:
|
|||||||
database};
|
database};
|
||||||
WriteStatement deleteAllSourcesStatement{"DELETE FROM sources", database};
|
WriteStatement deleteAllSourcesStatement{"DELETE FROM sources", database};
|
||||||
WriteStatement deleteAllSourceContextsStatement{"DELETE FROM sourceContexts", database};
|
WriteStatement deleteAllSourceContextsStatement{"DELETE FROM sourceContexts", database};
|
||||||
|
mutable ReadStatement<6> selectExportedTypesForTypeIdStatement{
|
||||||
|
"SELECT moduleId, name, ifnull(majorVersion, -1), ifnull(minorVersion, -1), typeId, "
|
||||||
|
"exportedTypeNameId FROM exportedTypeNames WHERE typeId IN carray(?1, ?2, 'int64') AND "
|
||||||
|
"kind=1 ORDER BY moduleId, name, majorVersion, minorVersion",
|
||||||
|
database};
|
||||||
|
WriteStatement upsertExportedTypeNamesWithVersionStatement{
|
||||||
|
"INSERT INTO exportedTypeNames(moduleId, name, kind, majorVersion, minorVersion, typeId) "
|
||||||
|
"VALUES(?1, ?2, ?3, ?4, ?5, ?6) ON CONFLICT DO UPDATE SET typeId=excluded.typeId",
|
||||||
|
database};
|
||||||
|
WriteStatement upsertExportedTypeNamesWithMajorVersionStatement{
|
||||||
|
"INSERT INTO exportedTypeNames(moduleId, name, kind, majorVersion, typeId) "
|
||||||
|
"VALUES(?1, ?2, ?3, ?4, ?5) ON CONFLICT DO UPDATE SET typeId=excluded.typeId",
|
||||||
|
database};
|
||||||
|
WriteStatement upsertExportedTypeNamesWithoutVersionStatement{
|
||||||
|
"INSERT INTO exportedTypeNames(moduleId, name, kind, typeId) VALUES(?1, ?2, ?3, ?4) ON "
|
||||||
|
"CONFLICT DO UPDATE SET typeId=excluded.typeId",
|
||||||
|
database};
|
||||||
|
WriteStatement upsertExportedTypeNameStatement{
|
||||||
|
"INSERT INTO exportedTypeNames(moduleId, name, kind, typeId) VALUES(?1, ?2, ?3, ?4) ON "
|
||||||
|
"CONFLICT DO UPDATE SET typeId=excluded.typeId WHERE typeId IS NOT excluded.typeId",
|
||||||
|
database};
|
||||||
|
WriteStatement deleteExportedTypeNameStatement{
|
||||||
|
"DELETE FROM exportedTypeNames WHERE exportedTypeNameId=?", database};
|
||||||
|
WriteStatement updateExportedTypeNameTypeIdStatement{
|
||||||
|
"UPDATE exportedTypeNames SET typeId=?2 WHERE exportedTypeNameId=?1", database};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include "projectstorageids.h"
|
#include "projectstorageids.h"
|
||||||
|
|
||||||
|
#include <tuple>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
@@ -30,6 +30,7 @@
|
|||||||
#include <utils/smallstring.h>
|
#include <utils/smallstring.h>
|
||||||
#include <utils/variant.h>
|
#include <utils/variant.h>
|
||||||
|
|
||||||
|
#include <tuple>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace QmlDesigner::Storage {
|
namespace QmlDesigner::Storage {
|
||||||
@@ -268,6 +269,13 @@ public:
|
|||||||
, version{version}
|
, version{version}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
explicit ExportedType(Utils::SmallStringView name, Version version, TypeId typeId, ModuleId moduleId)
|
||||||
|
: name{name}
|
||||||
|
, version{version}
|
||||||
|
, typeId{typeId}
|
||||||
|
, moduleId{moduleId}
|
||||||
|
{}
|
||||||
|
|
||||||
explicit ExportedType(Utils::SmallStringView name, int majorVersion, int minorVersion)
|
explicit ExportedType(Utils::SmallStringView name, int majorVersion, int minorVersion)
|
||||||
: name{name}
|
: name{name}
|
||||||
, version{majorVersion, minorVersion}
|
, version{majorVersion, minorVersion}
|
||||||
@@ -281,10 +289,37 @@ public:
|
|||||||
public:
|
public:
|
||||||
Utils::SmallString name;
|
Utils::SmallString name;
|
||||||
Storage::Version version;
|
Storage::Version version;
|
||||||
|
TypeId typeId;
|
||||||
|
ModuleId moduleId;
|
||||||
};
|
};
|
||||||
|
|
||||||
using ExportedTypes = std::vector<ExportedType>;
|
using ExportedTypes = std::vector<ExportedType>;
|
||||||
|
|
||||||
|
class ExportedTypeView
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit ExportedTypeView() = default;
|
||||||
|
explicit ExportedTypeView(int moduleId,
|
||||||
|
Utils::SmallStringView name,
|
||||||
|
int majorVersion,
|
||||||
|
int minorVersion,
|
||||||
|
int typeId,
|
||||||
|
long long exportedTypeNameId)
|
||||||
|
: name{name}
|
||||||
|
, version{majorVersion, minorVersion}
|
||||||
|
, typeId{typeId}
|
||||||
|
, moduleId{moduleId}
|
||||||
|
, exportedTypeNameId{exportedTypeNameId}
|
||||||
|
{}
|
||||||
|
|
||||||
|
public:
|
||||||
|
Utils::SmallStringView name;
|
||||||
|
Storage::Version version;
|
||||||
|
TypeId typeId;
|
||||||
|
ModuleId moduleId;
|
||||||
|
ExportedTypeNameId exportedTypeNameId;
|
||||||
|
};
|
||||||
|
|
||||||
class NativeType
|
class NativeType
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -591,6 +626,8 @@ public:
|
|||||||
PropertyDeclarationId aliasId;
|
PropertyDeclarationId aliasId;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class ChangeLevel { Full, Minimal };
|
||||||
|
|
||||||
class Type
|
class Type
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -605,7 +642,7 @@ public:
|
|||||||
FunctionDeclarations functionDeclarations = {},
|
FunctionDeclarations functionDeclarations = {},
|
||||||
SignalDeclarations signalDeclarations = {},
|
SignalDeclarations signalDeclarations = {},
|
||||||
EnumerationDeclarations enumerationDeclarations = {},
|
EnumerationDeclarations enumerationDeclarations = {},
|
||||||
TypeId typeId = TypeId{})
|
ChangeLevel changeLevel = ChangeLevel::Full)
|
||||||
: typeName{typeName}
|
: typeName{typeName}
|
||||||
, prototype{std::move(prototype)}
|
, prototype{std::move(prototype)}
|
||||||
, exportedTypes{std::move(exportedTypes)}
|
, exportedTypes{std::move(exportedTypes)}
|
||||||
@@ -616,7 +653,7 @@ public:
|
|||||||
, module{std::move(module)}
|
, module{std::move(module)}
|
||||||
, accessSemantics{accessSemantics}
|
, accessSemantics{accessSemantics}
|
||||||
, sourceId{sourceId}
|
, sourceId{sourceId}
|
||||||
, typeId{typeId}
|
, changeLevel{changeLevel}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
explicit Type(Utils::SmallStringView moduleName,
|
explicit Type(Utils::SmallStringView moduleName,
|
||||||
@@ -684,6 +721,8 @@ public:
|
|||||||
TypeAccessSemantics accessSemantics = TypeAccessSemantics::Invalid;
|
TypeAccessSemantics accessSemantics = TypeAccessSemantics::Invalid;
|
||||||
SourceId sourceId;
|
SourceId sourceId;
|
||||||
TypeId typeId;
|
TypeId typeId;
|
||||||
|
ModuleId moduleId;
|
||||||
|
ChangeLevel changeLevel = ChangeLevel::Full;
|
||||||
};
|
};
|
||||||
|
|
||||||
using Types = std::vector<Type>;
|
using Types = std::vector<Type>;
|
||||||
|
@@ -103,6 +103,8 @@ void ProjectUpdater::update()
|
|||||||
std::move(fileStatuses));
|
std::move(fileStatuses));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProjectUpdater::pathsWithIdsChanged(const std::vector<IdPaths> &idPaths) {}
|
||||||
|
|
||||||
void ProjectUpdater::parseTypeInfos(const QStringList &typeInfos,
|
void ProjectUpdater::parseTypeInfos(const QStringList &typeInfos,
|
||||||
SourceContextId directoryId,
|
SourceContextId directoryId,
|
||||||
Storage::Imports &imports,
|
Storage::Imports &imports,
|
||||||
|
@@ -28,6 +28,7 @@
|
|||||||
#include "filestatus.h"
|
#include "filestatus.h"
|
||||||
#include "nonlockingmutex.h"
|
#include "nonlockingmutex.h"
|
||||||
#include "projectstorageids.h"
|
#include "projectstorageids.h"
|
||||||
|
#include "projectstoragepathwatchertypes.h"
|
||||||
#include "projectstoragetypes.h"
|
#include "projectstoragetypes.h"
|
||||||
|
|
||||||
#include <qmljs/parser/qmldirparser_p.h>
|
#include <qmljs/parser/qmldirparser_p.h>
|
||||||
@@ -76,6 +77,7 @@ public:
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
|
void pathsWithIdsChanged(const std::vector<IdPaths> &idPaths);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class FileState {
|
enum class FileState {
|
||||||
|
@@ -122,6 +122,19 @@ MATCHER_P(IsExportedType,
|
|||||||
return type.name == name;
|
return type.name == name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MATCHER_P3(IsExportedType,
|
||||||
|
name,
|
||||||
|
majorVersion,
|
||||||
|
minorVersion,
|
||||||
|
std::string(negation ? "isn't " : "is ")
|
||||||
|
+ PrintToString(Storage::ExportedType{name,
|
||||||
|
Storage::Version{majorVersion, minorVersion}}))
|
||||||
|
{
|
||||||
|
const Storage::ExportedType &type = arg;
|
||||||
|
|
||||||
|
return type.name == name && type.version == Storage::Version{majorVersion, minorVersion};
|
||||||
|
}
|
||||||
|
|
||||||
MATCHER_P3(IsPropertyDeclaration,
|
MATCHER_P3(IsPropertyDeclaration,
|
||||||
name,
|
name,
|
||||||
typeName,
|
typeName,
|
||||||
@@ -417,6 +430,7 @@ protected:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
|
Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
|
||||||
|
//Sqlite::Database database{TESTDATA_DIR "/aaaa.db", Sqlite::JournalMode::Wal};
|
||||||
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};
|
||||||
@@ -4497,4 +4511,44 @@ TEST_F(ProjectStorage, EnsureThatPrototypesForRemovedTypesAreNotAnymoreRelinked)
|
|||||||
ASSERT_NO_THROW(storage.synchronize({}, {}, {}, {sourceId1, sourceId2}, {}));
|
ASSERT_NO_THROW(storage.synchronize({}, {}, {}, {sourceId1, sourceId2}, {}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ProjectStorage, MinimalUpdates)
|
||||||
|
{
|
||||||
|
auto types = createTypes();
|
||||||
|
storage.synchronize(modules,
|
||||||
|
imports,
|
||||||
|
types,
|
||||||
|
{sourceId1, sourceId2, moduleSourceId1, moduleSourceId2, moduleSourceId3},
|
||||||
|
{});
|
||||||
|
Storage::Type quickType{Storage::Module{"QtQuick"},
|
||||||
|
"QQuickItem",
|
||||||
|
{},
|
||||||
|
TypeAccessSemantics::Reference,
|
||||||
|
sourceId1,
|
||||||
|
{Storage::ExportedType{"Item", Storage::Version{2, 0}}},
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
Storage::ChangeLevel::Minimal};
|
||||||
|
|
||||||
|
storage.synchronize({modules[1]}, {}, {quickType}, {moduleSourceId2}, {});
|
||||||
|
|
||||||
|
ASSERT_THAT(storage.fetchTypes(),
|
||||||
|
UnorderedElementsAre(AllOf(IsStorageType(Storage::Module{"Qml"},
|
||||||
|
"QObject",
|
||||||
|
Storage::NativeType{},
|
||||||
|
TypeAccessSemantics::Reference,
|
||||||
|
sourceId2),
|
||||||
|
Field(&Storage::Type::exportedTypes,
|
||||||
|
UnorderedElementsAre(IsExportedType("Object"),
|
||||||
|
IsExportedType("Obj")))),
|
||||||
|
AllOf(IsStorageType(Storage::Module{"QtQuick"},
|
||||||
|
"QQuickItem",
|
||||||
|
Storage::NativeType{"QObject"},
|
||||||
|
TypeAccessSemantics::Reference,
|
||||||
|
sourceId1),
|
||||||
|
Field(&Storage::Type::exportedTypes,
|
||||||
|
UnorderedElementsAre(IsExportedType("Item", 2, 0))))));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
Reference in New Issue
Block a user