diff options
author | Maximilian Goldstein <max.goldstein@qt.io> | 2021-11-17 11:25:36 +0100 |
---|---|---|
committer | Maximilian Goldstein <max.goldstein@qt.io> | 2021-11-23 18:45:06 +0100 |
commit | a98747ab6c153e1d361ec64ea616764a71465fa4 (patch) | |
tree | f622b3329bc2ef98b5300fef1a38db74533dcc4d /tools/qmllint/main.cpp | |
parent | 608e1a805349b0c76fcd993c43f4f9d808c2d77f (diff) |
qmllint: Move most code into a separate library
This is necessary step for both making qmllint viable for use in
controls' tst_sanity, as well as for integration with the
language server.
As an additional upside it allows us to run our tests up to 10x faster.
Eventually we want to integrate all of this into qmlcompiler but due
to the state of some of the code we will keep qmllint in a separate
library as to keep qmlcompiler tidier.
Change-Id: Ic057ef0cd4424d28aa05e517d74280a442ec9c5a
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Diffstat (limited to 'tools/qmllint/main.cpp')
-rw-r--r-- | tools/qmllint/main.cpp | 183 |
1 files changed, 5 insertions, 178 deletions
diff --git a/tools/qmllint/main.cpp b/tools/qmllint/main.cpp index 3df510ed79..b7b64f0b2b 100644 --- a/tools/qmllint/main.cpp +++ b/tools/qmllint/main.cpp @@ -26,20 +26,13 @@ ** ****************************************************************************/ -#include "findwarnings.h" -#include "codegen.h" -#include "codegenwarninginterface.h" #include "../shared/qqmltoolingsettings.h" +#include <QtQmlLint/private/qqmllinter_p.h> + #include <QtQmlCompiler/private/qqmljsresourcefilemapper_p.h> #include <QtQmlCompiler/private/qqmljscompiler_p.h> -#include <QtQml/private/qqmljslexer_p.h> -#include <QtQml/private/qqmljsparser_p.h> -#include <QtQml/private/qqmljsengine_p.h> -#include <QtQml/private/qqmljsastvisitor_p.h> -#include <QtQml/private/qqmljsast_p.h> - #include <QtCore/qdebug.h> #include <QtCore/qfile.h> #include <QtCore/qfileinfo.h> @@ -48,7 +41,6 @@ #include <QtCore/qjsonobject.h> #include <QtCore/qjsonarray.h> #include <QtCore/qjsondocument.h> -#include <QtCore/qloggingcategory.h> #include <QtCore/qscopeguard.h> #if QT_CONFIG(commandlineparser) @@ -61,171 +53,6 @@ constexpr int JSON_LOGGING_FORMAT_REVISION = 1; -static bool lint_file(const QString &filename, const bool silent, const bool useAbsolutePath, - QJsonArray *json, const QStringList &qmlImportPaths, - const QStringList &qmltypesFiles, const QStringList &resourceFiles, - const QMap<QString, QQmlJSLogger::Option> &options, QQmlJSImporter &importer) -{ - QJsonArray warnings; - QJsonObject result; - - bool success = true; - - QScopeGuard jsonOutput([&] { - if (!json) - return; - - result[u"filename"_qs] = QFileInfo(filename).absoluteFilePath(); - result[u"warnings"] = warnings; - result[u"success"] = success; - - json->append(result); - }); - - auto addJsonWarning = [&](const QQmlJS::DiagnosticMessage &message) { - QJsonObject jsonMessage; - - QString type; - switch (message.type) { - case QtDebugMsg: - type = "debug"; - break; - case QtWarningMsg: - type = "warning"; - break; - case QtCriticalMsg: - type = "critical"; - break; - case QtFatalMsg: - type = "fatal"; - break; - case QtInfoMsg: - type = "info"; - break; - default: - type = "unknown"; - break; - } - - jsonMessage[u"type"_qs] = type; - - if (message.loc.isValid()) { - jsonMessage[u"line"_qs] = static_cast<int>(message.loc.startLine); - jsonMessage[u"column"_qs] = static_cast<int>(message.loc.startColumn); - jsonMessage[u"charOffset"_qs] = static_cast<int>(message.loc.offset); - jsonMessage[u"length"_qs] = static_cast<int>(message.loc.length); - } - - jsonMessage[u"message"_qs] = message.message; - - warnings << jsonMessage; - }; - - QFile file(filename); - if (!file.open(QFile::ReadOnly)) { - if (json) { - result[u"openFailed"] = true; - success = false; - } else if (!silent) { - qWarning() << "Failed to open file" << filename << file.error(); - } - return false; - } - - QString code = QString::fromUtf8(file.readAll()); - file.close(); - - QQmlJS::Engine engine; - QQmlJS::Lexer lexer(&engine); - - QFileInfo info(filename); - const QString lowerSuffix = info.suffix().toLower(); - const bool isESModule = lowerSuffix == QLatin1String("mjs"); - const bool isJavaScript = isESModule || lowerSuffix == QLatin1String("js"); - - lexer.setCode(code, /*lineno = */ 1, /*qmlMode=*/ !isJavaScript); - QQmlJS::Parser parser(&engine); - - success = isJavaScript ? (isESModule ? parser.parseModule() : parser.parseProgram()) - : parser.parse(); - - if (!success && !silent) { - const auto diagnosticMessages = parser.diagnosticMessages(); - for (const QQmlJS::DiagnosticMessage &m : diagnosticMessages) { - if (json) { - addJsonWarning(m); - } else { - qWarning().noquote() << QString::fromLatin1("%1:%2 : %3") - .arg(filename) - .arg(m.loc.startLine) - .arg(m.message); - } - } - } - - if (success && !isJavaScript) { - const auto check = [&](QQmlJSResourceFileMapper *mapper) { - if (importer.importPaths() != qmlImportPaths) - importer.setImportPaths(qmlImportPaths); - - importer.setResourceFileMapper(mapper); - - QQmlJSLogger logger(useAbsolutePath ? info.absoluteFilePath() : filename, code, - silent || json); - FindWarningVisitor v { - &importer, - &logger, - qmltypesFiles, - engine.comments(), - }; - - for (auto it = options.cbegin(); it != options.cend(); ++it) { - logger.setCategoryError(it.value().m_category, it.value().m_error); - logger.setCategoryLevel(it.value().m_category, it.value().m_level); - } - - parser.rootNode()->accept(&v); - success = v.check(); - - if (logger.hasErrors()) - return; - - QQmlJSTypeInfo typeInfo; - Codegen codegen { &importer, filename, qmltypesFiles, &logger, &typeInfo, code }; - QQmlJSSaveFunction saveFunction = [](const QV4::CompiledData::SaveableUnitPointer &, - const QQmlJSAotFunctionMap &, - QString *) { return true; }; - - QQmlJSCompileError error; - - QLoggingCategory::setFilterRules(u"qt.qml.compiler=false"_qs); - - CodegenWarningInterface interface(&logger); - qCompileQmlFile(filename, saveFunction, &codegen, &error, true, &interface); - - success &= !logger.hasWarnings() && !logger.hasErrors(); - - if (json) { - for (const auto &error : logger.errors()) - addJsonWarning(error); - for (const auto &warning : logger.warnings()) - addJsonWarning(warning); - for (const auto &info : logger.infos()) - addJsonWarning(info); - } - }; - - if (resourceFiles.isEmpty()) { - check(nullptr); - } else { - QQmlJSResourceFileMapper mapper(resourceFiles); - check(&mapper); - } - } - - return success; -} - int main(int argv, char *argc[]) { qSetGlobalQHashSeed(0); @@ -394,7 +221,7 @@ All warnings can be set to three levels: QStringList resourceFiles {}; #endif bool success = true; - QQmlJSImporter importer(qmlImportPaths, nullptr); + QQmlLinter linter(qmlImportPaths, useAbsolutePath); QJsonArray jsonFiles; @@ -439,8 +266,8 @@ All warnings can be set to three levels: const auto arguments = app.arguments(); for (const QString &filename : arguments) { #endif - success &= lint_file(filename, silent, useAbsolutePath, useJson ? &jsonFiles : nullptr, - qmlImportPaths, qmltypesFiles, resourceFiles, options, importer); + success &= linter.lintFile(filename, silent, useJson ? &jsonFiles : nullptr, qmlImportPaths, + qmltypesFiles, resourceFiles, options); } if (useJson) { |