1 | // Copyright (C) 2022 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_P_H |
5 | #define QQMLSA_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 <qtqmlcompilerexports.h> |
18 | |
19 | #include <private/qqmljslogger_p.h> |
20 | #include <QtCore/qset.h> |
21 | #include "qqmljsmetatypes_p.h" |
22 | |
23 | #include <map> |
24 | #include <unordered_map> |
25 | #include <vector> |
26 | #include <memory> |
27 | |
28 | QT_BEGIN_NAMESPACE |
29 | |
30 | class QQmlJSTypeResolver; |
31 | struct QQmlJSTypePropagator; |
32 | class QQmlJSImportVisitor; |
33 | |
34 | namespace QQmlSA { |
35 | |
36 | class Bindings; |
37 | class GenericPassPrivate; |
38 | class PassManager; |
39 | |
40 | enum class AccessSemantics { Reference, Value, None, Sequence }; |
41 | |
42 | enum class Flag { |
43 | Creatable = 0x1, |
44 | Composite = 0x2, |
45 | Singleton = 0x4, |
46 | Script = 0x8, |
47 | CustomParser = 0x10, |
48 | Array = 0x20, |
49 | InlineComponent = 0x40, |
50 | WrappedInImplicitComponent = 0x80, |
51 | HasBaseTypeError = 0x100, |
52 | HasExtensionNamespace = 0x200, |
53 | IsListProperty = 0x400, |
54 | }; |
55 | |
56 | struct BindingInfo |
57 | { |
58 | QString fullPropertyName; |
59 | QQmlSA::Binding binding; |
60 | QQmlSA::Element bindingScope; |
61 | bool isAttached; |
62 | }; |
63 | |
64 | struct PropertyPassInfo |
65 | { |
66 | QStringList properties; |
67 | std::shared_ptr<QQmlSA::PropertyPass> pass; |
68 | bool allowInheritance = true; |
69 | }; |
70 | |
71 | class BindingsPrivate |
72 | { |
73 | friend class QT_PREPEND_NAMESPACE(QQmlJSMetaPropertyBinding); |
74 | Q_DECLARE_PUBLIC(QQmlSA::Binding::Bindings) |
75 | |
76 | public: |
77 | explicit BindingsPrivate(QQmlSA::Binding::Bindings *); |
78 | BindingsPrivate(QQmlSA::Binding::Bindings *, const BindingsPrivate &); |
79 | BindingsPrivate(QQmlSA::Binding::Bindings *, BindingsPrivate &&); |
80 | ~BindingsPrivate() = default; |
81 | |
82 | QMultiHash<QString, Binding>::const_iterator constBegin() const; |
83 | QMultiHash<QString, Binding>::const_iterator constEnd() const; |
84 | |
85 | static QQmlSA::Binding::Bindings |
86 | createBindings(const QMultiHash<QString, QQmlJSMetaPropertyBinding> &); |
87 | static QQmlSA::Binding::Bindings |
88 | createBindings(QPair<QMultiHash<QString, QQmlJSMetaPropertyBinding>::const_iterator, |
89 | QMultiHash<QString, QQmlJSMetaPropertyBinding>::const_iterator>); |
90 | |
91 | private: |
92 | QMultiHash<QString, Binding> m_bindings; |
93 | QQmlSA::Binding::Bindings *q_ptr; |
94 | }; |
95 | |
96 | class BindingPrivate |
97 | { |
98 | friend class QT_PREPEND_NAMESPACE(QQmlJSMetaPropertyBinding); |
99 | Q_DECLARE_PUBLIC(Binding) |
100 | |
101 | public: |
102 | explicit BindingPrivate(Binding *); |
103 | BindingPrivate(Binding *, const BindingPrivate &); |
104 | |
105 | static QQmlSA::Binding createBinding(const QQmlJSMetaPropertyBinding &); |
106 | static QQmlJSMetaPropertyBinding binding(QQmlSA::Binding &binding); |
107 | static const QQmlJSMetaPropertyBinding binding(const QQmlSA::Binding &binding); |
108 | |
109 | private: |
110 | QQmlJSMetaPropertyBinding m_binding; |
111 | Binding *q_ptr; |
112 | }; |
113 | |
114 | class MethodPrivate |
115 | { |
116 | friend class QT_PREPEND_NAMESPACE(QQmlJSMetaMethod); |
117 | Q_DECLARE_PUBLIC(Method) |
118 | |
119 | public: |
120 | explicit MethodPrivate(Method *); |
121 | MethodPrivate(Method *, const MethodPrivate &); |
122 | |
123 | QString methodName() const; |
124 | QQmlSA::SourceLocation sourceLocation() const; |
125 | MethodType methodType() const; |
126 | |
127 | static QQmlSA::Method createMethod(const QQmlJSMetaMethod &); |
128 | static QQmlJSMetaMethod method(const QQmlSA::Method &); |
129 | |
130 | private: |
131 | QQmlJSMetaMethod m_method; |
132 | Method *q_ptr; |
133 | }; |
134 | |
135 | class MethodsPrivate |
136 | { |
137 | friend class QT_PREPEND_NAMESPACE(QQmlJSMetaMethod); |
138 | Q_DECLARE_PUBLIC(QQmlSA::Method::Methods) |
139 | |
140 | public: |
141 | explicit MethodsPrivate(QQmlSA::Method::Methods *); |
142 | MethodsPrivate(QQmlSA::Method::Methods *, const MethodsPrivate &); |
143 | MethodsPrivate(QQmlSA::Method::Methods *, MethodsPrivate &&); |
144 | ~MethodsPrivate() = default; |
145 | |
146 | QMultiHash<QString, Method>::const_iterator constBegin() const; |
147 | QMultiHash<QString, Method>::const_iterator constEnd() const; |
148 | |
149 | static QQmlSA::Method::Methods createMethods(const QMultiHash<QString, QQmlJSMetaMethod> &); |
150 | |
151 | private: |
152 | QMultiHash<QString, Method> m_methods; |
153 | QQmlSA::Method::Methods *q_ptr; |
154 | }; |
155 | |
156 | class PropertyPrivate |
157 | { |
158 | friend class QT_PREPEND_NAMESPACE(QQmlJSMetaProperty); |
159 | Q_DECLARE_PUBLIC(QQmlSA::Property) |
160 | |
161 | public: |
162 | explicit PropertyPrivate(Property *); |
163 | PropertyPrivate(Property *, const PropertyPrivate &); |
164 | PropertyPrivate(Property *, PropertyPrivate &&); |
165 | ~PropertyPrivate() = default; |
166 | |
167 | QString typeName() const; |
168 | bool isValid() const; |
169 | bool isReadonly() const; |
170 | QQmlSA::Element type() const; |
171 | |
172 | static QQmlJSMetaProperty property(const QQmlSA::Property &property); |
173 | static QQmlSA::Property createProperty(const QQmlJSMetaProperty &); |
174 | |
175 | private: |
176 | QQmlJSMetaProperty m_property; |
177 | QQmlSA::Property *q_ptr; |
178 | }; |
179 | |
180 | class Q_QMLCOMPILER_EXPORT PassManagerPrivate |
181 | { |
182 | friend class QT_PREPEND_NAMESPACE(QQmlJSScope); |
183 | |
184 | public: |
185 | Q_DISABLE_COPY_MOVE(PassManagerPrivate) |
186 | |
187 | friend class GenericPass; |
188 | PassManagerPrivate(QQmlJSImportVisitor *visitor, QQmlJSTypeResolver *resolver) |
189 | : m_visitor(visitor), m_typeResolver(resolver) |
190 | { |
191 | } |
192 | |
193 | static PassManagerPrivate *get(PassManager *manager) { return manager->d_func(); } |
194 | static const PassManagerPrivate *get(const PassManager *manager) { return manager->d_func(); } |
195 | static PassManager *createPassManager(QQmlJSImportVisitor *visitor, QQmlJSTypeResolver *resolver) |
196 | { |
197 | PassManager *result = new PassManager(); |
198 | result->d_ptr = std::make_unique<PassManagerPrivate>(args&: visitor, args&: resolver); |
199 | return result; |
200 | } |
201 | static void deletePassManager(PassManager *q) { delete q; } |
202 | |
203 | void registerElementPass(std::unique_ptr<ElementPass> pass); |
204 | bool registerPropertyPass(std::shared_ptr<PropertyPass> pass, QAnyStringView moduleName, |
205 | QAnyStringView typeName, |
206 | QAnyStringView propertyName = QAnyStringView(), |
207 | bool allowInheritance = true); |
208 | void analyze(const Element &root); |
209 | |
210 | bool hasImportedModule(QAnyStringView name) const; |
211 | |
212 | static QQmlJSImportVisitor *visitor(const QQmlSA::PassManager &); |
213 | static QQmlJSTypeResolver *resolver(const QQmlSA::PassManager &); |
214 | |
215 | |
216 | QSet<PropertyPass *> findPropertyUsePasses(const QQmlSA::Element &element, |
217 | const QString &propertyName); |
218 | |
219 | void analyzeWrite(const QQmlSA::Element &element, QString propertyName, |
220 | const QQmlSA::Element &value, const QQmlSA::Element &writeScope, |
221 | QQmlSA::SourceLocation location); |
222 | void analyzeRead(const QQmlSA::Element &element, QString propertyName, |
223 | const QQmlSA::Element &readScope, QQmlSA::SourceLocation location); |
224 | void analyzeBinding(const QQmlSA::Element &element, const QQmlSA::Element &value, |
225 | QQmlSA::SourceLocation location); |
226 | |
227 | void addBindingSourceLocations(const QQmlSA::Element &element, |
228 | const QQmlSA::Element &scope = QQmlSA::Element(), |
229 | const QString prefix = QString(), bool isAttached = false); |
230 | |
231 | std::vector<std::shared_ptr<ElementPass>> m_elementPasses; |
232 | std::multimap<QString, PropertyPassInfo> m_propertyPasses; |
233 | std::unordered_map<quint32, BindingInfo> m_bindingsByLocation; |
234 | QQmlJSImportVisitor *m_visitor; |
235 | QQmlJSTypeResolver *m_typeResolver; |
236 | }; |
237 | |
238 | class FixSuggestionPrivate |
239 | { |
240 | Q_DECLARE_PUBLIC(FixSuggestion) |
241 | friend class QT_PREPEND_NAMESPACE(QQmlJSFixSuggestion); |
242 | |
243 | public: |
244 | explicit FixSuggestionPrivate(FixSuggestion *); |
245 | FixSuggestionPrivate(FixSuggestion *, const QString &fixDescription, |
246 | const QQmlSA::SourceLocation &location, const QString &replacement); |
247 | FixSuggestionPrivate(FixSuggestion *, const FixSuggestionPrivate &); |
248 | FixSuggestionPrivate(FixSuggestion *, FixSuggestionPrivate &&); |
249 | ~FixSuggestionPrivate() = default; |
250 | |
251 | QString fixDescription() const; |
252 | QQmlSA::SourceLocation location() const; |
253 | QString replacement() const; |
254 | |
255 | void setFileName(const QString &); |
256 | QString fileName() const; |
257 | |
258 | void setHint(const QString &); |
259 | QString hint() const; |
260 | |
261 | void setAutoApplicable(bool autoApplicable = true); |
262 | bool isAutoApplicable() const; |
263 | |
264 | static QQmlJSFixSuggestion &fixSuggestion(QQmlSA::FixSuggestion &); |
265 | static const QQmlJSFixSuggestion &fixSuggestion(const QQmlSA::FixSuggestion &); |
266 | |
267 | private: |
268 | QQmlJSFixSuggestion m_fixSuggestion; |
269 | QQmlSA::FixSuggestion *q_ptr; |
270 | }; |
271 | |
272 | } // namespace QQmlSA |
273 | |
274 | QT_END_NAMESPACE |
275 | |
276 | #endif |
277 | |