diff options
| author | Sami Shalayel <sami.shalayel@qt.io> | 2024-08-09 14:16:24 +0200 |
|---|---|---|
| committer | Sami Shalayel <sami.shalayel@qt.io> | 2024-09-10 12:01:28 +0200 |
| commit | b1ff6073a7247c921e20cd98b2e3297e7368681b (patch) | |
| tree | b59a386d739ddb203889758272a3d727b8048ebf | |
| parent | 75603bfe1af69ca8a9ce45ee37dee722be8b800e (diff) | |
qmlls: find and use resource files from .qt/rcc
Search for resource files in .qt/rcc instead of only looking in
the .rcc folder, and update the resource file mapper in
setLoadPaths to actually use the resource files.
Amends d0fcb75aab1b5a91260fb378d761257e1f2e4787 to:
a) work on more sophisticated project structures with
"prefer"-directives
b) use resource files for all qmlls modules (previously only the
linting module was using resource files)
Also move the methods to find .qrc files into qqmljsutils_p.h and add a
new test file.
This patch fixes the spurious warning about SettingsData being not found
and the missing completion suggestion for the SettingsData type in
qml/popups/AdminDialog.qml on Ekke's project attached at QTBUG-126504.
The build folder structure was mimicked in sophisticatedBuildFolder for
the test.
Also change DomEnvironment::semanticAnalysis() to return a value instead
of a reference, and rename SemanticAnalysis::setLoadPaths to
SemanticAnalysis::updateLoadPaths because it will set the loadpaths on
all copies of semanticAnalysis instead of just setting it on the current
one.
Pick-to: 6.8 6.7
Task-number: QTBUG-127661
Task-number: QTBUG-126680
Change-Id: I47299711ced6cb952c4d3c1893495cb17a8eec7f
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
28 files changed, 217 insertions, 32 deletions
diff --git a/src/qmlcompiler/qqmljsutils.cpp b/src/qmlcompiler/qqmljsutils.cpp index 6de8741f1b..fcf56d4b96 100644 --- a/src/qmlcompiler/qqmljsutils.cpp +++ b/src/qmlcompiler/qqmljsutils.cpp @@ -5,6 +5,10 @@ #include "qqmljstyperesolver_p.h" #include "qqmljsscopesbyid_p.h" +#include <QtCore/qvarlengtharray.h> +#include <QtCore/qdir.h> +#include <QtCore/qdiriterator.h> + #include <algorithm> QT_BEGIN_NAMESPACE @@ -29,8 +33,7 @@ resolveAlias(ScopeForId scopeForId, const QQmlJSMetaProperty &property, // TODO: one could optimize the generated alias code for aliases pointing to aliases // e.g., if idA.myAlias -> idB.myAlias2 -> idC.myProp, then one could directly generate - // idA.myProp as pointing to idC.myProp. - // This gets complicated when idB.myAlias is in a different Component than where the + // idA.myProp as pointing to idC.myProp. // This gets complicated when idB.myAlias is in a different Component than where the // idA.myAlias is defined: scopeForId currently only contains the ids of the current // component and alias resolution on the ids of a different component fails then. if (QQmlJSMetaProperty nextProperty = property; nextProperty.isAlias()) { @@ -248,4 +251,34 @@ bool canCompareWithQUrl( && typeResolver->equals(rhsType, typeResolver->urlType()); } +static QVarLengthArray<QString, 2> resourceFoldersFromBuildFolder(const QString &buildFolder) +{ + QVarLengthArray<QString, 2> result; + const QDir dir(buildFolder); + if (dir.exists(u".rcc"_s)) { + result.append(dir.filePath(u".rcc"_s)); + } + if (dir.exists(u".qt/rcc"_s)) { + result.append(dir.filePath(u".qt/rcc"_s)); + } + return result; +} + + +QStringList QQmlJSUtils::resourceFilesFromBuildFolders(const QStringList &buildFolders) +{ + QStringList result; + for (const QString &path : buildFolders) { + for (const QString &resourceFolder : resourceFoldersFromBuildFolder(path)) { + QDirIterator it(resourceFolder, QStringList{ u"*.qrc"_s }, QDir::Files, + QDirIterator::Subdirectories); + while (it.hasNext()) { + result.append(it.next()); + } + } + } + return result; +} + + QT_END_NAMESPACE diff --git a/src/qmlcompiler/qqmljsutils_p.h b/src/qmlcompiler/qqmljsutils_p.h index c23399e9ae..1d6a642724 100644 --- a/src/qmlcompiler/qqmljsutils_p.h +++ b/src/qmlcompiler/qqmljsutils_p.h @@ -381,6 +381,8 @@ struct Q_QMLCOMPILER_EXPORT QQmlJSUtils path = QDir::cleanPath(path); return std::move(paths); } + + static QStringList resourceFilesFromBuildFolders(const QStringList &buildFolders); }; bool Q_QMLCOMPILER_EXPORT canStrictlyCompareWithVar( diff --git a/src/qmldom/qqmldom_utils.cpp b/src/qmldom/qqmldom_utils.cpp index a7c985644a..a3e73ac3ef 100644 --- a/src/qmldom/qqmldom_utils.cpp +++ b/src/qmldom/qqmldom_utils.cpp @@ -7,6 +7,7 @@ #include <QtCore/qstring.h> #include <QtCore/qmetaobject.h> #include <QtCore/qcbormap.h> +#include <QtCore/qvarlengtharray.h> QT_BEGIN_NAMESPACE @@ -17,23 +18,6 @@ namespace Dom { using namespace Qt::StringLiterals; -QStringList resourceFilesFromBuildFolders(const QStringList &buildFolders) -{ - QStringList result; - for (const QString &path : buildFolders) { - QDir dir(path); - if (!dir.cd(u".rcc"_s)) - continue; - - QDirIterator it(dir.canonicalPath(), QStringList{ u"*.qrc"_s }, QDir::Files, - QDirIterator::Subdirectories); - while (it.hasNext()) { - result.append(it.next()); - } - } - return result; -} - static QMetaEnum regionEnum = QMetaEnum::fromType<FileLocationRegion>(); QString fileLocationRegionName(FileLocationRegion region) diff --git a/src/qmldom/qqmldom_utils_p.h b/src/qmldom/qqmldom_utils_p.h index 6fcdb5fe10..c4cb8b0c16 100644 --- a/src/qmldom/qqmldom_utils_p.h +++ b/src/qmldom/qqmldom_utils_p.h @@ -38,8 +38,6 @@ qOverloadedVisitor(Ts...) -> qOverloadedVisitor<Ts...>; namespace QQmlJS { namespace Dom { -QStringList resourceFilesFromBuildFolders(const QStringList &buildFolders); - QString fileLocationRegionName(FileLocationRegion region); FileLocationRegion fileLocationRegionValue(QStringView region); diff --git a/src/qmldom/qqmldomtop.cpp b/src/qmldom/qqmldomtop.cpp index cfc20d50ef..d76f09fe00 100644 --- a/src/qmldom/qqmldomtop.cpp +++ b/src/qmldom/qqmldomtop.cpp @@ -17,6 +17,8 @@ #include <QtQml/private/qqmljsastvisitor_p.h> #include <QtQml/private/qqmljsast_p.h> +#include <QtQmlCompiler/private/qqmljsutils_p.h> + #include <QtCore/QBasicMutex> #include <QtCore/QCborArray> #include <QtCore/QDebug> @@ -1823,13 +1825,13 @@ DomEnvironment::DomEnvironment(const QStringList &loadPaths, Options options, Do not call this method inside of DomEnvironment's constructor! It requires weak_from_this() that only works after the constructor call finished. */ -DomEnvironment::SemanticAnalysis &DomEnvironment::semanticAnalysis() +DomEnvironment::SemanticAnalysis DomEnvironment::semanticAnalysis() { // QTBUG-124799: do not create a SemanticAnalysis in a temporary DomEnvironment, and use the one // from the base environment instead. if (m_base) { - auto &result = m_base->semanticAnalysis(); - result.setLoadPaths(m_loadPaths); + auto result = m_base->semanticAnalysis(); + result.updateLoadPaths(m_loadPaths); return result; } @@ -1843,17 +1845,26 @@ DomEnvironment::SemanticAnalysis &DomEnvironment::semanticAnalysis() DomEnvironment::SemanticAnalysis::SemanticAnalysis(const QStringList &loadPaths) : m_mapper( - std::make_shared<QQmlJSResourceFileMapper>(resourceFilesFromBuildFolders(loadPaths))), + std::make_shared<QQmlJSResourceFileMapper>(QQmlJSUtils::resourceFilesFromBuildFolders(loadPaths))), m_importer(std::make_shared<QQmlJSImporter>(loadPaths, m_mapper.get(), true)) { } -void DomEnvironment::SemanticAnalysis::setLoadPaths(const QStringList &loadPaths) +/*! +\internal + +Sets the new load paths in the importer and recreate the mapper. + +This affects all copies of SemanticAnalysis that use the same QQmlJSImporter and QQmlJSMapper +pointers. +*/ +void DomEnvironment::SemanticAnalysis::updateLoadPaths(const QStringList &loadPaths) { if (loadPaths == m_importer->importPaths()) return; m_importer->setImportPaths(loadPaths); + *m_mapper = QQmlJSResourceFileMapper(QQmlJSUtils::resourceFilesFromBuildFolders(loadPaths)); } std::shared_ptr<DomEnvironment> DomEnvironment::create(const QStringList &loadPaths, @@ -2153,7 +2164,7 @@ void DomEnvironment::setLoadPaths(const QStringList &v) m_loadPaths = v; if (m_semanticAnalysis) - m_semanticAnalysis->setLoadPaths(v); + m_semanticAnalysis->updateLoadPaths(v); } QStringList DomEnvironment::loadPaths() const @@ -2222,7 +2233,7 @@ void DomEnvironment::populateFromQmlFile(MutableDomItem &&qmlFile) }; if (m_domCreationOptions.testFlag(DomCreationOption::WithSemanticAnalysis)) { - auto &analysis = semanticAnalysis(); + SemanticAnalysis analysis = semanticAnalysis(); auto scope = analysis.m_importer->importFile(qmlFile.canonicalFilePath()); auto v = std::make_unique<QQmlDomAstCreatorWithQQmlJSScope>( scope, qmlFile, logger.get(), analysis.m_importer.get()); diff --git a/src/qmldom/qqmldomtop_p.h b/src/qmldom/qqmldomtop_p.h index afdea6b311..0b6dadb19d 100644 --- a/src/qmldom/qqmldomtop_p.h +++ b/src/qmldom/qqmldomtop_p.h @@ -1116,13 +1116,14 @@ private: struct SemanticAnalysis { SemanticAnalysis(const QStringList &loadPaths); - void setLoadPaths(const QStringList &loadPaths); + void updateLoadPaths(const QStringList &loadPaths); std::shared_ptr<QQmlJSResourceFileMapper> m_mapper; std::shared_ptr<QQmlJSImporter> m_importer; }; std::optional<SemanticAnalysis> m_semanticAnalysis; - SemanticAnalysis &semanticAnalysis(); +public: + SemanticAnalysis semanticAnalysis(); }; Q_DECLARE_OPERATORS_FOR_FLAGS(DomEnvironment::Options) diff --git a/src/qmlls/qqmllintsuggestions.cpp b/src/qmlls/qqmllintsuggestions.cpp index 506b7b9171..491f15ae9c 100644 --- a/src/qmlls/qqmllintsuggestions.cpp +++ b/src/qmlls/qqmllintsuggestions.cpp @@ -6,6 +6,7 @@ #include <QtLanguageServer/private/qlanguageserverspec_p.h> #include <QtQmlCompiler/private/qqmljslinter_p.h> #include <QtQmlCompiler/private/qqmljslogger_p.h> +#include <QtQmlCompiler/private/qqmljsutils_p.h> #include <QtQmlDom/private/qqmldom_utils_p.h> #include <QtQmlDom/private/qqmldomtop_p.h> #include <QtCore/qdebug.h> @@ -316,7 +317,7 @@ void QmlLintSuggestions::diagnoseHelper(const QByteArray &url, bool silent = true; const QString fileContents = doc.field(Fields::code).value().toString(); const QStringList qmltypesFiles; - const QStringList resourceFiles = resourceFilesFromBuildFolders(imports); + const QStringList resourceFiles = QQmlJSUtils::resourceFilesFromBuildFolders(imports); QList<QQmlJS::LoggerCategory> categories = QQmlJSLogger::defaultCategories(); diff --git a/tests/auto/qml/CMakeLists.txt b/tests/auto/qml/CMakeLists.txt index 6b81f4c616..f0d0fb49db 100644 --- a/tests/auto/qml/CMakeLists.txt +++ b/tests/auto/qml/CMakeLists.txt @@ -165,4 +165,5 @@ if(QT_FEATURE_private_tests) endif() if(NOT CMAKE_CROSSCOMPILING) add_subdirectory(qmltyperegistrar) + add_subdirectory(qqmljsutils) endif() diff --git a/tests/auto/qml/qqmljsutils/CMakeLists.txt b/tests/auto/qml/qqmljsutils/CMakeLists.txt new file mode 100644 index 0000000000..cff91f5b8b --- /dev/null +++ b/tests/auto/qml/qqmljsutils/CMakeLists.txt @@ -0,0 +1,29 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qqmljsutils LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + data) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_qqmljsutils + SOURCES + tst_qqmljsutils.h tst_qqmljsutils.cpp + LIBRARIES + Qt::QmlCompilerPrivate + Qt::QuickTestUtilsPrivate + TESTDATA ${test_data} + DEFINES + QT_QQMLJSUTILS_DATADIR="${CMAKE_CURRENT_SOURCE_DIR}/data" +) + +qt_internal_extend_target(tst_qqmljsutils CONDITION ANDROID OR IOS + DEFINES + QT_QQMLJSUTILS_DATADIR=":/data" +) diff --git a/tests/auto/qml/qqmljsutils/data/buildfolder/.qt/rcc/appuntitled72_raw_qml_0.qrc b/tests/auto/qml/qqmljsutils/data/buildfolder/.qt/rcc/appuntitled72_raw_qml_0.qrc new file mode 100644 index 0000000000..176ee061cf --- /dev/null +++ b/tests/auto/qml/qqmljsutils/data/buildfolder/.qt/rcc/appuntitled72_raw_qml_0.qrc @@ -0,0 +1,6 @@ +<RCC> + <qresource prefix="/qt/qml/MyModule/"> + <file alias="qml/HelloWorld.qml">../../HelloWorld.qml</file> + </qresource> +</RCC> + diff --git a/tests/auto/qml/qqmljsutils/data/buildfolder/HelloWorld.qml b/tests/auto/qml/qqmljsutils/data/buildfolder/HelloWorld.qml new file mode 100644 index 0000000000..3052615aef --- /dev/null +++ b/tests/auto/qml/qqmljsutils/data/buildfolder/HelloWorld.qml @@ -0,0 +1,3 @@ +import QtQuick + +Item {} diff --git a/tests/auto/qml/qqmljsutils/tst_qqmljsutils.cpp b/tests/auto/qml/qqmljsutils/tst_qqmljsutils.cpp new file mode 100644 index 0000000000..e16ffe46f5 --- /dev/null +++ b/tests/auto/qml/qqmljsutils/tst_qqmljsutils.cpp @@ -0,0 +1,17 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "tst_qqmljsutils.h" +#include <QtQmlCompiler/private/qqmljsutils_p.h> + +using namespace Qt::StringLiterals; + +void tst_qqmljsutils::findResourceFilesFromBuildFolders() +{ + const QString buildFolder = testFile("buildfolder"); + const QStringList resourceFiles = QQmlJSUtils::resourceFilesFromBuildFolders({ buildFolder}); + QCOMPARE(resourceFiles, + QStringList{ testFile(u"buildfolder/.qt/rcc/appuntitled72_raw_qml_0.qrc"_s) }); +}; + +QTEST_MAIN(tst_qqmljsutils) diff --git a/tests/auto/qml/qqmljsutils/tst_qqmljsutils.h b/tests/auto/qml/qqmljsutils/tst_qqmljsutils.h new file mode 100644 index 0000000000..8637feab17 --- /dev/null +++ b/tests/auto/qml/qqmljsutils/tst_qqmljsutils.h @@ -0,0 +1,21 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef TST_QQMLJSUTILS_P_H +#define TST_QQMLJSUTILS_P_H + +#include <QtQuickTestUtils/private/qmlutils_p.h> + +#include <QtTest/QtTest> + +class tst_qqmljsutils: public QQmlDataTest +{ + Q_OBJECT +public: + tst_qqmljsutils(): QQmlDataTest(QT_QQMLJSUTILS_DATADIR) { }; + +private slots: + void findResourceFilesFromBuildFolders(); +}; + +#endif // TST_QQMLJSUTILS_P_H diff --git a/tests/auto/qmldom/domdata/domitem/buildFolderWithQrc/.qt/rcc/someQrc.qrc b/tests/auto/qmldom/domdata/domitem/buildFolderWithQrc/.qt/rcc/someQrc.qrc new file mode 100644 index 0000000000..f09b9490b7 --- /dev/null +++ b/tests/auto/qmldom/domdata/domitem/buildFolderWithQrc/.qt/rcc/someQrc.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/qt/qml/MyModule/"> + <file alias="qml/HelloWorld.qml">../../HelloWorld.qml</file> + </qresource> +</RCC> diff --git a/tests/auto/qmldom/domdata/domitem/buildFolderWithQrc/HelloWorld.qml b/tests/auto/qmldom/domdata/domitem/buildFolderWithQrc/HelloWorld.qml new file mode 100644 index 0000000000..a1bf0dd1e9 --- /dev/null +++ b/tests/auto/qmldom/domdata/domitem/buildFolderWithQrc/HelloWorld.qml @@ -0,0 +1,6 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +import QtQuick + +Item {} diff --git a/tests/auto/qmldom/domitem/tst_qmldomitem.h b/tests/auto/qmldom/domitem/tst_qmldomitem.h index 5744b65be6..9f30dd1768 100644 --- a/tests/auto/qmldom/domitem/tst_qmldomitem.h +++ b/tests/auto/qmldom/domitem/tst_qmldomitem.h @@ -4316,6 +4316,25 @@ private slots: } } + void environmentSetLoadPaths() + { + DomCreationOptions options; + options.setFlag(DomCreationOption::WithScriptExpressions); + options.setFlag(DomCreationOption::WithSemanticAnalysis); + + auto envPtr = DomEnvironment::create( + QStringList{}, + QQmlJS::Dom::DomEnvironment::Option::SingleThreaded + | QQmlJS::Dom::DomEnvironment::Option::NoDependencies, + options); + + auto semanticAnalysis = envPtr->semanticAnalysis(); + QVERIFY(semanticAnalysis.m_mapper->isEmpty()); + envPtr->setLoadPaths(QStringList { baseDir + u"/buildFolderWithQrc"_s }); + QVERIFY(!semanticAnalysis.m_mapper->isEmpty()); + QVERIFY(semanticAnalysis.m_mapper->isFile(u"/qt/qml/MyModule/qml/HelloWorld.qml"_s)); + } + private: QString baseDir; QStringList qmltypeDirs; diff --git a/tests/auto/qmlls/utils/data/AdminDialogFromSource.qml b/tests/auto/qmlls/utils/data/AdminDialogFromSource.qml new file mode 100644 index 0000000000..4d57e38419 --- /dev/null +++ b/tests/auto/qmlls/utils/data/AdminDialogFromSource.qml @@ -0,0 +1,5 @@ +import QtQuick + +Item { + property LabelTitle title: LabelTitle {} +} diff --git a/tests/auto/qmlls/utils/data/sophisticatedBuildFolder/.qt/rcc/projectname_raw_qml_0.qrc b/tests/auto/qmlls/utils/data/sophisticatedBuildFolder/.qt/rcc/projectname_raw_qml_0.qrc new file mode 100644 index 0000000000..d496c59e1d --- /dev/null +++ b/tests/auto/qmlls/utils/data/sophisticatedBuildFolder/.qt/rcc/projectname_raw_qml_0.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/qt/qml/Me/Apps/Main/"> + <file alias="qml/popups/AdminDialog.qml">../../../AdminDialogFromSource.qml</file> + </qresource> +</RCC>
\ No newline at end of file diff --git a/tests/auto/qmlls/utils/data/sophisticatedBuildFolder/.qt/rcc/projectname_raw_qml_0_extra_qmldirs.qrc b/tests/auto/qmlls/utils/data/sophisticatedBuildFolder/.qt/rcc/projectname_raw_qml_0_extra_qmldirs.qrc new file mode 100644 index 0000000000..19eb738225 --- /dev/null +++ b/tests/auto/qmlls/utils/data/sophisticatedBuildFolder/.qt/rcc/projectname_raw_qml_0_extra_qmldirs.qrc @@ -0,0 +1,7 @@ +<RCC> + <qresource prefix="/qt/qml/Me/Apps/Main/"> + <file alias="qml/qmldir">../../Me/Apps/Main/qml/qmldir</file> + <file alias="qml/common/qmldir">../../Me/Apps/Main/qml/common/qmldir</file> + <file alias="qml/popups/qmldir">../../Me/Apps/Main/qml/popups/qmldir</file> + </qresource> +</RCC>
\ No newline at end of file diff --git a/tests/auto/qmlls/utils/data/sophisticatedBuildFolder/.qt/rcc/qmake_projectname.qrc b/tests/auto/qmlls/utils/data/sophisticatedBuildFolder/.qt/rcc/qmake_projectname.qrc new file mode 100644 index 0000000000..68036107a3 --- /dev/null +++ b/tests/auto/qmlls/utils/data/sophisticatedBuildFolder/.qt/rcc/qmake_projectname.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/qt/qml/Me/Apps/Main"> + <file alias="qmldir">../../Me/Apps/Main/qmldir</file> + </qresource> +</RCC> diff --git a/tests/auto/qmlls/utils/data/sophisticatedBuildFolder/Me/Apps/Main/qml/Main.qml b/tests/auto/qmlls/utils/data/sophisticatedBuildFolder/Me/Apps/Main/qml/Main.qml new file mode 100644 index 0000000000..3052615aef --- /dev/null +++ b/tests/auto/qmlls/utils/data/sophisticatedBuildFolder/Me/Apps/Main/qml/Main.qml @@ -0,0 +1,3 @@ +import QtQuick + +Item {} diff --git a/tests/auto/qmlls/utils/data/sophisticatedBuildFolder/Me/Apps/Main/qml/common/LabelTitle.qml b/tests/auto/qmlls/utils/data/sophisticatedBuildFolder/Me/Apps/Main/qml/common/LabelTitle.qml new file mode 100644 index 0000000000..3052615aef --- /dev/null +++ b/tests/auto/qmlls/utils/data/sophisticatedBuildFolder/Me/Apps/Main/qml/common/LabelTitle.qml @@ -0,0 +1,3 @@ +import QtQuick + +Item {} diff --git a/tests/auto/qmlls/utils/data/sophisticatedBuildFolder/Me/Apps/Main/qml/common/qmldir b/tests/auto/qmlls/utils/data/sophisticatedBuildFolder/Me/Apps/Main/qml/common/qmldir new file mode 100644 index 0000000000..06128366a7 --- /dev/null +++ b/tests/auto/qmlls/utils/data/sophisticatedBuildFolder/Me/Apps/Main/qml/common/qmldir @@ -0,0 +1 @@ +prefer :/qt/qml/Me/Apps/Main/ diff --git a/tests/auto/qmlls/utils/data/sophisticatedBuildFolder/Me/Apps/Main/qml/popups/AdminDialog.qml b/tests/auto/qmlls/utils/data/sophisticatedBuildFolder/Me/Apps/Main/qml/popups/AdminDialog.qml new file mode 100644 index 0000000000..a1b846292d --- /dev/null +++ b/tests/auto/qmlls/utils/data/sophisticatedBuildFolder/Me/Apps/Main/qml/popups/AdminDialog.qml @@ -0,0 +1,5 @@ +import QtQuick + +Item { + property LabelTitle label: LabelTitle {} +} diff --git a/tests/auto/qmlls/utils/data/sophisticatedBuildFolder/Me/Apps/Main/qml/popups/qmldir b/tests/auto/qmlls/utils/data/sophisticatedBuildFolder/Me/Apps/Main/qml/popups/qmldir new file mode 100644 index 0000000000..06128366a7 --- /dev/null +++ b/tests/auto/qmlls/utils/data/sophisticatedBuildFolder/Me/Apps/Main/qml/popups/qmldir @@ -0,0 +1 @@ +prefer :/qt/qml/Me/Apps/Main/ diff --git a/tests/auto/qmlls/utils/data/sophisticatedBuildFolder/Me/Apps/Main/qml/qmldir b/tests/auto/qmlls/utils/data/sophisticatedBuildFolder/Me/Apps/Main/qml/qmldir new file mode 100644 index 0000000000..06128366a7 --- /dev/null +++ b/tests/auto/qmlls/utils/data/sophisticatedBuildFolder/Me/Apps/Main/qml/qmldir @@ -0,0 +1 @@ +prefer :/qt/qml/Me/Apps/Main/ diff --git a/tests/auto/qmlls/utils/data/sophisticatedBuildFolder/Me/Apps/Main/qmldir b/tests/auto/qmlls/utils/data/sophisticatedBuildFolder/Me/Apps/Main/qmldir new file mode 100644 index 0000000000..edf90d9cc3 --- /dev/null +++ b/tests/auto/qmlls/utils/data/sophisticatedBuildFolder/Me/Apps/Main/qmldir @@ -0,0 +1,6 @@ +module Me.Apps.Main +prefer :/qt/qml/Me/Apps/Main/ +Main 254.0 qml/Main.qml +AdminDialog 254.0 qml/popups/AdminDialog.qml +LabelTitle 254.0 qml/common/LabelTitle.qml + diff --git a/tests/auto/qmlls/utils/tst_qmlls_utils.cpp b/tests/auto/qmlls/utils/tst_qmlls_utils.cpp index 2787adc4a3..7c59ffaa26 100644 --- a/tests/auto/qmlls/utils/tst_qmlls_utils.cpp +++ b/tests/auto/qmlls/utils/tst_qmlls_utils.cpp @@ -44,7 +44,8 @@ tst_qmlls_utils::createEnvironmentAndLoadFile(const QString &filePath) }; QStringList qmltypeDirs = - QStringList({ dataDirectory(), QLibraryInfo::path(QLibraryInfo::Qml2ImportsPath) }); + QStringList({ dataDirectory(), QLibraryInfo::path(QLibraryInfo::Qml2ImportsPath), + dataDirectory() + u"/sophisticatedBuildFolder"_s }); // This should be exactly the same options as qmlls uses in qqmlcodemodel. // Otherwise, this test will not test the codepaths also used by qmlls and will be useless. @@ -4324,6 +4325,11 @@ void tst_qmlls_utils::completions_data() << ExpectedCompletions{ { u"World"_s, CompletionItemKind::EnumMember }, { u"Hello"_s, CompletionItemKind::Enum } } << QStringList{}; + + QTest::newRow("viaResourceFile") + << testFile("AdminDialogFromSource.qml") << 4 << 33 + << ExpectedCompletions{ { u"LabelTitle"_s, CompletionItemKind::Constructor } } + << QStringList{}; } void tst_qmlls_utils::completions() |
