QmlDesigner: Ignore non qds folder in project

A new is inside project flag is introduced. Directories which contains a
"ignore-in-qds" file are ignored. Subdirectories which start with a '.'
are ignored, too.

Task-number: QDS-14916
Change-Id: I8a4c9198bdb7bfd98f116697c418d075affb574a
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Marco Bubke
2025-03-14 18:28:06 +01:00
committed by Thomas Hartmann
parent 28d58638e7
commit 47b0e1b14c
20 changed files with 1144 additions and 462 deletions

View File

@@ -76,6 +76,7 @@ public:
MetaInfoType type() const; MetaInfoType type() const;
bool isFileComponent() const; bool isFileComponent() const;
bool isSingleton() const; bool isSingleton() const;
bool isInsideProject() const;
FlagIs canBeContainer() const; FlagIs canBeContainer() const;
FlagIs forceClip() const; FlagIs forceClip() const;
FlagIs doesLayoutChildren() const; FlagIs doesLayoutChildren() const;

View File

@@ -1547,6 +1547,26 @@ bool NodeMetaInfo::isSingleton() const
} }
} }
bool NodeMetaInfo::isInsideProject() const
{
if constexpr (useProjectStorage()) {
if (!isValid())
return {};
using NanotraceHR::keyValue;
NanotraceHR::Tracer tracer{"is inside project", category(), keyValue("type id", m_typeId)};
auto isInsideProject = typeData().traits.isInsideProject;
tracer.end(keyValue("is inside project", isInsideProject));
return isInsideProject;
} else {
return false;
}
}
FlagIs NodeMetaInfo::canBeContainer() const FlagIs NodeMetaInfo::canBeContainer() const
{ {
if constexpr (useProjectStorage()) { if constexpr (useProjectStorage()) {

View File

@@ -125,6 +125,8 @@ void convertToString(String &string, const TypeTraitsKind &kind)
} }
} }
enum class IsInsideProject : char { No, Yes };
struct TypeTraits struct TypeTraits
{ {
constexpr TypeTraits() constexpr TypeTraits()
@@ -133,6 +135,7 @@ struct TypeTraits
, isFileComponent{false} , isFileComponent{false}
, usesCustomParser{false} , usesCustomParser{false}
, isSingleton{false} , isSingleton{false}
, isInsideProject{false}
, dummy{0U} , dummy{0U}
, canBeContainer{FlagIs::False} , canBeContainer{FlagIs::False}
, forceClip{FlagIs::False} , forceClip{FlagIs::False}
@@ -208,7 +211,8 @@ struct TypeTraits
unsigned int isFileComponent : 1; unsigned int isFileComponent : 1;
unsigned int usesCustomParser : 1; unsigned int usesCustomParser : 1;
unsigned int isSingleton : 1; unsigned int isSingleton : 1;
unsigned int dummy : 24; unsigned int isInsideProject : 1;
unsigned int dummy : 23;
}; };
unsigned int type; unsigned int type;

View File

