diff options
author | Marco Bubke <marco.bubke@qt.io> | 2024-04-03 16:38:23 +0200 |
---|---|---|
committer | Marco Bubke <marco.bubke@qt.io> | 2024-04-22 15:34:53 +0000 |
commit | e262ec1ebbb51402fdd8583e51f131ee5f04e3a6 (patch) | |
tree | 1c272053c53e84cf0e29aef9886f5a3511e2b4e5 /src | |
parent | e9ee1c6b567eb9a68be887254733ec5c1080c169 (diff) |
QmlDesigner: Integrate item library entries from project storage
Task-number: QDS-12102
Change-Id: Id6fbfcfb44d3b8c290f5e5d74addf33ef4d9a5e5
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
Reviewed-by: Qt CI Patch Build Bot <ci_patchbuild_bot@qt.io>
Diffstat (limited to 'src')
17 files changed, 386 insertions, 118 deletions
diff --git a/src/libs/languageutils/componentversion.cpp b/src/libs/languageutils/componentversion.cpp index 6c599e300b..f041740d3b 100644 --- a/src/libs/languageutils/componentversion.cpp +++ b/src/libs/languageutils/componentversion.cpp @@ -10,27 +10,17 @@ namespace LanguageUtils { -const int ComponentVersion::NoVersion = -1; -const int ComponentVersion::MaxVersion = std::numeric_limits<int>::max(); +// QTC_TEMP -ComponentVersion::ComponentVersion() - : _major(NoVersion), _minor(NoVersion) +ComponentVersion::ComponentVersion(QStringView versionString) + : _major(NoVersion) + , _minor(NoVersion) { -} - -ComponentVersion::ComponentVersion(int major, int minor) - : _major(major), _minor(minor) -{ -} - -ComponentVersion::ComponentVersion(const QString &versionString) - : _major(NoVersion), _minor(NoVersion) -{ - int dotIdx = versionString.indexOf(QLatin1Char('.')); + auto dotIdx = versionString.indexOf(QLatin1Char('.')); if (dotIdx == -1) return; bool ok = false; - int maybeMajor = versionString.left(dotIdx).toInt(&ok); + auto maybeMajor = versionString.left(dotIdx).toInt(&ok); if (!ok) return; int maybeMinor = versionString.mid(dotIdx + 1).toInt(&ok); @@ -40,15 +30,6 @@ ComponentVersion::ComponentVersion(const QString &versionString) _minor = maybeMinor; } -ComponentVersion::~ComponentVersion() -{ -} - -bool ComponentVersion::isValid() const -{ - return _major >= 0 && _minor >= 0; -} - QString ComponentVersion::toString() const { QByteArray temp; @@ -65,36 +46,4 @@ void ComponentVersion::addToHash(QCryptographicHash &hash) const hash.addData(reinterpret_cast<const char *>(&_minor), sizeof(_minor)); } -bool operator<(const ComponentVersion &lhs, const ComponentVersion &rhs) -{ - return lhs.majorVersion() < rhs.majorVersion() - || (lhs.majorVersion() == rhs.majorVersion() && lhs.minorVersion() < rhs.minorVersion()); -} - -bool operator<=(const ComponentVersion &lhs, const ComponentVersion &rhs) -{ - return lhs.majorVersion() < rhs.majorVersion() - || (lhs.majorVersion() == rhs.majorVersion() && lhs.minorVersion() <= rhs.minorVersion()); -} - -bool operator>(const ComponentVersion &lhs, const ComponentVersion &rhs) -{ - return rhs < lhs; -} - -bool operator>=(const ComponentVersion &lhs, const ComponentVersion &rhs) -{ - return rhs <= lhs; -} - -bool operator==(const ComponentVersion &lhs, const ComponentVersion &rhs) -{ - return lhs.majorVersion() == rhs.majorVersion() && lhs.minorVersion() == rhs.minorVersion(); -} - -bool operator!=(const ComponentVersion &lhs, const ComponentVersion &rhs) -{ - return !(lhs == rhs); -} - } // namespace LanguageUtils diff --git a/src/libs/languageutils/componentversion.h b/src/libs/languageutils/componentversion.h index 4b39e8402a..0ba332103a 100644 --- a/src/libs/languageutils/componentversion.h +++ b/src/libs/languageutils/componentversion.h @@ -9,6 +9,8 @@ QT_BEGIN_NAMESPACE class QCryptographicHash; QT_END_NAMESPACE +#include <QStringView> + namespace LanguageUtils { class LANGUAGEUTILS_EXPORT ComponentVersion @@ -17,25 +19,56 @@ class LANGUAGEUTILS_EXPORT ComponentVersion int _minor; public: - static const int NoVersion; - static const int MaxVersion; + static const int NoVersion = -1; + static const int MaxVersion = -1; + + ComponentVersion() + : _major(NoVersion) + , _minor(NoVersion) + {} - ComponentVersion(); - ComponentVersion(int major, int minor); - explicit ComponentVersion(const QString &versionString); - ~ComponentVersion(); + ComponentVersion(int major, int minor) + : _major(major) + , _minor(minor) + {} + + explicit ComponentVersion(QStringView versionString); + ~ComponentVersion() = default; int majorVersion() const { return _major; } int minorVersion() const { return _minor; } - friend bool LANGUAGEUTILS_EXPORT operator<(const ComponentVersion &lhs, const ComponentVersion &rhs); - friend bool LANGUAGEUTILS_EXPORT operator<=(const ComponentVersion &lhs, const ComponentVersion &rhs); - friend bool LANGUAGEUTILS_EXPORT operator>(const ComponentVersion &lhs, const ComponentVersion &rhs); - friend bool LANGUAGEUTILS_EXPORT operator>=(const ComponentVersion &lhs, const ComponentVersion &rhs); - friend bool LANGUAGEUTILS_EXPORT operator==(const ComponentVersion &lhs, const ComponentVersion &rhs); - friend bool LANGUAGEUTILS_EXPORT operator!=(const ComponentVersion &lhs, const ComponentVersion &rhs); + friend bool operator<(const ComponentVersion &lhs, const ComponentVersion &rhs) + { + return std::tie(lhs._major, lhs._minor) < std::tie(rhs._major, rhs._minor); + } + + friend bool operator<=(const ComponentVersion &lhs, const ComponentVersion &rhs) + { + return std::tie(lhs._major, lhs._minor) <= std::tie(rhs._major, rhs._minor); + } + + friend bool operator>(const ComponentVersion &lhs, const ComponentVersion &rhs) + { + return rhs < lhs; + } + + friend bool operator>=(const ComponentVersion &lhs, const ComponentVersion &rhs) + { + return rhs <= lhs; + } + + friend bool operator==(const ComponentVersion &lhs, const ComponentVersion &rhs) + { + return lhs.majorVersion() == rhs.majorVersion() && lhs.minorVersion() == rhs.minorVersion(); + } + + friend bool operator!=(const ComponentVersion &lhs, const ComponentVersion &rhs) + { + return !(lhs == rhs); + } - bool isValid() const; + bool isValid() const { return _major >= 0 && _minor >= 0; } QString toString() const; void addToHash(QCryptographicHash &hash) const; }; diff --git a/src/libs/sqlite/sqlitevalue.h b/src/libs/sqlite/sqlitevalue.h index ec4120139a..725682494b 100644 --- a/src/libs/sqlite/sqlitevalue.h +++ b/src/libs/sqlite/sqlitevalue.h @@ -34,7 +34,7 @@ public: explicit ValueBase(NullValue) {} explicit ValueBase(VariantType &&value) - : value(value) + : value(std::move(value)) {} explicit ValueBase(const char *value) @@ -44,6 +44,7 @@ public: explicit ValueBase(long long value) : value(value) {} + explicit ValueBase(int value) : value(static_cast<long long>(value)) {} @@ -61,11 +62,6 @@ public: {} - explicit ValueBase(StringType &&value) - : value(std::move(value)) - - {} - explicit ValueBase(BlobView value) : value(value) @@ -230,14 +226,42 @@ public: class ValueView : public ValueBase<Utils::SmallStringView, BlobView> { public: + ValueView() = default; + + explicit ValueView(NullValue) {} + explicit ValueView(ValueBase &&base) : ValueBase(std::move(base)) {} + explicit ValueView(Utils::SmallStringView value) + : ValueBase(value) + {} + + explicit ValueView(BlobView value) + : ValueBase(value) + {} + + explicit ValueView(long long value) + : ValueBase(value) + {} + + explicit ValueView(int value) + : ValueBase(static_cast<long long>(value)) + {} + + explicit ValueView(uint value) + : ValueBase(static_cast<long long>(value)) + {} + + explicit ValueView(double value) + : ValueBase(value) + {} + template<typename Type> static ValueView create(Type &&value_) { - return ValueView{ValueBase{value_}}; + return ValueView(std::forward<Type>(value_)); } }; diff --git a/src/libs/utils/smallstring.h b/src/libs/utils/smallstring.h index a8869b4ccf..52dd10602c 100644 --- a/src/libs/utils/smallstring.h +++ b/src/libs/utils/smallstring.h @@ -356,6 +356,14 @@ public: return false; } + bool startsWith(QStringView subStringToSearch) const noexcept + { + if (size() >= Utils::usize(subStringToSearch)) + return subStringToSearch == QLatin1StringView{data(), subStringToSearch.size()}; + + return false; + } + bool startsWith(char characterToSearch) const noexcept { return data()[0] == characterToSearch; diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp index 50bb01a5bb..3bff210520 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp @@ -296,15 +296,16 @@ void ItemLibraryModel::setSearchText(const QString &searchText) Import ItemLibraryModel::entryToImport(const ItemLibraryEntry &entry) { +#ifndef QDS_USE_PROJECTSTORAGE if (entry.majorVersion() == -1 && entry.minorVersion() == -1) return Import::createFileImport(entry.requiredImport()); - +#endif return Import::createLibraryImport(entry.requiredImport(), QString::number(entry.majorVersion()) + QLatin1Char('.') + QString::number(entry.minorVersion())); } -void ItemLibraryModel::update([[maybe_unused]] ItemLibraryInfo *itemLibraryInfo, Model *model) +void ItemLibraryModel::update(Model *model) { if (!model) return; diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h index 212ddf8e04..b04ea492d2 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h @@ -37,7 +37,7 @@ public: QString searchText() const; ItemLibraryImport *importByUrl(const QString &importName) const; - void update(ItemLibraryInfo *itemLibraryInfo, Model *model); + void update(Model *model); void updateUsedImports(const Imports &usedImports); QMimeData *getMimeData(const ItemLibraryEntry &itemLibraryEntry); diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp index 587489bc8c..ffefc43178 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp @@ -333,9 +333,7 @@ void ItemLibraryWidget::updateModel() m_compressionTimer.stop(); } -#ifndef QDS_USE_PROJECTSTORAGE - m_itemLibraryModel->update(m_itemLibraryInfo.data(), m_model.data()); -#endif + m_itemLibraryModel->update(m_model.data()); if (m_itemLibraryModel->rowCount() == 0 && !m_updateRetry) { m_updateRetry = true; // Only retry once to avoid endless loops diff --git a/src/plugins/qmldesigner/designercore/include/projectstorageids.h b/src/plugins/qmldesigner/designercore/include/projectstorageids.h index 90c174e04e..0b157e55e7 100644 --- a/src/plugins/qmldesigner/designercore/include/projectstorageids.h +++ b/src/plugins/qmldesigner/designercore/include/projectstorageids.h @@ -51,6 +51,8 @@ using SourceContextIds = std::vector<SourceContextId>; using SourceId = Sqlite::BasicId<BasicIdType::Source, int>; using SourceIds = std::vector<SourceId>; +template<std::size_t size> +using SmallSourceIds = QVarLengthArray<SourceId, size>; using ModuleId = Sqlite::BasicId<BasicIdType::Module, int>; using ModuleIds = std::vector<ModuleId>; diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h index ad606bcb90..70d5e92b25 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h @@ -484,6 +484,34 @@ public: return typeHints; } + SmallSourceIds<4> typeAnnotationSourceIds(SourceId directoryId) const override + { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"get type annotaion source ids"_t, + projectStorageCategory(), + keyValue("source id", directoryId)}; + + auto sourceIds = selectTypeAnnotationSourceIdsStatement + .template valuesWithTransaction<SmallSourceIds<4>>(directoryId); + + tracer.end(keyValue("source ids", sourceIds)); + + return sourceIds; + } + + SmallSourceIds<64> typeAnnotationDirectorySourceIds() const override + { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"get type annotaion source ids"_t, projectStorageCategory()}; + + auto sourceIds = selectTypeAnnotationDirectorySourceIdsStatement + .template valuesWithTransaction<SmallSourceIds<64>>(); + + tracer.end(keyValue("source ids", sourceIds)); + + return sourceIds; + } + Storage::Info::ItemLibraryEntries itemLibraryEntries(TypeId typeId) const override { using NanotraceHR::keyValue; @@ -518,6 +546,40 @@ public: return entries; } + Storage::Info::ItemLibraryEntries itemLibraryEntries(ImportId importId) const + { + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"get item library entries by import id"_t, + projectStorageCategory(), + keyValue("import id", importId)}; + + using Storage::Info::ItemLibraryProperties; + Storage::Info::ItemLibraryEntries entries; + + auto callback = [&](TypeId typeId_, + Utils::SmallStringView name, + Utils::SmallStringView iconPath, + Utils::SmallStringView category, + Utils::SmallStringView import, + Utils::SmallStringView toolTip, + Utils::SmallStringView properties, + Utils::SmallStringView extraFilePaths, + Utils::SmallStringView templatePath) { + auto &last = entries.emplace_back( + typeId_, name, iconPath, category, import, toolTip, templatePath); + if (properties.size()) + selectItemLibraryPropertiesStatement.readTo(last.properties, properties); + if (extraFilePaths.size()) + selectItemLibraryExtraFilePathsStatement.readTo(last.extraFilePaths, extraFilePaths); + }; + + selectItemLibraryEntriesByTypeIdStatement.readCallbackWithTransaction(callback, importId); + + tracer.end(keyValue("item library entries", entries)); + + return entries; + } + Storage::Info::ItemLibraryEntries itemLibraryEntries(SourceId sourceId) const override { using NanotraceHR::keyValue; @@ -1479,6 +1541,28 @@ private: annotation.typeId = fetchTypeIdByModuleIdAndExportedName(annotation.moduleId, annotation.typeName); } + + for (auto &annotation : typeAnnotations) { + if (!annotation.typeId) + qWarning() << moduleName(annotation.moduleId).toQString() + << annotation.typeName.toQString(); + } + + typeAnnotations.erase(std::remove_if(typeAnnotations.begin(), + typeAnnotations.end(), + [](const auto &annotation) { + return !annotation.typeId; + }), + typeAnnotations.end()); + } + + template<typename Value> + static Sqlite::ValueView createEmptyAsNull(const Value &value) + { + if (value.size()) + return Sqlite::ValueView::create(value); + + return Sqlite::ValueView{}; } void synchronizeTypeAnnotations(Storage::Synchronization::TypeAnnotations &typeAnnotations, @@ -1512,9 +1596,10 @@ private: insertTypeAnnotationStatement.write(annotation.typeId, annotation.sourceId, + annotation.directorySourceId, annotation.iconPath, - annotation.itemLibraryJson, - annotation.hintsJson); + createEmptyAsNull(annotation.itemLibraryJson), + createEmptyAsNull(annotation.hintsJson)); }; auto update = [&](const TypeAnnotationView &annotationFromDatabase, @@ -1533,8 +1618,8 @@ private: updateTypeAnnotationStatement.write(annotation.typeId, annotation.iconPath, - annotation.itemLibraryJson, - annotation.hintsJson); + createEmptyAsNull(annotation.itemLibraryJson), + createEmptyAsNull(annotation.hintsJson)); return Sqlite::UpdateChange::Update; } @@ -4285,11 +4370,15 @@ private: Sqlite::StrictColumnType::Integer, {Sqlite::PrimaryKey{}}); auto &sourceIdColumn = table.addColumn("sourceId", Sqlite::StrictColumnType::Integer); + auto &directorySourceIdColumn = table.addColumn("directorySourceId", + Sqlite::StrictColumnType::Integer); + table.addColumn("iconPath", Sqlite::StrictColumnType::Text); table.addColumn("itemLibrary", Sqlite::StrictColumnType::Text); table.addColumn("hints", Sqlite::StrictColumnType::Text); table.addUniqueIndex({sourceIdColumn, typeIdColumn}); + table.addIndex({directorySourceIdColumn}); table.initialize(database); } @@ -4926,9 +5015,10 @@ public: "SELECT typeId, iconPath, itemLibrary, hints FROM typeAnnotations WHERE " "sourceId IN carray(?1) ORDER BY typeId", database}; - WriteStatement<5> insertTypeAnnotationStatement{ - "INSERT INTO typeAnnotations(typeId, sourceId, iconPath, itemLibrary, hints) VALUES(?1, " - "?2, ?3, ?4, ?5)", + WriteStatement<6> insertTypeAnnotationStatement{ + "INSERT INTO " + " typeAnnotations(typeId, sourceId, directorySourceId, iconPath, itemLibrary, hints) " + "VALUES(?1, ?2, ?3, ?4, ?5, ?6)", database}; WriteStatement<4> updateTypeAnnotationStatement{ "UPDATE typeAnnotations SET iconPath=?2, itemLibrary=?3, hints=?4 WHERE typeId=?1", database}; @@ -4939,28 +5029,35 @@ public: mutable ReadStatement<2, 1> selectTypeHintsStatement{ "SELECT hints.key, hints.value " "FROM typeAnnotations, json_each(typeAnnotations.hints) AS hints " - "WHERE typeId=?1", + "WHERE typeId=?1 AND hints IS NOT NULL", database}; + mutable ReadStatement<1, 1> selectTypeAnnotationSourceIdsStatement{ + "SELECT sourceId FROM typeAnnotations WHERE directorySourceId=?1 ORDER BY sourceId", database}; + mutable ReadStatement<1, 0> selectTypeAnnotationDirectorySourceIdsStatement{ + "SELECT DISTINCT directorySourceId FROM typeAnnotations ORDER BY directorySourceId", database}; mutable ReadStatement<9> selectItemLibraryEntriesStatement{ "SELECT typeId, i.value->>'$.name', i.value->>'$.iconPath', i.value->>'$.category', " " i.value->>'$.import', i.value->>'$.toolTip', i.value->>'$.properties', " " i.value->>'$.extraFilePaths', i.value->>'$.templatePath' " - "FROM typeAnnotations, json_each(typeAnnotations.itemLibrary) AS i", + "FROM typeAnnotations AS ta , json_each(ta.itemLibrary) AS i " + "WHERE ta.itemLibrary IS NOT NULL", database}; mutable ReadStatement<9, 1> selectItemLibraryEntriesByTypeIdStatement{ "SELECT typeId, i.value->>'$.name', i.value->>'$.iconPath', i.value->>'$.category', " " i.value->>'$.import', i.value->>'$.toolTip', i.value->>'$.properties', " " i.value->>'$.extraFilePaths', i.value->>'$.templatePath' " - "FROM typeAnnotations, json_each(typeAnnotations.itemLibrary) AS i " - "WHERE typeId=?1", + "FROM typeAnnotations AS ta, json_each(ta.itemLibrary) AS i " + "WHERE typeId=?1 AND ta.itemLibrary IS NOT NULL", database}; mutable ReadStatement<9, 1> selectItemLibraryEntriesBySourceIdStatement{ - "SELECT typeId, i.value->>'$.name', i.value->>'$.iconPath', i.value->>'$.category', " + "SELECT typeId, i.value->>'$.name', i.value->>'$.iconPath', " + "i.value->>'$.category', " " i.value->>'$.import', i.value->>'$.toolTip', i.value->>'$.properties', " " i.value->>'$.extraFilePaths', i.value->>'$.templatePath' " "FROM typeAnnotations, json_each(typeAnnotations.itemLibrary) AS i " "WHERE typeId IN (SELECT DISTINCT typeId " - " FROM documentImports AS di JOIN exportedTypeNames USING(moduleId) " + " FROM documentImports AS di JOIN exportedTypeNames " + " USING(moduleId) " " WHERE di.sourceId=?)", database}; mutable ReadStatement<3, 1> selectItemLibraryPropertiesStatement{ diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageinterface.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageinterface.h index a67b629608..20d988f7aa 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageinterface.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageinterface.h @@ -57,6 +57,8 @@ public: = 0; virtual PropertyDeclarationId defaultPropertyDeclarationId(TypeId typeId) const = 0; virtual std::optional<Storage::Info::Type> type(TypeId typeId) const = 0; + virtual SmallSourceIds<4> typeAnnotationSourceIds(SourceId directoryId) const = 0; + virtual SmallSourceIds<64> typeAnnotationDirectorySourceIds() const = 0; virtual Utils::PathString typeIconPath(TypeId typeId) const = 0; virtual Storage::Info::TypeHints typeHints(TypeId typeId) const = 0; virtual Storage::Info::ItemLibraryEntries itemLibraryEntries(TypeId typeId) const = 0; diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstoragetypes.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstoragetypes.h index 5f80505da3..8d810d94bd 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstoragetypes.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstoragetypes.h @@ -1202,10 +1202,13 @@ using ProjectDatas = std::vector<ProjectData>; class TypeAnnotation { public: - TypeAnnotation(SourceId sourceId) + TypeAnnotation(SourceId sourceId, SourceId directorySourceId) : sourceId{sourceId} + , directorySourceId{directorySourceId} {} + TypeAnnotation(SourceId sourceId, + SourceId directorySourceId, Utils::SmallStringView typeName, ModuleId moduleId, Utils::SmallStringView iconPath, @@ -1219,6 +1222,7 @@ public: , sourceId{sourceId} , moduleId{moduleId} , traits{traits} + , directorySourceId{directorySourceId} {} template<typename String> @@ -1247,6 +1251,7 @@ public: SourceId sourceId; ModuleId moduleId; TypeTraits traits; + SourceId directorySourceId; }; using TypeAnnotations = std::vector<TypeAnnotation>; diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.cpp b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.cpp index 6948117db6..761d6371ef 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.cpp +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.cpp @@ -11,6 +11,7 @@ #include "qmltypesparserinterface.h" #include "sourcepath.h" #include "sourcepathcache.h" +#include "typeannotationreader.h" #include <tracing/qmldesignertracing.h> @@ -246,7 +247,8 @@ std::vector<IdPaths> createIdPaths(ProjectStorageUpdater::WatchedSourceIdsIds wa void ProjectStorageUpdater::update(QStringList directories, QStringList qmlTypesPaths, - const QString &propertyEditorResourcesPath) + const QString &propertyEditorResourcesPath, + const QStringList &typeAnnotationPaths) { NanotraceHR::Tracer tracer{"update"_t, category(), @@ -260,6 +262,7 @@ void ProjectStorageUpdater::update(QStringList directories, updateDirectories(directories, package, notUpdatedSourceIds, watchedSourceIds); updateQmlTypes(qmlTypesPaths, package, notUpdatedSourceIds, watchedSourceIds); updatePropertyEditorPaths(propertyEditorResourcesPath, package, notUpdatedSourceIds); + updateTypeAnnotations(typeAnnotationPaths, package, notUpdatedSourceIds); package.updatedSourceIds = filterNotUpdatedSourceIds(std::move(package.updatedSourceIds), std::move(notUpdatedSourceIds.sourceIds)); @@ -511,12 +514,134 @@ void ProjectStorageUpdater::updatePropertyEditorPaths( } } +namespace { + +template<typename SourceIds1, typename SourceIds2> +SmallSourceIds<16> mergedSourceIds(const SourceIds1 &sourceIds1, const SourceIds2 &sourceIds2) +{ + SmallSourceIds<16> mergedSourceIds; + + std::set_union(sourceIds1.begin(), + sourceIds1.end(), + sourceIds2.begin(), + sourceIds2.end(), + std::back_inserter(mergedSourceIds)); + + return mergedSourceIds; +} +} // namespace + +void ProjectStorageUpdater::updateTypeAnnotations(const QStringList &directoryPaths, + Storage::Synchronization::SynchronizationPackage &package, + NotUpdatedSourceIds ¬UpdatedSourceIds) +{ + NanotraceHR::Tracer tracer("update type annotations"_t, category()); + + std::map<SourceId, SmallSourceIds<16>> updatedSourceIdsDictonary; + + for (SourceId directoryId : m_projectStorage.typeAnnotationDirectorySourceIds()) + updatedSourceIdsDictonary[directoryId] = {}; + + for (const auto &directoryPath : directoryPaths) + updateTypeAnnotations(directoryPath, package, notUpdatedSourceIds, updatedSourceIdsDictonary); + + updateTypeAnnotationDirectories(package, notUpdatedSourceIds, updatedSourceIdsDictonary); +} + void ProjectStorageUpdater::updateTypeAnnotations( - const QString & /*propertyEditorResourcesPath*/, - Storage::Synchronization::SynchronizationPackage & /*package*/, - NotUpdatedSourceIds & /*notUpdatedSourceIds*/) + const QString &rootDirectoryPath, + Storage::Synchronization::SynchronizationPackage &package, + NotUpdatedSourceIds ¬UpdatedSourceIds, + std::map<SourceId, SmallSourceIds<16>> &updatedSourceIdsDictonary) +{ + NanotraceHR::Tracer tracer("update type annotation directory"_t, + category(), + keyValue("path", rootDirectoryPath)); + + if (rootDirectoryPath.isEmpty()) + return; + + QDirIterator directoryIterator{rootDirectoryPath, + {"*.metainfo"}, + QDir::NoDotAndDotDot | QDir::Files, + QDirIterator::Subdirectories}; + + while (directoryIterator.hasNext()) { + auto fileInfo = directoryIterator.nextFileInfo(); + auto filePath = fileInfo.filePath(); + SourceId sourceId = m_pathCache.sourceId(SourcePath{filePath}); + + auto directoryPath = fileInfo.canonicalPath(); + + SourceId directorySourceId = m_pathCache.sourceId(SourcePath{directoryPath + "/."}); + + auto state = fileState(sourceId, package, notUpdatedSourceIds); + if (state == FileState::Changed) + updateTypeAnnotation(directoryPath, fileInfo.filePath(), sourceId, directorySourceId, package); + + if (state != FileState::NotChanged) + updatedSourceIdsDictonary[directorySourceId].push_back(sourceId); + } +} + +void ProjectStorageUpdater::updateTypeAnnotationDirectories( + Storage::Synchronization::SynchronizationPackage &package, + NotUpdatedSourceIds ¬UpdatedSourceIds, + std::map<SourceId, SmallSourceIds<16>> &updatedSourceIdsDictonary) +{ + for (auto &[directorySourceId, updatedSourceIds] : updatedSourceIdsDictonary) { + auto directoryState = fileState(directorySourceId, package, notUpdatedSourceIds); + + if (directoryState != FileState::NotChanged) { + auto existingTypeAnnotationSourceIds = m_projectStorage.typeAnnotationSourceIds( + directorySourceId); + + std::sort(updatedSourceIds.begin(), updatedSourceIds.end()); + + auto changedSourceIds = mergedSourceIds(existingTypeAnnotationSourceIds, updatedSourceIds); + package.updatedTypeAnnotationSourceIds.insert(package.updatedTypeAnnotationSourceIds.end(), + changedSourceIds.begin(), + changedSourceIds.end()); + } else { + package.updatedTypeAnnotationSourceIds.insert(package.updatedTypeAnnotationSourceIds.end(), + updatedSourceIds.begin(), + updatedSourceIds.end()); + } + } +} + +namespace { +QString contentFromFile(const QString &path) { - // const auto typeAnnotations = dir.entryInfoList({"*.metainfo"}, QDir::Files); + QFile file{path}; + if (file.open(QIODevice::ReadOnly)) + return QString::fromUtf8(file.readAll()); + + return {}; +} +} // namespace + +void ProjectStorageUpdater::updateTypeAnnotation(const QString &directoryPath, + const QString &filePath, + SourceId sourceId, + SourceId directorySourceId, + Storage::Synchronization::SynchronizationPackage &package) +{ + NanotraceHR::Tracer tracer{"update type annotation path"_t, + category(), + keyValue("path", filePath), + keyValue("directory path", directoryPath)}; + + Storage::TypeAnnotationReader reader{m_projectStorage}; + + auto annotations = reader.parseTypeAnnotation(contentFromFile(filePath), + directoryPath, + sourceId, + directorySourceId); + auto &typeAnnotations = package.typeAnnotations; + package.typeAnnotations.insert(typeAnnotations.end(), + std::make_move_iterator(annotations.begin()), + std::make_move_iterator(annotations.end())); } void ProjectStorageUpdater::updatePropertyEditorPath( @@ -752,6 +877,7 @@ void ProjectStorageUpdater::parseProjectDatas(const Storage::Synchronization::Pr watchedSourceIds.qmlSourceIds.push_back(projectData.sourceId); parseQmlComponent(projectData.sourceId, package, notUpdatedSourceIds); + break; } } } diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.h index c779403565..e21531deea 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.h @@ -11,12 +11,15 @@ #include "projectstoragetypes.h" #include "sourcepath.h" +#include <modelfwd.h> + #include <tracing/qmldesignertracing.h> #include <qmljs/parser/qmldirparser_p.h> #include <QStringList> +#include <map> #include <vector> namespace Sqlite { @@ -40,7 +43,7 @@ public: using PathCache = SourcePathCache<ProjectStorage<Sqlite::Database>, NonLockingMutex>; ProjectStorageUpdater(FileSystemInterface &fileSystem, - ProjectStorageInterface &projectStorage, + ProjectStorageType &projectStorage, FileStatusCache &fileStatusCache, PathCache &pathCache, QmlDocumentParserInterface &qmlDocumentParser, @@ -59,7 +62,8 @@ public: void update(QStringList directories, QStringList qmlTypesPaths, - const QString &propertyEditorResourcesPath); + const QString &propertyEditorResourcesPath, + const QStringList &typeAnnotationPaths); void pathsWithIdsChanged(const std::vector<IdPaths> &idPaths) override; void pathsChanged(const SourceIds &filePathIds) override; @@ -157,9 +161,21 @@ private: void updatePropertyEditorPaths(const QString &propertyEditorResourcesPath, Storage::Synchronization::SynchronizationPackage &package, NotUpdatedSourceIds ¬UpdatedSourceIds); - void updateTypeAnnotations(const QString &propertyEditorResourcesPath, + void updateTypeAnnotations(const QString &directoryPath, + Storage::Synchronization::SynchronizationPackage &package, + NotUpdatedSourceIds ¬UpdatedSourceIds, + std::map<SourceId, SmallSourceIds<16>> &updatedSourceIdsDictonary); + void updateTypeAnnotationDirectories(Storage::Synchronization::SynchronizationPackage &package, + NotUpdatedSourceIds ¬UpdatedSourceIds, + std::map<SourceId, SmallSourceIds<16>> &updatedSourceIdsDictonary); + void updateTypeAnnotations(const QStringList &directoryPath, Storage::Synchronization::SynchronizationPackage &package, NotUpdatedSourceIds ¬UpdatedSourceIds); + void updateTypeAnnotation(const QString &directoryPath, + const QString &filePath, + SourceId sourceId, + SourceId directorySourceId, + Storage::Synchronization::SynchronizationPackage &package); void updatePropertyEditorPath(const QString &path, Storage::Synchronization::SynchronizationPackage &package, SourceId directorySourceId); @@ -209,7 +225,7 @@ private: private: std::vector<IdPaths> m_changedIdPaths; FileSystemInterface &m_fileSystem; - ProjectStorageInterface &m_projectStorage; + ProjectStorageType &m_projectStorage; FileStatusCache &m_fileStatusCache; PathCache &m_pathCache; QmlDocumentParserInterface &m_qmlDocumentParser; diff --git a/src/plugins/qmldesigner/designercore/projectstorage/typeannotationreader.cpp b/src/plugins/qmldesigner/designercore/projectstorage/typeannotationreader.cpp index b829e9db36..67a63542bc 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/typeannotationreader.cpp +++ b/src/plugins/qmldesigner/designercore/projectstorage/typeannotationreader.cpp @@ -27,11 +27,11 @@ constexpr auto propertyElementName = "Property"_L1; constexpr auto extraFileElementName = "ExtraFile"_L1; } // namespace -Synchronization::TypeAnnotations TypeAnnotationReader::parseTypeAnnotation(const QString &content, - const QString &directoryPath, - SourceId sourceId) +Synchronization::TypeAnnotations TypeAnnotationReader::parseTypeAnnotation( + const QString &content, const QString &directoryPath, SourceId sourceId, SourceId directorySourceId) { m_sourceId = sourceId; + m_directorySourceId = directorySourceId; m_directoryPath = directoryPath; m_parserState = ParsingDocument; if (!SimpleAbstractStreamReader::readFromSource(content)) { @@ -178,7 +178,7 @@ TypeAnnotationReader::ParserSate TypeAnnotationReader::readDocument(const QStrin TypeAnnotationReader::ParserSate TypeAnnotationReader::readMetaInfoRootElement(const QString &name) { if (name == typeElementName) { - m_typeAnnotations.emplace_back(m_sourceId); + m_typeAnnotations.emplace_back(m_sourceId, m_directorySourceId); m_itemLibraryEntries = json::array(); return ParsingType; } else { @@ -277,7 +277,7 @@ void TypeAnnotationReader::readItemLibraryEntryProperty(QStringView name, const } else if (name == "category"_L1) { m_itemLibraryEntries.back()["category"] = value; } else if (name == "libraryIcon"_L1) { - m_itemLibraryEntries.back()["iconPath"] = value; + m_itemLibraryEntries.back()["iconPath"] = absoluteFilePathForDocument(variant.toString()); } else if (name == "version"_L1) { // setVersion(value.toString()); } else if (name == "requiredImport"_L1) { @@ -427,8 +427,8 @@ void TypeAnnotationReader::setVersion(const QString &versionNumber) int minor = 0; if (!versionNumber.isEmpty()) { - int val; - bool ok; + int val = -1; + bool ok = false; if (versionNumber.contains('.'_L1)) { val = versionNumber.split('.'_L1).constFirst().toInt(&ok); major = ok ? val : major; diff --git a/src/plugins/qmldesigner/designercore/projectstorage/typeannotationreader.h b/src/plugins/qmldesigner/designercore/projectstorage/typeannotationreader.h index 9332d5bed9..a320493ee2 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/typeannotationreader.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/typeannotationreader.h @@ -49,7 +49,8 @@ public: Synchronization::TypeAnnotations parseTypeAnnotation(const QString &content, const QString &directoryPath, - SourceId sourceId); + SourceId sourceId, + SourceId directorySourceId); QStringList errors(); @@ -124,6 +125,7 @@ private: json m_itemLibraryEntries; Property m_currentProperty; SourceId m_sourceId; + SourceId m_directorySourceId; }; } // namespace QmlDesigner::Storage diff --git a/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp b/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp index c415863e8a..2aadc45f24 100644 --- a/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp +++ b/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp @@ -490,6 +490,11 @@ QString propertyEditorResourcesPath() return Core::ICore::resourcePath("qmldesigner/propertyEditorQmlSources").toString(); } +QString qtCreatorItemLibraryPath() +{ + return Core::ICore::resourcePath("qmldesigner/itemLibrary").toString(); +} + } // namespace void QmlDesignerProjectManager::projectAdded(::ProjectExplorer::Project *project) @@ -626,11 +631,13 @@ void QmlDesignerProjectManager::update() if constexpr (isUsingQmlDesignerLite()) { m_projectData->projectStorageData->updater.update(directoriesForLiteDesigner(), qmlTypesForLiteDesigner(), - propertyEditorResourcesPath()); + propertyEditorResourcesPath(), + {qtCreatorItemLibraryPath()}); } else { m_projectData->projectStorageData->updater.update(directories(m_projectData->activeTarget), qmlTypes(m_projectData->activeTarget), - propertyEditorResourcesPath()); + propertyEditorResourcesPath(), + {qtCreatorItemLibraryPath()}); } } diff --git a/src/plugins/qmldesigner/qtquickplugin/quick.metainfo b/src/plugins/qmldesigner/qtquickplugin/quick.metainfo index 3f3cdb7910..46cb42b60d 100644 --- a/src/plugins/qmldesigner/qtquickplugin/quick.metainfo +++ b/src/plugins/qmldesigner/qtquickplugin/quick.metainfo @@ -374,7 +374,6 @@ MetaInfo { name: "Keyframe" category: "none" version: "1.0" - requiredImport: "none" } } @@ -386,7 +385,6 @@ MetaInfo { name: "KeyframeGroup" category: "none" version: "1.0" - requiredImport: "none" } } |