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
28QT_BEGIN_NAMESPACE
29
30class QQmlJSTypeResolver;
31struct QQmlJSTypePropagator;
32class QQmlJSImportVisitor;
33
34namespace QQmlSA {
35
36class Bindings;
37class GenericPassPrivate;
38class PassManager;
39
40enum 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
54struct BindingInfo
55{
56 QString fullPropertyName;
57 QQmlSA::Binding binding;
58 QQmlSA::Element bindingScope;
59 bool isAttached;
60};
61
62struct PropertyPassInfo
63{
64 QStringList properties;
65 std::shared_ptr<QQmlSA::PropertyPass> pass;
66 bool allowInheritance = true;
67};
68
69class BindingsPrivate
70{
71 friend class QT_PREPEND_NAMESPACE(QQmlJSMetaPropertyBinding);
72 Q_DECLARE_PUBLIC(QQmlSA::Binding::Bindings)
73
74public:
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
89private:
90 QMultiHash<QString, Binding> m_bindings;
91 QQmlSA::Binding::Bindings *q_ptr;
92};
93
94class BindingPrivate
95{
96 friend class QT_PREPEND_NAMESPACE(QQmlJSMetaPropertyBinding);
97 Q_DECLARE_PUBLIC(Binding)
98
99public:
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
107private:
108 QQmlJSMetaPropertyBinding m_binding;
109 Binding *q_ptr;
110};
111
112class MethodPrivate
113{
114 friend class QT_PREPEND_NAMESPACE(QQmlJSMetaMethod);
115 Q_DECLARE_PUBLIC(Method)
116
117public:
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
128private:
129 QQmlJSMetaMethod m_method;
130 Method *q_ptr;
131};
132
133class MethodsPrivate
134{
135 friend class QT_PREPEND_NAMESPACE(QQmlJSMetaMethod);
136 Q_DECLARE_PUBLIC(QQmlSA::Method::Methods)
137
138public:
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
149private:
150 QMultiHash<QString, Method> m_methods;
151 QQmlSA::Method::Methods *q_ptr;
152};
153
154class PropertyPrivate
155{
156 friend class QT_PREPEND_NAMESPACE(QQmlJSMetaProperty);
157 Q_DECLARE_PUBLIC(QQmlSA::Property)
158
159public:
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
173private:
174 QQmlJSMetaProperty m_property;
175 QQmlSA::Property *q_ptr;
176};
177
178class Q_QMLCOMPILER_EXPORT PassManagerPrivate
179{
180 friend class QT_PREPEND_NAMESPACE(QQmlJSScope);
181
182public:
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
236class FixSuggestionPrivate
237{
238 Q_DECLARE_PUBLIC(FixSuggestion)
239 friend class QT_PREPEND_NAMESPACE(QQmlJSFixSuggestion);
240
241public:
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
265private:
266 QQmlJSFixSuggestion m_fixSuggestion;
267 QQmlSA::FixSuggestion *q_ptr;
268};
269
270} // namespace QQmlSA
271
272QT_END_NAMESPACE
273
274#endif
275

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