1// Copyright (C) 2025 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
4#ifndef QQMLJSLINTERVISITOR_P_H
5#define QQMLJSLINTERVISITOR_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16
17#include <private/qqmljsimportvisitor_p.h>
18
19#include <private/qqmljsengine_p.h>
20
21QT_BEGIN_NAMESPACE
22
23namespace QQmlJS {
24
25/*!
26 \internal
27 Extends QQmlJSImportVisitor with extra warnings that are required for linting but unrelated to
28 QQmlJSImportVisitor actual task that is constructing QQmlJSScopes. One example of such warnings
29 are purely syntactic checks, or warnings that don't affect compilation.
30 */
31class LinterVisitor final : public QQmlJSImportVisitor
32{
33public:
34 LinterVisitor(const QQmlJSScope::Ptr &target, QQmlJSImporter *importer, QQmlJSLogger *logger,
35 const QString &implicitImportDirectory,
36 const QStringList &qmldirFiles = QStringList(), QQmlJS::Engine *engine = nullptr);
37
38protected:
39 using QQmlJSImportVisitor::endVisit;
40 using QQmlJSImportVisitor::visit;
41
42 bool preVisit(QQmlJS::AST::Node *) override;
43 void postVisit(QQmlJS::AST::Node *) override;
44 QQmlJS::AST::Node *astParentOfVisitedNode() const;
45
46 void leaveEnvironment() override;
47
48 bool visit(QQmlJS::AST::StringLiteral *) override;
49 bool visit(AST::CommaExpression *) override;
50 bool visit(QQmlJS::AST::NewMemberExpression *) override;
51 bool visit(QQmlJS::AST::VoidExpression *ast) override;
52 bool visit(QQmlJS::AST::BinaryExpression *) override;
53 bool visit(QQmlJS::AST::UiImport *import) override;
54 bool visit(QQmlJS::AST::UiEnumDeclaration *uied) override;
55 bool visit(QQmlJS::AST::CaseBlock *) override;
56 bool visit(QQmlJS::AST::ExpressionStatement *ast) override;
57
58private:
59 struct SeenImport
60 {
61 QStringView filename;
62 QString uri;
63 QTypeRevision version;
64 QStringView id;
65 QQmlJS::AST::UiImport *uiImport;
66
67 SeenImport(QQmlJS::AST::UiImport *i) : filename(i->fileName), id(i->importId), uiImport(i)
68 {
69 if (i->importUri)
70 uri = i->importUri->toString();
71 if (i->version)
72 version = i->version->version;
73 }
74 friend bool comparesEqual(const SeenImport &lhs, const SeenImport &rhs) noexcept
75 {
76 return lhs.filename == rhs.filename && lhs.uri == rhs.uri
77 && lhs.version == rhs.version && lhs.id == rhs.id;
78 }
79 Q_DECLARE_EQUALITY_COMPARABLE(SeenImport)
80
81 friend size_t qHash(const SeenImport &i, size_t seed = 0)
82 {
83 return qHashMulti(seed, args: i.filename, args: i.uri, args: i.version, args: i.id);
84 }
85 };
86 QQmlJS::Engine *m_engine = nullptr;
87 QSet<SeenImport> m_seenImports;
88 std::vector<QQmlJS::AST::Node *> m_ancestryIncludingCurrentNode;
89
90 void handleDuplicateEnums(QQmlJS::AST::UiEnumMemberList *members, QStringView key,
91 const QQmlJS::SourceLocation &location);
92 void warnCaseNoFlowControl(QQmlJS::SourceLocation caseToken) const;
93 void checkCaseFallthrough(QQmlJS::AST::StatementList *statements, SourceLocation errorLoc,
94 SourceLocation nextLoc);
95 BindingExpressionParseResult parseBindingExpression(
96 const QString &name, const QQmlJS::AST::Statement *statement,
97 const QQmlJS::AST::UiPublicMember *associatedPropertyDefinition = nullptr) override;
98 void handleLiteralBinding(const QQmlJSMetaPropertyBinding &binding,
99 const AST::UiPublicMember *associatedPropertyDefinition) override;
100};
101
102} // namespace QQmlJS
103
104QT_END_NAMESPACE
105
106#endif // QQMLJSLINTERVISITOR_P_H
107

source code of qtdeclarative/src/qmlcompiler/qqmljslintervisitor_p.h