36class LinterVisitor
final :
public QQmlJSImportVisitor
40 const QString &implicitImportDirectory,
41 const QStringList &qmldirFiles = QStringList(), QQmlJS::Engine *engine =
nullptr);
46 using QQmlJSImportVisitor::endVisit;
47 using QQmlJSImportVisitor::visit;
49 bool preVisit(QQmlJS::AST::Node *)
override;
50 void postVisit(QQmlJS::AST::Node *)
override;
55 bool visit(QQmlJS::AST::StringLiteral *)
override;
56 bool visit(AST::CommaExpression *)
override;
57 bool visit(QQmlJS::AST::NewMemberExpression *)
override;
58 bool visit(QQmlJS::AST::VoidExpression *ast)
override;
59 bool visit(QQmlJS::AST::BinaryExpression *)
override;
60 bool visit(QQmlJS::AST::UiImport *import)
override;
61 bool visit(QQmlJS::AST::UiEnumDeclaration *uied)
override;
62 bool visit(QQmlJS::AST::CaseBlock *)
override;
63 bool visit(QQmlJS::AST::ExpressionStatement *ast)
override;
64 bool visit(QQmlJS::AST::FunctionDeclaration *fdecl)
override;
65 bool visit(QQmlJS::AST::FunctionExpression *fexpr)
override;
66 bool visit(QQmlJS::AST::UiPublicMember *publicMember)
override;
67 bool visit(QQmlJS::AST::UiObjectDefinition *objectDefinition)
override;
68 bool visit(QQmlJS::AST::Type *typeAnnotation)
override;
69 bool visit(QQmlJS::AST::UiPragma *pragma)
override;
71 bool visit(QQmlJS::AST::IdentifierExpression *idexp)
override;
72 void endVisit(QQmlJS::AST::FieldMemberExpression *fieldMember)
override;
74 bool visit(QQmlJS::AST::UiProgram *ast)
override;
75 void endVisit(QQmlJS::AST::UiProgram *ast)
override;
78 const QQmlJSScope::JavaScriptIdentifier &identifier)
override;
81 bool hadWarnings)
override;
83 bool isDependency)
override;
92 QTypeRevision version;
94 QQmlJS::AST::UiImport *uiImport;
96 SeenImport(QQmlJS::AST::UiImport *i) : filename(i->fileName), id(i->importId), uiImport(i)
99 uri = i->importUri->toString();
101 version = i->version->version;
103 friend bool comparesEqual(
const SeenImport &lhs,
const SeenImport &rhs)
noexcept
105 return lhs.filename == rhs.filename && lhs.uri == rhs.uri
106 && lhs.version == rhs.version && lhs.id == rhs.id;
108 Q_DECLARE_EQUALITY_COMPARABLE(SeenImport)
110 friend size_t qHash(
const SeenImport &i, size_t seed = 0)
112 return qHashMulti(seed, i.filename, i.uri, i.version, i.id);
115 QQmlJS::Engine *m_engine =
nullptr;
116 QSet<SeenImport> m_seenImports;
117 QSet<std::pair<
const QQmlJSScope *, QString>> misplacedJSIdentifiers;
118 std::vector<QQmlJS::AST::Node *> m_ancestryIncludingCurrentNode;
119 QQmlJS::LinterRenamedComponents m_renamedComponents;
122 QMultiHash<QString, QQmlJS::SourceLocation> m_importTypeLocationMap;
124 QMultiHash<QString, QQmlJS::SourceLocation> m_importStaticModuleLocationMap;
126 QSet<QQmlJS::SourceLocation> m_importLocations;
128 QSet<QString> m_usedTypes;
130 void handleDuplicateEnums(QQmlJS::AST::UiEnumMemberList *members, QStringView key,
131 const QQmlJS::SourceLocation &location);
132 void warnCaseNoFlowControl(QQmlJS::SourceLocation caseToken)
const;
133 void checkCaseFallthrough(QQmlJS::AST::StatementList *statements, SourceLocation errorLoc,
134 SourceLocation nextLoc);
136 const QString &name,
const QQmlJS::AST::Statement *statement,
137 const QQmlJS::AST::UiPublicMember *associatedPropertyDefinition =
nullptr)
override;
139 const AST::UiPublicMember *associatedPropertyDefinition)
override;
140 void handleUselessExpressionStatement(
const AST::ExpressionStatement *ast);
141 void handleRecursivelyInstantiatedType(AST::UiQualifiedId *qualifiedId);
142 void handleRenamedType(QQmlJS::AST::UiQualifiedId *id);
143 void checkSingletonRoot();
144 void checkFileSelections();
145 void checkUnusedImports();
147 bool m_rootIsSingleton =
false;