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;
bool isFileComponent() const;
bool isSingleton() const;
bool isInsideProject() const;
FlagIs canBeContainer() const;
FlagIs forceClip() 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
{
if constexpr (useProjectStorage()) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -709,6 +709,17 @@ std::ostream &operator<<(std::ostream &out, PropertyDeclarationTraits traits)
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)
{
return out << versionNumber.value;

View File

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

View File

@@ -273,6 +273,43 @@ TEST_F(NodeMetaInfo, component_is_singleton)
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)
{
auto metaInfo = model.qtQuickItemMetaInfo();
@@ -3355,3 +3392,4 @@ TEST_F(NodeMetaInfo, no_item_library_entries_for_default)
}
} // namespace

View File

@@ -167,7 +167,11 @@ TEST_F(QmlDocumentParser, prototype)
{
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")));
}
@@ -178,7 +182,11 @@ TEST_F(QmlDocumentParser, qualified_prototype)
QString component = R"(import Example 2.1 as Example
Example.Item{})";
auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath);
auto type = parser.parse(component,
imports,
qmlFileSourceId,
directoryPath,
Storage::IsInsideProject::No);
ASSERT_THAT(type,
HasPrototype(Synchronization::QualifiedImportedType(
@@ -190,7 +198,11 @@ TEST_F(QmlDocumentParser, properties)
{
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,
UnorderedElementsAre(IsPropertyDeclaration("foo",
@@ -204,7 +216,11 @@ TEST_F(QmlDocumentParser, qualified_properties)
QString component = R"(import Example 2.1 as Example
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,
UnorderedElementsAre(IsPropertyDeclaration(
@@ -221,7 +237,11 @@ TEST_F(QmlDocumentParser, enumeration_in_properties)
QString component = R"(import Example 2.1 as Example
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,
UnorderedElementsAre(
@@ -236,7 +256,11 @@ TEST_F(QmlDocumentParser, qualified_enumeration_in_properties)
QString component = R"(import Example 2.1 as Example
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,
UnorderedElementsAre(IsPropertyDeclaration(
@@ -257,7 +281,11 @@ TEST_F(QmlDocumentParser, imports)
import "../foo"
Example{})";
auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath);
auto type = parser.parse(component,
imports,
qmlFileSourceId,
directoryPath,
Storage::IsInsideProject::No);
ASSERT_THAT(imports,
UnorderedElementsAre(
@@ -276,7 +304,11 @@ TEST_F(QmlDocumentParser, imports_with_version)
import "../foo"
Example{})";
auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath);
auto type = parser.parse(component,
imports,
qmlFileSourceId,
directoryPath,
Storage::IsInsideProject::No);
ASSERT_THAT(imports,
UnorderedElementsAre(
@@ -295,7 +327,11 @@ TEST_F(QmlDocumentParser, imports_with_explict_directory)
import "."
Example{})";
auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath);
auto type = parser.parse(component,
imports,
qmlFileSourceId,
directoryPath,
Storage::IsInsideProject::No);
ASSERT_THAT(
imports,
@@ -308,7 +344,11 @@ TEST_F(QmlDocumentParser, functions)
{
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,
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}",
imports,
qmlFileSourceId,
directoryPath);
directoryPath,
Storage::IsInsideProject::No);
ASSERT_THAT(type.signalDeclarations,
UnorderedElementsAre(
@@ -343,7 +384,11 @@ TEST_F(QmlDocumentParser, enumeration)
enum Color{red, green, blue=10, white}
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,
UnorderedElementsAre(
@@ -373,7 +418,11 @@ TEST_F(QmlDocumentParser, DISABLED_duplicate_imports_are_removed)
Example{})";
auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath);
auto type = parser.parse(component,
imports,
qmlFileSourceId,
directoryPath,
Storage::IsInsideProject::No);
ASSERT_THAT(imports,
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,
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,
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,
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());
}
@@ -460,7 +525,11 @@ TEST_F(QmlDocumentParser, list_property)
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,
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,
UnorderedElementsAre(
@@ -497,7 +570,11 @@ TEST_F(QmlDocumentParser, qualified_list_property)
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,
UnorderedElementsAre(IsPropertyDeclaration(
@@ -516,7 +593,11 @@ TEST_F(QmlDocumentParser, default_property)
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"));
}
@@ -527,7 +608,11 @@ TEST_F(QmlDocumentParser, has_file_component_trait)
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);
}
@@ -538,7 +623,11 @@ TEST_F(QmlDocumentParser, has_is_reference_trait)
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);
}
@@ -549,7 +638,11 @@ TEST_F(QmlDocumentParser, is_singleton)
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);
}
@@ -559,9 +652,41 @@ TEST_F(QmlDocumentParser, is_not_singleton)
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);
}
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

View File

@@ -77,6 +77,13 @@ MATCHER_P(IsSingleton, value, std::string(negation ? "isn't singleton " : "is si
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>
auto IsTypeTrait(const Matcher &matcher)
{
@@ -203,7 +210,7 @@ TEST_F(QmlTypesParser, imports)
dependencies:
["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,
UnorderedElementsAre(IsImport(storage.moduleId("QML", ModuleKind::CppLibrary),
@@ -230,7 +237,7 @@ TEST_F(QmlTypesParser, types)
Component { name: "QObject"}
Component { name: "QQmlComponent"}})"};
parser.parse(source, imports, types, directoryInfo);
parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(types,
UnorderedElementsAre(IsType("QObject",
@@ -253,7 +260,7 @@ TEST_F(QmlTypesParser, prototype)
Component { name: "QQmlComponent"
prototype: "QObject"}})"};
parser.parse(source, imports, types, directoryInfo);
parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(types,
UnorderedElementsAre(IsType("QObject",
@@ -276,7 +283,7 @@ TEST_F(QmlTypesParser, extension)
Component { name: "QQmlComponent"
extension: "QObject"}})"};
parser.parse(source, imports, types, directoryInfo);
parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(types,
UnorderedElementsAre(IsType("QObject",
@@ -301,7 +308,7 @@ TEST_F(QmlTypesParser, ignore_java_script_extensions)
extensionIsJavaScript: true
}})"};
parser.parse(source, imports, types, directoryInfo);
parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(types,
Contains(IsType("QQmlComponent",
@@ -321,7 +328,7 @@ TEST_F(QmlTypesParser, exported_types)
ModuleId qmlModuleId = storage.moduleId("QML", 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(
types,
@@ -344,7 +351,7 @@ TEST_F(QmlTypesParser, properties)
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,
ElementsAre(Field(
@@ -378,7 +385,7 @@ TEST_F(QmlTypesParser, properties_with_qualified_types)
Property { name: "values2"; type: "Qt::Vector" }
}})"};
parser.parse(source, imports, types, directoryInfo);
parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(types,
Contains(
@@ -404,7 +411,7 @@ TEST_F(QmlTypesParser, properties_without_type)
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,
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,
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())));
}
@@ -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,
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,
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,
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,
Contains(Field(
@@ -628,7 +635,7 @@ TEST_F(QmlTypesParser, enumeration_is_exported_as_type)
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};
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"]
}})"};
parser.parse(source, imports, types, directoryInfo);
parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
QmlDesigner::Storage::TypeTraits traits{QmlDesigner::Storage::TypeTraitsKind::Value};
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"]
}})"};
parser.parse(source, imports, types, directoryInfo);
parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
QmlDesigner::Storage::TypeTraits traits{QmlDesigner::Storage::TypeTraitsKind::Value};
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,
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,
Contains(Field("Synchronization::Type::propertyDeclarations", &Synchronization::Type::propertyDeclarations,
@@ -805,7 +812,7 @@ TEST_F(QmlTypesParser, access_type_is_reference)
Component { name: "QObject"
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)));
}
@@ -817,7 +824,7 @@ TEST_F(QmlTypesParser, access_type_is_value)
Component { name: "QObject"
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)));
}
@@ -829,7 +836,7 @@ TEST_F(QmlTypesParser, access_type_is_sequence)
Component { name: "QObject"
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)));
}
@@ -841,7 +848,7 @@ TEST_F(QmlTypesParser, access_type_is_none)
Component { name: "QObject"
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)));
}
@@ -853,7 +860,7 @@ TEST_F(QmlTypesParser, uses_custom_parser)
Component { name: "QObject"
hasCustomParser: true }})"};
parser.parse(source, imports, types, directoryInfo);
parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(types, ElementsAre(IsTypeTrait(UsesCustomParser(true))));
}
@@ -865,7 +872,7 @@ TEST_F(QmlTypesParser, uses_no_custom_parser)
Component { name: "QObject"
hasCustomParser: false }})"};
parser.parse(source, imports, types, directoryInfo);
parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(types, ElementsAre(IsTypeTrait(UsesCustomParser(false))));
}
@@ -877,7 +884,7 @@ TEST_F(QmlTypesParser, default_property)
Component { name: "QObject"
defaultProperty: "children" }})"};
parser.parse(source, imports, types, directoryInfo);
parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(types,
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: "QQmlComponent"}})"};
parser.parse(source, imports, types, directoryInfo);
parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(types,
UnorderedElementsAre(IsType("QQmlComponent",
@@ -912,7 +919,7 @@ TEST_F(QmlTypesParser, is_singleton)
Component { name: "QObject"
isSingleton: true}})"};
parser.parse(source, imports, types, directoryInfo);
parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(types, ElementsAre(IsTypeTrait(IsSingleton(true))));
}
@@ -924,7 +931,7 @@ TEST_F(QmlTypesParser, is_not_singleton)
Component { name: "QObject"
isSingleton: false}})"};
parser.parse(source, imports, types, directoryInfo);
parser.parse(source, imports, types, directoryInfo, Storage::IsInsideProject::No);
ASSERT_THAT(types, ElementsAre(IsTypeTrait(IsSingleton(false))));
}
@@ -935,9 +942,31 @@ TEST_F(QmlTypesParser, is_by_default_not_singleton)
Module{
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))));
}
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