Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qqmljslintervisitor_p.h
Go to the documentation of this file.
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// Qt-Security score:significant
4
5#ifndef QQMLJSLINTERVISITOR_P_H
6#define QQMLJSLINTERVISITOR_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17
18#include <private/qqmljsimportvisitor_p.h>
19#include <private/qqmljslinterrenamedcomponents_p.h>
20
21#include <private/qqmljsengine_p.h>
22
23QT_BEGIN_NAMESPACE
24
25namespace QQmlJS {
26
27/*!
28 \internal
29 Extends QQmlJSImportVisitor with extra warnings that are required for linting but unrelated to
30 QQmlJSImportVisitor actual task that is constructing QQmlJSScopes. One example of such warnings
31 are purely syntactic checks, or warnings that don't affect compilation.
32 */
33class LinterVisitor final : public QQmlJSImportVisitor
34{
35public:
36 LinterVisitor(QQmlJSImporter *importer, QQmlJSLogger *logger,
37 const QString &implicitImportDirectory,
38 const QStringList &qmldirFiles = QStringList(), QQmlJS::Engine *engine = nullptr);
39
40 const LinterRenamedComponents &renamedComponents() const { return m_renamedComponents; }
41
42protected:
43 using QQmlJSImportVisitor::endVisit;
44 using QQmlJSImportVisitor::visit;
45
46 bool preVisit(QQmlJS::AST::Node *) override;
47 void postVisit(QQmlJS::AST::Node *) override;
49
51
52 bool visit(QQmlJS::AST::StringLiteral *) override;
53 bool visit(AST::CommaExpression *) override;
54 bool visit(QQmlJS::AST::NewMemberExpression *) override;
55 bool visit(QQmlJS::AST::VoidExpression *ast) override;
56 bool visit(QQmlJS::AST::BinaryExpression *) override;
57 bool visit(QQmlJS::AST::UiImport *import) override;
58 bool visit(QQmlJS::AST::UiEnumDeclaration *uied) override;
59 bool visit(QQmlJS::AST::CaseBlock *) override;
60 bool visit(QQmlJS::AST::ExpressionStatement *ast) override;
61 bool visit(QQmlJS::AST::FunctionDeclaration *fdecl) override;
62 bool visit(QQmlJS::AST::FunctionExpression *fexpr) override;
63 bool visit(QQmlJS::AST::UiPublicMember *publicMember) override;
64 bool visit(QQmlJS::AST::UiObjectDefinition *objectDefinition) override;
65 bool visit(QQmlJS::AST::Type *typeAnnotation) override;
66
67 bool visit(QQmlJS::AST::UiProgram *ast) override;
68
69 bool safeInsertJSIdentifier(QQmlJSScope::Ptr &scope, const QString &name,
70 const QQmlJSScope::JavaScriptIdentifier &identifier) override;
71
72private:
73 struct SeenImport
74 {
75 QStringView filename;
76 QString uri;
77 QTypeRevision version;
78 QStringView id;
79 QQmlJS::AST::UiImport *uiImport;
80
81 SeenImport(QQmlJS::AST::UiImport *i) : filename(i->fileName), id(i->importId), uiImport(i)
82 {
83 if (i->importUri)
84 uri = i->importUri->toString();
85 if (i->version)
86 version = i->version->version;
87 }
88 friend bool comparesEqual(const SeenImport &lhs, const SeenImport &rhs) noexcept
89 {
90 return lhs.filename == rhs.filename && lhs.uri == rhs.uri
91 && lhs.version == rhs.version && lhs.id == rhs.id;
92 }
93 Q_DECLARE_EQUALITY_COMPARABLE(SeenImport)
94
95 friend size_t qHash(const SeenImport &i, size_t seed = 0)
96 {
97 return qHashMulti(seed, i.filename, i.uri, i.version, i.id);
98 }
99 };
100 QQmlJS::Engine *m_engine = nullptr;
101 QSet<SeenImport> m_seenImports;
102 QSet<std::pair<const QQmlJSScope *, QString>> misplacedJSIdentifiers;
103 std::vector<QQmlJS::AST::Node *> m_ancestryIncludingCurrentNode;
104 QQmlJS::LinterRenamedComponents m_renamedComponents;
105
106 void handleDuplicateEnums(QQmlJS::AST::UiEnumMemberList *members, QStringView key,
107 const QQmlJS::SourceLocation &location);
108 void warnCaseNoFlowControl(QQmlJS::SourceLocation caseToken) const;
109 void checkCaseFallthrough(QQmlJS::AST::StatementList *statements, SourceLocation errorLoc,
110 SourceLocation nextLoc);
112 const QString &name, const QQmlJS::AST::Statement *statement,
113 const QQmlJS::AST::UiPublicMember *associatedPropertyDefinition = nullptr) override;
114 void handleLiteralBinding(const QQmlJSMetaPropertyBinding &binding,
115 const AST::UiPublicMember *associatedPropertyDefinition) override;
116 void handleUselessExpressionStatement(const AST::ExpressionStatement *ast);
117 void handleRecursivelyInstantiatedType(AST::UiQualifiedId *qualifiedId);
118 void handleRenamedType(QQmlJS::AST::UiQualifiedId *id);
119};
120
121} // namespace QQmlJS
122
123QT_END_NAMESPACE
124
125#endif // QQMLJSLINTERVISITOR_P_H
void postVisit(QQmlJS::AST::Node *) override
void handleLiteralBinding(const QQmlJSMetaPropertyBinding &binding, const AST::UiPublicMember *associatedPropertyDefinition) override
LinterVisitor(QQmlJSImporter *importer, QQmlJSLogger *logger, const QString &implicitImportDirectory, const QStringList &qmldirFiles=QStringList(), QQmlJS::Engine *engine=nullptr)
BindingExpressionParseResult parseBindingExpression(const QString &name, const QQmlJS::AST::Statement *statement, const QQmlJS::AST::UiPublicMember *associatedPropertyDefinition=nullptr) override
bool safeInsertJSIdentifier(QQmlJSScope::Ptr &scope, const QString &name, const QQmlJSScope::JavaScriptIdentifier &identifier) override
const LinterRenamedComponents & renamedComponents() const
bool visit(QQmlJS::AST::StringLiteral *) override
QQmlJS::AST::Node * astParentOfVisitedNode() const
bool preVisit(QQmlJS::AST::Node *) override
static void warnForMethodShadowingInBase(const QQmlJSScope::ConstPtr &base, const QString &name, const QQmlJS::SourceLocation &location, QQmlJSLogger *logger)
static bool isUselessExpressionStatement_impl(const ExpressionNode *ast)
static void warnForDuplicates(const QQmlJSScope::ConstPtr &scope, const QString &name, QLatin1String type, const QQmlJS::SourceLocation &location, OverrideInformations overrideFlags, QQmlJSLogger *logger)
static constexpr QLatin1String s_method
static void warnAboutLiteralConstructors(NewMemberExpression *expression, QQmlJSLogger *logger)
static SourceLocation confusingPluses(BinaryExpression *exp)
static bool isUselessExpressionStatement(const ExpressionStatement *ast)
static bool allCodePathsReturnInsideCase(Node *statement)
Q_DECLARE_FLAGS(OverrideInformations, OverrideInformation)
static SourceLocation confusingMinuses(BinaryExpression *exp)
static QList< const Statement * > possibleLastStatements(const StatementList *ast)
static constexpr QLatin1String s_property
static constexpr QLatin1String s_signal
static void warnForPropertyShadowingInBase(const QQmlJSScope::ConstPtr &base, const QString &name, const QQmlJS::SourceLocation &location, OverrideInformations overrideFlags, QQmlJSLogger *logger)
Combined button and popup list for selecting options.