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 | |
28 | QT_BEGIN_NAMESPACE |
29 | |
30 | namespace QQmlSA { |
31 | |
32 | class BindingPrivate; |
33 | class BindingsPrivate; |
34 | class Element; |
35 | class ElementPass; |
36 | class FixSuggestion; |
37 | class FixSuggestionPrivate; |
38 | class GenericPassPrivate; |
39 | class MethodPrivate; |
40 | class MethodsPrivate; |
41 | class PassManager; |
42 | class PassManagerPrivate; |
43 | class PropertyPass; |
44 | class PropertyPrivate; |
45 | enum class AccessSemantics; |
46 | struct BindingInfo; |
47 | struct PropertyPassInfo; |
48 | |
49 | enum class MethodType { Signal, Slot, Method, StaticMethod }; |
50 | |
51 | class Q_QMLCOMPILER_EXPORT Binding |
52 | { |
53 | Q_DECLARE_PRIVATE(Binding) |
54 | |
55 | public: |
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 | |
104 | private: |
105 | static bool operatorEqualsImpl(const Binding &, const Binding &); |
106 | |
107 | std::unique_ptr<BindingPrivate> d_ptr; |
108 | }; |
109 | |
110 | class Q_QMLCOMPILER_EXPORT Method |
111 | { |
112 | Q_DECLARE_PRIVATE(Method) |
113 | |
114 | public: |
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 | |
153 | private: |
154 | static bool operatorEqualsImpl(const Method &, const Method &); |
155 | |
156 | std::unique_ptr<MethodPrivate> d_ptr; |
157 | }; |
158 | |
159 | class Q_QMLCOMPILER_EXPORT Property |
160 | { |
161 | Q_DECLARE_PRIVATE(Property) |
162 | |
163 | public: |
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 | |
186 | private: |
187 | static bool operatorEqualsImpl(const Property &, const Property &); |
188 | |
189 | std::unique_ptr<PropertyPrivate> d_ptr; |
190 | }; |
191 | |
192 | class Q_QMLCOMPILER_EXPORT Element |
193 | { |
194 | friend class QT_PREPEND_NAMESPACE(QQmlJSScope); |
195 | |
196 | public: |
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 | |
254 | private: |
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 | |
271 | class Q_QMLCOMPILER_EXPORT GenericPass |
272 | { |
273 | Q_DECLARE_PRIVATE(GenericPass) |
274 | Q_DISABLE_COPY_MOVE(GenericPass) |
275 | |
276 | public: |
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 | |
298 | private: |
299 | std::unique_ptr<GenericPassPrivate> d_ptr; |
300 | }; |
301 | |
302 | class Q_QMLCOMPILER_EXPORT PassManager |
303 | { |
304 | Q_DISABLE_COPY_MOVE(PassManager) |
305 | Q_DECLARE_PRIVATE(PassManager) |
306 | |
307 | public: |
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 | |
323 | private: |
324 | PassManager(); |
325 | ~PassManager(); |
326 | |
327 | std::unique_ptr<PassManagerPrivate> d_ptr; |
328 | }; |
329 | |
330 | class Q_QMLCOMPILER_EXPORT LintPlugin |
331 | { |
332 | public: |
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 | |
341 | class Q_QMLCOMPILER_EXPORT PropertyPass : public GenericPass |
342 | { |
343 | public: |
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 | |
356 | class Q_QMLCOMPILER_EXPORT ElementPass : public GenericPass |
357 | { |
358 | public: |
359 | ElementPass(PassManager *manager) : GenericPass(manager) { } |
360 | |
361 | virtual bool shouldRun(const Element &element); |
362 | virtual void run(const Element &element) = 0; |
363 | }; |
364 | |
365 | class Q_QMLCOMPILER_EXPORT DebugElementPass : public ElementPass |
366 | { |
367 | void run(const Element &element) override; |
368 | }; |
369 | |
370 | class Q_QMLCOMPILER_EXPORT DebugPropertyPass : public QQmlSA::PropertyPass |
371 | { |
372 | public: |
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 | |
385 | class Q_QMLCOMPILER_EXPORT FixSuggestion |
386 | { |
387 | Q_DECLARE_PRIVATE(FixSuggestion) |
388 | |
389 | public: |
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 | |
421 | private: |
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 | |
431 | Q_DECLARE_INTERFACE(QQmlSA::LintPlugin, QmlLintPluginInterface_iid) |
432 | |
433 | QT_END_NAMESPACE |
434 | |
435 | #endif // QQMLSA_H |
436 |
Definitions
- MethodType
- Binding
- Bindings
- begin
- end
- operator==
- operator!=
- Method
- Methods
- begin
- end
- operator==
- operator!=
- Property
- operator==
- operator!=
- Element
- Element
- operator==
- operator!=
- qHash
- sizeofElement
- swap
- swap
- GenericPass
- GenericPass
- PassManager
- PassManager
- LintPlugin
- LintPlugin
- ~LintPlugin
- LintPlugin
- PropertyPass
- ElementPass
- ElementPass
- DebugElementPass
- DebugPropertyPass
- FixSuggestion
- operator==
Start learning QML with our Intro Training
Find out more