QmlDesigner: Add tracing for project storage updater

Change-Id: I4579a256e4402a045d906a36940582b8e0ff196b
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
This commit is contained in:
Marco Bubke
2024-03-20 12:10:41 +01:00
committed by Tim Jenssen
parent 12785d4eee
commit c76c90b601
10 changed files with 443 additions and 104 deletions

View File

@@ -3491,7 +3491,7 @@ private:
NanotraceHR::Tracer tracer{"fetch imported type name id"_t,
projectStorageCategory(),
keyValue("imported type name", typeName),
keyValue("kind", to_underlying(kind))};
keyValue("kind", kind)};
auto importedTypeNameId = selectImportedTypeNameIdStatement
.template value<ImportedTypeNameId>(kind, id, typeName);
@@ -3517,7 +3517,7 @@ private:
auto typeId = fetchTypeId(typeNameId, kind);
tracer.end(keyValue("type id", typeId), keyValue("type name kind", to_underlying(kind)));
tracer.end(keyValue("type id", typeId), keyValue("type name kind", kind));
return typeId;
}
@@ -3533,7 +3533,7 @@ private:
NanotraceHR::Tracer tracer{"fetch type id"_t,
projectStorageCategory(),
keyValue("type name id", typeNameId),
keyValue("type name kind", to_underlying(kind))};
keyValue("type name kind", kind)};
TypeId typeId;
if (kind == Storage::Synchronization::TypeNameKind::Exported) {
@@ -3566,7 +3566,7 @@ private:
using NanotraceHR::keyValue;
auto dict = dictonary(keyValue("property type id", result.propertyTypeId),
keyValue("property declaration id", result.propertyDeclarationId),
keyValue("property traits", to_underlying(result.propertyTraits)));
keyValue("property traits", result.propertyTraits));
convertToString(string, dict);
}

View File

@@ -12,6 +12,28 @@ namespace QmlDesigner {
enum class SourceType : int { Qml, QmlUi, QmlTypes, QmlDir, Directory };
template<typename String>
void convertToString(String &string, SourceType sourceType)
{
switch (sourceType) {
case SourceType::Qml:
convertToString(string, "Qml");
break;
case SourceType::QmlUi:
convertToString(string, "QmlUi");
break;
case SourceType::QmlTypes:
convertToString(string, "QmlTypes");
break;
case SourceType::QmlDir:
convertToString(string, "QmlDir");
break;
case SourceType::Directory:
convertToString(string, "Directory");
break;
}
}
class ProjectChunkId
{
public:
@@ -46,6 +68,17 @@ public:
friend bool operator<(ProjectChunkId first, ProjectPartId second) { return first.id < second; }
friend bool operator<(ProjectPartId first, ProjectChunkId second) { return first < second.id; }
template<typename String>
friend void convertToString(String &string, const ProjectChunkId &id)
{
using NanotraceHR::dictonary;
using NanotraceHR::keyValue;
auto dict = dictonary(keyValue("project part id", id.id),
keyValue("source type", id.sourceType));
convertToString(string, dict);
}
};
using ProjectChunkIds = std::vector<ProjectChunkId>;
@@ -67,6 +100,16 @@ public:
return first.id == second.id && first.sourceIds == second.sourceIds;
}
template<typename String>
friend void convertToString(String &string, const IdPaths &idPaths)
{
using NanotraceHR::dictonary;
using NanotraceHR::keyValue;
auto dict = dictonary(keyValue("id", idPaths.id), keyValue("source ids", idPaths.sourceIds));
convertToString(string, dict);
}
public:
ProjectChunkId id;
SourceIds sourceIds;

View File

@@ -899,7 +899,7 @@ public:
keyValue("traits", propertyDeclaration.traits),
keyValue("type id", propertyDeclaration.typeId),
keyValue("property type id", propertyDeclaration.propertyTypeId),
keyValue("kind", to_underlying(propertyDeclaration.kind)));
keyValue("kind", propertyDeclaration.kind));
convertToString(string, dict);
}
@@ -1100,7 +1100,7 @@ public:
keyValue("enumeration declarations", type.enumerationDeclarations),
keyValue("traits", type.traits),
keyValue("source id", type.sourceId),
keyValue("change level", to_underlying(type.changeLevel)),
keyValue("change level", type.changeLevel),
keyValue("default property name", type.defaultPropertyName));
convertToString(string, dict);
@@ -1185,7 +1185,7 @@ public:
auto dict = dictonary(keyValue("project source id", projectData.projectSourceId),
keyValue("source id", projectData.sourceId),
keyValue("module id", projectData.moduleId),
keyValue("file type", to_underlying(projectData.fileType)));
keyValue("file type", projectData.fileType));
convertToString(string, dict);
}

View File

