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