@@ -253,36 +253,53 @@ void addModuleExportedImports(Storage::Synchronization::ModuleExportedImports &i
} }
} }
std::vector<IdPaths> createIdPaths(ProjectStorageUpdater::WatchedSourceIdsIds watchedSourceIds, using Storage::IsInsideProject;
ProjectPartId projectPartId)
using WatchedSourceIds = ProjectStorageUpdater::WatchedSourceIds;
void appendIdPaths(WatchedSourceIds watchedSourceIds, ProjectPartId id, std::vector<IdPaths> &idPaths)
{ {
std::vector<IdPaths> idPaths; if (watchedSourceIds.directoryIds.size())
idPaths.reserve(4); idPaths.emplace_back(id, SourceType::Directory, std::move(watchedSourceIds.directoryIds));
idPaths.push_back({projectPartId, SourceType::Directory, std::move(watchedSourceIds.directoryIds)}); if (watchedSourceIds.qmldirSourceIds.size())
idPaths.push_back({projectPartId, SourceType::QmlDir, std::move(watchedSourceIds.qmldirSourceIds)}); idPaths.emplace_back(id, SourceType::QmlDir, std::move(watchedSourceIds.qmldirSourceIds));
idPaths.push_back({projectPartId, SourceType::Qml, std::move(watchedSourceIds.qmlSourceIds)});
idPaths.push_back(
{projectPartId, SourceType::QmlTypes, std::move(watchedSourceIds.qmltypesSourceIds)});
return idPaths; if (watchedSourceIds.qmlSourceIds.size())
idPaths.emplace_back(id, SourceType::Qml, std::move(watchedSourceIds.qmlSourceIds));
if (watchedSourceIds.qmltypesSourceIds.size())
idPaths.emplace_back(id, SourceType::QmlTypes, std::move(watchedSourceIds.qmltypesSourceIds));
} }
} // namespace } // namespace
void ProjectStorageUpdater::update(Update update) void ProjectStorageUpdater::update(Update update)
{ {
QStringList directories = std::move(update.directories); QStringList qtDirectories = std::move(update.qtDirectories);
const QString &propertyEditorResourcesPath = update.propertyEditorResourcesPath; const QString &propertyEditorResourcesPath = update.propertyEditorResourcesPath;
const QStringList &typeAnnotationPaths = update.typeAnnotationPaths; const QStringList &typeAnnotationPaths = update.typeAnnotationPaths;
const Utils::PathString projectDirectory = update.projectDirectory;
NanotraceHR::Tracer tracer{"update", category(), keyValue("directories", directories)}; NanotraceHR::Tracer tracer{"update",
category(),
keyValue("Qt directories", qtDirectories),
keyValue("project directory", projectDirectory)};
Storage::Synchronization::SynchronizationPackage package; Storage::Synchronization::SynchronizationPackage package;
WatchedSourceIdsIds watchedSourceIds{Utils::usize(directories)}; WatchedSourceIds watchedQtSourceIds{32};
NotUpdatedSourceIds notUpdatedSourceIds{Utils::usize(directories)}; WatchedSourceIds watchedProjectSourceIds{32};
NotUpdatedSourceIds notUpdatedSourceIds{1024};
updateDirectories(directories, package, notUpdatedSourceIds, watchedSourceIds); updateDirectories(qtDirectories, package, notUpdatedSourceIds, watchedQtSourceIds);
if (projectDirectory.size()) {
updateDirectory(projectDirectory,
{},
package,
notUpdatedSourceIds,
watchedProjectSourceIds,
IsInsideProject::Yes);
}
updatePropertyEditorPaths(propertyEditorResourcesPath, package, notUpdatedSourceIds); updatePropertyEditorPaths(propertyEditorResourcesPath, package, notUpdatedSourceIds);
updateTypeAnnotations(typeAnnotationPaths, package, notUpdatedSourceIds); updateTypeAnnotations(typeAnnotationPaths, package, notUpdatedSourceIds);
@@ -294,7 +311,11 @@ void ProjectStorageUpdater::update(Update update)
m_projectStorage.synchronize(std::move(package)); m_projectStorage.synchronize(std::move(package));
m_pathWatcher.updateIdPaths(createIdPaths(watchedSourceIds, m_projectPartId)); std::vector<IdPaths> idPaths;
idPaths.reserve(8);
appendIdPaths(std::move(watchedQtSourceIds), m_qtPartId, idPaths);
appendIdPaths(std::move(watchedProjectSourceIds), m_projectPartId, idPaths);
m_pathWatcher.updateIdPaths(idPaths);
} }
namespace { namespace {
@@ -320,13 +341,29 @@ bool isUnchanged(ProjectStorageUpdater::FileState state)
return !isChanged(state); return !isChanged(state);
} }
bool isChangedOrAdded(ProjectStorageUpdater::FileState state)
{
using FileState = ProjectStorageUpdater::FileState;
switch (state) {
case FileState::Changed:
case FileState::Added:
return true;
case FileState::Removed:
case FileState::NotExists:
case FileState::NotExistsUnchanged:
case FileState::Unchanged:
break;
}
return false;
}
template<typename... FileStates> template<typename... FileStates>
ProjectStorageUpdater::FileState combineState(FileStates... fileStates) ProjectStorageUpdater::FileState combineState(FileStates... fileStates)
{ {
if (((fileStates == ProjectStorageUpdater::FileState::Removed) && ...)) if (((fileStates == ProjectStorageUpdater::FileState::Removed) && ...))
return ProjectStorageUpdater::FileState::Removed; return ProjectStorageUpdater::FileState::Removed;
if (((fileStates == ProjectStorageUpdater::FileState::Added) && ...)) if (((fileStates == ProjectStorageUpdater::FileState::Added) || ...))
return ProjectStorageUpdater::FileState::Added; return ProjectStorageUpdater::FileState::Added;
if ((isChanged(fileStates) || ...)) if ((isChanged(fileStates) || ...))
@@ -371,7 +408,8 @@ void ProjectStorageUpdater::updateDirectoryChanged(Utils::SmallStringView direct
SourceContextId annotationDirectoryId, SourceContextId annotationDirectoryId,
Storage::Synchronization::SynchronizationPackage &package, Storage::Synchronization::SynchronizationPackage &package,
NotUpdatedSourceIds &notUpdatedSourceIds, NotUpdatedSourceIds &notUpdatedSourceIds,
WatchedSourceIdsIds &watchedSourceIdsIds, WatchedSourceIds &WatchedSourceIds,
IsInsideProject isInsideProject,
Tracer &tracer) Tracer &tracer)
{ {
QmlDirParser parser; QmlDirParser parser;
@@ -391,12 +429,8 @@ void ProjectStorageUpdater::updateDirectoryChanged(Utils::SmallStringView direct
auto imports = filterMultipleEntries(parser.imports()); auto imports = filterMultipleEntries(parser.imports());
addModuleExportedImports(package.moduleExportedImports, addModuleExportedImports(
moduleId, package.moduleExportedImports, moduleId, cppModuleId, moduleName, imports, m_projectStorage);
cppModuleId,
moduleName,
imports,
m_projectStorage);
tracer.tick("append updated module id", keyValue("module id", moduleId)); tracer.tick("append updated module id", keyValue("module id", moduleId));
package.updatedModuleIds.push_back(moduleId); package.updatedModuleIds.push_back(moduleId);
@@ -420,7 +454,8 @@ void ProjectStorageUpdater::updateDirectoryChanged(Utils::SmallStringView direct
cppModuleId, cppModuleId,
package, package,
notUpdatedSourceIds, notUpdatedSourceIds,
watchedSourceIdsIds); WatchedSourceIds,
isInsideProject);
} }
parseQmlComponents(createComponents(parser.components(), parseQmlComponents(createComponents(parser.components(),
moduleId, moduleId,
@@ -430,33 +465,36 @@ void ProjectStorageUpdater::updateDirectoryChanged(Utils::SmallStringView direct
directoryId, directoryId,
package, package,
notUpdatedSourceIds, notUpdatedSourceIds,
watchedSourceIdsIds, WatchedSourceIds,
qmldirState, qmldirState,
qmldirSourceId); qmldirSourceId,
isInsideProject);
tracer.tick("append updated project source id", keyValue("module id", moduleId)); tracer.tick("append updated project source id", keyValue("module id", moduleId));
package.updatedDirectoryInfoDirectoryIds.push_back(directoryId); package.updatedDirectoryInfoDirectoryIds.push_back(directoryId);
if (isInsideProject == IsInsideProject::Yes) {
if (isExisting(annotationDirectoryState)) { if (isExisting(annotationDirectoryState)) {
annotationDirectoryChanged(annotationDirectoryPath, annotationDirectoryChanged(annotationDirectoryPath,
directoryId, directoryId,
annotationDirectoryId, annotationDirectoryId,
moduleId, moduleId,
package, package);
notUpdatedSourceIds);
} else if (annotationDirectoryState == FileState::Removed) { } else if (annotationDirectoryState == FileState::Removed) {
package.updatedPropertyEditorQmlPathDirectoryIds.push_back(annotationDirectoryId); package.updatedPropertyEditorQmlPathDirectoryIds.push_back(annotationDirectoryId);
} }
} }
}
void ProjectStorageUpdater::updateDirectories(const QStringList &directories, void ProjectStorageUpdater::updateDirectories(const QStringList &directories,
Storage::Synchronization::SynchronizationPackage &package, Storage::Synchronization::SynchronizationPackage &package,
NotUpdatedSourceIds &notUpdatedSourceIds, NotUpdatedSourceIds &notUpdatedSourceIds,
WatchedSourceIdsIds &watchedSourceIdsIds) WatchedSourceIds &WatchedSourceIds)
{ {
NanotraceHR::Tracer tracer{"update directories", category()}; NanotraceHR::Tracer tracer{"update directories", category()};
for (const QString &directory : directories) for (const QString &directory : directories)
updateDirectory({directory}, {}, package, notUpdatedSourceIds, watchedSourceIdsIds); updateDirectory(
{directory}, {}, package, notUpdatedSourceIds, WatchedSourceIds, IsInsideProject::No);
} }
void ProjectStorageUpdater::updateSubdirectories(const Utils::PathString &directoryPath, void ProjectStorageUpdater::updateSubdirectories(const Utils::PathString &directoryPath,
@@ -465,7 +503,8 @@ void ProjectStorageUpdater::updateSubdirectories(const Utils::PathString &direct
const SourceContextIds &subdirectoriesToIgnore, const SourceContextIds &subdirectoriesToIgnore,
Storage::Synchronization::SynchronizationPackage &package, Storage::Synchronization::SynchronizationPackage &package,
NotUpdatedSourceIds &notUpdatedSourceIds, NotUpdatedSourceIds &notUpdatedSourceIds,
WatchedSourceIdsIds &watchedSourceIdsIds) WatchedSourceIds &WatchedSourceIds,
IsInsideProject isInsideProject)
{ {
struct Directory struct Directory
{ {
@@ -490,12 +529,34 @@ void ProjectStorageUpdater::updateSubdirectories(const Utils::PathString &direct
auto exisitingSubdirectoryPaths = m_fileSystem.subdirectories(directoryPath.toQString()); auto exisitingSubdirectoryPaths = m_fileSystem.subdirectories(directoryPath.toQString());
Directories existingSubdirecories; Directories existingSubdirecories;
auto skipDirectory = [&](std::string_view subdirectoryPath, SourceContextId sourceContextId) {
if (subdirectoryPath.ends_with("designer"))
return true;
if (isInsideProject == IsInsideProject::Yes) {
static SourceNameId ignoreInQdsSourceNameId = m_pathCache.sourceNameId("ignore-in-qds");
SourceId ignoreInQdsSourceId = SourceId::create(ignoreInQdsSourceNameId, sourceContextId);
auto ignoreInQdsState = fileState(ignoreInQdsSourceId, package, notUpdatedSourceIds);
if (isExisting(ignoreInQdsState))
return true;
} else {
if (subdirectoryPath.ends_with("/QtQuick/Scene2D")
|| subdirectoryPath.ends_with("/QtQuick/Scene3D"))
return true;
}
return false;
};
for (Utils::PathString subdirectoryPath : exisitingSubdirectoryPaths) { for (Utils::PathString subdirectoryPath : exisitingSubdirectoryPaths) {
if (subdirectoryPath.endsWith("designer") || subdirectoryPath.endsWith("/QtQuick/Scene2D") SourceContextId sourceContextId = m_pathCache.sourceContextId(subdirectoryPath);
|| subdirectoryPath.endsWith("/QtQuick/Scene3D"))
if (skipDirectory(subdirectoryPath, sourceContextId))
continue; continue;
SourceContextId sourceContextId = m_pathCache.sourceContextId(subdirectoryPath);
subdirectories.emplace_back(subdirectoryPath, sourceContextId); subdirectories.emplace_back(subdirectoryPath, sourceContextId);
existingSubdirecories.emplace_back(subdirectoryPath, sourceContextId); existingSubdirecories.emplace_back(subdirectoryPath, sourceContextId);
} }
@@ -504,20 +565,22 @@ void ProjectStorageUpdater::updateSubdirectories(const Utils::PathString &direct
auto removed = std::ranges::unique(subdirectories, {}, &Directory::sourceContextId); auto removed = std::ranges::unique(subdirectories, {}, &Directory::sourceContextId);
subdirectories.erase(removed.begin(), removed.end()); subdirectories.erase(removed.begin(), removed.end());
Utils::set_greedy_difference( auto updateDirectory = [&](const Directory &subdirectory) {
subdirectories, this->updateDirectory(subdirectory.path,
subdirectoriesToIgnore,
[&](const Directory &subdirectory) {
updateDirectory(subdirectory.path,
subdirectoriesToIgnore, subdirectoriesToIgnore,
package, package,
notUpdatedSourceIds, notUpdatedSourceIds,
watchedSourceIdsIds); WatchedSourceIds,
}, isInsideProject);
};
Utils::set_greedy_difference(subdirectories,
subdirectoriesToIgnore,
updateDirectory,
{}, {},
&Directory::sourceContextId); &Directory::sourceContextId);
if (directoryState == FileState::Changed) { if (isChanged(directoryState)) {
for (const auto &[subdirectoryPath, subdirectoryId] : existingSubdirecories) { for (const auto &[subdirectoryPath, subdirectoryId] : existingSubdirecories) {
package.directoryInfos.emplace_back(directoryId, package.directoryInfos.emplace_back(directoryId,
SourceId::create(SourceNameId{}, subdirectoryId), SourceId::create(SourceNameId{}, subdirectoryId),
@@ -532,8 +595,7 @@ void ProjectStorageUpdater::annotationDirectoryChanged(
SourceContextId directoryId, SourceContextId directoryId,
SourceContextId annotationDirectoryId, SourceContextId annotationDirectoryId,
ModuleId moduleId, ModuleId moduleId,
Storage::Synchronization::SynchronizationPackage &package, Storage::Synchronization::SynchronizationPackage &package)
NotUpdatedSourceIds &notUpdatedSourceIds)
{ {
NanotraceHR::Tracer tracer{"annotation directory changed", NanotraceHR::Tracer tracer{"annotation directory changed",
category(), category(),
@@ -542,15 +604,14 @@ void ProjectStorageUpdater::annotationDirectoryChanged(
package.updatedPropertyEditorQmlPathDirectoryIds.push_back(annotationDirectoryId); package.updatedPropertyEditorQmlPathDirectoryIds.push_back(annotationDirectoryId);
updatePropertyEditorFiles(directoryPath, annotationDirectoryId, moduleId, package, notUpdatedSourceIds); updatePropertyEditorFiles(directoryPath, annotationDirectoryId, moduleId, package);
} }
void ProjectStorageUpdater::updatePropertyEditorFiles( void ProjectStorageUpdater::updatePropertyEditorFiles(
Utils::SmallStringView directoryPath, Utils::SmallStringView directoryPath,
SourceContextId directoryId, SourceContextId directoryId,
ModuleId moduleId, ModuleId moduleId,
Storage::Synchronization::SynchronizationPackage &package, Storage::Synchronization::SynchronizationPackage &package)
NotUpdatedSourceIds &notUpdatedSourceIds)
{ {
NanotraceHR::Tracer tracer{"update property editor files", NanotraceHR::Tracer tracer{"update property editor files",
category(), category(),
@@ -562,21 +623,18 @@ void ProjectStorageUpdater::updatePropertyEditorFiles(
"*Specifics.qml", "*Specifics.qml",
"*SpecificsDynamic.qml"}); "*SpecificsDynamic.qml"});
for (const QString &fileName : fileNames) for (const QString &fileName : fileNames)
updatePropertyEditorFile(fileName, directoryId, moduleId, package, notUpdatedSourceIds); updatePropertyEditorFile(fileName, directoryId, moduleId, package);
} }
void ProjectStorageUpdater::updatePropertyEditorFile( void ProjectStorageUpdater::updatePropertyEditorFile(
const QString &fileName, const QString &fileName,
SourceContextId directoryId, SourceContextId directoryId,
ModuleId moduleId, ModuleId moduleId,
Storage::Synchronization::SynchronizationPackage &package, Storage::Synchronization::SynchronizationPackage &package)
NotUpdatedSourceIds &notUpdatedSourceIds)
{ {
Utils::PathString propertyEditorFileName{fileName}; Utils::PathString propertyEditorFileName{fileName};
auto propertyEditorSourceId = m_pathCache.sourceId(directoryId, propertyEditorFileName); auto propertyEditorSourceId = m_pathCache.sourceId(directoryId, propertyEditorFileName);
fileState(propertyEditorSourceId, package, notUpdatedSourceIds);
QRegularExpression regex{R"xo((\w+)(Specifics|Pane|SpecificsDynamic).qml)xo"}; QRegularExpression regex{R"xo((\w+)(Specifics|Pane|SpecificsDynamic).qml)xo"};
auto match = regex.match(fileName); auto match = regex.match(fileName);
@@ -589,7 +647,8 @@ void ProjectStorageUpdater::updateDirectory(const Utils::PathString &directoryPa
const SourceContextIds &subdirectoriesToIgnore, const SourceContextIds &subdirectoriesToIgnore,
Storage::Synchronization::SynchronizationPackage &package, Storage::Synchronization::SynchronizationPackage &package,
NotUpdatedSourceIds &notUpdatedSourceIds, NotUpdatedSourceIds &notUpdatedSourceIds,
WatchedSourceIdsIds &watchedSourceIdsIds) WatchedSourceIds &WatchedSourceIds,
IsInsideProject isInsideProject)
{ {
NanotraceHR::Tracer tracer{"update directory", category(), keyValue("directory", directoryPath)}; NanotraceHR::Tracer tracer{"update directory", category(), keyValue("directory", directoryPath)};
@@ -599,19 +658,19 @@ void ProjectStorageUpdater::updateDirectory(const Utils::PathString &directoryPa
auto directoryState = fileState(directoryId, package, notUpdatedSourceIds); auto directoryState = fileState(directoryId, package, notUpdatedSourceIds);
if (isExisting(directoryState)) if (isExisting(directoryState))
watchedSourceIdsIds.directoryIds.push_back(SourceId::create(SourceNameId{}, directoryId)); WatchedSourceIds.directoryIds.push_back(SourceId::create(SourceNameId{}, directoryId));
auto qmldirState = fileState(qmldirSourceId, package, notUpdatedSourceIds); auto qmldirState = fileState(qmldirSourceId, package, notUpdatedSourceIds);
if (isExisting(qmldirState)) if (isExisting(qmldirState))
watchedSourceIdsIds.qmldirSourceIds.push_back(qmldirSourceId); WatchedSourceIds.qmldirSourceIds.push_back(qmldirSourceId);
SourcePath annotationDirectoryPath{directoryPath + "/designer"}; SourcePath annotationDirectoryPath{directoryPath + "/designer"};
auto annotationDirectoryId = m_pathCache.sourceContextId(annotationDirectoryPath); auto annotationDirectoryId = m_pathCache.sourceContextId(annotationDirectoryPath);
auto annotationDirectoryState = fileState(annotationDirectoryId, package, notUpdatedSourceIds); auto annotationDirectoryState = fileState(annotationDirectoryId, package, notUpdatedSourceIds);
switch (combineState(directoryState, qmldirState, annotationDirectoryState)) { switch (combineState(directoryState, qmldirState, annotationDirectoryState)) {
case FileState::Changed:
case FileState::Added: case FileState::Added:
case FileState::Changed:
tracer.tick("update directory changed"); tracer.tick("update directory changed");
updateDirectoryChanged(directoryPath, updateDirectoryChanged(directoryPath,
annotationDirectoryPath, annotationDirectoryPath,
@@ -623,7 +682,8 @@ void ProjectStorageUpdater::updateDirectory(const Utils::PathString &directoryPa
annotationDirectoryId, annotationDirectoryId,
package, package,
notUpdatedSourceIds, notUpdatedSourceIds,
watchedSourceIdsIds, WatchedSourceIds,
isInsideProject,
tracer); tracer);
break; break;
case FileState::Unchanged: case FileState::Unchanged:
@@ -632,7 +692,8 @@ void ProjectStorageUpdater::updateDirectory(const Utils::PathString &directoryPa
parseDirectoryInfos(m_projectStorage.fetchDirectoryInfos(directoryId), parseDirectoryInfos(m_projectStorage.fetchDirectoryInfos(directoryId),
package, package,
notUpdatedSourceIds, notUpdatedSourceIds,
watchedSourceIdsIds); WatchedSourceIds,
isInsideProject);
break; break;
case FileState::Removed: { case FileState::Removed: {
tracer.tick("update directory don't exits"); tracer.tick("update directory don't exits");
@@ -660,7 +721,8 @@ void ProjectStorageUpdater::updateDirectory(const Utils::PathString &directoryPa
subdirectoriesToIgnore, subdirectoriesToIgnore,
package, package,
notUpdatedSourceIds, notUpdatedSourceIds,
watchedSourceIdsIds); WatchedSourceIds,
isInsideProject);
tracer.end(keyValue("qmldir source path", qmldirPath), tracer.end(keyValue("qmldir source path", qmldirPath),
keyValue("directory id", directoryId), keyValue("directory id", directoryId),
@@ -693,7 +755,7 @@ void ProjectStorageUpdater::updatePropertyEditorPaths(
auto state = fileState(directoryId, package, notUpdatedSourceIds); auto state = fileState(directoryId, package, notUpdatedSourceIds);
if (state == FileState::Changed) { if (isChanged(state)) {
updatePropertyEditorPath(pathInfo.filePath(), updatePropertyEditorPath(pathInfo.filePath(),
package, package,
directoryId, directoryId,
@@ -709,11 +771,7 @@ SmallSourceIds<16> mergedSourceIds(const SourceIds1 &sourceIds1, const SourceIds
{ {
SmallSourceIds<16> mergedSourceIds; SmallSourceIds<16> mergedSourceIds;
std::set_union(sourceIds1.begin(), std::ranges::set_union(sourceIds1, sourceIds2, std::back_inserter(mergedSourceIds));
sourceIds1.end(),
sourceIds2.begin(),
sourceIds2.end(),
std::back_inserter(mergedSourceIds));
return mergedSourceIds; return mergedSourceIds;
} }
@@ -764,10 +822,10 @@ void ProjectStorageUpdater::updateTypeAnnotations(
SourceContextId directoryId = m_pathCache.sourceContextId(Utils::PathString{directoryPath}); SourceContextId directoryId = m_pathCache.sourceContextId(Utils::PathString{directoryPath});
auto state = fileState(sourceId, package, notUpdatedSourceIds); auto state = fileState(sourceId, package, notUpdatedSourceIds);
if (state == FileState::Changed) if (isChangedOrAdded(state))
updateTypeAnnotation(directoryPath, fileInfo.filePath(), sourceId, directoryId, package); updateTypeAnnotation(directoryPath, fileInfo.filePath(), sourceId, directoryId, package);
if (state != FileState::Unchanged) if (isChanged(state))
updatedSourceIdsDictonary[directoryId].push_back(sourceId); updatedSourceIdsDictonary[directoryId].push_back(sourceId);
} }
} }
@@ -780,13 +838,14 @@ void ProjectStorageUpdater::updateTypeAnnotationDirectories(
for (auto &[directoryId, updatedSourceIds] : updatedSourceIdsDictonary) { for (auto &[directoryId, updatedSourceIds] : updatedSourceIdsDictonary) {
auto directoryState = fileState(directoryId, package, notUpdatedSourceIds); auto directoryState = fileState(directoryId, package, notUpdatedSourceIds);
if (directoryState != FileState::Unchanged) { if (isChanged(directoryState)) {
auto existingTypeAnnotationSourceIds = m_projectStorage.typeAnnotationSourceIds( auto storedTypeAnnotationSourceIds = m_projectStorage.typeAnnotationSourceIds(directoryId);
directoryId); storedTypeAnnotationSourceIds.removeIf(
[&](SourceId sourceId) { return m_fileStatusCache.find(sourceId).isExisting(); });
std::sort(updatedSourceIds.begin(), updatedSourceIds.end()); std::ranges::sort(updatedSourceIds);
auto changedSourceIds = mergedSourceIds(existingTypeAnnotationSourceIds, updatedSourceIds); auto changedSourceIds = mergedSourceIds(storedTypeAnnotationSourceIds, updatedSourceIds);
package.updatedTypeAnnotationSourceIds.insert(package.updatedTypeAnnotationSourceIds.end(), package.updatedTypeAnnotationSourceIds.insert(package.updatedTypeAnnotationSourceIds.end(),
changedSourceIds.begin(), changedSourceIds.begin(),
changedSourceIds.end()); changedSourceIds.end());
@@ -881,8 +940,7 @@ void ProjectStorageUpdater::updatePropertyEditorFilePath(
typeName, typeName,
pathId, pathId,
directoryId); directoryId);
tracer.tick("append property editor qml paths", tracer.tick("append property editor qml paths", keyValue("property editor qml paths", paths));
keyValue("property editor qml paths", paths));
} }
} }
@@ -912,6 +970,40 @@ bool contains(const Container &container, Id id)
{ {
return std::find(container.begin(), container.end(), id) != container.end(); return std::find(container.begin(), container.end(), id) != container.end();
} }
struct ProjectChunkSourceIds
{
ProjectChunkSourceIds()
{
directory.reserve(32);
qmlDocument.reserve(128);
qmltypes.reserve(32);
}
SourceIds directory;
SourceIds qmlDocument;
SourceIds qmltypes;
};
void appendProjectChunkSourceIds(ProjectChunkSourceIds &ids,
const ProjectChunkId &projectChunkId,
const SourceIds &sourceIds)
{
switch (projectChunkId.sourceType) {
case SourceType::Directory:
case SourceType::QmlDir:
ids.directory.insert(ids.directory.end(), sourceIds.begin(), sourceIds.end());
break;
case SourceType::Qml:
case SourceType::QmlUi:
ids.qmlDocument.insert(ids.qmlDocument.end(), sourceIds.begin(), sourceIds.end());
break;
case SourceType::QmlTypes:
ids.qmltypes.insert(ids.qmltypes.end(), sourceIds.begin(), sourceIds.end());
break;
}
}
} // namespace } // namespace
void ProjectStorageUpdater::pathsWithIdsChanged(const std::vector<IdPaths> &changedIdPaths) void ProjectStorageUpdater::pathsWithIdsChanged(const std::vector<IdPaths> &changedIdPaths)
@@ -924,58 +1016,73 @@ void ProjectStorageUpdater::pathsWithIdsChanged(const std::vector<IdPaths> &chan
Storage::Synchronization::SynchronizationPackage package; Storage::Synchronization::SynchronizationPackage package;
WatchedSourceIdsIds watchedSourceIds{10}; WatchedSourceIds watchedQtSourceIds{10};
WatchedSourceIds watchedProjectSourceIds{10};
NotUpdatedSourceIds notUpdatedSourceIds{10}; NotUpdatedSourceIds notUpdatedSourceIds{10};
std::vector<IdPaths> idPaths; std::vector<IdPaths> idPaths;
idPaths.reserve(4); idPaths.reserve(4);
SourceIds directorySourceIds; ProjectChunkSourceIds project;
directorySourceIds.reserve(32); ProjectChunkSourceIds qt;
SourceIds qmlDocumentSourceIds;
qmlDocumentSourceIds.reserve(128);
SourceIds qmltypesSourceIds;
qmltypesSourceIds.reserve(32);
for (const auto &[projectChunkId, sourceIds] : m_changedIdPaths) { for (const auto &[projectChunkId, sourceIds] : m_changedIdPaths) {
if (projectChunkId.id != m_projectPartId) if (projectChunkId.id == m_projectPartId)
continue; appendProjectChunkSourceIds(project, projectChunkId, sourceIds);
else if (projectChunkId.id == m_qtPartId)
switch (projectChunkId.sourceType) { appendProjectChunkSourceIds(qt, projectChunkId, sourceIds);
case SourceType::Directory:
case SourceType::QmlDir:
directorySourceIds.insert(directorySourceIds.end(), sourceIds.begin(), sourceIds.end());
break;
case SourceType::Qml:
case SourceType::QmlUi:
qmlDocumentSourceIds.insert(qmlDocumentSourceIds.end(), sourceIds.begin(), sourceIds.end());
break;
case SourceType::QmlTypes:
qmltypesSourceIds.insert(qmltypesSourceIds.end(), sourceIds.begin(), sourceIds.end());
break;
}
} }
auto updateDirectory = [&](const SourceIds &directorySourceIds,
WatchedSourceIds &watchedSourceIds) {
auto directoryIds = filterUniqueSourceContextIds(directorySourceIds); auto directoryIds = filterUniqueSourceContextIds(directorySourceIds);
for (auto directoryId : directoryIds) { for (auto directoryId : directoryIds) {
Utils::PathString directory = m_pathCache.sourceContextPath(directoryId); Utils::PathString directory = m_pathCache.sourceContextPath(directoryId);
updateDirectory(directory, directoryIds, package, notUpdatedSourceIds, watchedSourceIds); this->updateDirectory(directory,
directoryIds,
package,
notUpdatedSourceIds,
watchedSourceIds,
IsInsideProject::No);
} }
for (SourceId sourceId : filterUniqueSourceIds(qmlDocumentSourceIds)) { return directoryIds;
};
auto qtDirectoryIds = updateDirectory(qt.directory, watchedQtSourceIds);
auto projectDirectoryIds = updateDirectory(project.directory, watchedProjectSourceIds);
auto parseQmlComponent = [&](SourceIds qmlDocumentSourceIds,
const SourceContextIds &directoryIds,
IsInsideProject isInsideProject) {
for (SourceId sourceId : filterUniqueSourceIds(std::move(qmlDocumentSourceIds))) {
if (!contains(directoryIds, sourceId.contextId())) if (!contains(directoryIds, sourceId.contextId()))
parseQmlComponent(sourceId, package, notUpdatedSourceIds); this->parseQmlComponent(sourceId, package, notUpdatedSourceIds, isInsideProject);
} }
};
try { parseQmlComponent(std::move(qt.qmlDocument), qtDirectoryIds, IsInsideProject::No);
parseQmlComponent(std::move(project.qmlDocument), projectDirectoryIds, IsInsideProject::Yes);
auto parseTypeInfo = [&](SourceIds qmltypesSourceIds,
const SourceContextIds &directoryIds,
IsInsideProject isInsideProject) {
for (SourceId sourceId : filterUniqueSourceIds(std::move(qmltypesSourceIds))) { for (SourceId sourceId : filterUniqueSourceIds(std::move(qmltypesSourceIds))) {
if (!contains(directoryIds, sourceId.contextId())) { if (!contains(directoryIds, sourceId.contextId())) {
QString qmltypesPath{m_pathCache.sourcePath(sourceId)}; QString qmltypesPath{m_pathCache.sourcePath(sourceId)};
auto directoryInfo = m_projectStorage.fetchDirectoryInfo(sourceId); auto directoryInfo = m_projectStorage.fetchDirectoryInfo(sourceId);
if (directoryInfo) if (directoryInfo)
parseTypeInfo(*directoryInfo, qmltypesPath, package, notUpdatedSourceIds); this->parseTypeInfo(*directoryInfo,
qmltypesPath,
package,
notUpdatedSourceIds,
isInsideProject);
} }
} }
};
try {
parseTypeInfo(std::move(qt.qmltypes), qtDirectoryIds, IsInsideProject::No);
parseTypeInfo(std::move(project.qmltypes), projectDirectoryIds, IsInsideProject::Yes);
} catch (const QmlDesigner::CannotParseQmlTypesFile &) { } catch (const QmlDesigner::CannotParseQmlTypesFile &) {
return; return;
} }
@@ -992,9 +1099,17 @@ void ProjectStorageUpdater::pathsWithIdsChanged(const std::vector<IdPaths> &chan
return; return;
} }
if (directoryIds.size()) { auto directoryIdsSize = projectDirectoryIds.size() + qtDirectoryIds.size();
m_pathWatcher.updateContextIdPaths(createIdPaths(watchedSourceIds, m_projectPartId), if (directoryIdsSize > 0) {
directoryIds); SourceContextIds directoryIds;
std::vector<IdPaths> newIdPaths;
idPaths.reserve(8);
appendIdPaths(std::move(watchedQtSourceIds), m_qtPartId, newIdPaths);
appendIdPaths(std::move(watchedProjectSourceIds), m_projectPartId, newIdPaths);
directoryIds.reserve(directoryIdsSize);
std::ranges::merge(projectDirectoryIds, qtDirectoryIds, std::back_inserter(directoryIds));
m_pathWatcher.updateContextIdPaths(newIdPaths, directoryIds);
} }
m_changedIdPaths.clear(); m_changedIdPaths.clear();
@@ -1010,7 +1125,8 @@ void ProjectStorageUpdater::parseTypeInfos(const QStringList &typeInfos,
ModuleId moduleId, ModuleId moduleId,
Storage::Synchronization::SynchronizationPackage &package, Storage::Synchronization::SynchronizationPackage &package,
NotUpdatedSourceIds &notUpdatedSourceIds, NotUpdatedSourceIds &notUpdatedSourceIds,
WatchedSourceIdsIds &watchedSourceIds) WatchedSourceIds &watchedSourceIds,
IsInsideProject isInsideProject)
{ {
NanotraceHR::Tracer tracer{"parse type infos", NanotraceHR::Tracer tracer{"parse type infos",
category(), category(),
@@ -1043,7 +1159,7 @@ void ProjectStorageUpdater::parseTypeInfos(const QStringList &typeInfos,
const QString qmltypesPath = directoryPath + "/" + typeInfo; const QString qmltypesPath = directoryPath + "/" + typeInfo;
parseTypeInfo(directoryInfo, qmltypesPath, package, notUpdatedSourceIds); parseTypeInfo(directoryInfo, qmltypesPath, package, notUpdatedSourceIds, isInsideProject);
} }
} }
@@ -1051,7 +1167,8 @@ void ProjectStorageUpdater::parseDirectoryInfos(
const Storage::Synchronization::DirectoryInfos &directoryInfos, const Storage::Synchronization::DirectoryInfos &directoryInfos,
Storage::Synchronization::SynchronizationPackage &package, Storage::Synchronization::SynchronizationPackage &package,
NotUpdatedSourceIds &notUpdatedSourceIds, NotUpdatedSourceIds &notUpdatedSourceIds,
WatchedSourceIdsIds &watchedSourceIds) WatchedSourceIds &watchedSourceIds,
IsInsideProject isInsideProject)
{ {
NanotraceHR::Tracer tracer{"parse project datas", category()}; NanotraceHR::Tracer tracer{"parse project datas", category()};
@@ -1061,13 +1178,13 @@ void ProjectStorageUpdater::parseDirectoryInfos(
watchedSourceIds.qmltypesSourceIds.push_back(directoryInfo.sourceId); watchedSourceIds.qmltypesSourceIds.push_back(directoryInfo.sourceId);
QString qmltypesPath{m_pathCache.sourcePath(directoryInfo.sourceId)}; QString qmltypesPath{m_pathCache.sourcePath(directoryInfo.sourceId)};
parseTypeInfo(directoryInfo, qmltypesPath, package, notUpdatedSourceIds); parseTypeInfo(directoryInfo, qmltypesPath, package, notUpdatedSourceIds, isInsideProject);
break; break;
} }
case Storage::Synchronization::FileType::QmlDocument: { case Storage::Synchronization::FileType::QmlDocument: {
watchedSourceIds.qmlSourceIds.push_back(directoryInfo.sourceId); watchedSourceIds.qmlSourceIds.push_back(directoryInfo.sourceId);
parseQmlComponent(directoryInfo.sourceId, package, notUpdatedSourceIds); parseQmlComponent(directoryInfo.sourceId, package, notUpdatedSourceIds, isInsideProject);
break; break;
} }
case Storage::Synchronization::FileType::Directory: case Storage::Synchronization::FileType::Directory:
@@ -1079,11 +1196,10 @@ void ProjectStorageUpdater::parseDirectoryInfos(
auto ProjectStorageUpdater::parseTypeInfo(const Storage::Synchronization::DirectoryInfo &directoryInfo, auto ProjectStorageUpdater::parseTypeInfo(const Storage::Synchronization::DirectoryInfo &directoryInfo,
const QString &qmltypesPath, const QString &qmltypesPath,
Storage::Synchronization::SynchronizationPackage &package, Storage::Synchronization::SynchronizationPackage &package,
NotUpdatedSourceIds &notUpdatedSourceIds) -> FileState NotUpdatedSourceIds &notUpdatedSourceIds,
IsInsideProject isInsideProject) -> FileState
{ {
NanotraceHR::Tracer tracer{"parse type info", NanotraceHR::Tracer tracer{"parse type info", category(), keyValue("qmltypes path", qmltypesPath)};
category(),
keyValue("qmltypes path", qmltypesPath)};
auto state = fileState(directoryInfo.sourceId, package, notUpdatedSourceIds); auto state = fileState(directoryInfo.sourceId, package, notUpdatedSourceIds);
switch (state) { switch (state) {
@@ -1093,7 +1209,7 @@ auto ProjectStorageUpdater::parseTypeInfo(const Storage::Synchronization::Direct
package.updatedSourceIds.push_back(directoryInfo.sourceId); package.updatedSourceIds.push_back(directoryInfo.sourceId);
const auto content = m_fileSystem.contentAsQString(qmltypesPath); const auto content = m_fileSystem.contentAsQString(qmltypesPath);
m_qmlTypesParser.parse(content, package.imports, package.types, directoryInfo); m_qmlTypesParser.parse(content, package.imports, package.types, directoryInfo, isInsideProject);
break; break;
} }
case FileState::Unchanged: { case FileState::Unchanged: {
@@ -1118,9 +1234,10 @@ void ProjectStorageUpdater::parseQmlComponent(Utils::SmallStringView relativeFil
SourceContextId directoryId, SourceContextId directoryId,
Storage::Synchronization::SynchronizationPackage &package, Storage::Synchronization::SynchronizationPackage &package,
NotUpdatedSourceIds &notUpdatedSourceIds, NotUpdatedSourceIds &notUpdatedSourceIds,
WatchedSourceIdsIds &watchedSourceIds, WatchedSourceIds &watchedSourceIds,
FileState qmldirState, FileState qmldirState,
SourceId qmldirSourceId) SourceId qmldirSourceId,
IsInsideProject isInsideProject)
{ {
NanotraceHR::Tracer tracer{"parse qml component", NanotraceHR::Tracer tracer{"parse qml component",
category(), category(),
@@ -1171,7 +1288,7 @@ void ProjectStorageUpdater::parseQmlComponent(Utils::SmallStringView relativeFil
case FileState::Changed: case FileState::Changed:
tracer.tick("update from qml document", keyValue("source id", sourceId)); tracer.tick("update from qml document", keyValue("source id", sourceId));
const auto content = m_fileSystem.contentAsQString(QString{qmlFilePath}); const auto content = m_fileSystem.contentAsQString(QString{qmlFilePath});
type = m_qmlDocumentParser.parse(content, package.imports, sourceId, directoryPath); type = m_qmlDocumentParser.parse(content, package.imports, sourceId, directoryPath, isInsideProject);
break; break;
} }
@@ -1193,7 +1310,8 @@ void ProjectStorageUpdater::parseQmlComponent(Utils::SmallStringView relativeFil
void ProjectStorageUpdater::parseQmlComponent(SourceId sourceId, void ProjectStorageUpdater::parseQmlComponent(SourceId sourceId,
Storage::Synchronization::SynchronizationPackage &package, Storage::Synchronization::SynchronizationPackage &package,
NotUpdatedSourceIds &notUpdatedSourceIds) NotUpdatedSourceIds &notUpdatedSourceIds,
IsInsideProject isInsideProject)
{ {
NanotraceHR::Tracer tracer{"parse qml component", category(), keyValue("source id", sourceId)}; NanotraceHR::Tracer tracer{"parse qml component", category(), keyValue("source id", sourceId)};
@@ -1210,7 +1328,11 @@ void ProjectStorageUpdater::parseQmlComponent(SourceId sourceId,
SourcePath sourcePath = m_pathCache.sourcePath(sourceId); SourcePath sourcePath = m_pathCache.sourcePath(sourceId);
const auto content = m_fileSystem.contentAsQString(QString{sourcePath}); const auto content = m_fileSystem.contentAsQString(QString{sourcePath});
auto type = m_qmlDocumentParser.parse(content, package.imports, sourceId, sourcePath.directory()); auto type = m_qmlDocumentParser.parse(content,
package.imports,
sourceId,
sourcePath.directory(),
isInsideProject);
type.typeName = sourcePath.name(); type.typeName = sourcePath.name();
type.traits = Storage::TypeTraitsKind::Reference; type.traits = Storage::TypeTraitsKind::Reference;
@@ -1222,15 +1344,6 @@ void ProjectStorageUpdater::parseQmlComponent(SourceId sourceId,
package.types.push_back(std::move(type)); package.types.push_back(std::move(type));
} }
ProjectStorageUpdater::FileState ProjectStorageUpdater::fileState(
SourceContextId sourceContextId,
Storage::Synchronization::SynchronizationPackage &package,
NotUpdatedSourceIds &notUpdatedSourceIds) const
{
auto sourceId = SourceId::create(SourceNameId{}, sourceContextId);
return fileState(sourceId, package, notUpdatedSourceIds);
}
namespace { namespace {
template<typename Callback> template<typename Callback>
@@ -1289,9 +1402,10 @@ void ProjectStorageUpdater::parseQmlComponents(Components components,
SourceContextId directoryId, SourceContextId directoryId,
Storage::Synchronization::SynchronizationPackage &package, Storage::Synchronization::SynchronizationPackage &package,
NotUpdatedSourceIds &notUpdatedSourceIds, NotUpdatedSourceIds &notUpdatedSourceIds,
WatchedSourceIdsIds &watchedSourceIdsIds, WatchedSourceIds &WatchedSourceIds,
FileState qmldirState, FileState qmldirState,
SourceId qmldirSourceId) SourceId qmldirSourceId,
IsInsideProject isInsideProject)
{ {
NanotraceHR::Tracer tracer{"parse qml components", NanotraceHR::Tracer tracer{"parse qml components",
category(), category(),
@@ -1312,9 +1426,10 @@ void ProjectStorageUpdater::parseQmlComponents(Components components,
directoryId, directoryId,
package, package,
notUpdatedSourceIds, notUpdatedSourceIds,
watchedSourceIdsIds, WatchedSourceIds,
qmldirState, qmldirState,
qmldirSourceId); qmldirSourceId,
isInsideProject);
}; };
rangeForTheSameFileName(components, callback); rangeForTheSameFileName(components, callback);
@@ -1368,4 +1483,13 @@ ProjectStorageUpdater::FileState ProjectStorageUpdater::fileState(
return FileState::Unchanged; return FileState::Unchanged;
} }
ProjectStorageUpdater::FileState ProjectStorageUpdater::fileState(
SourceContextId sourceContextId,
Storage::Synchronization::SynchronizationPackage &package,
NotUpdatedSourceIds &notUpdatedSourceIds) const
{
auto sourceId = SourceId::create(SourceNameId{}, sourceContextId);
return fileState(sourceId, package, notUpdatedSourceIds);
}
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -50,7 +50,8 @@ public:
QmlTypesParserInterface &qmlTypesParser, QmlTypesParserInterface &qmlTypesParser,
class ProjectStoragePathWatcherInterface &pathWatcher, class ProjectStoragePathWatcherInterface &pathWatcher,
ProjectStorageErrorNotifierInterface &errorNotifier, ProjectStorageErrorNotifierInterface &errorNotifier,
ProjectPartId projectPartId) ProjectPartId projectPartId,
ProjectPartId qtPartId)
: m_fileSystem{fileSystem} : m_fileSystem{fileSystem}
, m_projectStorage{projectStorage} , m_projectStorage{projectStorage}
, m_fileStatusCache{fileStatusCache} , m_fileStatusCache{fileStatusCache}
@@ -60,13 +61,15 @@ public:
, m_pathWatcher{pathWatcher} , m_pathWatcher{pathWatcher}
, m_errorNotifier{errorNotifier} , m_errorNotifier{errorNotifier}
, m_projectPartId{projectPartId} , m_projectPartId{projectPartId}
, m_qtPartId{qtPartId}
{} {}
struct Update struct Update
{ {
QStringList directories = {}; QStringList qtDirectories = {};
const QString propertyEditorResourcesPath = {}; const QString propertyEditorResourcesPath = {};
const QStringList typeAnnotationPaths = {}; const QStringList typeAnnotationPaths = {};
QString projectDirectory = {};
}; };
void update(Update update); void update(Update update);
@@ -106,9 +109,9 @@ public:
enum class FileState { Unchanged, Changed, NotExists, NotExistsUnchanged, Added, Removed }; enum class FileState { Unchanged, Changed, NotExists, NotExistsUnchanged, Added, Removed };
struct WatchedSourceIdsIds struct WatchedSourceIds
{ {
WatchedSourceIdsIds(std::size_t reserve) WatchedSourceIds(std::size_t reserve)
{ {
directoryIds.reserve(reserve); directoryIds.reserve(reserve);
qmldirSourceIds.reserve(reserve); qmldirSourceIds.reserve(reserve);
@@ -135,23 +138,25 @@ public:
}; };
private: private:
using IsInsideProject = Storage::IsInsideProject;
void updateDirectories(const QStringList &directories, void updateDirectories(const QStringList &directories,
Storage::Synchronization::SynchronizationPackage &package, Storage::Synchronization::SynchronizationPackage &package,
NotUpdatedSourceIds &notUpdatedSourceIds, NotUpdatedSourceIds &notUpdatedSourceIds,
WatchedSourceIdsIds &watchedSourceIdsIds); WatchedSourceIds &WatchedSourceIds);
void updateDirectory(const Utils::PathString &directory, void updateDirectory(const Utils::PathString &directory,
const SourceContextIds &subdirecoriesToIgnore, const SourceContextIds &subdirecoriesToIgnore,
Storage::Synchronization::SynchronizationPackage &package, Storage::Synchronization::SynchronizationPackage &package,
NotUpdatedSourceIds &notUpdatedSourceIds, NotUpdatedSourceIds &notUpdatedSourceIds,
WatchedSourceIdsIds &watchedSourceIdsIds); WatchedSourceIds &WatchedSourceIds,
IsInsideProject isInsideProject);
void updateSubdirectories(const Utils::PathString &directory, void updateSubdirectories(const Utils::PathString &directory,
SourceContextId directoryId, SourceContextId directoryId,
FileState directoryFileState, FileState directoryFileState,
const SourceContextIds &subdirecoriesToIgnore, const SourceContextIds &subdirecoriesToIgnore,
Storage::Synchronization::SynchronizationPackage &package, Storage::Synchronization::SynchronizationPackage &package,
NotUpdatedSourceIds &notUpdatedSourceIds, NotUpdatedSourceIds &notUpdatedSourceIds,
WatchedSourceIdsIds &watchedSourceIdsIds); WatchedSourceIds &WatchedSourceIds,
IsInsideProject isInsideProject);
void updateDirectoryChanged(Utils::SmallStringView directoryPath, void updateDirectoryChanged(Utils::SmallStringView directoryPath,
Utils::SmallStringView annotationDirectoryPath, Utils::SmallStringView annotationDirectoryPath,
FileState qmldirState, FileState qmldirState,
@@ -162,24 +167,22 @@ private:
SourceContextId annotationDirectoryId, SourceContextId annotationDirectoryId,
Storage::Synchronization::SynchronizationPackage &package, Storage::Synchronization::SynchronizationPackage &package,
NotUpdatedSourceIds &notUpdatedSourceIds, NotUpdatedSourceIds &notUpdatedSourceIds,
WatchedSourceIdsIds &watchedSourceIdsIds, WatchedSourceIds &WatchedSourceIds,
IsInsideProject isInsideProject,
ProjectStorageTracing::Category::TracerType &tracer); ProjectStorageTracing::Category::TracerType &tracer);
void annotationDirectoryChanged(Utils::SmallStringView directoryPath, void annotationDirectoryChanged(Utils::SmallStringView directoryPath,
SourceContextId directoryId, SourceContextId directoryId,
SourceContextId annotationDirectoryId, SourceContextId annotationDirectoryId,
ModuleId moduleId, ModuleId moduleId,
Storage::Synchronization::SynchronizationPackage &package, Storage::Synchronization::SynchronizationPackage &package);
NotUpdatedSourceIds &notUpdatedSourceIds);
void updatePropertyEditorFiles(Utils::SmallStringView directyPath, void updatePropertyEditorFiles(Utils::SmallStringView directyPath,
SourceContextId directoryId, SourceContextId directoryId,
ModuleId moduleId, ModuleId moduleId,
Storage::Synchronization::SynchronizationPackage &package, Storage::Synchronization::SynchronizationPackage &package);
NotUpdatedSourceIds &notUpdatedSourceIds);
void updatePropertyEditorFile(const QString &fileName, void updatePropertyEditorFile(const QString &fileName,
SourceContextId directoryId, SourceContextId directoryId,
ModuleId moduleId, ModuleId moduleId,
Storage::Synchronization::SynchronizationPackage &package, Storage::Synchronization::SynchronizationPackage &package);
NotUpdatedSourceIds &notUpdatedSourceIds);
void updatePropertyEditorPaths(const QString &propertyEditorResourcesPath, void updatePropertyEditorPaths(const QString &propertyEditorResourcesPath,
Storage::Synchronization::SynchronizationPackage &package, Storage::Synchronization::SynchronizationPackage &package,
NotUpdatedSourceIds &notUpdatedSourceIds); NotUpdatedSourceIds &notUpdatedSourceIds);
@@ -215,34 +218,40 @@ private:
ModuleId moduleId, ModuleId moduleId,
Storage::Synchronization::SynchronizationPackage &package, Storage::Synchronization::SynchronizationPackage &package,
NotUpdatedSourceIds &notUpdatedSourceIds, NotUpdatedSourceIds &notUpdatedSourceIds,
WatchedSourceIdsIds &watchedSourceIdsIds); WatchedSourceIds &WatchedSourceIds,
IsInsideProject isInsideProject);
void parseDirectoryInfos(const Storage::Synchronization::DirectoryInfos &directoryInfos, void parseDirectoryInfos(const Storage::Synchronization::DirectoryInfos &directoryInfos,
Storage::Synchronization::SynchronizationPackage &package, Storage::Synchronization::SynchronizationPackage &package,
NotUpdatedSourceIds &notUpdatedSourceIds, NotUpdatedSourceIds &notUpdatedSourceIds,
WatchedSourceIdsIds &watchedSourceIdsIds); WatchedSourceIds &WatchedSourceIds,
IsInsideProject isInsideProject);
FileState parseTypeInfo(const Storage::Synchronization::DirectoryInfo &directoryInfo, FileState parseTypeInfo(const Storage::Synchronization::DirectoryInfo &directoryInfo,
const QString &qmltypesPath, const QString &qmltypesPath,
Storage::Synchronization::SynchronizationPackage &package, Storage::Synchronization::SynchronizationPackage &package,
NotUpdatedSourceIds &notUpdatedSourceIds); NotUpdatedSourceIds &notUpdatedSourceIds,
IsInsideProject isInsideProject);
void parseQmlComponents(Components components, void parseQmlComponents(Components components,
SourceContextId directoryId, SourceContextId directoryId,
Storage::Synchronization::SynchronizationPackage &package, Storage::Synchronization::SynchronizationPackage &package,
NotUpdatedSourceIds &notUpdatedSourceIds, NotUpdatedSourceIds &notUpdatedSourceIds,
WatchedSourceIdsIds &watchedSourceIdsIds, WatchedSourceIds &WatchedSourceIds,
FileState qmldirState, FileState qmldirState,
SourceId qmldirSourceId); SourceId qmldirSourceId,
IsInsideProject isInsideProject);
void parseQmlComponent(Utils::SmallStringView fileName, void parseQmlComponent(Utils::SmallStringView fileName,
Utils::SmallStringView directory, Utils::SmallStringView directory,
Storage::Synchronization::ExportedTypes exportedTypes, Storage::Synchronization::ExportedTypes exportedTypes,
SourceContextId directoryId, SourceContextId directoryId,
Storage::Synchronization::SynchronizationPackage &package, Storage::Synchronization::SynchronizationPackage &package,
NotUpdatedSourceIds &notUpdatedSourceIds, NotUpdatedSourceIds &notUpdatedSourceIds,
WatchedSourceIdsIds &watchedSourceIdsIds, WatchedSourceIds &WatchedSourceIds,
FileState qmldirState, FileState qmldirState,
SourceId qmldirSourceId); SourceId qmldirSourceId,
IsInsideProject isInsideProject);
void parseQmlComponent(SourceId sourceId, void parseQmlComponent(SourceId sourceId,
Storage::Synchronization::SynchronizationPackage &package, Storage::Synchronization::SynchronizationPackage &package,
NotUpdatedSourceIds &notUpdatedSourceIds); NotUpdatedSourceIds &notUpdatedSourceIds,
IsInsideProject isInsideProject);
FileState fileState(SourceId sourceId, FileState fileState(SourceId sourceId,
Storage::Synchronization::SynchronizationPackage &package, Storage::Synchronization::SynchronizationPackage &package,
@@ -262,6 +271,7 @@ private:
ProjectStoragePathWatcherInterface &m_pathWatcher; ProjectStoragePathWatcherInterface &m_pathWatcher;
ProjectStorageErrorNotifierInterface &m_errorNotifier; ProjectStorageErrorNotifierInterface &m_errorNotifier;
ProjectPartId m_projectPartId; ProjectPartId m_projectPartId;
ProjectPartId m_qtPartId;
}; };
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -25,6 +25,7 @@ namespace QmlDesigner {
constexpr auto category = ProjectStorageTracing::projectStorageUpdaterCategory; constexpr auto category = ProjectStorageTracing::projectStorageUpdaterCategory;
using NanotraceHR::keyValue; using NanotraceHR::keyValue;
using Storage::IsInsideProject;
using Tracer = ProjectStorageTracing::Category::TracerType; using Tracer = ProjectStorageTracing::Category::TracerType;
namespace QmlDom = QQmlJS::Dom; namespace QmlDom = QQmlJS::Dom;
@@ -306,7 +307,7 @@ bool isSingleton(const QmlDom::QmlFile *qmlFile)
return std::ranges::find(pragmas, "Singleton"_L1, &QQmlJS::Dom::Pragma::name) != pragmas.end(); return std::ranges::find(pragmas, "Singleton"_L1, &QQmlJS::Dom::Pragma::name) != pragmas.end();
} }
Storage::TypeTraits createTypeTraits(const QmlDom::QmlFile *qmlFile) Storage::TypeTraits createTypeTraits(const QmlDom::QmlFile *qmlFile, IsInsideProject isInsideProject)
{ {
Storage::TypeTraits traits = Storage::TypeTraitsKind::Reference; Storage::TypeTraits traits = Storage::TypeTraitsKind::Reference;
@@ -314,6 +315,8 @@ Storage::TypeTraits createTypeTraits(const QmlDom::QmlFile *qmlFile)
traits.isSingleton = isSingleton(qmlFile); traits.isSingleton = isSingleton(qmlFile);
traits.isInsideProject = isInsideProject == IsInsideProject::Yes;
return traits; return traits;
} }
@@ -322,7 +325,8 @@ Storage::TypeTraits createTypeTraits(const QmlDom::QmlFile *qmlFile)
Storage::Synchronization::Type QmlDocumentParser::parse(const QString &sourceContent, Storage::Synchronization::Type QmlDocumentParser::parse(const QString &sourceContent,
Storage::Imports &imports, Storage::Imports &imports,
SourceId sourceId, SourceId sourceId,
Utils::SmallStringView directoryPath) Utils::SmallStringView directoryPath,
IsInsideProject isInsideProject)
{ {
NanotraceHR::Tracer tracer{"qml document parser parse", NanotraceHR::Tracer tracer{"qml document parser parse",
category(), category(),
@@ -372,7 +376,7 @@ Storage::Synchronization::Type QmlDocumentParser::parse(const QString &sourceCon
directoryPath, directoryPath,
m_storage); m_storage);
type.traits = createTypeTraits(qmlFile); type.traits = createTypeTraits(qmlFile, isInsideProject);
type.prototype = createImportedTypeName(qmlObject.name(), qualifiedImports); type.prototype = createImportedTypeName(qmlObject.name(), qualifiedImports);
type.defaultPropertyName = qmlObject.localDefaultPropertyName(); type.defaultPropertyName = qmlObject.localDefaultPropertyName();
addImports(imports, qmlFile->imports(), sourceId, directoryPath, m_storage); addImports(imports, qmlFile->imports(), sourceId, directoryPath, m_storage);
@@ -390,7 +394,8 @@ Storage::Synchronization::Type QmlDocumentParser::parse(
[[maybe_unused]] const QString &sourceContent, [[maybe_unused]] const QString &sourceContent,
[[maybe_unused]] Storage::Imports &imports, [[maybe_unused]] Storage::Imports &imports,
[[maybe_unused]] SourceId sourceId, [[maybe_unused]] SourceId sourceId,
[[maybe_unused]] Utils::SmallStringView directoryPath) [[maybe_unused]] Utils::SmallStringView directoryPath,
[[maybe_unused]] IsInsideProject isInsideProject)
{ {
return Storage::Synchronization::Type{}; return Storage::Synchronization::Type{};
} }

View File

@@ -32,7 +32,8 @@ public:
Storage::Synchronization::Type parse(const QString &sourceContent, Storage::Synchronization::Type parse(const QString &sourceContent,
Storage::Imports &imports, Storage::Imports &imports,
SourceId sourceId, SourceId sourceId,
Utils::SmallStringView directoryPath) override; Utils::SmallStringView directoryPath,
IsInsideProject isInsideProject) override;
private: private:
// m_pathCache and m_storage are only used when compiled for QDS // m_pathCache and m_storage are only used when compiled for QDS

View File

@@ -12,10 +12,13 @@ namespace QmlDesigner {
class QmlDocumentParserInterface class QmlDocumentParserInterface
{ {
public: public:
using IsInsideProject = Storage::IsInsideProject;
virtual Storage::Synchronization::Type parse(const QString &sourceContent, virtual Storage::Synchronization::Type parse(const QString &sourceContent,
Storage::Imports &imports, Storage::Imports &imports,
SourceId sourceId, SourceId sourceId,
Utils::SmallStringView directoryPath) Utils::SmallStringView directoryPath,
IsInsideProject isInsideProject)
= 0; = 0;
protected: protected:

View File

@@ -27,6 +27,7 @@ namespace QmlDesigner {
constexpr auto category = ProjectStorageTracing::projectStorageUpdaterCategory; constexpr auto category = ProjectStorageTracing::projectStorageUpdaterCategory;
using NanotraceHR::keyValue; using NanotraceHR::keyValue;
using Storage::IsInsideProject;
using Tracer = ProjectStorageTracing::Category::TracerType; using Tracer = ProjectStorageTracing::Category::TracerType;
using Storage::ModuleKind; using Storage::ModuleKind;
namespace QmlDom = QQmlJS::Dom; namespace QmlDom = QQmlJS::Dom;
@@ -120,15 +121,16 @@ Storage::TypeTraits createAccessTypeTraits(QQmlJSScope::AccessSemantics accessSe
Storage::TypeTraits createTypeTraits(QQmlJSScope::AccessSemantics accessSematics, Storage::TypeTraits createTypeTraits(QQmlJSScope::AccessSemantics accessSematics,
bool hasCustomParser, bool hasCustomParser,
bool isSingleton) bool isSingleton,
IsInsideProject isInsideProject)
{ {
auto typeTrait = createAccessTypeTraits(accessSematics); auto typeTrait = createAccessTypeTraits(accessSematics);
if (hasCustomParser) typeTrait.usesCustomParser = hasCustomParser;
typeTrait.usesCustomParser = true;
if (isSingleton) typeTrait.isSingleton = isSingleton;
typeTrait.isSingleton = true;
typeTrait.isInsideProject = isInsideProject == IsInsideProject::Yes;
return typeTrait; return typeTrait;
} }
@@ -444,7 +446,8 @@ void addType(Storage::Synchronization::Types &types,
ModuleId cppModuleId, ModuleId cppModuleId,
const QQmlJSExportedScope &exportScope, const QQmlJSExportedScope &exportScope,
QmlTypesParser::ProjectStorage &storage, QmlTypesParser::ProjectStorage &storage,
const ComponentWithoutNamespaces &componentNameWithoutNamespace) const ComponentWithoutNamespaces &componentNameWithoutNamespace,
IsInsideProject isInsideProject)
{ {
NanotraceHR::Tracer tracer{"add type", NanotraceHR::Tracer tracer{"add type",
category(), category(),
@@ -466,7 +469,8 @@ void addType(Storage::Synchronization::Types &types,
Storage::Synchronization::ImportedType{extensionTypeName(component)}, Storage::Synchronization::ImportedType{extensionTypeName(component)},
createTypeTraits(component.accessSemantics(), createTypeTraits(component.accessSemantics(),
component.hasCustomParser(), component.hasCustomParser(),
component.isSingleton()), component.isSingleton(),
isInsideProject),
sourceId, sourceId,
createExports(exports, typeName, storage, cppModuleId), createExports(exports, typeName, storage, cppModuleId),
createProperties(component.ownProperties(), enumerationTypes, componentNameWithoutNamespace), createProperties(component.ownProperties(), enumerationTypes, componentNameWithoutNamespace),
@@ -509,7 +513,8 @@ void addTypes(Storage::Synchronization::Types &types,
const Storage::Synchronization::DirectoryInfo &directoryInfo, const Storage::Synchronization::DirectoryInfo &directoryInfo,
const QList<QQmlJSExportedScope> &objects, const QList<QQmlJSExportedScope> &objects,
QmlTypesParser::ProjectStorage &storage, QmlTypesParser::ProjectStorage &storage,
const ComponentWithoutNamespaces &componentNameWithoutNamespaces) const ComponentWithoutNamespaces &componentNameWithoutNamespaces,
IsInsideProject isInsideProject)
{ {
NanotraceHR::Tracer tracer{"add types", category()}; NanotraceHR::Tracer tracer{"add types", category()};
types.reserve(Utils::usize(objects) + types.size()); types.reserve(Utils::usize(objects) + types.size());
@@ -525,7 +530,8 @@ void addTypes(Storage::Synchronization::Types &types,
directoryInfo.moduleId, directoryInfo.moduleId,
object, object,
storage, storage,
componentNameWithoutNamespaces); componentNameWithoutNamespaces,
isInsideProject);
} }
} }
@@ -534,7 +540,8 @@ void addTypes(Storage::Synchronization::Types &types,
void QmlTypesParser::parse(const QString &sourceContent, void QmlTypesParser::parse(const QString &sourceContent,
Storage::Imports &imports, Storage::Imports &imports,
Storage::Synchronization::Types &types, Storage::Synchronization::Types &types,
const Storage::Synchronization::DirectoryInfo &directoryInfo) const Storage::Synchronization::DirectoryInfo &directoryInfo,
IsInsideProject isInsideProject)
{ {
NanotraceHR::Tracer tracer{"qmltypes parser parse", category()}; NanotraceHR::Tracer tracer{"qmltypes parser parse", category()};
@@ -548,7 +555,7 @@ void QmlTypesParser::parse(const QString &sourceContent,
auto componentNameWithoutNamespaces = createComponentNameWithoutNamespaces(components); auto componentNameWithoutNamespaces = createComponentNameWithoutNamespaces(components);
addImports(imports, directoryInfo.sourceId, dependencies, m_storage, directoryInfo.moduleId); addImports(imports, directoryInfo.sourceId, dependencies, m_storage, directoryInfo.moduleId);
addTypes(types, directoryInfo, components, m_storage, componentNameWithoutNamespaces); addTypes(types, directoryInfo, components, m_storage, componentNameWithoutNamespaces, isInsideProject);
} }
#else #else
@@ -556,7 +563,8 @@ void QmlTypesParser::parse(const QString &sourceContent,
void QmlTypesParser::parse([[maybe_unused]] const QString &sourceContent, void QmlTypesParser::parse([[maybe_unused]] const QString &sourceContent,
[[maybe_unused]] Storage::Imports &imports, [[maybe_unused]] Storage::Imports &imports,
[[maybe_unused]] Storage::Synchronization::Types &types, [[maybe_unused]] Storage::Synchronization::Types &types,
[[maybe_unused]] const Storage::Synchronization::DirectoryInfo &directoryInfo) [[maybe_unused]] const Storage::Synchronization::DirectoryInfo &directoryInfo,
[[maybe_unused]] IsInsideProject isInsideProject)
{} {}
#endif #endif

View File

@@ -33,7 +33,8 @@ public:
void parse(const QString &sourceContent, void parse(const QString &sourceContent,
Storage::Imports &imports, Storage::Imports &imports,
Storage::Synchronization::Types &types, Storage::Synchronization::Types &types,
const Storage::Synchronization::DirectoryInfo &directoryInfo) override; const Storage::Synchronization::DirectoryInfo &directoryInfo,
IsInsideProject isInsideProject) override;
private: private:
#ifdef QDS_BUILD_QMLPARSER #ifdef QDS_BUILD_QMLPARSER

View File

@@ -12,10 +12,13 @@ namespace QmlDesigner {
class QmlTypesParserInterface class QmlTypesParserInterface
{ {
public: public:
using IsInsideProject = Storage::IsInsideProject;
virtual void parse(const QString &sourceContent, virtual void parse(const QString &sourceContent,
Storage::Imports &imports, Storage::Imports &imports,
Storage::Synchronization::Types &types, Storage::Synchronization::Types &types,
const Storage::Synchronization::DirectoryInfo &directoryInfo) const Storage::Synchronization::DirectoryInfo &directoryInfo,
IsInsideProject isInsideProject)
= 0; = 0;
protected: protected:

View File

@@ -184,6 +184,24 @@ Sqlite::JournalMode projectStorageJournalMode()
return Sqlite::JournalMode::Wal; return Sqlite::JournalMode::Wal;
} }
[[maybe_unused]] QString qmlPath(::ProjectExplorer::Target *target)
{
auto qt = QtSupport::QtKitAspect::qtVersion(target->kit());
if (qt)
return qt->qmlPath().path();
return QLibraryInfo::path(QLibraryInfo::QmlImportsPath);
}
[[maybe_unused]] QString qmlPath(::ProjectExplorer::Project *project)
{
auto qt = QtSupport::QtKitAspect::qtVersion(project->activeKit());
if (qt)
return qt->qmlPath().path();
return QLibraryInfo::path(QLibraryInfo::QmlImportsPath);
}
class ProjectStorageData class ProjectStorageData
{ {
public: public:
@@ -195,7 +213,10 @@ public:
, qmlDocumentParser{storage, pathCache} , qmlDocumentParser{storage, pathCache}
, pathWatcher{pathCache, fileSystem, &updater} , pathWatcher{pathCache, fileSystem, &updater}
, projectPartId{ProjectPartId::create( , projectPartId{ProjectPartId::create(
pathCache.sourceId(SourcePath{project->projectDirectory().toUrlishString() + "/."}).internalId())} pathCache.sourceContextId(Utils::PathString{project->projectDirectory().path()})
.internalId())}
, qtPartId{ProjectPartId::create(
pathCache.sourceContextId(Utils::PathString{qmlPath(project)}).internalId())}
, updater{fileSystem, , updater{fileSystem,
storage, storage,
fileStatusCache, fileStatusCache,
@@ -204,7 +225,8 @@ public:
qmlTypesParser, qmlTypesParser,
pathWatcher, pathWatcher,
errorNotifier, errorNotifier,
projectPartId} projectPartId,
qtPartId}
{} {}
Sqlite::Database database; Sqlite::Database database;
ProjectStorageErrorNotifier errorNotifier; ProjectStorageErrorNotifier errorNotifier;
@@ -215,6 +237,7 @@ public:
QmlTypesParser qmlTypesParser{storage}; QmlTypesParser qmlTypesParser{storage};
ProjectStoragePathWatcher<QFileSystemWatcher, QTimer, PathCacheType> pathWatcher; ProjectStoragePathWatcher<QFileSystemWatcher, QTimer, PathCacheType> pathWatcher;
ProjectPartId projectPartId; ProjectPartId projectPartId;
ProjectPartId qtPartId;
ProjectStorageUpdater updater; ProjectStorageUpdater updater;
}; };
@@ -363,22 +386,11 @@ void QmlDesignerProjectManager::editorsClosed(const QList<::Core::IEditor *> &)
namespace { namespace {
[[maybe_unused]] QString qmlPath(::ProjectExplorer::Target *target) [[maybe_unused]] QString projectDirectory(::ProjectExplorer::Target *target)
{
auto qt = QtSupport::QtKitAspect::qtVersion(target->kit());
if (qt)
return qt->qmlPath().path();
return QLibraryInfo::path(QLibraryInfo::QmlImportsPath);
}
[[maybe_unused]] void projectQmldirPaths(::ProjectExplorer::Target *target, QStringList &qmldirPaths)
{ {
::QmlProjectManager::QmlBuildSystem *buildSystem = getQmlBuildSystem(target); ::QmlProjectManager::QmlBuildSystem *buildSystem = getQmlBuildSystem(target);
const Utils::FilePath projectDirectoryPath = buildSystem->canonicalProjectDir(); return buildSystem->canonicalProjectDir().path();
qmldirPaths.push_back(projectDirectoryPath.path());
} }
[[maybe_unused]] void qtQmldirPaths(::ProjectExplorer::Target *target, QStringList &qmldirPaths) [[maybe_unused]] void qtQmldirPaths(::ProjectExplorer::Target *target, QStringList &qmldirPaths)
@@ -414,10 +426,6 @@ namespace {
qmldirPaths.reserve(100); qmldirPaths.reserve(100);
qtQmldirPaths(target, qmldirPaths); qtQmldirPaths(target, qmldirPaths);
projectQmldirPaths(target, qmldirPaths);
std::sort(qmldirPaths.begin(), qmldirPaths.end());
qmldirPaths.erase(std::unique(qmldirPaths.begin(), qmldirPaths.end()), qmldirPaths.end());
return qmldirPaths; return qmldirPaths;
} }
@@ -584,13 +592,17 @@ void QmlDesignerProjectManager::update()
try { try {
if constexpr (isUsingQmlDesignerLite()) { if constexpr (isUsingQmlDesignerLite()) {
m_projectData->projectStorageData->updater.update({directoriesForLiteDesigner(), m_projectData->projectStorageData->updater.update(
{directoriesForLiteDesigner(),
propertyEditorResourcesPath(), propertyEditorResourcesPath(),
{qtCreatorItemLibraryPath()}}); {qtCreatorItemLibraryPath()},
projectDirectory(m_projectData->activeTarget)});
} else { } else {
m_projectData->projectStorageData->updater.update({directories(m_projectData->activeTarget), m_projectData->projectStorageData->updater.update(
{directories(m_projectData->activeTarget),
propertyEditorResourcesPath(), propertyEditorResourcesPath(),
{qtCreatorItemLibraryPath()}}); {qtCreatorItemLibraryPath()},
projectDirectory(m_projectData->activeTarget)});
} }
} catch (const Sqlite::Exception &exception) { } catch (const Sqlite::Exception &exception) {
const auto &location = exception.location(); const auto &location = exception.location();

View File

@@ -15,6 +15,7 @@ public:
(const QString &sourceContent, (const QString &sourceContent,
QmlDesigner::Storage::Imports &imports, QmlDesigner::Storage::Imports &imports,
QmlDesigner::SourceId sourceId, QmlDesigner::SourceId sourceId,
Utils::SmallStringView directoryPath), Utils::SmallStringView directoryPath,
IsInsideProject isInsideProject),
(override)); (override));
}; };

View File

@@ -15,6 +15,7 @@ public:
(const QString &sourceContent, (const QString &sourceContent,
QmlDesigner::Storage::Imports &imports, QmlDesigner::Storage::Imports &imports,
QmlDesigner::Storage::Synchronization::Types &types, QmlDesigner::Storage::Synchronization::Types &types,
const QmlDesigner::Storage::Synchronization::DirectoryInfo &directoryInfo), const QmlDesigner::Storage::Synchronization::DirectoryInfo &directoryInfo,
IsInsideProject isInsideProject),
(override)); (override));
}; };

View File

@@ -709,6 +709,17 @@ std::ostream &operator<<(std::ostream &out, PropertyDeclarationTraits traits)
return out << ")"; return out << ")";
} }
std::ostream &operator<<(std::ostream &out, IsInsideProject isInsideProject)
{
switch (isInsideProject) {
case IsInsideProject::No:
return out << "IsInsideProject::No";
case IsInsideProject::Yes:
return out << "IsInsideProject::Yes";
}
return out;
}
std::ostream &operator<<(std::ostream &out, VersionNumber versionNumber) std::ostream &operator<<(std::ostream &out, VersionNumber versionNumber)
{ {
return out << versionNumber.value; return out << versionNumber.value;

View File

@@ -182,6 +182,7 @@ std::ostream &operator<<(std::ostream &out, const FontCollectorSizesAuxiliaryDat
namespace Storage { namespace Storage {
enum class PropertyDeclarationTraits : int; enum class PropertyDeclarationTraits : int;
enum class TypeTraitsKind : unsigned int; enum class TypeTraitsKind : unsigned int;
enum class IsInsideProject : char;
struct TypeTraits; struct TypeTraits;
class Import; class Import;
class Version; class Version;
@@ -190,6 +191,7 @@ class VersionNumber;
std::ostream &operator<<(std::ostream &out, PropertyDeclarationTraits traits); std::ostream &operator<<(std::ostream &out, PropertyDeclarationTraits traits);
std::ostream &operator<<(std::ostream &out, TypeTraitsKind kind); std::ostream &operator<<(std::ostream &out, TypeTraitsKind kind);
std::ostream &operator<<(std::ostream &out, TypeTraits traits); std::ostream &operator<<(std::ostream &out, TypeTraits traits);
std::ostream &operator<<(std::ostream &out, IsInsideProject isInsideProject);
std::ostream &operator<<(std::ostream &out, const Import &import); std::ostream &operator<<(std::ostream &out, const Import &import);
std::ostream &operator<<(std::ostream &out, VersionNumber versionNumber); std::ostream &operator<<(std::ostream &out, VersionNumber versionNumber);
std::ostream &operator<<(std::ostream &out, Version version); std::ostream &operator<<(std::ostream &out, Version version);

View File

@@ -273,6 +273,43 @@ TEST_F(NodeMetaInfo, component_is_singleton)
ASSERT_TRUE(isSingleton); ASSERT_TRUE(isSingleton);
} }
TEST_F(NodeMetaInfo, object_is_not_inside_project)
{
bool isInsideProject = objectMetaInfo.isInsideProject();
ASSERT_FALSE(isInsideProject);
}
TEST_F(NodeMetaInfo, default_is_not_inside_project)
{
bool isInsideProject = QmlDesigner::NodeMetaInfo{}.isInsideProject();
ASSERT_FALSE(isInsideProject);
}
TEST_F(NodeMetaInfo, invalid_is_not_inside_project)
{
auto node = model.createModelNode("Foo");
auto metaInfo = node.metaInfo();
bool isInsideProject = metaInfo.isInsideProject();
ASSERT_FALSE(isInsideProject);
}
TEST_F(NodeMetaInfo, component_is_inside_project)
{
auto moduleId = projectStorageMock.createModule("/path/to/project", ModuleKind::PathLibrary);
TypeTraits traits{TypeTraitsKind::Reference};
traits.isInsideProject = true;
auto typeId = projectStorageMock.createType(moduleId, "Foo", traits);
QmlDesigner::NodeMetaInfo metaInfo{typeId, &projectStorageMock};
bool isInsideProject = metaInfo.isInsideProject();
ASSERT_TRUE(isInsideProject);
}
TEST_F(NodeMetaInfo, has_property) TEST_F(NodeMetaInfo, has_property)
{ {
auto metaInfo = model.qtQuickItemMetaInfo(); auto metaInfo = model.qtQuickItemMetaInfo();
@@ -3355,3 +3392,4 @@ TEST_F(NodeMetaInfo, no_item_library_entries_for_default)
} }
} // namespace } // namespace

View File

@@ -167,7 +167,11 @@ TEST_F(QmlDocumentParser, prototype)
{ {
QString component = "Example{}"; QString component = "Example{}";
auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); auto type = parser.parse(component,
imports,
qmlFileSourceId,
directoryPath,
Storage::IsInsideProject::No);
ASSERT_THAT(type, HasPrototype(Synchronization::ImportedType("Example"))); ASSERT_THAT(type, HasPrototype(Synchronization::ImportedType("Example")));
} }
@@ -178,7 +182,11 @@ TEST_F(QmlDocumentParser, qualified_prototype)
QString component = R"(import Example 2.1 as Example QString component = R"(import Example 2.1 as Example
Example.Item{})"; Example.Item{})";
auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); auto type = parser.parse(component,
imports,
qmlFileSourceId,
directoryPath,
Storage::IsInsideProject::No);
ASSERT_THAT(type, ASSERT_THAT(type,
HasPrototype(Synchronization::QualifiedImportedType( HasPrototype(Synchronization::QualifiedImportedType(
@@ -190,7 +198,11 @@ TEST_F(QmlDocumentParser, properties)
{ {
QString component = R"(Example{ property int foo })"; QString component = R"(Example{ property int foo })";
auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); auto type = parser.parse(component,
imports,
qmlFileSourceId,
directoryPath,
Storage::IsInsideProject::No);
ASSERT_THAT(type.propertyDeclarations, ASSERT_THAT(type.propertyDeclarations,
UnorderedElementsAre(IsPropertyDeclaration("foo", UnorderedElementsAre(IsPropertyDeclaration("foo",
@@ -204,7 +216,11 @@ TEST_F(QmlDocumentParser, qualified_properties)
QString component = R"(import Example 2.1 as Example QString component = R"(import Example 2.1 as Example
Item{ property Example.Foo foo})"; Item{ property Example.Foo foo})";
auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); auto type = parser.parse(component,
imports,
qmlFileSourceId,
directoryPath,
Storage::IsInsideProject::No);
ASSERT_THAT(type.propertyDeclarations, ASSERT_THAT(type.propertyDeclarations,
UnorderedElementsAre(IsPropertyDeclaration( UnorderedElementsAre(IsPropertyDeclaration(
@@ -221,7 +237,11 @@ TEST_F(QmlDocumentParser, enumeration_in_properties)
QString component = R"(import Example 2.1 as Example QString component = R"(import Example 2.1 as Example
Item{ property Enumeration.Foo foo})"; Item{ property Enumeration.Foo foo})";
auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); auto type = parser.parse(component,
imports,
qmlFileSourceId,
directoryPath,
Storage::IsInsideProject::No);
ASSERT_THAT(type.propertyDeclarations, ASSERT_THAT(type.propertyDeclarations,
UnorderedElementsAre( UnorderedElementsAre(
@@ -236,7 +256,11 @@ TEST_F(QmlDocumentParser, qualified_enumeration_in_properties)
QString component = R"(import Example 2.1 as Example QString component = R"(import Example 2.1 as Example
Item{ property Example.Enumeration.Foo foo})"; Item{ property Example.Enumeration.Foo foo})";
auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); auto type = parser.parse(component,
imports,
qmlFileSourceId,
directoryPath,
Storage::IsInsideProject::No);
ASSERT_THAT(type.propertyDeclarations, ASSERT_THAT(type.propertyDeclarations,
UnorderedElementsAre(IsPropertyDeclaration( UnorderedElementsAre(IsPropertyDeclaration(
@@ -257,7 +281,11 @@ TEST_F(QmlDocumentParser, imports)
import "../foo" import "../foo"
Example{})"; Example{})";
auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); auto type = parser.parse(component,
imports,
qmlFileSourceId,
directoryPath,
Storage::IsInsideProject::No);
ASSERT_THAT(imports, ASSERT_THAT(imports,
UnorderedElementsAre( UnorderedElementsAre(
@@ -276,7 +304,11 @@ TEST_F(QmlDocumentParser, imports_with_version)
import "../foo" import "../foo"
Example{})"; Example{})";
auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); auto type = parser.parse(component,
imports,
qmlFileSourceId,
directoryPath,
Storage::IsInsideProject::No);
ASSERT_THAT(imports, ASSERT_THAT(imports,
UnorderedElementsAre( UnorderedElementsAre(
@@ -295,7 +327,11 @@ TEST_F(QmlDocumentParser, imports_with_explict_directory)
import "." import "."
Example{})"; Example{})";
auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); auto type = parser.parse(component,
imports,
qmlFileSourceId,
directoryPath,
Storage::IsInsideProject::No);
ASSERT_THAT( ASSERT_THAT(
imports, imports,
@@ -308,7 +344,11 @@ TEST_F(QmlDocumentParser, functions)
{ {
QString component = "Example{\n function someScript(x, y) {}\n function otherFunction() {}\n}"; QString component = "Example{\n function someScript(x, y) {}\n function otherFunction() {}\n}";
auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); auto type = parser.parse(component,
imports,
qmlFileSourceId,
directoryPath,
Storage::IsInsideProject::No);
ASSERT_THAT(type.functionDeclarations, ASSERT_THAT(type.functionDeclarations,
UnorderedElementsAre( UnorderedElementsAre(
@@ -326,7 +366,8 @@ TEST_F(QmlDocumentParser, signals)
auto type = parser.parse("Example{\n signal someSignal(int x, real y)\n signal signal2()\n}", auto type = parser.parse("Example{\n signal someSignal(int x, real y)\n signal signal2()\n}",
imports, imports,
qmlFileSourceId, qmlFileSourceId,
directoryPath); directoryPath,
Storage::IsInsideProject::No);
ASSERT_THAT(type.signalDeclarations, ASSERT_THAT(type.signalDeclarations,
UnorderedElementsAre( UnorderedElementsAre(
@@ -343,7 +384,11 @@ TEST_F(QmlDocumentParser, enumeration)
enum Color{red, green, blue=10, white} enum Color{red, green, blue=10, white}
enum State{On,Off}})"; enum State{On,Off}})";
auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); auto type = parser.parse(component,
imports,
qmlFileSourceId,
directoryPath,
Storage::IsInsideProject::No);
ASSERT_THAT(type.enumerationDeclarations, ASSERT_THAT(type.enumerationDeclarations,
UnorderedElementsAre( UnorderedElementsAre(
@@ -373,7 +418,11 @@ TEST_F(QmlDocumentParser, DISABLED_duplicate_imports_are_removed)
Example{})"; Example{})";
auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); auto type = parser.parse(component,
imports,
qmlFileSourceId,
directoryPath,
Storage::IsInsideProject::No);
ASSERT_THAT(imports, ASSERT_THAT(imports,
UnorderedElementsAre( UnorderedElementsAre(
@@ -393,7 +442,11 @@ TEST_F(QmlDocumentParser, alias_item_properties)
} }
})"; })";
auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); auto type = parser.parse(component,
imports,
qmlFileSourceId,
directoryPath,
Storage::IsInsideProject::No);
ASSERT_THAT(type.propertyDeclarations, ASSERT_THAT(type.propertyDeclarations,
UnorderedElementsAre(IsPropertyDeclaration("delegate", UnorderedElementsAre(IsPropertyDeclaration("delegate",
@@ -410,7 +463,11 @@ TEST_F(QmlDocumentParser, alias_properties)
} }
})"; })";
auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); auto type = parser.parse(component,
imports,
qmlFileSourceId,
directoryPath,
Storage::IsInsideProject::No);
ASSERT_THAT(type.propertyDeclarations, ASSERT_THAT(type.propertyDeclarations,
UnorderedElementsAre( UnorderedElementsAre(
@@ -429,7 +486,11 @@ TEST_F(QmlDocumentParser, indirect_alias_properties)
} }
})"; })";
auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); auto type = parser.parse(component,
imports,
qmlFileSourceId,
directoryPath,
Storage::IsInsideProject::No);
ASSERT_THAT(type.propertyDeclarations, ASSERT_THAT(type.propertyDeclarations,
UnorderedElementsAre( UnorderedElementsAre(
@@ -449,7 +510,11 @@ TEST_F(QmlDocumentParser, invalid_alias_properties_are_skipped)
} }
})"; })";
auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); auto type = parser.parse(component,
imports,
qmlFileSourceId,
directoryPath,
Storage::IsInsideProject::No);
ASSERT_THAT(type.propertyDeclarations, IsEmpty()); ASSERT_THAT(type.propertyDeclarations, IsEmpty());
} }
@@ -460,7 +525,11 @@ TEST_F(QmlDocumentParser, list_property)
property list<Foo> foos property list<Foo> foos
})"; })";
auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); auto type = parser.parse(component,
imports,
qmlFileSourceId,
directoryPath,
Storage::IsInsideProject::No);
ASSERT_THAT(type.propertyDeclarations, ASSERT_THAT(type.propertyDeclarations,
UnorderedElementsAre( UnorderedElementsAre(
@@ -480,7 +549,11 @@ TEST_F(QmlDocumentParser, alias_on_list_property)
} }
})"; })";
auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); auto type = parser.parse(component,
imports,
qmlFileSourceId,
directoryPath,
Storage::IsInsideProject::No);
ASSERT_THAT(type.propertyDeclarations, ASSERT_THAT(type.propertyDeclarations,
UnorderedElementsAre( UnorderedElementsAre(
@@ -497,7 +570,11 @@ TEST_F(QmlDocumentParser, qualified_list_property)
property list<Example.Foo> foos property list<Example.Foo> foos
})"; })";
auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); auto type = parser.parse(component,
imports,
qmlFileSourceId,
directoryPath,
Storage::IsInsideProject::No);
ASSERT_THAT(type.propertyDeclarations, ASSERT_THAT(type.propertyDeclarations,
UnorderedElementsAre(IsPropertyDeclaration( UnorderedElementsAre(IsPropertyDeclaration(
@@ -516,7 +593,11 @@ TEST_F(QmlDocumentParser, default_property)
default property list<Example.Foo> foos default property list<Example.Foo> foos
})"; })";
auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); auto type = parser.parse(component,
imports,
qmlFileSourceId,
directoryPath,
Storage::IsInsideProject::No);
ASSERT_THAT(type.defaultPropertyName, Eq("foos")); ASSERT_THAT(type.defaultPropertyName, Eq("foos"));
} }
@@ -527,7 +608,11 @@ TEST_F(QmlDocumentParser, has_file_component_trait)
Item{ Item{
})"; })";
auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); auto type = parser.parse(component,
imports,
qmlFileSourceId,
directoryPath,
Storage::IsInsideProject::No);
ASSERT_TRUE(type.traits.isFileComponent); ASSERT_TRUE(type.traits.isFileComponent);
} }
@@ -538,7 +623,11 @@ TEST_F(QmlDocumentParser, has_is_reference_trait)
Item{ Item{
})"; })";
auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); auto type = parser.parse(component,
imports,
qmlFileSourceId,
directoryPath,
Storage::IsInsideProject::No);
ASSERT_THAT(type.traits.kind, QmlDesigner::Storage::TypeTraitsKind::Reference); ASSERT_THAT(type.traits.kind, QmlDesigner::Storage::TypeTraitsKind::Reference);
} }
@@ -549,7 +638,11 @@ TEST_F(QmlDocumentParser, is_singleton)
Item{ Item{
})"; })";
auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); auto type = parser.parse(component,
imports,
qmlFileSourceId,
directoryPath,
Storage::IsInsideProject::No);
ASSERT_TRUE(type.traits.isSingleton); ASSERT_TRUE(type.traits.isSingleton);
} }
@@ -559,9 +652,41 @@ TEST_F(QmlDocumentParser, is_not_singleton)
QString component = R"(Item{ QString component = R"(Item{
})"; })";
auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); auto type = parser.parse(component,
imports,
qmlFileSourceId,
directoryPath,
Storage::IsInsideProject::No);
ASSERT_FALSE(type.traits.isSingleton); ASSERT_FALSE(type.traits.isSingleton);
} }
TEST_F(QmlDocumentParser, is_inside_project)
{
QString component = R"(Item{
})";
auto type = parser.parse(component,
imports,
qmlFileSourceId,
directoryPath,
Storage::IsInsideProject::Yes);
ASSERT_TRUE(type.traits.isInsideProject);
}
TEST_F(QmlDocumentParser, is_not_inside_project)
{
QString component = R"(Item{
})";
auto type = parser.parse(component,
imports,
qmlFileSourceId,
directoryPath,
Storage::IsInsideProject::No);
ASSERT_FALSE(type.traits.isInsideProject);
}
} // namespace } // namespace

View File

@@ -77,6 +77,13 @@ MATCHER_P(IsSingleton, value, std::string(negation ? "isn't singleton " : "is si
return traits.isSingleton == value; return traits.isSingleton == value;
} }
MATCHER_P(IsInsideProject, value, std::string(negation ? "isn't inside project " : "is inside project "))
{
const Storage::TypeTraits &traits = arg;
return traits.isInsideProject == value;
}
template<typename Matcher> template<typename Matcher>
auto IsTypeTrait(const Matcher &matcher) auto IsTypeTrait(const Matcher &matcher)
{ {
@@ -203,7 +210,7 @@ TEST_F(QmlTypesParser, imports)
dependencies: dependencies:
["QtQuick 2.15", "QtQuick.Window 2.1", "QtFoo 6"]})"}; ["QtQuick 2.15", "QtQuick.Window 2.1", "QtFoo 6"]})"};
parser.parse(source, imports, types, directoryInfo); parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(imports, ASSERT_THAT(imports,
UnorderedElementsAre(IsImport(storage.moduleId("QML", ModuleKind::CppLibrary), UnorderedElementsAre(IsImport(storage.moduleId("QML", ModuleKind::CppLibrary),
@@ -230,7 +237,7 @@ TEST_F(QmlTypesParser, types)
Component { name: "QObject"} Component { name: "QObject"}
Component { name: "QQmlComponent"}})"}; Component { name: "QQmlComponent"}})"};
parser.parse(source, imports, types, directoryInfo); parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(types, ASSERT_THAT(types,
UnorderedElementsAre(IsType("QObject", UnorderedElementsAre(IsType("QObject",
@@ -253,7 +260,7 @@ TEST_F(QmlTypesParser, prototype)
Component { name: "QQmlComponent" Component { name: "QQmlComponent"
prototype: "QObject"}})"}; prototype: "QObject"}})"};
parser.parse(source, imports, types, directoryInfo); parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(types, ASSERT_THAT(types,
UnorderedElementsAre(IsType("QObject", UnorderedElementsAre(IsType("QObject",
@@ -276,7 +283,7 @@ TEST_F(QmlTypesParser, extension)
Component { name: "QQmlComponent" Component { name: "QQmlComponent"
extension: "QObject"}})"}; extension: "QObject"}})"};
parser.parse(source, imports, types, directoryInfo); parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(types, ASSERT_THAT(types,
UnorderedElementsAre(IsType("QObject", UnorderedElementsAre(IsType("QObject",
@@ -301,7 +308,7 @@ TEST_F(QmlTypesParser, ignore_java_script_extensions)
extensionIsJavaScript: true extensionIsJavaScript: true
}})"}; }})"};
parser.parse(source, imports, types, directoryInfo); parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(types, ASSERT_THAT(types,
Contains(IsType("QQmlComponent", Contains(IsType("QQmlComponent",
@@ -321,7 +328,7 @@ TEST_F(QmlTypesParser, exported_types)
ModuleId qmlModuleId = storage.moduleId("QML", ModuleKind::QmlLibrary); ModuleId qmlModuleId = storage.moduleId("QML", ModuleKind::QmlLibrary);
ModuleId qtQmlModuleId = storage.moduleId("QtQml", ModuleKind::QmlLibrary); ModuleId qtQmlModuleId = storage.moduleId("QtQml", ModuleKind::QmlLibrary);
parser.parse(source, imports, types, directoryInfo); parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT( ASSERT_THAT(
types, types,
@@ -344,7 +351,7 @@ TEST_F(QmlTypesParser, properties)
Property { name: "targets"; type: "QQuickItem"; isList: true; isReadonly: true; isPointer: true } Property { name: "targets"; type: "QQuickItem"; isList: true; isReadonly: true; isPointer: true }
}})"}; }})"};
parser.parse(source, imports, types, directoryInfo); parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(types, ASSERT_THAT(types,
ElementsAre(Field( ElementsAre(Field(
@@ -378,7 +385,7 @@ TEST_F(QmlTypesParser, properties_with_qualified_types)
Property { name: "values2"; type: "Qt::Vector" } Property { name: "values2"; type: "Qt::Vector" }
}})"}; }})"};
parser.parse(source, imports, types, directoryInfo); parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(types, ASSERT_THAT(types,
Contains( Contains(
@@ -404,7 +411,7 @@ TEST_F(QmlTypesParser, properties_without_type)
Property { name: "target"; type: "QObject"; isPointer: true } Property { name: "target"; type: "QObject"; isPointer: true }
}})"}; }})"};
parser.parse(source, imports, types, directoryInfo); parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(types, ASSERT_THAT(types,
ElementsAre( ElementsAre(
@@ -437,7 +444,7 @@ TEST_F(QmlTypesParser, functions)
} }
}})"}; }})"};
parser.parse(source, imports, types, directoryInfo); parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(types, ASSERT_THAT(types,
ElementsAre(Field( ElementsAre(Field(
@@ -468,7 +475,7 @@ TEST_F(QmlTypesParser, skip_java_script_functions)
} }
}})"}; }})"};
parser.parse(source, imports, types, directoryInfo); parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(types, ElementsAre(Field("Synchronization::Type::functionDeclarations", &Synchronization::Type::functionDeclarations, IsEmpty()))); ASSERT_THAT(types, ElementsAre(Field("Synchronization::Type::functionDeclarations", &Synchronization::Type::functionDeclarations, IsEmpty())));
} }
@@ -488,7 +495,7 @@ TEST_F(QmlTypesParser, functions_with_qualified_types)
} }
}})"}; }})"};
parser.parse(source, imports, types, directoryInfo); parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(types, ASSERT_THAT(types,
Contains( Contains(
@@ -523,7 +530,7 @@ TEST_F(QmlTypesParser, signals)
} }
}})"}; }})"};
parser.parse(source, imports, types, directoryInfo); parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(types, ASSERT_THAT(types,
ElementsAre(Field("Synchronization::Type::signalDeclarations", &Synchronization::Type::signalDeclarations, ElementsAre(Field("Synchronization::Type::signalDeclarations", &Synchronization::Type::signalDeclarations,
@@ -556,7 +563,7 @@ TEST_F(QmlTypesParser, signals_with_qualified_types)
} }
}})"}; }})"};
parser.parse(source, imports, types, directoryInfo); parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(types, ASSERT_THAT(types,
Contains( Contains(
@@ -589,7 +596,7 @@ TEST_F(QmlTypesParser, enumerations)
} }
}})"}; }})"};
parser.parse(source, imports, types, directoryInfo); parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(types, ASSERT_THAT(types,
Contains(Field( Contains(Field(
@@ -628,7 +635,7 @@ TEST_F(QmlTypesParser, enumeration_is_exported_as_type)
exports: ["QML/QtObject 1.0", "QtQml/QtObject 2.1"] exports: ["QML/QtObject 1.0", "QtQml/QtObject 2.1"]
}})"}; }})"};
parser.parse(source, imports, types, directoryInfo); parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
QmlDesigner::Storage::TypeTraits traits{QmlDesigner::Storage::TypeTraitsKind::Value}; QmlDesigner::Storage::TypeTraits traits{QmlDesigner::Storage::TypeTraitsKind::Value};
traits.isEnum = true; traits.isEnum = true;
@@ -674,7 +681,7 @@ TEST_F(QmlTypesParser, enumeration_is_exported_as_type_with_alias)
exports: ["QML/QtObject 1.0", "QtQml/QtObject 2.1"] exports: ["QML/QtObject 1.0", "QtQml/QtObject 2.1"]
}})"}; }})"};
parser.parse(source, imports, types, directoryInfo); parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
QmlDesigner::Storage::TypeTraits traits{QmlDesigner::Storage::TypeTraitsKind::Value}; QmlDesigner::Storage::TypeTraits traits{QmlDesigner::Storage::TypeTraitsKind::Value};
traits.isEnum = true; traits.isEnum = true;
@@ -722,7 +729,7 @@ TEST_F(QmlTypesParser, enumeration_is_exported_as_type_with_alias_too)
exports: ["QML/QtObject 1.0", "QtQml/QtObject 2.1"] exports: ["QML/QtObject 1.0", "QtQml/QtObject 2.1"]
}})"}; }})"};
parser.parse(source, imports, types, directoryInfo); parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
QmlDesigner::Storage::TypeTraits traits{QmlDesigner::Storage::TypeTraitsKind::Value}; QmlDesigner::Storage::TypeTraits traits{QmlDesigner::Storage::TypeTraitsKind::Value};
traits.isEnum = true; traits.isEnum = true;
@@ -760,7 +767,7 @@ TEST_F(QmlTypesParser, enumeration_is_referenced_by_qualified_name)
} }
}})"}; }})"};
parser.parse(source, imports, types, directoryInfo); parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(types, ASSERT_THAT(types,
Contains(Field("Synchronization::Type::propertyDeclarations", &Synchronization::Type::propertyDeclarations, Contains(Field("Synchronization::Type::propertyDeclarations", &Synchronization::Type::propertyDeclarations,
@@ -788,7 +795,7 @@ TEST_F(QmlTypesParser, alias_enumeration_is_referenced_by_qualified_name)
} }
}})"}; }})"};
parser.parse(source, imports, types, directoryInfo); parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(types, ASSERT_THAT(types,
Contains(Field("Synchronization::Type::propertyDeclarations", &Synchronization::Type::propertyDeclarations, Contains(Field("Synchronization::Type::propertyDeclarations", &Synchronization::Type::propertyDeclarations,
@@ -805,7 +812,7 @@ TEST_F(QmlTypesParser, access_type_is_reference)
Component { name: "QObject" Component { name: "QObject"
accessSemantics: "reference"}})"}; accessSemantics: "reference"}})"};
parser.parse(source, imports, types, directoryInfo); parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(types, ElementsAre(IsTypeTrait(Storage::TypeTraitsKind::Reference))); ASSERT_THAT(types, ElementsAre(IsTypeTrait(Storage::TypeTraitsKind::Reference)));
} }
@@ -817,7 +824,7 @@ TEST_F(QmlTypesParser, access_type_is_value)
Component { name: "QObject" Component { name: "QObject"
accessSemantics: "value"}})"}; accessSemantics: "value"}})"};
parser.parse(source, imports, types, directoryInfo); parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(types, ElementsAre(IsTypeTrait(Storage::TypeTraitsKind::Value))); ASSERT_THAT(types, ElementsAre(IsTypeTrait(Storage::TypeTraitsKind::Value)));
} }
@@ -829,7 +836,7 @@ TEST_F(QmlTypesParser, access_type_is_sequence)
Component { name: "QObject" Component { name: "QObject"
accessSemantics: "sequence"}})"}; accessSemantics: "sequence"}})"};
parser.parse(source, imports, types, directoryInfo); parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(types, ElementsAre(IsTypeTrait(Storage::TypeTraitsKind::Sequence))); ASSERT_THAT(types, ElementsAre(IsTypeTrait(Storage::TypeTraitsKind::Sequence)));
} }
@@ -841,7 +848,7 @@ TEST_F(QmlTypesParser, access_type_is_none)
Component { name: "QObject" Component { name: "QObject"
accessSemantics: "none"}})"}; accessSemantics: "none"}})"};
parser.parse(source, imports, types, directoryInfo); parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(types, ElementsAre(IsTypeTrait(Storage::TypeTraitsKind::None))); ASSERT_THAT(types, ElementsAre(IsTypeTrait(Storage::TypeTraitsKind::None)));
} }
@@ -853,7 +860,7 @@ TEST_F(QmlTypesParser, uses_custom_parser)
Component { name: "QObject" Component { name: "QObject"
hasCustomParser: true }})"}; hasCustomParser: true }})"};
parser.parse(source, imports, types, directoryInfo); parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(types, ElementsAre(IsTypeTrait(UsesCustomParser(true)))); ASSERT_THAT(types, ElementsAre(IsTypeTrait(UsesCustomParser(true))));
} }
@@ -865,7 +872,7 @@ TEST_F(QmlTypesParser, uses_no_custom_parser)
Component { name: "QObject" Component { name: "QObject"
hasCustomParser: false }})"}; hasCustomParser: false }})"};
parser.parse(source, imports, types, directoryInfo); parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(types, ElementsAre(IsTypeTrait(UsesCustomParser(false)))); ASSERT_THAT(types, ElementsAre(IsTypeTrait(UsesCustomParser(false))));
} }
@@ -877,7 +884,7 @@ TEST_F(QmlTypesParser, default_property)
Component { name: "QObject" Component { name: "QObject"
defaultProperty: "children" }})"}; defaultProperty: "children" }})"};
parser.parse(source, imports, types, directoryInfo); parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(types, ASSERT_THAT(types,
ElementsAre(Field("Synchronization::Type::defaultPropertyName", &Synchronization::Type::defaultPropertyName, Eq("children")))); ElementsAre(Field("Synchronization::Type::defaultPropertyName", &Synchronization::Type::defaultPropertyName, Eq("children"))));
@@ -895,7 +902,7 @@ TEST_F(QmlTypesParser, skip_template_item)
Component { name: "QQuickItem"} Component { name: "QQuickItem"}
Component { name: "QQmlComponent"}})"}; Component { name: "QQmlComponent"}})"};
parser.parse(source, imports, types, directoryInfo); parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(types, ASSERT_THAT(types,
UnorderedElementsAre(IsType("QQmlComponent", UnorderedElementsAre(IsType("QQmlComponent",
@@ -912,7 +919,7 @@ TEST_F(QmlTypesParser, is_singleton)
Component { name: "QObject" Component { name: "QObject"
isSingleton: true}})"}; isSingleton: true}})"};
parser.parse(source, imports, types, directoryInfo); parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(types, ElementsAre(IsTypeTrait(IsSingleton(true)))); ASSERT_THAT(types, ElementsAre(IsTypeTrait(IsSingleton(true))));
} }
@@ -924,7 +931,7 @@ TEST_F(QmlTypesParser, is_not_singleton)
Component { name: "QObject" Component { name: "QObject"
isSingleton: false}})"}; isSingleton: false}})"};
parser.parse(source, imports, types, directoryInfo); parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(types, ElementsAre(IsTypeTrait(IsSingleton(false)))); ASSERT_THAT(types, ElementsAre(IsTypeTrait(IsSingleton(false))));
} }
@@ -935,9 +942,31 @@ TEST_F(QmlTypesParser, is_by_default_not_singleton)
Module{ Module{
Component { name: "QObject"}})"}; Component { name: "QObject"}})"};
parser.parse(source, imports, types, directoryInfo); parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(types, ElementsAre(IsTypeTrait(IsSingleton(false)))); ASSERT_THAT(types, ElementsAre(IsTypeTrait(IsSingleton(false))));
} }
TEST_F(QmlTypesParser, is_inside_project)
{
QString source{R"(import QtQuick.tooling 1.2
Module{
Component { name: "QObject"}})"};
parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::Yes);
ASSERT_THAT(types, ElementsAre(IsTypeTrait(IsInsideProject(true))));
}
TEST_F(QmlTypesParser, is_not_inside_project)
{
QString source{R"(import QtQuick.tooling 1.2
Module{
Component { name: "QObject"}})"};
parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(types, ElementsAre(IsTypeTrait(IsInsideProject(false))));
}
} // namespace } // namespace