1// Copyright (C) 2023 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 QQMLSA_H
5#define QQMLSA_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is part of the qmllint plugin API, with limited compatibility guarantees.
12// Usage of this API may make your code source and binary incompatible with
13// future versions of Qt.
14//
15
16#include <QtQmlCompiler/qqmlsaconstants.h>
17#include <QtQmlCompiler/qqmljsloggingutils.h>
18
19#include <QtQmlCompiler/qtqmlcompilerexports.h>
20
21#include <QtCore/qhash.h>
22#include <QtCore/qsharedpointer.h>
23#include <QtCore/qplugin.h>
24#include <QtQmlCompiler/qqmlsasourcelocation.h>
25
26#include <unordered_map>
27
28QT_BEGIN_NAMESPACE
29
30namespace QQmlSA {
31
32class BindingPrivate;
33class BindingsPrivate;
34class Element;
35class ElementPass;
36class FixSuggestion;
37class FixSuggestionPrivate;
38class GenericPassPrivate;
39class MethodPrivate;
40class MethodsPrivate;
41class PassManager;
42class PassManagerPrivate;
43class PropertyPass;
44class PropertyPrivate;
45enum class AccessSemantics;
46struct BindingInfo;
47struct PropertyPassInfo;
48
49enum class MethodType { Signal, Slot, Method, StaticMethod };
50
51class Q_QMLCOMPILER_EXPORT Binding
52{
53 Q_DECLARE_PRIVATE(Binding)
54
55public:
56 class Q_QMLCOMPILER_EXPORT Bindings
57 {
58 Q_DECLARE_PRIVATE(Bindings)
59
60 public:
61 Bindings();
62 Bindings(const Bindings &);
63 ~Bindings();
64
65 QMultiHash<QString, Binding>::const_iterator begin() const { return constBegin(); }
66 QMultiHash<QString, Binding>::const_iterator end() const { return constEnd(); }
67 QMultiHash<QString, Binding>::const_iterator constBegin() const;
68 QMultiHash<QString, Binding>::const_iterator constEnd() const;
69
70 private:
71 std::unique_ptr<BindingsPrivate> d_ptr;
72 };
73
74 Binding();
75 Binding(const Binding &);
76 Binding(Binding &&) noexcept;
77 Binding &operator=(const Binding &);
78 Binding &operator=(Binding &&) noexcept;
79 ~Binding();
80
81 Element groupType() const;
82 BindingType bindingType() const;
83 QString stringValue() const;
84 QString propertyName() const;
85 Element attachingType() const;
86 QQmlSA::SourceLocation sourceLocation() const;
87 double numberValue() const;
88 ScriptBindingKind scriptKind() const;
89 bool hasObject() const;
90 Element objectType() const;
91 bool hasUndefinedScriptValue() const;
92
93 friend bool operator==(const Binding &lhs, const Binding &rhs)
94 {
95 return operatorEqualsImpl(lhs, rhs);
96 }
97 friend bool operator!=(const Binding &lhs, const Binding &rhs)
98 {
99 return !operatorEqualsImpl(lhs, rhs);
100 }
101
102 static bool isLiteralBinding(BindingType);
103
104private:
105 static bool operatorEqualsImpl(const Binding &, const Binding &);
106
107 std::unique_ptr<BindingPrivate> d_ptr;
108};
109
110class Q_QMLCOMPILER_EXPORT Method
111{
112 Q_DECLARE_PRIVATE(Method)
113
114public:
115 class Q_QMLCOMPILER_EXPORT Methods
116 {
117 Q_DECLARE_PRIVATE(Methods)
118
119 public:
120 Methods();
121 Methods(const Methods &);
122 ~Methods();
123
124 QMultiHash<QString, Method>::const_iterator begin() const { return constBegin(); }
125 QMultiHash<QString, Method>::const_iterator end() const { return constEnd(); }
126 QMultiHash<QString, Method>::const_iterator constBegin() const;
127 QMultiHash<QString, Method>::const_iterator constEnd() const;
128
129 private:
130 std::unique_ptr<MethodsPrivate> d_ptr;
131 };
132
133 Method();
134 Method(const Method &);
135 Method(Method &&) noexcept;
136 Method &operator=(const Method &);
137 Method &operator=(Method &&) noexcept;
138 ~Method();
139
140 QString methodName() const;
141 QQmlSA::SourceLocation sourceLocation() const;
142 MethodType methodType() const;
143
144 friend bool operator==(const Method &lhs, const Method &rhs)
145 {
146 return operatorEqualsImpl(lhs, rhs);
147 }
148 friend bool operator!=(const Method &lhs, const Method &rhs)
149 {
150 return !operatorEqualsImpl(lhs, rhs);
151 }
152
153private:
154 static bool operatorEqualsImpl(const Method &, const Method &);
155
156 std::unique_ptr<MethodPrivate> d_ptr;
157};
158
159class Q_QMLCOMPILER_EXPORT Property
160{
161 Q_DECLARE_PRIVATE(Property)
162
163public:
164 Property();
165 Property(const Property &);
166 Property(Property &&) noexcept;
167 Property &operator=(const Property &);
168 Property &operator=(Property &&) noexcept;
169 ~Property();
170
171 QString typeName() const;
172 bool isValid() const;
173 bool isReadonly() const;
174 QQmlSA::Element type() const;
175
176 friend bool operator==(const Property &lhs, const Property &rhs)
177 {
178 return operatorEqualsImpl(lhs, rhs);
179 }
180
181 friend bool operator!=(const Property &lhs, const Property &rhs)
182 {
183 return !operatorEqualsImpl(lhs, rhs);
184 }
185
186private:
187 static bool operatorEqualsImpl(const Property &, const Property &);
188
189 std::unique_ptr<PropertyPrivate> d_ptr;
190};
191
192class Q_QMLCOMPILER_EXPORT Element
193{
194 friend class QT_PREPEND_NAMESPACE(QQmlJSScope);
195
196public:
197 Element();
198 Element(const Element &);
199 Element(Element &&other) noexcept
200 {
201 memcpy(dest: m_data, src: other.m_data, n: sizeofElement);
202 memset(s: other.m_data, c: 0, n: sizeofElement);
203 }
204 Element &operator=(const Element &);
205 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(Element)
206 ~Element();
207
208 ScopeType scopeType() const;
209 Element baseType() const;
210 QString baseTypeName() const;
211 Element parentScope() const;
212 bool inherits(const Element &) const;
213
214 bool isNull() const;
215 QString internalId() const;
216 AccessSemantics accessSemantics() const;
217 bool isComposite() const;
218
219 bool hasProperty(const QString &propertyName) const;
220 bool hasOwnProperty(const QString &propertyName) const;
221 Property property(const QString &propertyName) const;
222 bool isPropertyRequired(const QString &propertyName) const;
223 QString defaultPropertyName() const;
224
225 bool hasMethod(const QString &methodName) const;
226 Method::Methods ownMethods() const;
227
228 QQmlSA::SourceLocation sourceLocation() const;
229 QString filePath() const;
230
231 bool hasPropertyBindings(const QString &name) const;
232 bool hasOwnPropertyBindings(const QString &propertyName) const;
233
234 Binding::Bindings ownPropertyBindings() const;
235 Binding::Bindings ownPropertyBindings(const QString &propertyName) const;
236 QList<Binding> propertyBindings(const QString &propertyName) const;
237
238 explicit operator bool() const;
239 bool operator!() const;
240
241 QString name() const;
242
243 friend inline bool operator==(const QQmlSA::Element &lhs, const QQmlSA::Element &rhs)
244 {
245 return operatorEqualsImpl(lhs, rhs);
246 }
247 friend inline bool operator!=(const Element &lhs, const Element &rhs) { return !(lhs == rhs); }
248
249 friend inline qsizetype qHash(const Element &key, qsizetype seed = 0) noexcept
250 {
251 return qHashImpl(key, seed);
252 }
253
254private:
255 static bool operatorEqualsImpl(const Element &, const Element &);
256 static qsizetype qHashImpl(const Element &key, qsizetype seed) noexcept;
257
258 static constexpr qsizetype sizeofElement = 2 * sizeof(QSharedPointer<int>);
259 alignas(QSharedPointer<int>) char m_data[sizeofElement];
260
261 void swap(Element &other) noexcept
262 {
263 char t[sizeofElement];
264 memcpy(dest: t, src: m_data, n: sizeofElement);
265 memcpy(dest: m_data, src: other.m_data, n: sizeofElement);
266 memcpy(dest: other.m_data, src: t, n: sizeofElement);
267 }
268 friend void swap(Element &lhs, Element &rhs) noexcept { lhs.swap(other&: rhs); }
269};
270
271class Q_QMLCOMPILER_EXPORT GenericPass
272{
273 Q_DECLARE_PRIVATE(GenericPass)
274 Q_DISABLE_COPY_MOVE(GenericPass)
275
276public:
277 GenericPass(PassManager *manager);
278 virtual ~GenericPass();
279
280 void emitWarning(QAnyStringView diagnostic, LoggerWarningId id);
281 void emitWarning(QAnyStringView diagnostic, LoggerWarningId id,
282 QQmlSA::SourceLocation srcLocation);
283 void emitWarning(QAnyStringView diagnostic, LoggerWarningId id,
284 QQmlSA::SourceLocation srcLocation, const QQmlSA::FixSuggestion &fix);
285
286 Element resolveTypeInFileScope(QAnyStringView typeName);
287 Element resolveAttachedInFileScope(QAnyStringView typeName);
288 Element resolveType(QAnyStringView moduleName, QAnyStringView typeName); // #### TODO: revisions
289 Element resolveBuiltinType(QAnyStringView typeName) const;
290 Element resolveAttached(QAnyStringView moduleName, QAnyStringView typeName);
291 Element resolveLiteralType(const Binding &binding);
292
293 Element resolveIdToElement(QAnyStringView id, const Element &context);
294 QString resolveElementToId(const Element &element, const Element &context);
295
296 QString sourceCode(QQmlSA::SourceLocation location);
297
298private:
299 std::unique_ptr<GenericPassPrivate> d_ptr;
300};
301
302class Q_QMLCOMPILER_EXPORT PassManager
303{
304 Q_DISABLE_COPY_MOVE(PassManager)
305 Q_DECLARE_PRIVATE(PassManager)
306
307public:
308 void registerElementPass(std::unique_ptr<ElementPass> pass);
309 bool registerPropertyPass(std::shared_ptr<PropertyPass> pass, QAnyStringView moduleName,
310 QAnyStringView typeName,
311 QAnyStringView propertyName = QAnyStringView(),
312 bool allowInheritance = true);
313 void analyze(const Element &root);
314
315 bool hasImportedModule(QAnyStringView name) const;
316
317 bool isCategoryEnabled(LoggerWarningId category) const;
318
319 std::vector<std::shared_ptr<ElementPass>> elementPasses() const;
320 std::multimap<QString, PropertyPassInfo> propertyPasses() const;
321 std::unordered_map<quint32, BindingInfo> bindingsByLocation() const;
322
323private:
324 PassManager();
325 ~PassManager();
326
327 std::unique_ptr<PassManagerPrivate> d_ptr;
328};
329
330class Q_QMLCOMPILER_EXPORT LintPlugin
331{
332public:
333 LintPlugin() = default;
334 virtual ~LintPlugin() = default;
335
336 Q_DISABLE_COPY_MOVE(LintPlugin)
337
338 virtual void registerPasses(PassManager *manager, const Element &rootElement) = 0;
339};
340
341class Q_QMLCOMPILER_EXPORT PropertyPass : public GenericPass
342{
343public:
344 PropertyPass(PassManager *manager);
345
346 virtual void onBinding(const QQmlSA::Element &element, const QString &propertyName,
347 const QQmlSA::Binding &binding, const QQmlSA::Element &bindingScope,
348 const QQmlSA::Element &value);
349 virtual void onRead(const QQmlSA::Element &element, const QString &propertyName,
350 const QQmlSA::Element &readScope, QQmlSA::SourceLocation location);
351 virtual void onWrite(const QQmlSA::Element &element, const QString &propertyName,
352 const QQmlSA::Element &value, const QQmlSA::Element &writeScope,
353 QQmlSA::SourceLocation location);
354};
355
356class Q_QMLCOMPILER_EXPORT ElementPass : public GenericPass
357{
358public:
359 ElementPass(PassManager *manager) : GenericPass(manager) { }
360
361 virtual bool shouldRun(const Element &element);
362 virtual void run(const Element &element) = 0;
363};
364
365class Q_QMLCOMPILER_EXPORT DebugElementPass : public ElementPass
366{
367 void run(const Element &element) override;
368};
369
370class Q_QMLCOMPILER_EXPORT DebugPropertyPass : public QQmlSA::PropertyPass
371{
372public:
373 DebugPropertyPass(QQmlSA::PassManager *manager);
374
375 void onRead(const QQmlSA::Element &element, const QString &propertyName,
376 const QQmlSA::Element &readScope, QQmlSA::SourceLocation location) override;
377 void onBinding(const QQmlSA::Element &element, const QString &propertyName,
378 const QQmlSA::Binding &binding, const QQmlSA::Element &bindingScope,
379 const QQmlSA::Element &value) override;
380 void onWrite(const QQmlSA::Element &element, const QString &propertyName,
381 const QQmlSA::Element &value, const QQmlSA::Element &writeScope,
382 QQmlSA::SourceLocation location) override;
383};
384
385class Q_QMLCOMPILER_EXPORT FixSuggestion
386{
387 Q_DECLARE_PRIVATE(FixSuggestion)
388
389public:
390 FixSuggestion(const QString &fixDescription, const QQmlSA::SourceLocation &location,
391 const QString &replacement = QString());
392 FixSuggestion(const FixSuggestion &);
393 FixSuggestion(FixSuggestion &&) noexcept;
394 FixSuggestion &operator=(const FixSuggestion &);
395 FixSuggestion &operator=(FixSuggestion &&) noexcept;
396 ~FixSuggestion();
397
398 QString fixDescription() const;
399 QQmlSA::SourceLocation location() const;
400 QString replacement() const;
401
402 void setFileName(const QString &);
403 QString fileName() const;
404
405 void setHint(const QString &);
406 QString hint() const;
407
408 void setAutoApplicable(bool autoApplicable = true);
409 bool isAutoApplicable() const;
410
411 friend bool operator==(const FixSuggestion &lhs, const FixSuggestion &rhs)
412 {
413 return operatorEqualsImpl(lhs, rhs);
414 }
415
416 friend bool operator!=(const FixSuggestion &lhs, const FixSuggestion &rhs)
417 {
418 return !operatorEqualsImpl(lhs, rhs);
419 }
420
421private:
422 static bool operatorEqualsImpl(const FixSuggestion &, const FixSuggestion &);
423
424 std::unique_ptr<FixSuggestionPrivate> d_ptr;
425};
426
427} // namespace QQmlSA
428
429#define QmlLintPluginInterface_iid "org.qt-project.Qt.Qml.SA.LintPlugin/1.0"
430
431Q_DECLARE_INTERFACE(QQmlSA::LintPlugin, QmlLintPluginInterface_iid)
432
433QT_END_NAMESPACE
434
435#endif // QQMLSA_H
436

Provided by KDAB

Privacy Policy
Start learning QML with our Intro Training
Find out more

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