forked from qt-creator/qt-creator
QmlDesigner: Parse components recursively
Change-Id: I8fa892cce8e34b5e58cbdde04c57e30b9fc74866 Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Tim Jenssen <tim.jenssen@qt.io> Reviewed-by: Qt CI Patch Build Bot <ci_patchbuild_bot@qt.io>
This commit is contained in:
@@ -48,6 +48,8 @@ using EnumerationDeclarationIds = std::vector<EnumerationDeclarationId>;
|
||||
|
||||
using SourceContextId = Sqlite::BasicId<BasicIdType::SourceContext, int>;
|
||||
using SourceContextIds = std::vector<SourceContextId>;
|
||||
template<std::size_t size>
|
||||
using SmallSourceContextIds = QVarLengthArray<SourceContextId, size>;
|
||||
|
||||
using SourceId = Sqlite::BasicId<BasicIdType::Source, int>;
|
||||
using SourceIds = std::vector<SourceId>;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QDir>
|
||||
#include <QDirIterator>
|
||||
#include <QFileInfo>
|
||||
|
||||
namespace QmlDesigner {
|
||||
@@ -69,6 +70,18 @@ QString FileSystem::contentAsQString(const QString &filePath) const
|
||||
return {};
|
||||
}
|
||||
|
||||
QStringList FileSystem::subdirectories(const QString &directoryPath) const
|
||||
{
|
||||
QStringList directoryPaths;
|
||||
directoryPaths.reserve(100);
|
||||
QDirIterator directoryIterator{directoryPath, QDir::Dirs | QDir::NoDotAndDotDot};
|
||||
|
||||
while (directoryIterator.hasNext())
|
||||
directoryPaths.push_back(directoryIterator.next());
|
||||
|
||||
return directoryPaths;
|
||||
}
|
||||
|
||||
void FileSystem::remove(const SourceIds &sourceIds)
|
||||
{
|
||||
for (SourceId sourceId : sourceIds)
|
||||
|
||||
@@ -31,6 +31,7 @@ public:
|
||||
long long lastModified(SourceId sourceId) const override;
|
||||
FileStatus fileStatus(SourceId sourceId) const override;
|
||||
QString contentAsQString(const QString &filePath) const override;
|
||||
QStringList subdirectories(const QString &directoryPath) const override;
|
||||
|
||||
void remove(const SourceIds &sourceIds) override;
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ public:
|
||||
virtual FileStatus fileStatus(SourceId sourceId) const = 0;
|
||||
virtual void remove(const SourceIds &sourceIds) = 0;
|
||||
virtual QString contentAsQString(const QString &filePath) const = 0;
|
||||
virtual QStringList subdirectories(const QString &directoryPath) const = 0;
|
||||
|
||||
protected:
|
||||
~FileSystemInterface() = default;
|
||||
|
||||
@@ -519,6 +519,12 @@ struct ProjectStorage::Statements
|
||||
"SELECT directorySourceId, sourceId, moduleId, fileType FROM directoryInfos WHERE "
|
||||
"directorySourceId=?1",
|
||||
database};
|
||||
mutable Sqlite::ReadStatement<4, 2> selectDirectoryInfosForSourceIdAndFileTypeStatement{
|
||||
"SELECT directorySourceId, sourceId, moduleId, fileType FROM directoryInfos WHERE "
|
||||
"directorySourceId=?1 AND fileType=?2",
|
||||
database};
|
||||
mutable Sqlite::ReadStatement<1, 2> selectDirectoryInfosSourceIdsForSourceIdAndFileTypeStatement{
|
||||
"SELECT sourceId FROM directoryInfos WHERE directorySourceId=?1 AND fileType=?2", database};
|
||||
mutable Sqlite::ReadStatement<4, 1> selectDirectoryInfoForSourceIdStatement{
|
||||
"SELECT directorySourceId, sourceId, moduleId, fileType FROM directoryInfos WHERE "
|
||||
"sourceId=?1 LIMIT 1",
|
||||
@@ -1073,10 +1079,11 @@ public:
|
||||
Sqlite::StrictColumnType::Integer);
|
||||
auto &sourceIdColumn = table.addColumn("sourceId", Sqlite::StrictColumnType::Integer);
|
||||
table.addColumn("moduleId", Sqlite::StrictColumnType::Integer);
|
||||
table.addColumn("fileType", Sqlite::StrictColumnType::Integer);
|
||||
auto &fileTypeColumn = table.addColumn("fileType", Sqlite::StrictColumnType::Integer);
|
||||
|
||||
table.addPrimaryKeyContraint({directorySourceIdColumn, sourceIdColumn});
|
||||
table.addUniqueIndex({sourceIdColumn});
|
||||
table.addIndex({directorySourceIdColumn, fileTypeColumn});
|
||||
|
||||
table.initialize(database);
|
||||
}
|
||||
@@ -1196,7 +1203,7 @@ void ProjectStorage::synchronize(Storage::Synchronization::SynchronizationPackag
|
||||
|
||||
linkAliases(insertedAliasPropertyDeclarations, updatedAliasPropertyDeclarations);
|
||||
|
||||
synchronizeDirectoryInfos(package.directoryInfos, package.updatedProjectSourceIds);
|
||||
synchronizeDirectoryInfos(package.directoryInfos, package.updatedDirectoryInfoSourceIds);
|
||||
|
||||
commonTypeCache_.resetTypeIds();
|
||||
});
|
||||
@@ -2116,7 +2123,7 @@ FileStatus ProjectStorage::fetchFileStatus(SourceId sourceId) const
|
||||
std::optional<Storage::Synchronization::DirectoryInfo> ProjectStorage::fetchDirectoryInfo(SourceId sourceId) const
|
||||
{
|
||||
using NanotraceHR::keyValue;
|
||||
NanotraceHR::Tracer tracer{"fetch project data"_t,
|
||||
NanotraceHR::Tracer tracer{"fetch directory info"_t,
|
||||
projectStorageCategory(),
|
||||
keyValue("source id", sourceId)};
|
||||
|
||||
@@ -2124,7 +2131,7 @@ std::optional<Storage::Synchronization::DirectoryInfo> ProjectStorage::fetchDire
|
||||
.optionalValueWithTransaction<Storage::Synchronization::DirectoryInfo>(
|
||||
sourceId);
|
||||
|
||||
tracer.end(keyValue("project data", directoryInfo));
|
||||
tracer.end(keyValue("directory info", directoryInfo));
|
||||
|
||||
return directoryInfo;
|
||||
}
|
||||
@@ -2132,7 +2139,7 @@ std::optional<Storage::Synchronization::DirectoryInfo> ProjectStorage::fetchDire
|
||||
Storage::Synchronization::DirectoryInfos ProjectStorage::fetchDirectoryInfos(SourceId directorySourceId) const
|
||||
{
|
||||
using NanotraceHR::keyValue;
|
||||
NanotraceHR::Tracer tracer{"fetch project datas by source id"_t,
|
||||
NanotraceHR::Tracer tracer{"fetch directory infos by source id"_t,
|
||||
projectStorageCategory(),
|
||||
keyValue("source id", directorySourceId)};
|
||||
|
||||
@@ -2140,7 +2147,25 @@ Storage::Synchronization::DirectoryInfos ProjectStorage::fetchDirectoryInfos(Sou
|
||||
.valuesWithTransaction<Storage::Synchronization::DirectoryInfo, 1024>(
|
||||
directorySourceId);
|
||||
|
||||
tracer.end(keyValue("project datas", directoryInfos));
|
||||
tracer.end(keyValue("directory infos", directoryInfos));
|
||||
|
||||
return directoryInfos;
|
||||
}
|
||||
|
||||
Storage::Synchronization::DirectoryInfos ProjectStorage::fetchDirectoryInfos(
|
||||
SourceId directorySourceId, Storage::Synchronization::FileType fileType) const
|
||||
{
|
||||
using NanotraceHR::keyValue;
|
||||
NanotraceHR::Tracer tracer{"fetch directory infos by source id and file type"_t,
|
||||
projectStorageCategory(),
|
||||
keyValue("source id", directorySourceId),
|
||||
keyValue("file type", fileType)};
|
||||
|
||||
auto directoryInfos = s->selectDirectoryInfosForSourceIdAndFileTypeStatement
|
||||
.valuesWithTransaction<Storage::Synchronization::DirectoryInfo, 16>(
|
||||
directorySourceId, fileType);
|
||||
|
||||
tracer.end(keyValue("directory infos", directoryInfos));
|
||||
|
||||
return directoryInfos;
|
||||
}
|
||||
@@ -2149,7 +2174,7 @@ Storage::Synchronization::DirectoryInfos ProjectStorage::fetchDirectoryInfos(
|
||||
const SourceIds &directorySourceIds) const
|
||||
{
|
||||
using NanotraceHR::keyValue;
|
||||
NanotraceHR::Tracer tracer{"fetch project datas by source ids"_t,
|
||||
NanotraceHR::Tracer tracer{"fetch directory infos by source ids"_t,
|
||||
projectStorageCategory(),
|
||||
keyValue("source ids", directorySourceIds)};
|
||||
|
||||
@@ -2157,11 +2182,27 @@ Storage::Synchronization::DirectoryInfos ProjectStorage::fetchDirectoryInfos(
|
||||
.valuesWithTransaction<Storage::Synchronization::DirectoryInfo, 64>(
|
||||
toIntegers(directorySourceIds));
|
||||
|
||||
tracer.end(keyValue("project datas", directoryInfos));
|
||||
tracer.end(keyValue("directory infos", directoryInfos));
|
||||
|
||||
return directoryInfos;
|
||||
}
|
||||
|
||||
SmallSourceIds<32> ProjectStorage::fetchSubdirectorySourceIds(SourceId directorySourceId) const
|
||||
{
|
||||
using NanotraceHR::keyValue;
|
||||
NanotraceHR::Tracer tracer{"fetch subdirectory source ids"_t,
|
||||
projectStorageCategory(),
|
||||
keyValue("source id", directorySourceId)};
|
||||
|
||||
auto sourceIds = s->selectDirectoryInfosSourceIdsForSourceIdAndFileTypeStatement
|
||||
.valuesWithTransaction<SmallSourceIds<32>>(
|
||||
directorySourceId, Storage::Synchronization::FileType::Directory);
|
||||
|
||||
tracer.end(keyValue("source ids", sourceIds));
|
||||
|
||||
return sourceIds;
|
||||
}
|
||||
|
||||
void ProjectStorage::setPropertyEditorPathId(TypeId typeId, SourceId pathId)
|
||||
{
|
||||
Sqlite::ImmediateSessionTransaction transaction{database};
|
||||
@@ -2466,9 +2507,9 @@ void ProjectStorage::synchronizeTypes(Storage::Synchronization::Types &types,
|
||||
}
|
||||
|
||||
void ProjectStorage::synchronizeDirectoryInfos(Storage::Synchronization::DirectoryInfos &directoryInfos,
|
||||
const SourceIds &updatedProjectSourceIds)
|
||||
const SourceIds &updatedDirectoryInfoSourceIds)
|
||||
{
|
||||
NanotraceHR::Tracer tracer{"synchronize project datas"_t, projectStorageCategory()};
|
||||
NanotraceHR::Tracer tracer{"synchronize directory infos"_t, projectStorageCategory()};
|
||||
|
||||
auto compareKey = [](auto &&first, auto &&second) {
|
||||
auto directorySourceIdDifference = first.directorySourceId - second.directorySourceId;
|
||||
@@ -2484,13 +2525,13 @@ void ProjectStorage::synchronizeDirectoryInfos(Storage::Synchronization::Directo
|
||||
});
|
||||
|
||||
auto range = s->selectDirectoryInfosForSourceIdsStatement.range<Storage::Synchronization::DirectoryInfo>(
|
||||
toIntegers(updatedProjectSourceIds));
|
||||
toIntegers(updatedDirectoryInfoSourceIds));
|
||||
|
||||
auto insert = [&](const Storage::Synchronization::DirectoryInfo &directoryInfo) {
|
||||
using NanotraceHR::keyValue;
|
||||
NanotraceHR::Tracer tracer{"insert project data"_t,
|
||||
NanotraceHR::Tracer tracer{"insert directory info"_t,
|
||||
projectStorageCategory(),
|
||||
keyValue("project data", directoryInfo)};
|
||||
keyValue("directory info", directoryInfo)};
|
||||
|
||||
if (!directoryInfo.directorySourceId)
|
||||
throw DirectoryInfoHasInvalidProjectSourceId{};
|
||||
@@ -2508,10 +2549,11 @@ void ProjectStorage::synchronizeDirectoryInfos(Storage::Synchronization::Directo
|
||||
if (directoryInfoFromDatabase.fileType != directoryInfo.fileType
|
||||
|| !compareInvalidAreTrue(directoryInfoFromDatabase.moduleId, directoryInfo.moduleId)) {
|
||||
using NanotraceHR::keyValue;
|
||||
NanotraceHR::Tracer tracer{"update project data"_t,
|
||||
NanotraceHR::Tracer tracer{"update directory info"_t,
|
||||
projectStorageCategory(),
|
||||
keyValue("project data", directoryInfo),
|
||||
keyValue("project data from database", directoryInfoFromDatabase)};
|
||||
keyValue("directory info", directoryInfo),
|
||||
keyValue("directory info from database",
|
||||
directoryInfoFromDatabase)};
|
||||
|
||||
s->updateDirectoryInfoStatement.write(directoryInfo.directorySourceId,
|
||||
directoryInfo.sourceId,
|
||||
@@ -2525,9 +2567,9 @@ void ProjectStorage::synchronizeDirectoryInfos(Storage::Synchronization::Directo
|
||||
|
||||
auto remove = [&](const Storage::Synchronization::DirectoryInfo &directoryInfo) {
|
||||
using NanotraceHR::keyValue;
|
||||
NanotraceHR::Tracer tracer{"remove project data"_t,
|
||||
NanotraceHR::Tracer tracer{"remove directory info"_t,
|
||||
projectStorageCategory(),
|
||||
keyValue("project data", directoryInfo)};
|
||||
keyValue("directory info", directoryInfo)};
|
||||
|
||||
s->deleteDirectoryInfoStatement.write(directoryInfo.directorySourceId, directoryInfo.sourceId);
|
||||
};
|
||||
|
||||
@@ -232,8 +232,10 @@ public:
|
||||
std::optional<Storage::Synchronization::DirectoryInfo> fetchDirectoryInfo(SourceId sourceId) const override;
|
||||
|
||||
Storage::Synchronization::DirectoryInfos fetchDirectoryInfos(SourceId directorySourceId) const override;
|
||||
|
||||
Storage::Synchronization::DirectoryInfos fetchDirectoryInfos(
|
||||
SourceId directorySourceId, Storage::Synchronization::FileType fileType) const override;
|
||||
Storage::Synchronization::DirectoryInfos fetchDirectoryInfos(const SourceIds &directorySourceIds) const;
|
||||
SmallSourceIds<32> fetchSubdirectorySourceIds(SourceId directorySourceId) const override;
|
||||
|
||||
void setPropertyEditorPathId(TypeId typeId, SourceId pathId);
|
||||
|
||||
@@ -561,7 +563,7 @@ private:
|
||||
const SourceIds &updatedSourceIds);
|
||||
|
||||
void synchronizeDirectoryInfos(Storage::Synchronization::DirectoryInfos &directoryInfos,
|
||||
const SourceIds &updatedProjectSourceIds);
|
||||
const SourceIds &updatedDirectoryInfoSourceIds);
|
||||
|
||||
void synchronizeFileStatuses(FileStatuses &fileStatuses, const SourceIds &updatedSourceIds);
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#include <sqlite/sqlitevalue.h>
|
||||
#include <utils/smallstring.h>
|
||||
|
||||
#include <QVarLengthArray>
|
||||
|
||||
#include <array>
|
||||
#include <tuple>
|
||||
#include <variant>
|
||||
@@ -15,6 +17,9 @@
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
template<std::size_t size>
|
||||
using SmallPathStrings = QVarLengthArray<Utils::PathString, size>;
|
||||
|
||||
template<typename Enumeration>
|
||||
constexpr std::underlying_type_t<Enumeration> to_underlying(Enumeration enumeration) noexcept
|
||||
{
|
||||
|
||||
@@ -81,7 +81,11 @@ public:
|
||||
|
||||
virtual FileStatus fetchFileStatus(SourceId sourceId) const = 0;
|
||||
virtual Storage::Synchronization::DirectoryInfos fetchDirectoryInfos(SourceId sourceId) const = 0;
|
||||
virtual Storage::Synchronization::DirectoryInfos fetchDirectoryInfos(
|
||||
SourceId directorySourceId, Storage::Synchronization::FileType) const
|
||||
= 0;
|
||||
virtual std::optional<Storage::Synchronization::DirectoryInfo> fetchDirectoryInfo(SourceId sourceId) const = 0;
|
||||
virtual SmallSourceIds<32> fetchSubdirectorySourceIds(SourceId directorySourceId) const = 0;
|
||||
|
||||
virtual SourceId propertyEditorPathId(TypeId typeId) const = 0;
|
||||
virtual const Storage::Info::CommonTypeCache<ProjectStorageType> &commonTypeCache() const = 0;
|
||||
|
||||
@@ -82,7 +82,7 @@ void convertToString(String &string, const TypeNameKind &kind)
|
||||
}
|
||||
}
|
||||
|
||||
enum class FileType : char { QmlTypes, QmlDocument };
|
||||
enum class FileType : char { QmlTypes, QmlDocument, Directory };
|
||||
|
||||
template<typename String>
|
||||
void convertToString(String &string, const FileType &type)
|
||||
@@ -94,6 +94,9 @@ void convertToString(String &string, const FileType &type)
|
||||
case FileType::QmlDocument:
|
||||
convertToString(string, "QmlDocument");
|
||||
break;
|
||||
case FileType::Directory:
|
||||
convertToString(string, "Directory");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1291,9 +1294,9 @@ public:
|
||||
, fileStatuses(std::move(fileStatuses))
|
||||
{}
|
||||
|
||||
SynchronizationPackage(SourceIds updatedProjectSourceIds, DirectoryInfos directoryInfos)
|
||||
SynchronizationPackage(SourceIds updatedDirectoryInfoSourceIds, DirectoryInfos directoryInfos)
|
||||
: directoryInfos(std::move(directoryInfos))
|
||||
, updatedProjectSourceIds(std::move(updatedProjectSourceIds))
|
||||
, updatedDirectoryInfoSourceIds(std::move(updatedDirectoryInfoSourceIds))
|
||||
{}
|
||||
|
||||
public:
|
||||
@@ -1303,7 +1306,7 @@ public:
|
||||
SourceIds updatedFileStatusSourceIds;
|
||||
FileStatuses fileStatuses;
|
||||
DirectoryInfos directoryInfos;
|
||||
SourceIds updatedProjectSourceIds;
|
||||
SourceIds updatedDirectoryInfoSourceIds;
|
||||
Imports moduleDependencies;
|
||||
SourceIds updatedModuleDependencySourceIds;
|
||||
ModuleExportedImports moduleExportedImports;
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
#include "sourcepathcache.h"
|
||||
#include "typeannotationreader.h"
|
||||
|
||||
#include <tracing/qmldesignertracing.h>
|
||||
|
||||
#include <sqlitedatabase.h>
|
||||
#include <tracing/qmldesignertracing.h>
|
||||
#include <utils/set_algorithm.h>
|
||||
|
||||
#include <QDirIterator>
|
||||
#include <QRegularExpression>
|
||||
@@ -102,6 +102,8 @@ ProjectStorageUpdater::Components createComponents(
|
||||
}
|
||||
|
||||
for (const QmlDirParser::Component &qmlDirParserComponent : qmlDirParserComponents) {
|
||||
if (qmlDirParserComponent.fileName.contains('/'))
|
||||
continue;
|
||||
components.push_back(ProjectStorageUpdater::Component{qmlDirParserComponent.fileName,
|
||||
qmlDirParserComponent.typeName,
|
||||
moduleId,
|
||||
@@ -285,6 +287,8 @@ void ProjectStorageUpdater::update(QStringList directories,
|
||||
|
||||
try {
|
||||
m_projectStorage.synchronize(std::move(package));
|
||||
} catch (const TypeNameDoesNotExists &exception) {
|
||||
qDebug() << "missing type: " << exception.what();
|
||||
} catch (...) {
|
||||
qWarning() << "Project storage could not been updated!";
|
||||
}
|
||||
@@ -323,7 +327,7 @@ void ProjectStorageUpdater::updateQmlTypes(const QStringList &qmlTypesPaths,
|
||||
tracer.tick("append project data"_t, keyValue("project data", directoryInfo));
|
||||
package.directoryInfos.push_back(std::move(directoryInfo));
|
||||
tracer.tick("append updated project source ids"_t, keyValue("source id", sourceId));
|
||||
package.updatedProjectSourceIds.push_back(sourceId);
|
||||
package.updatedDirectoryInfoSourceIds.push_back(sourceId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -409,7 +413,7 @@ void ProjectStorageUpdater::updateDirectoryChanged(std::string_view directoryPat
|
||||
watchedSourceIdsIds,
|
||||
qmldirState);
|
||||
tracer.tick("append updated project source id"_t, keyValue("module id", moduleId));
|
||||
package.updatedProjectSourceIds.push_back(directorySourceId);
|
||||
package.updatedDirectoryInfoSourceIds.push_back(directorySourceId);
|
||||
}
|
||||
|
||||
void ProjectStorageUpdater::updateDirectories(const QStringList &directories,
|
||||
@@ -420,10 +424,111 @@ void ProjectStorageUpdater::updateDirectories(const QStringList &directories,
|
||||
NanotraceHR::Tracer tracer{"update directories"_t, category()};
|
||||
|
||||
for (const QString &directory : directories)
|
||||
updateDirectory({directory}, package, notUpdatedSourceIds, watchedSourceIdsIds);
|
||||
updateDirectory({directory}, {}, package, notUpdatedSourceIds, watchedSourceIdsIds);
|
||||
}
|
||||
|
||||
void ProjectStorageUpdater::updateSubdirectories(const Utils::PathString &directoryPath,
|
||||
SourceId directorySourceId,
|
||||
FileState directoryState,
|
||||
const SourceContextIds &subdirectoriesToIgnore,
|
||||
Storage::Synchronization::SynchronizationPackage &package,
|
||||
NotUpdatedSourceIds ¬UpdatedSourceIds,
|
||||
WatchedSourceIdsIds &watchedSourceIdsIds)
|
||||
{
|
||||
struct Directory
|
||||
{
|
||||
Directory(Utils::SmallStringView path, SourceContextId sourceContextId, SourceId sourceId)
|
||||
: path{path}
|
||||
, sourceContextId{sourceContextId}
|
||||
, sourceId{sourceId}
|
||||
{}
|
||||
|
||||
bool operator<(const Directory &other) const
|
||||
{
|
||||
return sourceContextId < other.sourceContextId;
|
||||
}
|
||||
|
||||
bool operator==(const Directory &other) const
|
||||
{
|
||||
return sourceContextId == other.sourceContextId;
|
||||
}
|
||||
|
||||
Utils::PathString path;
|
||||
SourceContextId sourceContextId;
|
||||
SourceId sourceId;
|
||||
};
|
||||
|
||||
struct Compare
|
||||
{
|
||||
bool operator()(const Directory &first, const Directory &second) const
|
||||
{
|
||||
return first.sourceContextId < second.sourceContextId;
|
||||
}
|
||||
|
||||
bool operator()(const Directory &first, SourceContextId second) const
|
||||
{
|
||||
return first.sourceContextId < second;
|
||||
}
|
||||
|
||||
bool operator()(SourceContextId first, const Directory &second) const
|
||||
{
|
||||
return first < second.sourceContextId;
|
||||
}
|
||||
};
|
||||
|
||||
using Directories = QVarLengthArray<Directory, 32>;
|
||||
|
||||
auto subdirectorySourceIds = m_projectStorage.fetchSubdirectorySourceIds(directorySourceId);
|
||||
auto subdirectories = Utils::transform<Directories>(
|
||||
subdirectorySourceIds, [&](SourceId sourceId) -> Directory {
|
||||
auto sourceContextId = m_pathCache.sourceContextId(sourceId);
|
||||
auto subdirectoryPath = m_pathCache.sourceContextPath(sourceContextId);
|
||||
return {subdirectoryPath, sourceContextId, sourceId};
|
||||
});
|
||||
|
||||
auto exisitingSubdirectoryPaths = m_fileSystem.subdirectories(directoryPath.toQString());
|
||||
Directories existingSubdirecories;
|
||||
for (const QString &subdirectory : exisitingSubdirectoryPaths) {
|
||||
if (subdirectory.endsWith("/designer") || subdirectory.endsWith("/QtQuick/Scene2D")
|
||||
|| subdirectory.endsWith("/QtQuick/Scene3D"))
|
||||
continue;
|
||||
Utils::PathString subdirectoryPath = subdirectory;
|
||||
auto [sourceContextId, sourceId] = m_pathCache.sourceContextAndSourceId(
|
||||
SourcePath{subdirectoryPath + "/."});
|
||||
subdirectories.emplace_back(subdirectoryPath, sourceContextId, sourceId);
|
||||
existingSubdirecories.emplace_back(subdirectoryPath, sourceContextId, sourceId);
|
||||
}
|
||||
|
||||
std::sort(subdirectories.begin(), subdirectories.end());
|
||||
subdirectories.erase(std::unique(subdirectories.begin(), subdirectories.end()),
|
||||
subdirectories.end());
|
||||
|
||||
std::set_difference(subdirectories.begin(),
|
||||
subdirectories.end(),
|
||||
subdirectoriesToIgnore.begin(),
|
||||
subdirectoriesToIgnore.end(),
|
||||
Utils::make_iterator([&](const Directory &subdirectory) {
|
||||
updateDirectory(subdirectory.path,
|
||||
subdirectoriesToIgnore,
|
||||
package,
|
||||
notUpdatedSourceIds,
|
||||
watchedSourceIdsIds);
|
||||
}),
|
||||
Compare{});
|
||||
|
||||
if (directoryState == FileState::Changed) {
|
||||
for (const auto &[subdirectoryPath, sourceContextId, subdirectorySourceId] :
|
||||
existingSubdirecories) {
|
||||
package.directoryInfos.emplace_back(directorySourceId,
|
||||
subdirectorySourceId,
|
||||
ModuleId{},
|
||||
Storage::Synchronization::FileType::Directory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectStorageUpdater::updateDirectory(const Utils::PathString &directoryPath,
|
||||
const SourceContextIds &subdirectoriesToIgnore,
|
||||
Storage::Synchronization::SynchronizationPackage &package,
|
||||
NotUpdatedSourceIds ¬UpdatedSourceIds,
|
||||
WatchedSourceIdsIds &watchedSourceIdsIds)
|
||||
@@ -472,7 +577,7 @@ void ProjectStorageUpdater::updateDirectory(const Utils::PathString &directoryPa
|
||||
|
||||
package.updatedFileStatusSourceIds.push_back(directorySourceId);
|
||||
package.updatedFileStatusSourceIds.push_back(qmldirSourceId);
|
||||
package.updatedProjectSourceIds.push_back(directorySourceId);
|
||||
package.updatedDirectoryInfoSourceIds.push_back(directorySourceId);
|
||||
package.updatedSourceIds.push_back(qmldirSourceId);
|
||||
auto qmlDirectoryInfos = m_projectStorage.fetchDirectoryInfos(directorySourceId);
|
||||
for (const Storage::Synchronization::DirectoryInfo &directoryInfo : qmlDirectoryInfos) {
|
||||
@@ -487,6 +592,14 @@ void ProjectStorageUpdater::updateDirectory(const Utils::PathString &directoryPa
|
||||
}
|
||||
}
|
||||
|
||||
updateSubdirectories(directoryPath,
|
||||
directorySourceId,
|
||||
directoryState,
|
||||
subdirectoriesToIgnore,
|
||||
package,
|
||||
notUpdatedSourceIds,
|
||||
watchedSourceIdsIds);
|
||||
|
||||
tracer.end(keyValue("qmldir source path", qmldirSourcePath),
|
||||
keyValue("directory source path", directorySourcePath),
|
||||
keyValue("directory id", directoryId),
|
||||
@@ -788,7 +901,11 @@ void ProjectStorageUpdater::pathsWithIdsChanged(const std::vector<IdPaths> &chan
|
||||
|
||||
for (auto sourceContextId : directorySourceContextIds) {
|
||||
Utils::PathString directory = m_pathCache.sourceContextPath(sourceContextId);
|
||||
updateDirectory(directory, package, notUpdatedSourceIds, watchedSourceIds);
|
||||
updateDirectory(directory,
|
||||
directorySourceContextIds,
|
||||
package,
|
||||
notUpdatedSourceIds,
|
||||
watchedSourceIds);
|
||||
}
|
||||
|
||||
for (SourceId sourceId : filterUniqueSourceIds(qmlDocumentSourceIds)) {
|
||||
@@ -867,7 +984,7 @@ void ProjectStorageUpdater::parseTypeInfos(const QStringList &typeInfos,
|
||||
tracer.tick("append module dependenct source source id"_t, keyValue("source id", sourceId));
|
||||
package.updatedModuleDependencySourceIds.push_back(sourceId);
|
||||
|
||||
auto directoryInfo = package.directoryInfos.emplace_back(
|
||||
const auto &directoryInfo = package.directoryInfos.emplace_back(
|
||||
directorySourceId, sourceId, moduleId, Storage::Synchronization::FileType::QmlTypes);
|
||||
tracer.tick("append project data"_t, keyValue("source id", sourceId));
|
||||
|
||||
@@ -898,6 +1015,8 @@ void ProjectStorageUpdater::parseDirectoryInfos(
|
||||
parseQmlComponent(directoryInfo.sourceId, package, notUpdatedSourceIds);
|
||||
break;
|
||||
}
|
||||
case Storage::Synchronization::FileType::Directory:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,9 +143,17 @@ private:
|
||||
WatchedSourceIdsIds &watchedSourceIdsIds);
|
||||
|
||||
void updateDirectory(const Utils::PathString &directory,
|
||||
const SourceContextIds &subdirecoriesToIgnore,
|
||||
Storage::Synchronization::SynchronizationPackage &package,
|
||||
NotUpdatedSourceIds ¬UpdatedSourceIds,
|
||||
WatchedSourceIdsIds &watchedSourceIdsIds);
|
||||
void updateSubdirectories(const Utils::PathString &directory,
|
||||
SourceId directorySourceId,
|
||||
FileState directoryFileState,
|
||||
const SourceContextIds &subdirecoriesToIgnore,
|
||||
Storage::Synchronization::SynchronizationPackage &package,
|
||||
NotUpdatedSourceIds ¬UpdatedSourceIds,
|
||||
WatchedSourceIdsIds &watchedSourceIdsIds);
|
||||
void updateDirectoryChanged(std::string_view directoryPath,
|
||||
FileState qmldirState,
|
||||
SourcePath qmldirSourcePath,
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#include <utils/smallstring.h>
|
||||
|
||||
#include <QVarLengthArray>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class SourcePath : public Utils::PathString
|
||||
@@ -128,5 +130,6 @@ private:
|
||||
};
|
||||
|
||||
using SourcePaths = std::vector<SourcePath>;
|
||||
|
||||
template<std::size_t size>
|
||||
using SmallSourcePaths = QVarLengthArray<SourcePath, size>;
|
||||
} // namespace QmlDesigner
|
||||
|
||||
@@ -341,81 +341,32 @@ Utils::FilePath qmlPath(::ProjectExplorer::Target *target)
|
||||
return {};
|
||||
}
|
||||
|
||||
template<typename... Path>
|
||||
bool skipDirectoriesWith(const QStringView directoryPath, const Path &...paths)
|
||||
{
|
||||
return (directoryPath.contains(paths) || ...);
|
||||
}
|
||||
|
||||
template<typename... Path>
|
||||
bool skipDirectoriesEndsWith(const QStringView directoryPath, const Path &...paths)
|
||||
{
|
||||
return (directoryPath.endsWith(paths) || ...);
|
||||
}
|
||||
|
||||
bool skipPath(const QString &directoryPath)
|
||||
{
|
||||
return skipDirectoriesWith(directoryPath,
|
||||
u"QtApplicationManager",
|
||||
u"QtInterfaceFramework",
|
||||
u"QtOpcUa",
|
||||
u"Qt3D",
|
||||
u"Scene2D",
|
||||
u"Scene3D",
|
||||
u"QtWayland",
|
||||
u"Qt5Compat",
|
||||
u"QtCharts",
|
||||
u"QtLocation",
|
||||
u"QtPositioning",
|
||||
u"MaterialEditor",
|
||||
u"QtTextToSpeech",
|
||||
u"QtWebEngine",
|
||||
u"Qt/labs",
|
||||
u"QtDataVisualization")
|
||||
|| skipDirectoriesEndsWith(directoryPath, u"designer");
|
||||
}
|
||||
|
||||
void collectQmldirPaths(const QString &path, QStringList &qmldirPaths)
|
||||
{
|
||||
QDirIterator dirIterator{path, QDir::Dirs | QDir::NoDotAndDotDot, QDirIterator::Subdirectories};
|
||||
|
||||
QString rootQmldirPath = path + "/qmldir";
|
||||
if (!skipPath(path) && QFileInfo::exists(rootQmldirPath))
|
||||
qmldirPaths.push_back(path);
|
||||
|
||||
while (dirIterator.hasNext()) {
|
||||
auto directoryPath = dirIterator.next();
|
||||
|
||||
QString qmldirPath = directoryPath + "/qmldir";
|
||||
if (!skipPath(directoryPath) && QFileInfo::exists(qmldirPath))
|
||||
qmldirPaths.push_back(directoryPath);
|
||||
}
|
||||
}
|
||||
|
||||
[[maybe_unused]] void projectQmldirPaths(::ProjectExplorer::Target *target, QStringList &qmldirPaths)
|
||||
{
|
||||
::QmlProjectManager::QmlBuildSystem *buildSystem = getQmlBuildSystem(target);
|
||||
|
||||
const Utils::FilePath projectDirectoryPath = buildSystem->canonicalProjectDir();
|
||||
const QStringList importPaths = buildSystem->importPaths();
|
||||
const QDir projectDirectory(projectDirectoryPath.toString());
|
||||
|
||||
for (const QString &importPath : importPaths)
|
||||
collectQmldirPaths(importPath, qmldirPaths);
|
||||
qmldirPaths.push_back(projectDirectoryPath.path());
|
||||
}
|
||||
|
||||
[[maybe_unused]] void qtQmldirPaths(::ProjectExplorer::Target *target, QStringList &qmldirPaths)
|
||||
{
|
||||
if constexpr (useProjectStorage())
|
||||
collectQmldirPaths(qmlPath(target).toString(), qmldirPaths);
|
||||
if constexpr (useProjectStorage()) {
|
||||
auto qmlRootPath = qmlPath(target).toString();
|
||||
qmldirPaths.push_back(qmlRootPath + "/QtQml");
|
||||
qmldirPaths.push_back(qmlRootPath + "/QtQuick");
|
||||
qmldirPaths.push_back(qmlRootPath + "/QtQuick3D");
|
||||
qmldirPaths.push_back(qmlRootPath + "/Qt5Compat");
|
||||
}
|
||||
}
|
||||
|
||||
[[maybe_unused]] void qtQmldirPathsForLiteDesigner(QStringList &qmldirPaths)
|
||||
{
|
||||
if constexpr (useProjectStorage()) {
|
||||
auto qmlRootPath = QLibraryInfo::path(QLibraryInfo::QmlImportsPath);
|
||||
collectQmldirPaths(qmlRootPath + "/QtQml", qmldirPaths);
|
||||
collectQmldirPaths(qmlRootPath + "/QtQuick", qmldirPaths);
|
||||
qmldirPaths.push_back(qmlRootPath + "/QtQml");
|
||||
qmldirPaths.push_back(qmlRootPath + "/QtQuick");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user