@@ -12,6 +12,8 @@
#include "sourcepath.h"
#include "sourcepathcache.h"
#include <tracing/qmldesignertracing.h>
#include <sqlitedatabase.h>
#include <QDirIterator>
@@ -21,6 +23,26 @@
#include <functional>
namespace QmlDesigner {
constexpr auto category = ProjectStorageTracing::projectStorageUpdaterCategory;
using NanotraceHR::keyValue;
using Tracer = ProjectStorageTracing::Category::TracerType;
template<typename String>
void convertToString(String &string, const ProjectStorageUpdater::FileState &state)
{
switch (state) {
case ProjectStorageUpdater::FileState::Changed:
convertToString(string, "Changed");
break;
case ProjectStorageUpdater::FileState::NotChanged:
convertToString(string, "NotChanged");
break;
case ProjectStorageUpdater::FileState::NotExists:
convertToString(string, "NotExists");
break;
}
}
namespace {
QStringList filterMultipleEntries(QStringList qmlTypes)
@@ -110,10 +132,15 @@ SourceIds filterNotUpdatedSourceIds(SourceIds updatedSourceIds, SourceIds notUpd
return filteredUpdatedSourceIds;
}
void addSourceIds(SourceIds &sourceIds, const Storage::Synchronization::ProjectDatas &projectDatas)
void addSourceIds(SourceIds &sourceIds,
const Storage::Synchronization::ProjectDatas &projectDatas,
TracerLiteral message,
Tracer &tracer)
{
for (const auto &projectData : projectDatas)
for (const auto &projectData : projectDatas) {
tracer.tick(message, keyValue("source id", projectData.sourceId));
sourceIds.push_back(projectData.sourceId);
}
}
Storage::Version convertVersion(LanguageUtils::ComponentVersion version)
@@ -131,34 +158,71 @@ Storage::Synchronization::IsAutoVersion convertToIsAutoVersion(QmlDirParser::Imp
void addDependencies(Storage::Imports &dependencies,
SourceId sourceId,
const QList<QmlDirParser::Import> &qmldirDependencies,
ProjectStorageInterface &projectStorage)
ProjectStorageInterface &projectStorage,
TracerLiteral message,
Tracer &tracer)
{
for (const QmlDirParser::Import &qmldirDependency : qmldirDependencies) {
ModuleId moduleId = projectStorage.moduleId(Utils::PathString{qmldirDependency.module}
+ "-cppnative");
dependencies.emplace_back(moduleId, Storage::Version{}, sourceId);
auto &import = dependencies.emplace_back(moduleId, Storage::Version{}, sourceId);
tracer.tick(message, keyValue("import", import));
}
}
void addModuleExportedImport(Storage::Synchronization::ModuleExportedImports &imports,
ModuleId moduleId,
ModuleId exportedModuleId,
Storage::Version version,
Storage::Synchronization::IsAutoVersion isAutoVersion,
std::string_view moduleName,
std::string_view exportedModuleName)
{
NanotraceHR::Tracer tracer{"add module exported imports"_t,
category(),
keyValue("module id", moduleId),
keyValue("exported module id", exportedModuleId),
keyValue("version", version),
keyValue("is auto version", isAutoVersion),
keyValue("module name", moduleName),
keyValue("exported module name", exportedModuleName)};
imports.emplace_back(moduleId, exportedModuleId, version, isAutoVersion);
}
void addModuleExportedImports(Storage::Synchronization::ModuleExportedImports &imports,
ModuleId moduleId,
ModuleId cppModuleId,
std::string_view moduleName,
std::string_view cppModuleName,
const QList<QmlDirParser::Import> &qmldirImports,
ProjectStorageInterface &projectStorage)
{
for (const QmlDirParser::Import &qmldirImport : qmldirImports) {
ModuleId exportedModuleId = projectStorage.moduleId(Utils::PathString{qmldirImport.module});
imports.emplace_back(moduleId,
exportedModuleId,
convertVersion(qmldirImport.version),
convertToIsAutoVersion(qmldirImport.flags));
NanotraceHR::Tracer tracer{"add module exported imports"_t,
category(),
keyValue("cpp module id", cppModuleId),
keyValue("module id", moduleId)};
ModuleId exportedCppModuleId = projectStorage.moduleId(
Utils::PathString{qmldirImport.module} + "-cppnative");
imports.emplace_back(cppModuleId,
exportedCppModuleId,
Storage::Version{},
Storage::Synchronization::IsAutoVersion::No);
for (const QmlDirParser::Import &qmldirImport : qmldirImports) {
Utils::PathString exportedModuleName{qmldirImport.module};
ModuleId exportedModuleId = projectStorage.moduleId(exportedModuleName);
addModuleExportedImport(imports,
moduleId,
exportedModuleId,
convertVersion(qmldirImport.version),
convertToIsAutoVersion(qmldirImport.flags),
moduleName,
exportedModuleName);
exportedModuleName += "-cppnative";
ModuleId exportedCppModuleId = projectStorage.moduleId(exportedModuleName);
addModuleExportedImport(imports,
cppModuleId,
exportedCppModuleId,
Storage::Version{},
Storage::Synchronization::IsAutoVersion::No,
cppModuleName,
exportedModuleName);
}
}
@@ -184,6 +248,11 @@ void ProjectStorageUpdater::update(QStringList directories,
QStringList qmlTypesPaths,
const QString &propertyEditorResourcesPath)
{
NanotraceHR::Tracer tracer{"update"_t,
category(),
keyValue("directories", directories),
keyValue("qml types paths", qmlTypesPaths)};
Storage::Synchronization::SynchronizationPackage package;
WatchedSourceIdsIds watchedSourceIds{Utils::span{directories}.size()};
NotUpdatedSourceIds notUpdatedSourceIds{Utils::span{directories}.size()};
@@ -215,11 +284,16 @@ void ProjectStorageUpdater::updateQmlTypes(const QStringList &qmlTypesPaths,
if (qmlTypesPaths.empty())
return;
NanotraceHR::Tracer tracer{"update qmltypes file"_t, category()};
ModuleId moduleId = m_projectStorage.moduleId("QML-cppnative");
for (const QString &qmlTypesPath : qmlTypesPaths) {
SourceId sourceId = m_pathCache.sourceId(SourcePath{qmlTypesPath});
watchedSourceIdsIds.qmltypesSourceIds.push_back(sourceId);
tracer.tick("append watched qml types source id"_t,
keyValue("source id", sourceId),
keyValue("qml types path", qmlTypesPath));
Storage::Synchronization::ProjectData projectData{sourceId,
sourceId,
@@ -232,7 +306,9 @@ void ProjectStorageUpdater::updateQmlTypes(const QStringList &qmlTypesPaths,
notUpdatedSourceIds);
if (state == FileState::Changed) {
tracer.tick("append project data"_t, keyValue("project data", projectData));
package.projectDatas.push_back(std::move(projectData));
tracer.tick("append updated project source ids"_t, keyValue("source id", sourceId));
package.updatedProjectSourceIds.push_back(sourceId);
}
}
@@ -250,13 +326,86 @@ ProjectStorageUpdater::FileState combineState(FileStates... fileStates)
return ProjectStorageUpdater::FileState::NotExists;
}
} // namespace
void ProjectStorageUpdater::updateDirectoryChanged(std::string_view directoryPath,
FileState qmldirState,
SourcePath qmldirSourcePath,
SourceId qmldirSourceId,
SourceId directorySourceId,
SourceContextId directoryId,
Storage::Synchronization::SynchronizationPackage &package,
NotUpdatedSourceIds &notUpdatedSourceIds,
WatchedSourceIdsIds &watchedSourceIdsIds,
Tracer &tracer)
{
QmlDirParser parser;
if (qmldirState != FileState::NotExists)
parser.parse(m_fileSystem.contentAsQString(QString{qmldirSourcePath}));
if (qmldirState != FileState::NotChanged) {
tracer.tick("append updated source id"_t, keyValue("module id", qmldirSourceId));
package.updatedSourceIds.push_back(qmldirSourceId);
}
Utils::PathString moduleName{parser.typeNamespace()};
ModuleId moduleId = m_projectStorage.moduleId(moduleName);
Utils::PathString cppModuleName = moduleName + "-cppnative";
ModuleId cppModuleId = m_projectStorage.moduleId(cppModuleName);
ModuleId pathModuleId = m_projectStorage.moduleId(directoryPath);
auto imports = filterMultipleEntries(parser.imports());
addModuleExportedImports(package.moduleExportedImports,
moduleId,
cppModuleId,
moduleName,
cppModuleName,
imports,
m_projectStorage);
tracer.tick("append updated module id"_t, keyValue("module id", moduleId));
package.updatedModuleIds.push_back(moduleId);
const auto qmlProjectDatas = m_projectStorage.fetchProjectDatas(directorySourceId);
addSourceIds(package.updatedSourceIds, qmlProjectDatas, "append updated source id"_t, tracer);
addSourceIds(package.updatedFileStatusSourceIds,
qmlProjectDatas,
"append updated file status source id"_t,
tracer);
auto qmlTypes = filterMultipleEntries(parser.typeInfos());
if (!qmlTypes.isEmpty()) {
parseTypeInfos(qmlTypes,
filterMultipleEntries(parser.dependencies()),
imports,
directorySourceId,
directoryPath,
cppModuleId,
package,
notUpdatedSourceIds,
watchedSourceIdsIds);
}
parseQmlComponents(
createComponents(parser.components(), moduleId, pathModuleId, m_fileSystem, directoryPath),
directorySourceId,
directoryId,
package,
notUpdatedSourceIds,
watchedSourceIdsIds,
qmldirState);
tracer.tick("append updated project source id"_t, keyValue("module id", moduleId));
package.updatedProjectSourceIds.push_back(directorySourceId);
}
void ProjectStorageUpdater::updateDirectories(const QStringList &directories,
Storage::Synchronization::SynchronizationPackage &package,
NotUpdatedSourceIds &notUpdatedSourceIds,
WatchedSourceIdsIds &watchedSourceIdsIds)
{
NanotraceHR::Tracer tracer{"update directories"_t, category()};
for (const QString &directory : directories)
updateDirectory({directory}, package, notUpdatedSourceIds, watchedSourceIdsIds);
}
@@ -266,8 +415,10 @@ void ProjectStorageUpdater::updateDirectory(const Utils::PathString &directoryPa
NotUpdatedSourceIds &notUpdatedSourceIds,
WatchedSourceIdsIds &watchedSourceIdsIds)
{
NanotraceHR::Tracer tracer{"update directory"_t, category(), keyValue("directory", directoryPath)};
SourcePath qmldirSourcePath{directoryPath + "/qmldir"};
auto [directoryId, qmlDirSourceId] = m_pathCache.sourceContextAndSourceId(qmldirSourcePath);
auto [directoryId, qmldirSourceId] = m_pathCache.sourceContextAndSourceId(qmldirSourcePath);
SourcePath directorySourcePath{directoryPath + "/."};
auto directorySourceId = m_pathCache.sourceId(directorySourcePath);
@@ -275,62 +426,28 @@ void ProjectStorageUpdater::updateDirectory(const Utils::PathString &directoryPa
if (directoryState != FileState::NotExists)
watchedSourceIdsIds.directorySourceIds.push_back(directorySourceId);
auto qmldirState = fileState(qmlDirSourceId, package, notUpdatedSourceIds);
auto qmldirState = fileState(qmldirSourceId, package, notUpdatedSourceIds);
if (qmldirState != FileState::NotExists)
watchedSourceIdsIds.qmldirSourceIds.push_back(qmlDirSourceId);
watchedSourceIdsIds.qmldirSourceIds.push_back(qmldirSourceId);
switch (combineState(directoryState, qmldirState)) {
case FileState::Changed: {
QmlDirParser parser;
if (qmldirState != FileState::NotExists)
parser.parse(m_fileSystem.contentAsQString(QString{qmldirSourcePath}));
if (qmldirState != FileState::NotChanged)
package.updatedSourceIds.push_back(qmlDirSourceId);
Utils::PathString moduleName{parser.typeNamespace()};
ModuleId moduleId = m_projectStorage.moduleId(moduleName);
ModuleId cppModuleId = m_projectStorage.moduleId(moduleName + "-cppnative");
ModuleId pathModuleId = m_projectStorage.moduleId(directoryPath);
auto imports = filterMultipleEntries(parser.imports());
addModuleExportedImports(package.moduleExportedImports,
moduleId,
cppModuleId,
imports,
m_projectStorage);
package.updatedModuleIds.push_back(moduleId);
const auto qmlProjectDatas = m_projectStorage.fetchProjectDatas(directorySourceId);
addSourceIds(package.updatedSourceIds, qmlProjectDatas);
addSourceIds(package.updatedFileStatusSourceIds, qmlProjectDatas);
auto qmlTypes = filterMultipleEntries(parser.typeInfos());
if (!qmlTypes.isEmpty()) {
parseTypeInfos(qmlTypes,
filterMultipleEntries(parser.dependencies()),
imports,
directorySourceId,
directoryPath,
cppModuleId,
package,
notUpdatedSourceIds,
watchedSourceIdsIds);
}
parseQmlComponents(
createComponents(parser.components(), moduleId, pathModuleId, m_fileSystem, directoryPath),
directorySourceId,
directoryId,
package,
notUpdatedSourceIds,
watchedSourceIdsIds,
qmldirState);
package.updatedProjectSourceIds.push_back(directorySourceId);
tracer.tick("update directory changed"_t);
updateDirectoryChanged(directoryPath,
qmldirState,
qmldirSourcePath,
qmldirSourceId,
directorySourceId,
directoryId,
package,
notUpdatedSourceIds,
watchedSourceIdsIds,
tracer);
break;
}
case FileState::NotChanged: {
tracer.tick("update directory not changed"_t);
parseProjectDatas(m_projectStorage.fetchProjectDatas(directorySourceId),
package,
notUpdatedSourceIds,
@@ -338,19 +455,32 @@ void ProjectStorageUpdater::updateDirectory(const Utils::PathString &directoryPa
break;
}
case FileState::NotExists: {
tracer.tick("update directory don't exits"_t);
package.updatedFileStatusSourceIds.push_back(directorySourceId);
package.updatedFileStatusSourceIds.push_back(qmlDirSourceId);
package.updatedFileStatusSourceIds.push_back(qmldirSourceId);
package.updatedProjectSourceIds.push_back(directorySourceId);
package.updatedSourceIds.push_back(qmlDirSourceId);
package.updatedSourceIds.push_back(qmldirSourceId);
auto qmlProjectDatas = m_projectStorage.fetchProjectDatas(directorySourceId);
for (const Storage::Synchronization::ProjectData &projectData : qmlProjectDatas) {
tracer.tick("append updated source id"_t, keyValue("source id", projectData.sourceId));
package.updatedSourceIds.push_back(projectData.sourceId);
tracer.tick("append updated file status source id"_t,
keyValue("source id", projectData.sourceId));
package.updatedFileStatusSourceIds.push_back(projectData.sourceId);
}
break;
}
}
tracer.end(keyValue("qmldir source path", qmldirSourcePath),
keyValue("directory source path", directorySourcePath),
keyValue("directory id", directoryId),
keyValue("qmldir source id", qmldirSourceId),
keyValue("directory source source id", directorySourceId),
keyValue("qmldir state", qmldirState),
keyValue("directory state", directoryState));
}
void ProjectStorageUpdater::updatePropertyEditorPaths(
@@ -358,6 +488,10 @@ void ProjectStorageUpdater::updatePropertyEditorPaths(
Storage::Synchronization::SynchronizationPackage &package,
NotUpdatedSourceIds &notUpdatedSourceIds)
{
NanotraceHR::Tracer tracer{"update property editor paths"_t,
category(),
keyValue("property editor resources path", propertyEditorResourcesPath)};
if (propertyEditorResourcesPath.isEmpty())
return;
@@ -390,6 +524,13 @@ void ProjectStorageUpdater::updatePropertyEditorPath(
Storage::Synchronization::SynchronizationPackage &package,
SourceId directorySourceId)
{
NanotraceHR::Tracer tracer{"update property editor path"_t,
category(),
keyValue("directory path", directoryPath),
keyValue("directory source id", directorySourceId)};
tracer.tick("append updated property editor qml path source id"_t,
keyValue("source id", directorySourceId));
package.updatedPropertyEditorQmlPathSourceIds.push_back(directorySourceId);
auto dir = QDir{directoryPath};
const auto fileInfos = dir.entryInfoList({"*Pane.qml", "*Specifics.qml"}, QDir::Files);
@@ -402,6 +543,11 @@ void ProjectStorageUpdater::updatePropertyEditorFilePath(
Storage::Synchronization::SynchronizationPackage &package,
SourceId directorySourceId)
{
NanotraceHR::Tracer tracer{"update property editor file path"_t,
category(),
keyValue("directory path", path),
keyValue("directory source id", directorySourceId)};
QRegularExpression regex{R"xo(.+\/(\w+)\/(\w+)(Specifics|Pane).qml)xo"};
auto match = regex.match(path);
QString oldModuleName;
@@ -414,7 +560,12 @@ void ProjectStorageUpdater::updatePropertyEditorFilePath(
}
Storage::TypeNameString typeName{match.capturedView(2)};
SourceId pathId = m_pathCache.sourceId(SourcePath{path});
package.propertyEditorQmlPaths.emplace_back(moduleId, typeName, pathId, directorySourceId);
const auto &paths = package.propertyEditorQmlPaths.emplace_back(moduleId,
typeName,
pathId,
directorySourceId);
tracer.tick("append property editor qml paths"_t,
keyValue("property editor qml paths", paths));
}
}
@@ -451,6 +602,10 @@ bool contains(const Container &container, Id id)
void ProjectStorageUpdater::pathsWithIdsChanged(const std::vector<IdPaths> &changedIdPaths)
{
NanotraceHR::Tracer tracer{"paths with ids changed"_t,
category(),
keyValue("id paths", changedIdPaths)};
m_changedIdPaths.insert(m_changedIdPaths.end(), changedIdPaths.begin(), changedIdPaths.end());
Storage::Synchronization::SynchronizationPackage package;
@@ -543,21 +698,35 @@ void ProjectStorageUpdater::parseTypeInfos(const QStringList &typeInfos,
NotUpdatedSourceIds &notUpdatedSourceIds,
WatchedSourceIdsIds &watchedSourceIds)
{
NanotraceHR::Tracer tracer{"parse type infos"_t,
category(),
keyValue("directory source id", directorySourceId),
keyValue("directory path", directoryPath),
keyValue("module id", moduleId)};
for (const QString &typeInfo : typeInfos) {
NanotraceHR::Tracer tracer{"parse type info"_t, category(), keyValue("type info", typeInfo)};
Utils::PathString qmltypesPath = Utils::PathString::join(
{directoryPath, "/", Utils::SmallString{typeInfo}});
SourceId sourceId = m_pathCache.sourceId(SourcePathView{qmltypesPath});
tracer.tick("append qmltypes source id"_t, keyValue("source id", sourceId));
watchedSourceIds.qmltypesSourceIds.push_back(sourceId);
addDependencies(package.moduleDependencies,
sourceId,
joinImports(qmldirDependencies, qmldirImports),
m_projectStorage);
m_projectStorage,
"append module dependency"_t,
tracer);
tracer.tick("append module dependenct source source id"_t, keyValue("source id", sourceId));
package.updatedModuleDependencySourceIds.push_back(sourceId);
auto projectData = package.projectDatas.emplace_back(
directorySourceId, sourceId, moduleId, Storage::Synchronization::FileType::QmlTypes);
tracer.tick("append project data"_t, keyValue("source id", sourceId));
parseTypeInfo(projectData, qmltypesPath, package, notUpdatedSourceIds);
}
@@ -568,6 +737,8 @@ void ProjectStorageUpdater::parseProjectDatas(const Storage::Synchronization::Pr
NotUpdatedSourceIds &notUpdatedSourceIds,
WatchedSourceIdsIds &watchedSourceIds)
{
NanotraceHR::Tracer tracer{"parse project datas"_t, category()};
for (const Storage::Synchronization::ProjectData &projectData : projectDatas) {
switch (projectData.fileType) {
case Storage::Synchronization::FileType::QmlTypes: {
@@ -591,9 +762,14 @@ auto ProjectStorageUpdater::parseTypeInfo(const Storage::Synchronization::Projec
Storage::Synchronization::SynchronizationPackage &package,
NotUpdatedSourceIds &notUpdatedSourceIds) -> FileState
{
NanotraceHR::Tracer tracer{"parse type info"_t,
category(),
keyValue("qmltypes path", qmltypesPath)};
auto state = fileState(projectData.sourceId, package, notUpdatedSourceIds);
switch (state) {
case FileState::Changed: {
tracer.tick("append updated source ids"_t, keyValue("source id", projectData.sourceId));
package.updatedSourceIds.push_back(projectData.sourceId);
const auto content = m_fileSystem.contentAsQString(QString{qmltypesPath});
@@ -601,6 +777,7 @@ auto ProjectStorageUpdater::parseTypeInfo(const Storage::Synchronization::Projec
break;
}
case FileState::NotChanged: {
tracer.tick("append not updated source ids"_t, keyValue("source id", projectData.sourceId));
notUpdatedSourceIds.sourceIds.push_back(projectData.sourceId);
break;
}
@@ -608,6 +785,8 @@ auto ProjectStorageUpdater::parseTypeInfo(const Storage::Synchronization::Projec
throw CannotParseQmlTypesFile{};
}
tracer.end(keyValue("state", state));
return state;
}
@@ -620,6 +799,14 @@ void ProjectStorageUpdater::parseQmlComponent(Utils::SmallStringView relativeFil
WatchedSourceIdsIds &watchedSourceIds,
FileState qmldirState)
{
NanotraceHR::Tracer tracer{"parse qml component"_t,
category(),
keyValue("relative file path", relativeFilePath),
keyValue("directory path", directoryPath),
keyValue("exported types", exportedTypes),
keyValue("directory source id", directorySourceId),
keyValue("qmldir state", qmldirState)};
if (std::find(relativeFilePath.begin(), relativeFilePath.end(), '+') != relativeFilePath.end())
return;
@@ -629,16 +816,18 @@ void ProjectStorageUpdater::parseQmlComponent(Utils::SmallStringView relativeFil
Storage::Synchronization::Type type;
auto state = fileState(sourceId, package, notUpdatedSourceIds);
tracer.tick("append watched qml source id"_t, keyValue("source id", sourceId));
watchedSourceIds.qmlSourceIds.push_back(sourceId);
switch (state) {
case FileState::NotChanged:
if (qmldirState == FileState::NotExists) {
tracer.tick("append not updated source id"_t, keyValue("source id", sourceId));
notUpdatedSourceIds.sourceIds.emplace_back(sourceId);
package.projectDatas.emplace_back(directorySourceId,
sourceId,
ModuleId{},
Storage::Synchronization::FileType::QmlDocument);
const auto &projectData = package.projectDatas.emplace_back(
directorySourceId, sourceId, ModuleId{}, Storage::Synchronization::FileType::QmlDocument);
tracer.tick("append project data"_t, keyValue("project data", projectData));
return;
}
@@ -652,11 +841,11 @@ void ProjectStorageUpdater::parseQmlComponent(Utils::SmallStringView relativeFil
break;
}
package.projectDatas.emplace_back(directorySourceId,
sourceId,
ModuleId{},
Storage::Synchronization::FileType::QmlDocument);
const auto &projectData = package.projectDatas.emplace_back(
directorySourceId, sourceId, ModuleId{}, Storage::Synchronization::FileType::QmlDocument);
tracer.tick("append project data"_t, keyValue("project data", projectData));
tracer.tick("append updated source id"_t, keyValue("source id", sourceId));
package.updatedSourceIds.push_back(sourceId);
type.typeName = SourcePath{qmlFilePath}.name();
@@ -664,6 +853,8 @@ void ProjectStorageUpdater::parseQmlComponent(Utils::SmallStringView relativeFil
type.sourceId = sourceId;
type.exportedTypes = std::move(exportedTypes);
tracer.end(keyValue("type", type));
package.types.push_back(std::move(type));
}
@@ -671,10 +862,13 @@ void ProjectStorageUpdater::parseQmlComponent(SourceId sourceId,
Storage::Synchronization::SynchronizationPackage &package,
NotUpdatedSourceIds &notUpdatedSourceIds)
{
NanotraceHR::Tracer tracer{"parse qml component"_t, category(), keyValue("source id", sourceId)};
auto state = fileState(sourceId, package, notUpdatedSourceIds);
if (state == FileState::NotChanged)
return;
tracer.tick("append updated source id"_t, keyValue("source id", sourceId));
package.updatedSourceIds.push_back(sourceId);
if (state == FileState::NotExists)
@@ -690,6 +884,8 @@ void ProjectStorageUpdater::parseQmlComponent(SourceId sourceId,
type.sourceId = sourceId;
type.changeLevel = Storage::Synchronization::ChangeLevel::ExcludeExportedTypes;
tracer.end(keyValue("type", type));
package.types.push_back(std::move(type));
}
@@ -736,6 +932,12 @@ void ProjectStorageUpdater::parseQmlComponents(Components components,
WatchedSourceIdsIds &watchedSourceIdsIds,
FileState qmldirState)
{
NanotraceHR::Tracer tracer{"parse qml components"_t,
category(),
keyValue("directory source id", directorySourceId),
keyValue("directory id", directoryId),
keyValue("qmldir state", qmldirState)};
std::sort(components.begin(), components.end(), [](auto &&first, auto &&second) {
return first.fileName < second.fileName;
});
@@ -763,22 +965,37 @@ ProjectStorageUpdater::FileState ProjectStorageUpdater::fileState(
Storage::Synchronization::SynchronizationPackage &package,
NotUpdatedSourceIds &notUpdatedSourceIds) const
{
NanotraceHR::Tracer tracer{"update property editor paths"_t,
category(),
keyValue("source id", sourceId)};
auto currentFileStatus = m_fileStatusCache.find(sourceId);
if (!currentFileStatus.isValid()) {
tracer.tick("append updated file status source id"_t, keyValue("source id", sourceId));
package.updatedFileStatusSourceIds.push_back(sourceId);
tracer.end(keyValue("state", FileState::NotExists));
return FileState::NotExists;
}
auto projectStorageFileStatus = m_projectStorage.fetchFileStatus(sourceId);
if (!projectStorageFileStatus.isValid() || projectStorageFileStatus != currentFileStatus) {
tracer.tick("append file status"_t, keyValue("file status", sourceId));
package.fileStatuses.push_back(currentFileStatus);
tracer.tick("append updated file status source id"_t, keyValue("source id", sourceId));
package.updatedFileStatusSourceIds.push_back(sourceId);
tracer.end(keyValue("state", FileState::Changed));
return FileState::Changed;
}
tracer.tick("append not updated file status source id"_t, keyValue("source id", sourceId));
notUpdatedSourceIds.fileStatusSourceIds.push_back(sourceId);
tracer.end(keyValue("state", FileState::NotChanged));
return FileState::NotChanged;
}

View File

@@ -11,6 +11,8 @@
#include "projectstoragetypes.h"
#include "sourcepath.h"
#include <tracing/qmldesignertracing.h>
#include <qmljs/parser/qmldirparser_p.h>
#include <QStringList>
@@ -141,6 +143,16 @@ private:
Storage::Synchronization::SynchronizationPackage &package,
NotUpdatedSourceIds &notUpdatedSourceIds,
WatchedSourceIdsIds &watchedSourceIdsIds);
void updateDirectoryChanged(std::string_view directoryPath,
FileState qmldirState,
SourcePath qmldirSourcePath,
SourceId qmldirSourceId,
SourceId directorySourceId,
SourceContextId directoryId,
Storage::Synchronization::SynchronizationPackage &package,
NotUpdatedSourceIds &notUpdatedSourceIds,
WatchedSourceIdsIds &watchedSourceIdsIds,
ProjectStorageTracing::Category::TracerType &tracer);
void updatePropertyEditorPaths(const QString &propertyEditorResourcesPath,
Storage::Synchronization::SynchronizationPackage &package,

View File

@@ -10,6 +10,8 @@
#include <sqlitedatabase.h>
#include <tracing/qmldesignertracing.h>
#ifdef QDS_BUILD_QMLPARSER
#include <private/qqmldomtop_p.h>
#endif
@@ -21,6 +23,10 @@ namespace QmlDesigner {
#ifdef QDS_BUILD_QMLPARSER
constexpr auto category = ProjectStorageTracing::projectStorageUpdaterCategory;
using NanotraceHR::keyValue;
using Tracer = ProjectStorageTracing::Category::TracerType;
namespace QmlDom = QQmlJS::Dom;
namespace Synchronization = Storage::Synchronization;
@@ -84,6 +90,11 @@ QualifiedImports createQualifiedImports(const QList<QmlDom::Import> &qmlImports,
Utils::SmallStringView directoryPath,
QmlDocumentParser::ProjectStorage &storage)
{
NanotraceHR::Tracer tracer{"create qualified imports"_t,
category(),
keyValue("sourceId", sourceId),
keyValue("directoryPath", directoryPath)};
QualifiedImports qualifiedImports;
for (const QmlDom::Import &qmlImport : qmlImports) {
@@ -92,6 +103,8 @@ QualifiedImports createQualifiedImports(const QList<QmlDom::Import> &qmlImports,
createImport(qmlImport, sourceId, directoryPath, storage));
}
tracer.end(keyValue("qualified imports", qualifiedImports));
return qualifiedImports;
}
@@ -280,6 +293,11 @@ Storage::Synchronization::Type QmlDocumentParser::parse(const QString &sourceCon
SourceId sourceId,
Utils::SmallStringView directoryPath)
{
NanotraceHR::Tracer tracer{"qml document parser parse"_t,
category(),
keyValue("sourceId", sourceId),
keyValue("directoryPath", directoryPath)};
Storage::Synchronization::Type type;
using Option = QmlDom::DomEnvironment::Option;

View File

@@ -5,6 +5,8 @@
#include "projectstorage.h"
#include <tracing/qmldesignertracing.h>
#include <sqlitedatabase.h>
#ifdef QDS_BUILD_QMLPARSER
@@ -21,6 +23,10 @@ namespace QmlDesigner {
#ifdef QDS_BUILD_QMLPARSER
constexpr auto category = ProjectStorageTracing::projectStorageUpdaterCategory;
using NanotraceHR::keyValue;
using Tracer = ProjectStorageTracing::Category::TracerType;
namespace QmlDom = QQmlJS::Dom;
namespace {
@@ -31,6 +37,8 @@ using Storage::TypeNameString;
ComponentWithoutNamespaces createComponentNameWithoutNamespaces(const QList<QQmlJSExportedScope> &objects)
{
NanotraceHR::Tracer tracer{"parse qmltypes file"_t, category()};
ComponentWithoutNamespaces componentWithoutNamespaces;
for (const auto &object : objects) {
@@ -46,13 +54,15 @@ ComponentWithoutNamespaces createComponentNameWithoutNamespaces(const QList<QQml
name);
}
tracer.end(keyValue("components without namespace", componentWithoutNamespaces));
return componentWithoutNamespaces;
}
void appendImports(Storage::Imports &imports,
const QString &dependency,
SourceId sourceId,
QmlTypesParser::ProjectStorage &storage)
const Storage::Import &appendImports(Storage::Imports &imports,
const QString &dependency,
SourceId sourceId,
QmlTypesParser::ProjectStorage &storage)
{
auto spaceFound = std::find_if(dependency.begin(), dependency.end(), [](QChar c) {
return c.isSpace();
@@ -62,7 +72,7 @@ void appendImports(Storage::Imports &imports,
moduleName.append("-cppnative");
ModuleId cppModuleId = storage.moduleId(moduleName);
imports.emplace_back(cppModuleId, Storage::Version{}, sourceId);
return imports.emplace_back(cppModuleId, Storage::Version{}, sourceId);
}
void addImports(Storage::Imports &imports,
@@ -71,13 +81,25 @@ void addImports(Storage::Imports &imports,
QmlTypesParser::ProjectStorage &storage,
ModuleId cppModuleId)
{
for (const QString &dependency : dependencies)
appendImports(imports, dependency, sourceId, storage);
NanotraceHR::Tracer tracer{
"add imports"_t,
category(),
keyValue("source id", sourceId),
keyValue("module id", cppModuleId),
};
imports.emplace_back(cppModuleId, Storage::Version{}, sourceId);
for (const QString &dependency : dependencies) {
const auto &import = appendImports(imports, dependency, sourceId, storage);
tracer.tick("append import"_t, keyValue("import", import), keyValue("dependency", dependency));
}
if (ModuleId qmlCppModuleId = storage.moduleId("QML-cppnative"); cppModuleId != qmlCppModuleId)
imports.emplace_back(qmlCppModuleId, Storage::Version{}, sourceId);
const auto &import = imports.emplace_back(cppModuleId, Storage::Version{}, sourceId);
tracer.tick("append import"_t, keyValue("import", import));
if (ModuleId qmlCppModuleId = storage.moduleId("QML-cppnative"); cppModuleId != qmlCppModuleId) {
const auto &import = imports.emplace_back(qmlCppModuleId, Storage::Version{}, sourceId);
tracer.tick("append import"_t, keyValue("import", import));
}
}
Storage::TypeTraits createAccessTypeTraits(QQmlJSScope::AccessSemantics accessSematics)
@@ -412,6 +434,11 @@ void addType(Storage::Synchronization::Types &types,
QmlTypesParser::ProjectStorage &storage,
const ComponentWithoutNamespaces &componentNameWithoutNamespace)
{
NanotraceHR::Tracer tracer{"add type"_t,
category(),
keyValue("source id", sourceId),
keyValue("module id", cppModuleId)};
const auto &component = *exportScope.scope;
auto [functionsDeclarations, signalDeclarations] = createFunctionAndSignals(
@@ -421,7 +448,7 @@ void addType(Storage::Synchronization::Types &types,
auto exports = exportScope.exports;
auto enumerationTypes = addEnumerationTypes(types, typeName, sourceId, cppModuleId, enumerations);
types.emplace_back(
const auto &type = types.emplace_back(
Utils::SmallStringView{typeName},
Storage::Synchronization::ImportedType{TypeNameString{component.baseTypeName()}},
Storage::Synchronization::ImportedType{TypeNameString{component.extensionTypeName()}},
@@ -432,6 +459,7 @@ void addType(Storage::Synchronization::Types &types,
std::move(functionsDeclarations),
std::move(signalDeclarations),
createEnumeration(enumerations));
tracer.end(keyValue("type", type));
}
void addTypes(Storage::Synchronization::Types &types,
@@ -440,6 +468,7 @@ void addTypes(Storage::Synchronization::Types &types,
QmlTypesParser::ProjectStorage &storage,
const ComponentWithoutNamespaces &componentNameWithoutNamespaces)
{
NanotraceHR::Tracer tracer{"add types"_t, category()};
types.reserve(Utils::usize(objects) + types.size());
for (const auto &object : objects)
@@ -458,6 +487,8 @@ void QmlTypesParser::parse(const QString &sourceContent,
Storage::Synchronization::Types &types,
const Storage::Synchronization::ProjectData &projectData)
{
NanotraceHR::Tracer tracer{"qmltypes parser parse"_t, category()};
QQmlJSTypeDescriptionReader reader({}, sourceContent);
QList<QQmlJSExportedScope> components;
QStringList dependencies;

View File

@@ -117,6 +117,12 @@ public:
std::ptrdiff_t slashIndex() const { return m_slashIndex; }
template<typename String>
friend void convertToString(String &string, const SourcePath &path)
{
convertToString(string, path.toStringView());
}
private:
std::ptrdiff_t m_slashIndex = -1;
};

View File

@@ -68,14 +68,22 @@ Category &category()
namespace ProjectStorageTracing {
NanotraceHR::StringViewWithStringArgumentsCategory<projectStorageTracingStatus()> &projectStorageCategory()
Category &projectStorageCategory()
{
thread_local NanotraceHR::StringViewWithStringArgumentsCategory<projectStorageTracingStatus()>
projectStorageCategory_{"project storage"_t,
Tracing::eventQueueWithStringArguments(),
projectStorageCategory};
thread_local Category category{"project storage"_t,
Tracing::eventQueueWithStringArguments(),
projectStorageCategory};
return projectStorageCategory_;
return category;
}
Category &projectStorageUpdaterCategory()
{
thread_local Category category{"project storage updater"_t,
Tracing::eventQueueWithStringArguments(),
projectStorageCategory};
return category;
}
} // namespace ProjectStorageTracing

View File

@@ -55,7 +55,11 @@ constexpr NanotraceHR::Tracing projectStorageTracingStatus()
#endif
}
[[gnu::pure]] NanotraceHR::StringViewWithStringArgumentsCategory<projectStorageTracingStatus()> &
projectStorageCategory();
using Category = NanotraceHR::StringViewWithStringArgumentsCategory<projectStorageTracingStatus()>;
[[gnu::pure]] Category &projectStorageCategory();
[[gnu::pure]] Category &projectStorageUpdaterCategory();
} // namespace ProjectStorageTracing
} // namespace QmlDesigner