QmlDesigner: Use QQmlDirParser from Qt

The QmlDirParser from qmljs has a different behavior.

Change-Id: Iaf59bcd977b3ab99a6d949f20b0af3371c7cc3d1
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Marco Bubke
2025-03-20 18:38:36 +01:00
committed by Thomas Hartmann
parent 47b0e1b14c
commit 726b45ac94
5 changed files with 57 additions and 54 deletions

View File

@@ -2433,7 +2433,7 @@ void ProjectStorage::synchronizeTypeAnnotations(Storage::Synchronization::TypeAn
auto compareKey = [](auto &&first, auto &&second) { return first.typeId <=> second.typeId; }; auto compareKey = [](auto &&first, auto &&second) { return first.typeId <=> second.typeId; };
std::ranges::sort(typeAnnotations, std::ranges::less{}, &TypeAnnotation::typeId); std::ranges::sort(typeAnnotations, {}, &TypeAnnotation::typeId);
auto range = s->selectTypeAnnotationsForSourceIdsStatement.range<TypeAnnotationView>( auto range = s->selectTypeAnnotationsForSourceIdsStatement.range<TypeAnnotationView>(
toIntegers(updatedTypeAnnotationSourceIds)); toIntegers(updatedTypeAnnotationSourceIds));
@@ -2549,7 +2549,7 @@ void ProjectStorage::synchronizeTypes(Storage::Synchronization::Types &types,
} }
} }
std::ranges::sort(types, std::ranges::less{}, &Type::typeId); std::ranges::sort(types, {}, &Type::typeId);
unique(exportedSourceIds); unique(exportedSourceIds);
@@ -2649,7 +2649,7 @@ void ProjectStorage::synchronizeFileStatuses(FileStatuses &fileStatuses,
auto compareKey = [](auto &&first, auto &&second) { return first.sourceId <=> second.sourceId; }; auto compareKey = [](auto &&first, auto &&second) { return first.sourceId <=> second.sourceId; };
std::ranges::sort(fileStatuses, std::ranges::less{}, &FileStatus::sourceId); std::ranges::sort(fileStatuses, {}, &FileStatus::sourceId);
auto range = s->selectFileStatusesForSourceIdsStatement.range<FileStatus>( auto range = s->selectFileStatusesForSourceIdsStatement.range<FileStatus>(
toIntegers(updatedSourceIds)); toIntegers(updatedSourceIds));
@@ -4012,7 +4012,7 @@ void ProjectStorage::synchronizePropertyEditorPaths(
SourceContextIds updatedPropertyEditorQmlPathsSourceContextIds) SourceContextIds updatedPropertyEditorQmlPathsSourceContextIds)
{ {
using Storage::Synchronization::PropertyEditorQmlPath; using Storage::Synchronization::PropertyEditorQmlPath;
std::ranges::sort(paths, std::ranges::less{}, &PropertyEditorQmlPath::typeId); std::ranges::sort(paths, {}, &PropertyEditorQmlPath::typeId);
auto range = s->selectPropertyEditorPathsForForSourceIdsStatement.range<PropertyEditorQmlPathView>( auto range = s->selectPropertyEditorPathsForForSourceIdsStatement.range<PropertyEditorQmlPathView>(
toIntegers(updatedPropertyEditorQmlPathsSourceContextIds)); toIntegers(updatedPropertyEditorQmlPathsSourceContextIds));

View File

@@ -112,7 +112,7 @@ CannotParseQmlDocumentFile::CannotParseQmlDocumentFile(const Sqlite::source_loca
const char *CannotParseQmlDocumentFile::what() const noexcept const char *CannotParseQmlDocumentFile::what() const noexcept
{ {
return "Cannot parse qml types file!"; return "Cannot parse qml document file!";
} }
DirectoryInfoHasInvalidProjectSourceId::DirectoryInfoHasInvalidProjectSourceId( DirectoryInfoHasInvalidProjectSourceId::DirectoryInfoHasInvalidProjectSourceId(

View File

@@ -22,6 +22,8 @@
#include <QDirIterator> #include <QDirIterator>
#include <QRegularExpression> #include <QRegularExpression>
#include <private/qqmldirparser_p.h>
#include <algorithm> #include <algorithm>
#include <functional> #include <functional>
@@ -65,35 +67,32 @@ QStringList filterMultipleEntries(QStringList qmlTypes)
return qmlTypes; return qmlTypes;
} }
QList<QmlDirParser::Import> filterMultipleEntries(QList<QmlDirParser::Import> imports) QList<QQmlDirParser::Import> filterMultipleEntries(QList<QQmlDirParser::Import> imports)
{ {
std::stable_sort(imports.begin(), imports.end(), [](auto &&first, auto &&second) { std::ranges::stable_sort(imports, {}, &QQmlDirParser::Import::module);
return first.module < second.module; auto removedRange = std::ranges::unique(imports, {}, &QQmlDirParser::Import::module);
}); imports.erase(removedRange.begin(), removedRange.end());
imports.erase(std::unique(imports.begin(),
imports.end(),
[](auto &&first, auto &&second) {
return first.module == second.module;
}),
imports.end());
return imports; return imports;
} }
QList<QmlDirParser::Import> joinImports(const QList<QmlDirParser::Import> &firstImports, std::vector<Utils::PathString> toImportNames(const QList<QQmlDirParser::Import> &imports)
const QList<QmlDirParser::Import> &secondImports)
{ {
QList<QmlDirParser::Import> imports; return Utils::transform<std::vector<Utils::PathString>>(imports, &QQmlDirParser::Import::module);
}
std::vector<Utils::PathString> joinImports(const std::vector<Utils::PathString> &firstImports,
const std::vector<Utils::PathString> &secondImports)
{
std::vector<Utils::PathString> imports;
imports.reserve(firstImports.size() + secondImports.size()); imports.reserve(firstImports.size() + secondImports.size());
imports.append(firstImports); std::ranges::set_union(firstImports, secondImports, std::back_inserter(imports));
imports.append(secondImports);
imports = filterMultipleEntries(std::move(imports));
return imports; return imports;
} }
ProjectStorageUpdater::Components createComponents( ProjectStorageUpdater::Components createComponents(
const QMultiHash<QString, QmlDirParser::Component> &qmlDirParserComponents, const QMultiHash<QString, QQmlDirParser::Component> &qmlDirParserComponents,
ModuleId moduleId, ModuleId moduleId,
ModuleId pathModuleId, ModuleId pathModuleId,
FileSystemInterface &fileSystem, FileSystemInterface &fileSystem,
@@ -112,14 +111,14 @@ ProjectStorageUpdater::Components createComponents(
ProjectStorageUpdater::Component{fileName, typeName, pathModuleId, -1, -1}); ProjectStorageUpdater::Component{fileName, typeName, pathModuleId, -1, -1});
} }
for (const QmlDirParser::Component &qmlDirParserComponent : qmlDirParserComponents) { for (const QQmlDirParser::Component &qmlDirParserComponent : qmlDirParserComponents) {
if (qmlDirParserComponent.fileName.contains('/')) if (qmlDirParserComponent.fileName.contains('/'))
continue; continue;
components.push_back(ProjectStorageUpdater::Component{qmlDirParserComponent.fileName, components.emplace_back(qmlDirParserComponent.fileName,
qmlDirParserComponent.typeName, qmlDirParserComponent.typeName,
moduleId, moduleId,
qmlDirParserComponent.majorVersion, qmlDirParserComponent.version.majorVersion(),
qmlDirParserComponent.minorVersion}); qmlDirParserComponent.version.minorVersion());
} }
return components; return components;
@@ -157,28 +156,33 @@ void addSourceIds(SourceIds &sourceIds,
} }
} }
Storage::Version convertVersion(LanguageUtils::ComponentVersion version) Storage::Version convertVersion(QTypeRevision version)
{ {
return Storage::Version{version.majorVersion(), version.minorVersion()}; return Storage::Version{version.hasMajorVersion() ? version.majorVersion() : -1,
version.hasMinorVersion() ? version.minorVersion() : -1};
} }
Storage::Synchronization::IsAutoVersion convertToIsAutoVersion(QmlDirParser::Import::Flags flags) Storage::Synchronization::IsAutoVersion convertToIsAutoVersion(QQmlDirParser::Import::Flags flags,
QTypeRevision version)
{ {
if (flags & QmlDirParser::Import::Flag::Auto) if (flags & QQmlDirParser::Import::Flag::Auto)
return Storage::Synchronization::IsAutoVersion::Yes; return Storage::Synchronization::IsAutoVersion::Yes;
if (!version.isValid())
return Storage::Synchronization::IsAutoVersion::Yes;
return Storage::Synchronization::IsAutoVersion::No; return Storage::Synchronization::IsAutoVersion::No;
} }
void addDependencies(Storage::Imports &dependencies, void addDependencies(Storage::Imports &dependencies,
SourceId sourceId, SourceId sourceId,
const QList<QmlDirParser::Import> &qmldirDependencies, const std::vector<Utils::PathString> &qmldirDependencies,
ProjectStorageInterface &projectStorage, ProjectStorageInterface &projectStorage,
TracerLiteral message, TracerLiteral message,
Tracer &tracer) Tracer &tracer)
{ {
for (const QmlDirParser::Import &qmldirDependency : qmldirDependencies) { for (std::string_view qmldirDependency : qmldirDependencies) {
ModuleId moduleId = projectStorage.moduleId(Utils::PathString{qmldirDependency.module}, ModuleId moduleId = projectStorage.moduleId(qmldirDependency, Storage::ModuleKind::CppLibrary);
Storage::ModuleKind::CppLibrary);
auto &import = dependencies.emplace_back(moduleId, Storage::Version{}, sourceId); auto &import = dependencies.emplace_back(moduleId, Storage::Version{}, sourceId);
tracer.tick(message, keyValue("import", import)); tracer.tick(message, keyValue("import", import));
} }
@@ -206,16 +210,17 @@ void addModuleExportedImport(Storage::Synchronization::ModuleExportedImports &im
imports.emplace_back(moduleId, exportedModuleId, version, isAutoVersion); imports.emplace_back(moduleId, exportedModuleId, version, isAutoVersion);
} }
bool isOptionalImport(QmlDirParser::Import::Flags flags) bool isOptionalImport(QQmlDirParser::Import::Flags flags)
{ {
return flags & QmlDirParser::Import::Optional && !(flags & QmlDirParser::Import::OptionalDefault); return flags & QQmlDirParser::Import::Optional
&& !(flags & QQmlDirParser::Import::OptionalDefault);
} }
void addModuleExportedImports(Storage::Synchronization::ModuleExportedImports &imports, void addModuleExportedImports(Storage::Synchronization::ModuleExportedImports &imports,
ModuleId moduleId, ModuleId moduleId,
ModuleId cppModuleId, ModuleId cppModuleId,
std::string_view moduleName, std::string_view moduleName,
const QList<QmlDirParser::Import> &qmldirImports, const QList<QQmlDirParser::Import> &qmldirImports,
ProjectStorageInterface &projectStorage) ProjectStorageInterface &projectStorage)
{ {
NanotraceHR::Tracer tracer{"add module exported imports", NanotraceHR::Tracer tracer{"add module exported imports",
@@ -223,7 +228,7 @@ void addModuleExportedImports(Storage::Synchronization::ModuleExportedImports &i
keyValue("cpp module id", cppModuleId), keyValue("cpp module id", cppModuleId),
keyValue("module id", moduleId)}; keyValue("module id", moduleId)};
for (const QmlDirParser::Import &qmldirImport : qmldirImports) { for (const QQmlDirParser::Import &qmldirImport : qmldirImports) {
if (isOptionalImport(qmldirImport.flags)) if (isOptionalImport(qmldirImport.flags))
continue; continue;
@@ -235,7 +240,7 @@ void addModuleExportedImports(Storage::Synchronization::ModuleExportedImports &i
moduleId, moduleId,
exportedModuleId, exportedModuleId,
convertVersion(qmldirImport.version), convertVersion(qmldirImport.version),
convertToIsAutoVersion(qmldirImport.flags), convertToIsAutoVersion(qmldirImport.flags, qmldirImport.version),
moduleName, moduleName,
ModuleKind::QmlLibrary, ModuleKind::QmlLibrary,
exportedModuleName); exportedModuleName);
@@ -412,7 +417,7 @@ void ProjectStorageUpdater::updateDirectoryChanged(Utils::SmallStringView direct
IsInsideProject isInsideProject, IsInsideProject isInsideProject,
Tracer &tracer) Tracer &tracer)
{ {
QmlDirParser parser; QQmlDirParser parser;
if (isExisting(qmldirState)) if (isExisting(qmldirState))
parser.parse(m_fileSystem.contentAsQString(QString{qmldirSourcePath})); parser.parse(m_fileSystem.contentAsQString(QString{qmldirSourcePath}));
@@ -447,8 +452,8 @@ void ProjectStorageUpdater::updateDirectoryChanged(Utils::SmallStringView direct
if (!qmlTypes.isEmpty()) { if (!qmlTypes.isEmpty()) {
parseTypeInfos(qmlTypes, parseTypeInfos(qmlTypes,
filterMultipleEntries(parser.dependencies()), toImportNames(filterMultipleEntries(parser.dependencies())),
imports, toImportNames(imports),
directoryId, directoryId,
directoryPathAsQString, directoryPathAsQString,
cppModuleId, cppModuleId,
@@ -1118,8 +1123,8 @@ void ProjectStorageUpdater::pathsWithIdsChanged(const std::vector<IdPaths> &chan
void ProjectStorageUpdater::pathsChanged(const SourceIds &) {} void ProjectStorageUpdater::pathsChanged(const SourceIds &) {}
void ProjectStorageUpdater::parseTypeInfos(const QStringList &typeInfos, void ProjectStorageUpdater::parseTypeInfos(const QStringList &typeInfos,
const QList<QmlDirParser::Import> &qmldirDependencies, const std::vector<Utils::PathString> &qmldirDependencies,
const QList<QmlDirParser::Import> &qmldirImports, const std::vector<Utils::PathString> &qmldirImports,
SourceContextId directoryId, SourceContextId directoryId,
const QString &directoryPath, const QString &directoryPath,
ModuleId moduleId, ModuleId moduleId,
@@ -1217,9 +1222,9 @@ auto ProjectStorageUpdater::parseTypeInfo(const Storage::Synchronization::Direct
notUpdatedSourceIds.sourceIds.push_back(directoryInfo.sourceId); notUpdatedSourceIds.sourceIds.push_back(directoryInfo.sourceId);
break; break;
} }
case FileState::Removed:
case FileState::NotExists: case FileState::NotExists:
case FileState::NotExistsUnchanged: case FileState::NotExistsUnchanged:
case FileState::Removed:
throw CannotParseQmlTypesFile{}; throw CannotParseQmlTypesFile{};
} }

View File

@@ -16,8 +16,6 @@
#include <tracing/qmldesignertracing.h> #include <tracing/qmldesignertracing.h>
#include <qmljs/parser/qmldirparser_p.h>
#include <QStringList> #include <QStringList>
#include <map> #include <map>
@@ -211,8 +209,8 @@ private:
SourceContextId directoryId, SourceContextId directoryId,
long long pathOffset); long long pathOffset);
void parseTypeInfos(const QStringList &typeInfos, void parseTypeInfos(const QStringList &typeInfos,
const QList<QmlDirParser::Import> &qmldirDependencies, const std::vector<Utils::PathString> &qmldirDependencies,
const QList<QmlDirParser::Import> &qmldirImports, const std::vector<Utils::PathString> &qmldirImports,
SourceContextId directoryId, SourceContextId directoryId,
const QString &directoryPath, const QString &directoryPath,
ModuleId moduleId, ModuleId moduleId,

View File

@@ -2068,7 +2068,7 @@ TEST_F(ProjectStorageUpdater, synchronize_qmldir_imports)
ModuleExportedImport{exampleModuleId, ModuleExportedImport{exampleModuleId,
quickModuleId, quickModuleId,
Storage::Version{}, Storage::Version{},
IsAutoVersion::No}, IsAutoVersion::Yes},
ModuleExportedImport{exampleCppNativeModuleId, ModuleExportedImport{exampleCppNativeModuleId,
quickCppNativeModuleId, quickCppNativeModuleId,
Storage::Version{}, Storage::Version{},
@@ -2130,7 +2130,7 @@ TEST_F(ProjectStorageUpdater, synchronize_qmldir_imports_with_double_entries)
ModuleExportedImport{exampleModuleId, ModuleExportedImport{exampleModuleId,
quickModuleId, quickModuleId,
Storage::Version{}, Storage::Version{},
IsAutoVersion::No}, IsAutoVersion::Yes},
ModuleExportedImport{exampleCppNativeModuleId, ModuleExportedImport{exampleCppNativeModuleId,
quickCppNativeModuleId, quickCppNativeModuleId,
Storage::Version{}, Storage::Version{},
@@ -2174,7 +2174,7 @@ TEST_F(ProjectStorageUpdater, synchronize_qmldir_default_imports)
ModuleExportedImport{exampleModuleId, ModuleExportedImport{exampleModuleId,
quickModuleId, quickModuleId,
Storage::Version{}, Storage::Version{},
IsAutoVersion::No}, IsAutoVersion::Yes},
ModuleExportedImport{exampleCppNativeModuleId, ModuleExportedImport{exampleCppNativeModuleId,
quickCppNativeModuleId, quickCppNativeModuleId,
Storage::Version{}, Storage::Version{},