qmllint: Provide import paths and resource files when linting modules

Those are just as important for modules as for single files.

Pick-to: 6.5
Change-Id: I201d62c61988abc2dfba6300a1cfc355203fec75
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
This commit is contained in:
Ulf Hermann 2023-02-06 08:08:05 +01:00
parent d15efae7e1
commit 5c594515f6
8 changed files with 71 additions and 11 deletions

View File

@ -603,8 +603,9 @@ QQmlJSLinter::LintResult QQmlJSLinter::lintFile(const QString &filename,
return success ? LintSuccess : HasWarnings;
}
QQmlJSLinter::LintResult QQmlJSLinter::lintModule(const QString &module, const bool silent,
QJsonArray *json)
QQmlJSLinter::LintResult QQmlJSLinter::lintModule(
const QString &module, const bool silent, QJsonArray *json,
const QStringList &qmlImportPaths, const QStringList &resourceFiles)
{
// Make sure that we don't expose an old logger if we return before a new one is created.
m_logger.reset();
@ -612,6 +613,15 @@ QQmlJSLinter::LintResult QQmlJSLinter::lintModule(const QString &module, const b
// We can't lint properly if a module has already been pre-cached
m_importer.clearCache();
if (m_importer.importPaths() != qmlImportPaths)
m_importer.setImportPaths(qmlImportPaths);
QQmlJSResourceFileMapper mapper(resourceFiles);
if (!resourceFiles.isEmpty())
m_importer.setResourceFileMapper(&mapper);
else
m_importer.setResourceFileMapper(nullptr);
QJsonArray warnings;
QJsonObject result;

View File

@ -113,7 +113,8 @@ public:
const QStringList &qmldirFiles, const QStringList &resourceFiles,
const QList<QQmlJSLogger::Category> &categories);
LintResult lintModule(const QString &uri, const bool silent, QJsonArray *json);
LintResult lintModule(const QString &uri, const bool silent, QJsonArray *json,
const QStringList &qmlImportPaths, const QStringList &resourceFiles);
FixResult applyFixes(QString *fixedCode, bool silent);

View File

@ -0,0 +1,11 @@
import QtQuick
import QtQuick.Controls
Window {
width: 640; height: 480
visible: true
Button {
text: "a"
}
}

View File

@ -0,0 +1,3 @@
module moduleWithQrc
prefer :/qt/qml/moduleWithQrc/

View File

@ -0,0 +1,6 @@
<RCC>
<qresource prefix="/qt/qml/qmllint65/">
<file alias="main.qml">moduleWithQrc/main.qml</file>
</qresource>
</RCC>

View File

@ -0,0 +1,6 @@
<RCC>
<qresource prefix="/qt/qml/qmllint65">
<file alias="qmldir">moduleWithQrc/qmldir</file>
</qresource>
</RCC>

View File

@ -1388,15 +1388,19 @@ void TestQmllint::callQmllint(const QString &fileToLint, bool shouldSucceed, QJs
QQmlJSLinter::LintResult lintResult;
const QStringList resolvedImportPaths = defaultImports == UseDefaultImports
? m_defaultImportPaths + importPaths
: importPaths;
if (type == LintFile) {
const QList<QQmlJSLogger::Category> resolvedCategories = categories != nullptr
? *categories
: QQmlJSLogger::defaultCategories();
lintResult = m_linter.lintFile(
lintedFile, nullptr, true, &jsonOutput,
defaultImports == UseDefaultImports ? m_defaultImportPaths + importPaths
: importPaths,
qmldirFiles, resources,
categories != nullptr ? *categories : QQmlJSLogger::defaultCategories());
lintedFile, nullptr, true, &jsonOutput, resolvedImportPaths, qmldirFiles,
resources, resolvedCategories);
} else {
lintResult = m_linter.lintModule(fileToLint, true, &jsonOutput);
lintResult = m_linter.lintModule(
fileToLint, true, &jsonOutput, resolvedImportPaths, resources);
}
bool success = lintResult == QQmlJSLinter::LintSuccess;
@ -1689,10 +1693,14 @@ void TestQmllint::importMultipartUri()
void TestQmllint::lintModule_data()
{
QTest::addColumn<QString>("module");
QTest::addColumn<QStringList>("importPaths");
QTest::addColumn<QStringList>("resources");
QTest::addColumn<Result>("result");
QTest::addRow("Things")
<< u"Things"_s
<< QStringList()
<< QStringList()
<< Result {
{ Message {
u"Type \"QPalette\" not found. Used in SomethingEntirelyStrange.palette"_s,
@ -1702,16 +1710,30 @@ void TestQmllint::lintModule_data()
};
QTest::addRow("missingQmltypes")
<< u"Fake5Compat.GraphicalEffects.private"_s
<< QStringList()
<< QStringList()
<< Result { { Message { u"QML types file does not exist"_s } } };
QTest::addRow("moduleWithQrc")
<< u"moduleWithQrc"_s
<< QStringList({ testFile("hidden") })
<< QStringList({
testFile("hidden/qmake_moduleWithQrc.qrc"),
testFile("hidden/moduleWithQrc_raw_qml_0.qrc")
})
<< Result::clean();
}
void TestQmllint::lintModule()
{
QFETCH(QString, module);
QFETCH(QStringList, importPaths);
QFETCH(QStringList, resources);
QFETCH(Result, result);
QJsonArray warnings;
callQmllint(module, false, &warnings, {}, {}, {}, {}, nullptr, false, LintModule);
callQmllint(module, result.flags & Result::ExitsNormally, &warnings, importPaths, {}, resources,
UseDefaultImports, nullptr, false, LintModule);
checkResult(warnings, result);
}

View File

@ -363,7 +363,8 @@ All warnings can be set to three levels:
QQmlJSLinter::LintResult lintResult;
if (parser.isSet(moduleOption)) {
lintResult = linter.lintModule(filename, silent, useJson ? &jsonFiles : nullptr);
lintResult = linter.lintModule(filename, silent, useJson ? &jsonFiles : nullptr,
qmlImportPaths, resourceFiles);
} else {
lintResult = linter.lintFile(filename, nullptr, silent || isFixing,
useJson ? &jsonFiles : nullptr, qmlImportPaths,