diff --git a/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.cpp b/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.cpp index c4a2bae6178..a46315310a2 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.cpp +++ b/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.cpp @@ -32,6 +32,7 @@ #include +#include #include namespace QmlDesigner { @@ -53,30 +54,28 @@ Storage::Version convertVersion(QmlDom::Version version) Utils::PathString convertUri(const QString &uri) { - Utils::PathString path{QStringView{uri.begin() + 7, uri.end()}}; - if (path.endsWith("/.")) - return path; - if (path.endsWith("/")) { - path += "."; - return path; - } + QStringView localPath{uri.begin() + 7, uri.end()}; - path += "/."; - return path; + std::filesystem::path path{ + std::u16string_view{localPath.utf16(), static_cast(localPath.size())}}; + + auto x = std::filesystem::weakly_canonical(path); + + return Utils::PathString{x.generic_string()}; } void addImports(Storage::Imports &imports, const QList &qmlImports, SourceId sourceId, - SourceContextId sourceContextId, - QmlDocumentParser::PathCache &pathCache, + const QString &directoryPath, QmlDocumentParser::ProjectStorage &storage) { for (const QmlDom::Import &qmlImport : qmlImports) { if (qmlImport.uri == u"file://.") { - auto moduleId = storage.moduleId(pathCache.sourceContextPath(sourceContextId)); + auto moduleId = storage.moduleId(Utils::PathString{directoryPath}); imports.emplace_back(moduleId, Storage::Version{}, sourceId); } else if (qmlImport.uri.startsWith(u"file://")) { + auto x = convertUri(qmlImport.uri); auto moduleId = storage.moduleId(convertUri(qmlImport.uri)); imports.emplace_back(moduleId, Storage::Version{}, sourceId); } else { @@ -144,7 +143,7 @@ void addEnumeraton(Storage::Type &type, const QmlDom::Component &component) Storage::Type QmlDocumentParser::parse(const QString &sourceContent, Storage::Imports &imports, SourceId sourceId, - SourceContextId sourceContextId) + const QString &directoryPath) { Storage::Type type; @@ -155,9 +154,11 @@ Storage::Type QmlDocumentParser::parse(const QString &sourceContent, QmlDom::DomItem items; + QString filePath{directoryPath + "/foo.qml"}; + environment.loadFile( - {}, - {}, + filePath, + filePath, sourceContent, QDateTime{}, [&](QmlDom::Path, const QmlDom::DomItem &, const QmlDom::DomItem &newItems) { @@ -185,7 +186,7 @@ Storage::Type QmlDocumentParser::parse(const QString &sourceContent, type.prototype = Storage::ImportedType{Utils::SmallString{qmlObject.name()}}; - addImports(imports, qmlFile->imports(), sourceId, sourceContextId, m_pathCache, m_storage); + addImports(imports, qmlFile->imports(), sourceId, directoryPath, m_storage); addPropertyDeclarations(type, qmlObject); addFunctionAndSignalDeclarations(type, qmlObject); diff --git a/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.h b/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.h index e2dd2434058..c256f74309a 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.h @@ -46,18 +46,16 @@ public: using ProjectStorage = QmlDesigner::ProjectStorage; using PathCache = QmlDesigner::SourcePathCache; - QmlDocumentParser(PathCache &pathCache, ProjectStorage &storage) - : m_pathCache{pathCache} - , m_storage{storage} + QmlDocumentParser(ProjectStorage &storage) + : m_storage{storage} {} - virtual Storage::Type parse(const QString &sourceContent, - Storage::Imports &imports, - SourceId sourceId, - SourceContextId sourceContextId); + Storage::Type parse(const QString &sourceContent, + Storage::Imports &imports, + SourceId sourceId, + const QString &directoryPath); private: - PathCache &m_pathCache; ProjectStorage &m_storage; }; } // namespace QmlDesigner diff --git a/tests/unit/unittest/qmldocumentparser-test.cpp b/tests/unit/unittest/qmldocumentparser-test.cpp index 451003ba33c..1e890c6fc69 100644 --- a/tests/unit/unittest/qmldocumentparser-test.cpp +++ b/tests/unit/unittest/qmldocumentparser-test.cpp @@ -129,17 +129,17 @@ protected: QmlDesigner::ProjectStorage storage{database, database.isInitialized()}; QmlDesigner::SourcePathCache> sourcePathCache{ storage}; - QmlDesigner::QmlDocumentParser parser{sourcePathCache, storage}; + QmlDesigner::QmlDocumentParser parser{storage}; Storage::Imports imports; SourceId qmlFileSourceId{sourcePathCache.sourceId("path/to/qmlfile.qml")}; SourceContextId qmlFileSourceContextId{sourcePathCache.sourceContextId(qmlFileSourceId)}; - SourceId directorySourceId{sourcePathCache.sourceId("path/to/.")}; - ModuleId directoryModuleId{&directorySourceId}; + QString directoryPath{"/path/to"}; + ModuleId directoryModuleId{storage.moduleId("/path/to")}; }; TEST_F(QmlDocumentParser, Prototype) { - auto type = parser.parse("Example{}", imports, qmlFileSourceId, qmlFileSourceContextId); + auto type = parser.parse("Example{}", imports, qmlFileSourceId, directoryPath); ASSERT_THAT(type, HasPrototype(Storage::ImportedType("Example"))); } @@ -150,7 +150,7 @@ TEST_F(QmlDocumentParser, DISABLED_QualifiedPrototype) auto type = parser.parse("import Example as Example\n Example.Item{}", imports, qmlFileSourceId, - qmlFileSourceContextId); + directoryPath); ASSERT_THAT(type, HasPrototype(Storage::QualifiedImportedType( @@ -159,10 +159,7 @@ TEST_F(QmlDocumentParser, DISABLED_QualifiedPrototype) TEST_F(QmlDocumentParser, Properties) { - auto type = parser.parse("Example{\n property int foo\n}", - imports, - qmlFileSourceId, - qmlFileSourceContextId); + auto type = parser.parse("Example{\n property int foo\n}", imports, qmlFileSourceId, directoryPath); ASSERT_THAT(type.propertyDeclarations, UnorderedElementsAre(IsPropertyDeclaration("foo", @@ -170,16 +167,18 @@ TEST_F(QmlDocumentParser, Properties) Storage::PropertyDeclarationTraits::None))); } -TEST_F(QmlDocumentParser, DISABLED_Imports) +TEST_F(QmlDocumentParser, Imports) { - ModuleId fooDirectoryModuleId = storage.moduleId("path/to/foo/."); + ModuleId fooDirectoryModuleId = storage.moduleId("/path/foo"); ModuleId qmlModuleId = storage.moduleId("QML"); ModuleId qtQmlModuleId = storage.moduleId("QtQml"); ModuleId qtQuickModuleId = storage.moduleId("QtQuick"); - auto type = parser.parse("import QtQuick\n import \"../foo\"\nExample{}", + auto type = parser.parse(R"(import QtQuick + import "../foo" + Example{})", imports, qmlFileSourceId, - qmlFileSourceContextId); + directoryPath); ASSERT_THAT(imports, UnorderedElementsAre( @@ -196,7 +195,7 @@ TEST_F(QmlDocumentParser, Functions) "Example{\n function someScript(x, y) {}\n function otherFunction() {}\n}", imports, qmlFileSourceId, - qmlFileSourceContextId); + directoryPath); ASSERT_THAT(type.functionDeclarations, UnorderedElementsAre(AllOf(IsFunctionDeclaration("otherFunction", ""), @@ -212,7 +211,7 @@ TEST_F(QmlDocumentParser, Signals) auto type = parser.parse("Example{\n signal someSignal(int x, real y)\n signal signal2()\n}", imports, qmlFileSourceId, - qmlFileSourceContextId); + directoryPath); ASSERT_THAT(type.signalDeclarations, UnorderedElementsAre(AllOf(IsSignalDeclaration("someSignal"), @@ -229,7 +228,7 @@ TEST_F(QmlDocumentParser, Enumeration) "State{On,Off}\n}", imports, qmlFileSourceId, - qmlFileSourceContextId); + directoryPath); ASSERT_THAT(type.enumerationDeclarations, UnorderedElementsAre(