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:
Marco Bubke
2024-05-06 17:02:32 +02:00
parent fd2c7db691
commit f296f9d77c
19 changed files with 566 additions and 125 deletions

View File

@@ -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>;

View File

@@ -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)

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);
};

View File

@@ -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);

View File

@@ -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
{

View File

@@ -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;

View File

@@ -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;

View File

@@ -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 &notUpdatedSourceIds,
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 &notUpdatedSourceIds,
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;
}
}
}

View File

@@ -143,9 +143,17 @@ private:
WatchedSourceIdsIds &watchedSourceIdsIds);
void updateDirectory(const Utils::PathString &directory,
const SourceContextIds &subdirecoriesToIgnore,
Storage::Synchronization::SynchronizationPackage &package,
NotUpdatedSourceIds &notUpdatedSourceIds,
WatchedSourceIdsIds &watchedSourceIdsIds);
void updateSubdirectories(const Utils::PathString &directory,
SourceId directorySourceId,
FileState directoryFileState,
const SourceContextIds &subdirecoriesToIgnore,
Storage::Synchronization::SynchronizationPackage &package,
NotUpdatedSourceIds &notUpdatedSourceIds,
WatchedSourceIdsIds &watchedSourceIdsIds);
void updateDirectoryChanged(std::string_view directoryPath,
FileState qmldirState,
SourcePath qmldirSourcePath,

View File

@@ -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

View File

@@ -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");
}
}