qmlcompiler: Remove qmllint library

Since all of the superfluous components of qmllint have been
removed now, we can just move what little custom linter logic
remains to qmlcompiler.

Change-Id: I91c752cb895e7d6c6f2dd4e2ccafb6cd05afa225
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
Maximilian Goldstein 2022-02-03 12:01:35 +01:00
parent d08038ba70
commit 07917626f5
18 changed files with 90 additions and 190 deletions

View File

@ -73,7 +73,6 @@ add_subdirectory(plugins)
if(QT_FEATURE_qml_devtools)
add_subdirectory(qmlcompiler)
add_subdirectory(qmllint)
add_subdirectory(qmldom)
# Build qmlcachegen now, so that we can use it in src/imports.

View File

@ -31,6 +31,8 @@ qt_internal_add_module(QmlCompilerPrivate
qqmljstyperesolver.cpp qqmljstyperesolver_p.h
qresourcerelocater.cpp qresourcerelocater_p.h
qqmljsutils_p.h qqmljsutils.cpp
qqmljslinter_p.h qqmljslinter.cpp
qqmljslintercodegen_p.h qqmljslintercodegen.cpp
PUBLIC_LIBRARIES
Qt::CorePrivate
Qt::QmlPrivate

View File

@ -26,10 +26,9 @@
**
****************************************************************************/
#include "qqmllinter_p.h"
#include "qqmljslinter_p.h"
#include "codegen_p.h"
#include "codegenwarninginterface_p.h"
#include "qqmljslintercodegen_p.h"
#include <QtQmlCompiler/private/qqmljsimporter_p.h>
#include <QtQmlCompiler/private/qqmljsimportvisitor_p.h>
@ -47,12 +46,35 @@
QT_BEGIN_NAMESPACE
QQmlLinter::QQmlLinter(const QStringList &importPaths, bool useAbsolutePath)
class CodegenWarningInterface final : public QV4::Compiler::CodegenWarningInterface
{
public:
CodegenWarningInterface(QQmlJSLogger *logger) : m_logger(logger) { }
void reportVarUsedBeforeDeclaration(const QString &name, const QString &fileName,
QQmlJS::SourceLocation declarationLocation,
QQmlJS::SourceLocation accessLocation) override
{
Q_UNUSED(fileName)
m_logger->logWarning(
u"Variable \"%1\" is used here before its declaration. The declaration is at %2:%3."_qs
.arg(name)
.arg(declarationLocation.startLine)
.arg(declarationLocation.startColumn),
Log_Type, accessLocation);
}
private:
QQmlJSLogger *m_logger;
};
QQmlJSLinter::QQmlJSLinter(const QStringList &importPaths, bool useAbsolutePath)
: m_useAbsolutePath(useAbsolutePath), m_importer(importPaths, nullptr)
{
}
void QQmlLinter::parseComments(QQmlJSLogger *logger, const QList<QQmlJS::SourceLocation> &comments)
void QQmlJSLinter::parseComments(QQmlJSLogger *logger,
const QList<QQmlJS::SourceLocation> &comments)
{
QHash<int, QSet<QQmlJSLoggerCategory>> disablesPerLine;
QHash<int, QSet<QQmlJSLoggerCategory>> enablesPerLine;
@ -128,10 +150,10 @@ void QQmlLinter::parseComments(QQmlJSLogger *logger, const QList<QQmlJS::SourceL
}
}
bool QQmlLinter::lintFile(const QString &filename, const QString *fileContents, const bool silent,
QJsonArray *json, const QStringList &qmlImportPaths,
const QStringList &qmldirFiles, const QStringList &resourceFiles,
const QMap<QString, QQmlJSLogger::Option> &options)
bool QQmlJSLinter::lintFile(const QString &filename, const QString *fileContents, const bool silent,
QJsonArray *json, const QStringList &qmlImportPaths,
const QStringList &qmldirFiles, const QStringList &resourceFiles,
const QMap<QString, QQmlJSLogger::Option> &options)
{
// Make sure that we don't expose an old logger if we return before a new one is created.
m_logger.reset();
@ -213,11 +235,10 @@ bool QQmlLinter::lintFile(const QString &filename, const QString *fileContents,
QFile file(filename);
if (!file.open(QFile::ReadOnly)) {
if (json) {
addJsonWarning(QQmlJS::DiagnosticMessage {
QStringLiteral("Failed to open file %1: %2").arg(filename, file.errorString()),
QtCriticalMsg,
QQmlJS::SourceLocation()
});
addJsonWarning(
QQmlJS::DiagnosticMessage { QStringLiteral("Failed to open file %1: %2")
.arg(filename, file.errorString()),
QtCriticalMsg, QQmlJS::SourceLocation() });
success = false;
} else if (!silent) {
qWarning() << "Failed to open file" << filename << file.error();
@ -299,11 +320,11 @@ bool QQmlLinter::lintFile(const QString &filename, const QString *fileContents,
QQmlJSTypeResolver typeResolver(&m_importer);
// Type resolving is using document parent mode here so that it produces fewer false positives
// on the "parent" property of QQuickItem. It does produce a few false negatives this way
// because items can be reparented. Furthermore, even if items are not reparented, the document
// parent may indeed not be their visual parent. See QTBUG-95530. Eventually, we'll need
// cleverer logic to deal with this.
// Type resolving is using document parent mode here so that it produces fewer false
// positives on the "parent" property of QQuickItem. It does produce a few false
// negatives this way because items can be reparented. Furthermore, even if items are
// not reparented, the document parent may indeed not be their visual parent. See
// QTBUG-95530. Eventually, we'll need cleverer logic to deal with this.
typeResolver.setParentMode(QQmlJSTypeResolver::UseDocumentParent);
typeResolver.init(&v, parser.rootNode());
@ -319,11 +340,11 @@ bool QQmlLinter::lintFile(const QString &filename, const QString *fileContents,
const QStringList resourcePaths = mapper
? mapper->resourcePaths(QQmlJSResourceFileMapper::localFileFilter(filename))
: QStringList();
const QString resolvedPath = (resourcePaths.size() == 1)
? u':' + resourcePaths.first()
: filename;
const QString resolvedPath =
(resourcePaths.size() == 1) ? u':' + resourcePaths.first() : filename;
Codegen codegen { &m_importer, resolvedPath, qmldirFiles, m_logger.get(), &typeInfo };
QQmlJSLinterCodegen codegen { &m_importer, resolvedPath, qmldirFiles, m_logger.get(),
&typeInfo };
codegen.setTypeResolver(std::move(typeResolver));
QQmlJSSaveFunction saveFunction = [](const QV4::CompiledData::SaveableUnitPointer &,
const QQmlJSAotFunctionMap &,

View File

@ -26,8 +26,8 @@
**
****************************************************************************/
#ifndef QMLLINT_P_H
#define QMLLINT_P_H
#ifndef QMLJSLINTER_P_H
#define QMLJSLINTER_P_H
//
// W A R N I N G
@ -51,10 +51,10 @@
QT_BEGIN_NAMESPACE
class QQmlLinter
class QQmlJSLinter
{
public:
QQmlLinter(const QStringList &importPaths, bool useAbsolutePath = false);
QQmlJSLinter(const QStringList &importPaths, bool useAbsolutePath = false);
bool lintFile(const QString &filename, const QString *fileContents, const bool silent,
QJsonArray *json, const QStringList &qmlImportPaths,
@ -73,4 +73,4 @@ private:
QT_END_NAMESPACE
#endif // QMLLINT_P_H
#endif // QMLJSLINTER_P_H

View File

@ -26,7 +26,7 @@
**
****************************************************************************/
#include "codegen_p.h"
#include "qqmljslintercodegen_p.h"
#include <QtQmlCompiler/private/qqmljsimportvisitor_p.h>
#include <QtQmlCompiler/private/qqmljsshadowcheck_p.h>
@ -38,14 +38,15 @@
QT_BEGIN_NAMESPACE
Codegen::Codegen(QQmlJSImporter *importer, const QString &fileName,
const QStringList &qmldirFiles, QQmlJSLogger *logger, QQmlJSTypeInfo *typeInfo)
: QQmlJSAotCompiler(importer, fileName, qmldirFiles, logger)
, m_typeInfo(typeInfo)
QQmlJSLinterCodegen::QQmlJSLinterCodegen(QQmlJSImporter *importer, const QString &fileName,
const QStringList &qmldirFiles, QQmlJSLogger *logger,
QQmlJSTypeInfo *typeInfo)
: QQmlJSAotCompiler(importer, fileName, qmldirFiles, logger), m_typeInfo(typeInfo)
{
}
void Codegen::setDocument(const QmlIR::JSCodeGen *codegen, const QmlIR::Document *document)
void QQmlJSLinterCodegen::setDocument(const QmlIR::JSCodeGen *codegen,
const QmlIR::Document *document)
{
Q_UNUSED(codegen);
m_document = document;
@ -54,14 +55,15 @@ void Codegen::setDocument(const QmlIR::JSCodeGen *codegen, const QmlIR::Document
}
std::variant<QQmlJSAotFunction, QQmlJS::DiagnosticMessage>
Codegen::compileBinding(const QV4::Compiler::Context *context, const QmlIR::Binding &irBinding)
QQmlJSLinterCodegen::compileBinding(const QV4::Compiler::Context *context,
const QmlIR::Binding &irBinding)
{
QQmlJSFunctionInitializer initializer(&m_typeResolver, m_currentObject, m_currentScope);
QQmlJS::DiagnosticMessage initializationError;
const QString name = m_document->stringAt(irBinding.propertyNameIndex);
QQmlJSCompilePass::Function function = initializer.run(
context, name, irBinding, &initializationError);
QQmlJSCompilePass::Function function =
initializer.run(context, name, irBinding, &initializationError);
if (initializationError.isValid())
diagnose(initializationError.message, initializationError.type, initializationError.loc);
@ -80,13 +82,14 @@ Codegen::compileBinding(const QV4::Compiler::Context *context, const QmlIR::Bind
}
std::variant<QQmlJSAotFunction, QQmlJS::DiagnosticMessage>
Codegen::compileFunction(const QV4::Compiler::Context *context, const QmlIR::Function &irFunction)
QQmlJSLinterCodegen::compileFunction(const QV4::Compiler::Context *context,
const QmlIR::Function &irFunction)
{
QQmlJS::DiagnosticMessage initializationError;
QQmlJSFunctionInitializer initializer(&m_typeResolver, m_currentObject, m_currentScope);
const QString name = m_document->stringAt(irFunction.nameIndex);
QQmlJSCompilePass::Function function = initializer.run(
context, name, irFunction, &initializationError);
QQmlJSCompilePass::Function function =
initializer.run(context, name, irFunction, &initializationError);
if (initializationError.isValid())
diagnose(initializationError.message, initializationError.type, initializationError.loc);
@ -99,10 +102,9 @@ Codegen::compileFunction(const QV4::Compiler::Context *context, const QmlIR::Fun
return QQmlJSAotFunction {};
}
bool Codegen::analyzeFunction(
const QV4::Compiler::Context *context,
QQmlJSCompilePass::Function *function,
QQmlJS::DiagnosticMessage *error)
bool QQmlJSLinterCodegen::analyzeFunction(const QV4::Compiler::Context *context,
QQmlJSCompilePass::Function *function,
QQmlJS::DiagnosticMessage *error)
{
QQmlJSTypePropagator propagator(m_unitGenerator, &m_typeResolver, m_logger, m_typeInfo);
QQmlJSCompilePass::InstructionAnnotations annotations = propagator.run(function, error);

View File

@ -26,8 +26,8 @@
**
****************************************************************************/
#ifndef CODEGEN_P_H
#define CODEGEN_P_H
#ifndef QQMLJSLINTERCODEGEN_P_H
#define QQMLJSLINTERCODEGEN_P_H
//
// W A R N I N G
@ -56,11 +56,12 @@
QT_BEGIN_NAMESPACE
class Codegen : public QQmlJSAotCompiler
class QQmlJSLinterCodegen : public QQmlJSAotCompiler
{
public:
Codegen(QQmlJSImporter *importer, const QString &fileName, const QStringList &qmldirFiles,
QQmlJSLogger *logger, QQmlJSTypeInfo *typeInfo);
QQmlJSLinterCodegen(QQmlJSImporter *importer, const QString &fileName,
const QStringList &qmldirFiles, QQmlJSLogger *logger,
QQmlJSTypeInfo *typeInfo);
void setDocument(const QmlIR::JSCodeGen *codegen, const QmlIR::Document *document) override;
std::variant<QQmlJSAotFunction, QQmlJS::DiagnosticMessage>
@ -78,8 +79,7 @@ private:
QQmlJSTypeInfo *m_typeInfo;
bool analyzeFunction(const QV4::Compiler::Context *context,
QQmlJSCompilePass::Function *function,
QQmlJS::DiagnosticMessage *error);
QQmlJSCompilePass::Function *function, QQmlJS::DiagnosticMessage *error);
};
QT_END_NAMESPACE

View File

@ -1,12 +0,0 @@
qt_internal_add_module(QmlLintPrivate
STATIC
INTERNAL_MODULE
SOURCES
codegen_p.h codegen.cpp
codegenwarninginterface_p.h codegenwarninginterface.cpp
qqmllinter_p.h qqmllinter.cpp
PUBLIC_LIBRARIES
Qt::CorePrivate
Qt::QmlPrivate
Qt::QmlCompilerPrivate
)

View File

@ -1,48 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "codegenwarninginterface_p.h"
#include <QtQmlCompiler/private/qqmljslogger_p.h>
QT_BEGIN_NAMESPACE
void CodegenWarningInterface::reportVarUsedBeforeDeclaration(
const QString &name, const QString &fileName, QQmlJS::SourceLocation declarationLocation,
QQmlJS::SourceLocation accessLocation)
{
Q_UNUSED(fileName)
m_logger->logWarning(
u"Variable \"%1\" is used here before its declaration. The declaration is at %2:%3."_qs
.arg(name)
.arg(declarationLocation.startLine)
.arg(declarationLocation.startColumn),
Log_Type, accessLocation);
}
QT_END_NAMESPACE

View File

@ -1,62 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef CODEGENWARNINGINTERFACE_P_H
#define CODEGENWARNINGINTERFACE_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
#include <QtQml/private/qv4codegen_p.h>
QT_BEGIN_NAMESPACE
class QQmlJSLogger;
class CodegenWarningInterface final : public QV4::Compiler::CodegenWarningInterface
{
public:
CodegenWarningInterface(QQmlJSLogger *logger) : m_logger(logger) { }
void reportVarUsedBeforeDeclaration(const QString &name, const QString &fileName,
QQmlJS::SourceLocation declarationLocation,
QQmlJS::SourceLocation accessLocation) override;
private:
QQmlJSLogger *m_logger;
};
QT_END_NAMESPACE
#endif // CODEGENWARNINGINTERFACE_P_H

View File

@ -16,7 +16,7 @@ qt_internal_add_test(tst_qmllint
PUBLIC_LIBRARIES
Qt::Gui
Qt::QuickTestUtilsPrivate
Qt::QmlLintPrivate
Qt::QmlCompilerPrivate
TESTDATA ${test_data}
)

View File

@ -31,7 +31,7 @@
#include <QProcess>
#include <QString>
#include <QtQuickTestUtils/private/qmlutils_p.h>
#include <QtQmlLint/private/qqmllinter_p.h>
#include <QtQmlCompiler/private/qqmljslinter_p.h>
class TestQmllint: public QQmlDataTest
{
@ -115,7 +115,7 @@ private:
QString m_qmltyperegistrarPath;
QStringList m_defaultImportPaths;
QQmlLinter m_linter;
QQmlJSLinter m_linter;
};
TestQmllint::TestQmllint()
@ -1374,7 +1374,7 @@ void TestQmllint::missingBuiltinsNoCrash()
{
// We cannot use the normal linter here since the other tests might have cached the builtins
// alread
QQmlLinter linter(m_defaultImportPaths);
QQmlJSLinter linter(m_defaultImportPaths);
QJsonArray jsonOutput;
QJsonArray warnings;
@ -1396,7 +1396,7 @@ void TestQmllint::absolutePath()
{
// We cannot use the normal linter here since we need to set a different parameter in the
// constructor
QQmlLinter linter(m_defaultImportPaths, true);
QQmlJSLinter linter(m_defaultImportPaths, true);
const QString absolutePath = QFileInfo(testFile("memberNotFound.qml")).absoluteFilePath();

View File

@ -72,7 +72,7 @@ set(qml_sources
LocallyImported.qml
LocalWithOnCompleted.qml
LocallyImported_context.qml
# SingletonThing.qml
# SingletonThing.qml
)
set(js_sources

View File

@ -23,7 +23,7 @@ qt_internal_add_test(tst_sanity
Qt::QuickTest
Qt::QuickTestUtilsPrivate
Qt::TestPrivate
Qt::QmlLintPrivate
Qt::QmlCompilerPrivate
)
#### Keys ignored in scope 1:.:.:sanity.pro:<TRUE>:

View File

@ -40,7 +40,7 @@
#include <QtQml/private/qqmlmetatype_p.h>
#include <QtQuickTestUtils/private/visualtestutils_p.h>
#include <QtQuickControlsTestUtils/private/controlstestutils_p.h>
#include <QtQmlLint/private/qqmllinter_p.h>
#include <QtQmlCompiler/private/qqmljslinter_p.h>
using namespace QQuickVisualTestUtils;
using namespace QQuickControlsTestUtils;
@ -63,7 +63,7 @@ private:
QMap<QString, QString> installedQmlFiles;
QStringList m_importPaths;
QQmlLinter m_linter;
QQmlJSLinter m_linter;
QMap<QString, QQmlJSLogger::Option> m_options;
};

View File

@ -15,7 +15,6 @@ qt_internal_add_tool(${target_name}
PUBLIC_LIBRARIES
Qt::CorePrivate
Qt::QmlCompilerPrivate
Qt::QmlLintPrivate
)
qt_internal_return_unless_building_tools()

View File

@ -28,10 +28,9 @@
#include "../shared/qqmltoolingsettings.h"
#include <QtQmlLint/private/qqmllinter_p.h>
#include <QtQmlCompiler/private/qqmljsresourcefilemapper_p.h>
#include <QtQmlCompiler/private/qqmljscompiler_p.h>
#include <QtQmlCompiler/private/qqmljslinter_p.h>
#include <QtCore/qdebug.h>
#include <QtCore/qfile.h>
@ -224,7 +223,7 @@ All warnings can be set to three levels:
QStringList resourceFiles = defaultResourceFiles;
bool success = true;
QQmlLinter linter(qmlImportPaths, useAbsolutePath);
QQmlJSLinter linter(qmlImportPaths, useAbsolutePath);
QJsonArray jsonFiles;

View File

@ -24,6 +24,6 @@ qt_internal_add_tool(${target_name}
Qt::CorePrivate
Qt::QmlDomPrivate
Qt::LanguageServerPrivate
Qt::QmlLintPrivate
Qt::QmlCompilerPrivate
)
qt_internal_return_unless_building_tools()

View File

@ -27,7 +27,7 @@
****************************************************************************/
#include "qmllintsuggestions.h"
#include <QtLanguageServer/private/qlanguageserverspec_p.h>
#include <QtQmlLint/private/qqmllinter_p.h>
#include <QtQmlCompiler/private/qqmljslinter_p.h>
#include <QtQmlCompiler/private/qqmljslogger_p.h>
#include <QtCore/qlibraryinfo.h>
#include <QtCore/qtimer.h>
@ -135,7 +135,7 @@ void QmlLintSuggestions::diagnose(const QByteArray &uri)
QStringList resourceFiles;
QMap<QString, QQmlJSLogger::Option> options;
QQmlLinter linter(imports, useAbsolutePath);
QQmlJSLinter linter(imports, useAbsolutePath);
linter.lintFile(filename, &fileContents, silent, &json, imports, qmltypesFiles,
resourceFiles, options);