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 | MethodType methodType() const; |
125 | |
126 | static QQmlSA::Method createMethod(const QQmlJSMetaMethod &); |
127 | static QQmlJSMetaMethod method(const QQmlSA::Method &); |
128 | |
129 | private: |
130 | QQmlJSMetaMethod m_method; |
131 | Method *q_ptr; |
132 | }; |
133 | |
134 | class MethodsPrivate |
135 | { |
136 | friend class QT_PREPEND_NAMESPACE(QQmlJSMetaMethod); |
137 | Q_DECLARE_PUBLIC(QQmlSA::Method::Methods) |
138 | |
139 | public: |
140 | explicit MethodsPrivate(QQmlSA::Method::Methods *); |
141 | MethodsPrivate(QQmlSA::Method::Methods *, const MethodsPrivate &); |
142 | MethodsPrivate(QQmlSA::Method::Methods *, MethodsPrivate &&); |
143 | ~MethodsPrivate() = default; |
144 | |
145 | QMultiHash<QString, Method>::const_iterator constBegin() const; |
146 | QMultiHash<QString, Method>::const_iterator constEnd() const; |
147 | |
148 | static QQmlSA::Method::Methods createMethods(const QMultiHash<QString, QQmlJSMetaMethod> &); |
149 | |
150 | private: |
151 | QMultiHash<QString, Method> m_methods; |
152 | QQmlSA::Method::Methods *q_ptr; |
153 | }; |
154 | |
155 | class PropertyPrivate |
156 | { |
157 | friend class QT_PREPEND_NAMESPACE(QQmlJSMetaProperty); |
158 | Q_DECLARE_PUBLIC(QQmlSA::Property) |
159 | |
160 | public: |
161 | explicit PropertyPrivate(Property *); |
162 | PropertyPrivate(Property *, const PropertyPrivate &); |
163 | PropertyPrivate(Property *, PropertyPrivate &&); |
164 | ~PropertyPrivate() = default; |
165 | |
166 | QString typeName() const; |
167 | bool isValid() const; |
168 | |
169 | static QQmlJSMetaProperty property(const QQmlSA::Property &property); |
170 | static QQmlSA::Property createProperty(const QQmlJSMetaProperty &); |
171 | |
172 | private: |
173 | QQmlJSMetaProperty m_property; |
174 | QQmlSA::Property *q_ptr; |
175 | }; |
176 | |
177 | class Q_QMLCOMPILER_EXPORT PassManagerPrivate |
178 | { |
179 | friend class QT_PREPEND_NAMESPACE(QQmlJSScope); |
180 | |
181 | Q_DECLARE_PUBLIC(PassManager) |
182 | |
183 | public: |
184 | Q_DISABLE_COPY_MOVE(PassManagerPrivate) |
185 | |
186 | friend class GenericPass; |
187 | PassManagerPrivate(PassManager *manager, QQmlJSImportVisitor *visitor, |
188 | QQmlJSTypeResolver *resolver) |
189 | : m_visitor(visitor), m_typeResolver(resolver), q_ptr{ manager } |
190 | { |
191 | Q_UNUSED(m_typeResolver); |
192 | } |
193 | void registerElementPass(std::unique_ptr<ElementPass> pass); |
194 | bool registerPropertyPass(std::shared_ptr<PropertyPass> pass, QAnyStringView moduleName, |
195 | QAnyStringView typeName, |
196 | QAnyStringView propertyName = QAnyStringView(), |
197 | bool allowInheritance = true); |
198 | void analyze(const Element &root); |
199 | |
200 | bool hasImportedModule(QAnyStringView name) const; |
201 | |
202 | static QQmlJSImportVisitor *visitor(const QQmlSA::PassManager &); |
203 | static QQmlJSTypeResolver *resolver(const QQmlSA::PassManager &); |
204 | |
205 | private: |
206 | friend struct ::QQmlJSTypePropagator; |
207 | |
208 | QSet<PropertyPass *> findPropertyUsePasses(const QQmlSA::Element &element, |
209 | const QString &propertyName); |
210 | |
211 | void analyzeWrite(const QQmlSA::Element &element, QString propertyName, |
212 | const QQmlSA::Element &value, const QQmlSA::Element &writeScope, |
213 | QQmlSA::SourceLocation location); |
214 | void analyzeRead(const QQmlSA::Element &element, QString propertyName, |
215 | const QQmlSA::Element &readScope, QQmlSA::SourceLocation location); |
216 | void analyzeBinding(const QQmlSA::Element &element, const QQmlSA::Element &value, |
217 | QQmlSA::SourceLocation location); |
218 | |
219 | void addBindingSourceLocations(const QQmlSA::Element &element, |
220 | const QQmlSA::Element &scope = QQmlSA::Element(), |
221 | const QString prefix = QString(), bool isAttached = false); |
222 | |
223 | std::vector<std::shared_ptr<ElementPass>> m_elementPasses; |
224 | std::multimap<QString, PropertyPassInfo> m_propertyPasses; |
225 | std::unordered_map<quint32, BindingInfo> m_bindingsByLocation; |
226 | QQmlJSImportVisitor *m_visitor; |
227 | QQmlJSTypeResolver *m_typeResolver; |
228 | |
229 | PassManager *q_ptr; |
230 | }; |
231 | |
232 | class FixSuggestionPrivate |
233 | { |
234 | Q_DECLARE_PUBLIC(FixSuggestion) |
235 | friend class QT_PREPEND_NAMESPACE(QQmlJSFixSuggestion); |
236 | |
237 | public: |
238 | explicit FixSuggestionPrivate(FixSuggestion *); |
239 | FixSuggestionPrivate(FixSuggestion *, const QString &fixDescription, |
240 | const QQmlSA::SourceLocation &location, const QString &replacement); |
241 | FixSuggestionPrivate(FixSuggestion *, const FixSuggestionPrivate &); |
242 | FixSuggestionPrivate(FixSuggestion *, FixSuggestionPrivate &&); |
243 | ~FixSuggestionPrivate() = default; |
244 | |
245 | QString fixDescription() const; |
246 | QQmlSA::SourceLocation location() const; |
247 | QString replacement() const; |
248 | |
249 | void setFileName(const QString &); |
250 | QString fileName() const; |
251 | |
252 | void setHint(const QString &); |
253 | QString hint() const; |
254 | |
255 | void setAutoApplicable(bool autoApplicable = true); |
256 | bool isAutoApplicable() const; |
257 | |
258 | static QQmlJSFixSuggestion &fixSuggestion(QQmlSA::FixSuggestion &); |
259 | static const QQmlJSFixSuggestion &fixSuggestion(const QQmlSA::FixSuggestion &); |
260 | |
261 | private: |
262 | QQmlJSFixSuggestion m_fixSuggestion; |
263 | QQmlSA::FixSuggestion *q_ptr; |
264 | }; |
265 | |
266 | } // namespace QQmlSA |
267 | |
268 | QT_END_NAMESPACE |
269 | |
270 | #endif |
271 | |