1 | // Copyright (C) 2019 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 QQMLJSSCOPE_P_H |
5 | #define QQMLJSSCOPE_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 "qqmljsmetatypes_p.h" |
20 | #include "qdeferredpointer_p.h" |
21 | #include "qqmljsannotation_p.h" |
22 | #include "qqmlsaconstants.h" |
23 | #include "qqmlsa_p.h" |
24 | |
25 | #include <QtQml/private/qqmljssourcelocation_p.h> |
26 | |
27 | #include <QtCore/qfileinfo.h> |
28 | #include <QtCore/qhash.h> |
29 | #include <QtCore/qset.h> |
30 | #include <QtCore/qstring.h> |
31 | #include <QtCore/qversionnumber.h> |
32 | #include "qqmlsaconstants.h" |
33 | |
34 | #include <optional> |
35 | |
36 | QT_BEGIN_NAMESPACE |
37 | |
38 | class QQmlJSImporter; |
39 | |
40 | namespace QQmlJS { |
41 | |
42 | class ConstPtrWrapperIterator |
43 | { |
44 | public: |
45 | using Ptr = QDeferredSharedPointer<QQmlJSScope>; |
46 | using ConstPtr = QDeferredSharedPointer<const QQmlJSScope>; |
47 | using iterator_category = std::forward_iterator_tag; |
48 | using difference_type = std::ptrdiff_t; |
49 | using value_type = ConstPtr; |
50 | using pointer = value_type *; |
51 | using reference = value_type &; |
52 | |
53 | ConstPtrWrapperIterator(QList<Ptr>::const_iterator iterator) : m_iterator(iterator) { } |
54 | |
55 | friend bool operator==(const ConstPtrWrapperIterator &a, const ConstPtrWrapperIterator &b) |
56 | { |
57 | return a.m_iterator == b.m_iterator; |
58 | } |
59 | friend bool operator!=(const ConstPtrWrapperIterator &a, const ConstPtrWrapperIterator &b) |
60 | { |
61 | return a.m_iterator != b.m_iterator; |
62 | } |
63 | |
64 | reference operator*() |
65 | { |
66 | if (!m_pointer) |
67 | m_pointer = *m_iterator; |
68 | return m_pointer; |
69 | } |
70 | pointer operator->() |
71 | { |
72 | if (!m_pointer) |
73 | m_pointer = *m_iterator; |
74 | return &m_pointer; |
75 | } |
76 | |
77 | ConstPtrWrapperIterator &operator++() |
78 | { |
79 | m_iterator++; |
80 | m_pointer = {}; |
81 | return *this; |
82 | } |
83 | ConstPtrWrapperIterator operator++(int) |
84 | { |
85 | auto before = *this; |
86 | ++(*this); |
87 | return before; |
88 | } |
89 | |
90 | private: |
91 | QList<Ptr>::const_iterator m_iterator; |
92 | ConstPtr m_pointer; |
93 | }; |
94 | |
95 | class Export { |
96 | public: |
97 | Export() = default; |
98 | Export(QString package, QString type, QTypeRevision version, QTypeRevision revision); |
99 | |
100 | bool isValid() const; |
101 | |
102 | QString package() const { return m_package; } |
103 | QString type() const { return m_type; } |
104 | QTypeRevision version() const { return m_version; } |
105 | QTypeRevision revision() const { return m_revision; } |
106 | |
107 | private: |
108 | QString m_package; |
109 | QString m_type; |
110 | QTypeRevision m_version; |
111 | QTypeRevision m_revision; |
112 | }; |
113 | |
114 | template<typename Pointer> |
115 | struct ExportedScope { |
116 | Pointer scope; |
117 | QList<Export> exports; |
118 | }; |
119 | |
120 | template<typename Pointer> |
121 | struct ImportedScope { |
122 | Pointer scope; |
123 | QTypeRevision revision; |
124 | }; |
125 | |
126 | struct ContextualTypes; |
127 | |
128 | } // namespace QQmlJS |
129 | |
130 | class Q_QMLCOMPILER_EXPORT QQmlJSScope |
131 | { |
132 | friend QQmlSA::Element; |
133 | |
134 | public: |
135 | explicit QQmlJSScope(const QString &internalName); |
136 | QQmlJSScope(QQmlJSScope &&) = default; |
137 | QQmlJSScope &operator=(QQmlJSScope &&) = default; |
138 | |
139 | using Ptr = QDeferredSharedPointer<QQmlJSScope>; |
140 | using WeakPtr = QDeferredWeakPointer<QQmlJSScope>; |
141 | using ConstPtr = QDeferredSharedPointer<const QQmlJSScope>; |
142 | using WeakConstPtr = QDeferredWeakPointer<const QQmlJSScope>; |
143 | |
144 | using AccessSemantics = QQmlSA::AccessSemantics; |
145 | using ScopeType = QQmlSA::ScopeType; |
146 | |
147 | using InlineComponentNameType = QString; |
148 | using RootDocumentNameType = std::monostate; // an empty type that has std::hash |
149 | /*! |
150 | * A Hashable type to differentiate document roots from different inline components. |
151 | */ |
152 | using InlineComponentOrDocumentRootName = |
153 | std::variant<InlineComponentNameType, RootDocumentNameType>; |
154 | |
155 | enum Flag { |
156 | Creatable = 0x1, |
157 | Composite = 0x2, |
158 | JavaScriptBuiltin = 0x4, |
159 | Singleton = 0x8, |
160 | Script = 0x10, |
161 | CustomParser = 0x20, |
162 | Array = 0x40, |
163 | InlineComponent = 0x80, |
164 | WrappedInImplicitComponent = 0x100, |
165 | HasBaseTypeError = 0x200, |
166 | ExtensionIsNamespace = 0x400, |
167 | IsListProperty = 0x800, |
168 | Structured = 0x1000, |
169 | ExtensionIsJavaScript = 0x2000, |
170 | EnforcesScopedEnums = 0x4000, |
171 | }; |
172 | Q_DECLARE_FLAGS(Flags, Flag) |
173 | Q_FLAGS(Flags); |
174 | |
175 | using Export = QQmlJS::Export; |
176 | template <typename Pointer> |
177 | using ImportedScope = QQmlJS::ImportedScope<Pointer>; |
178 | template <typename Pointer> |
179 | using ExportedScope = QQmlJS::ExportedScope<Pointer>; |
180 | |
181 | struct JavaScriptIdentifier |
182 | { |
183 | enum Kind { |
184 | Parameter, |
185 | FunctionScoped, |
186 | LexicalScoped, |
187 | Injected |
188 | }; |
189 | |
190 | Kind kind = FunctionScoped; |
191 | QQmlJS::SourceLocation location; |
192 | std::optional<QString> typeName; |
193 | bool isConst = false; |
194 | QQmlJSScope::WeakConstPtr scope = {}; |
195 | }; |
196 | |
197 | enum BindingTargetSpecifier { |
198 | SimplePropertyTarget, // e.g. `property int p: 42` |
199 | ListPropertyTarget, // e.g. `property list<Item> pList: [ Text {} ]` |
200 | UnnamedPropertyTarget // default property bindings, where property name is unspecified |
201 | }; |
202 | |
203 | template <typename Key, typename Value> |
204 | using QMultiHashRange = QPair<typename QMultiHash<Key, Value>::iterator, |
205 | typename QMultiHash<Key, Value>::iterator>; |
206 | |
207 | static QQmlJSScope::Ptr create() { return QSharedPointer<QQmlJSScope>(new QQmlJSScope); } |
208 | static QQmlJSScope::Ptr create(const QString &internalName); |
209 | static QQmlJSScope::Ptr clone(const QQmlJSScope::ConstPtr &origin); |
210 | |
211 | static QQmlJSScope::ConstPtr findCurrentQMLScope(const QQmlJSScope::ConstPtr &scope); |
212 | |
213 | QQmlJSScope::Ptr parentScope(); |
214 | QQmlJSScope::ConstPtr parentScope() const; |
215 | static void reparent(const QQmlJSScope::Ptr &parentScope, const QQmlJSScope::Ptr &childScope); |
216 | |
217 | void insertJSIdentifier(const QString &name, const JavaScriptIdentifier &identifier); |
218 | QHash<QString, JavaScriptIdentifier> ownJSIdentifiers() const; |
219 | void insertPropertyIdentifier(const QQmlJSMetaProperty &prop); |
220 | |
221 | ScopeType scopeType() const { return m_scopeType; } |
222 | void setScopeType(ScopeType type) { m_scopeType = type; } |
223 | |
224 | void addOwnMethod(const QQmlJSMetaMethod &method) { m_methods.insert(key: method.methodName(), value: method); } |
225 | QMultiHashRange<QString, QQmlJSMetaMethod> mutableOwnMethodsRange(const QString &name) |
226 | { |
227 | return m_methods.equal_range(key: name); |
228 | } |
229 | QMultiHash<QString, QQmlJSMetaMethod> ownMethods() const { return m_methods; } |
230 | QList<QQmlJSMetaMethod> ownMethods(const QString &name) const { return m_methods.values(key: name); } |
231 | bool hasOwnMethod(const QString &name) const { return m_methods.contains(key: name); } |
232 | |
233 | bool hasMethod(const QString &name) const; |
234 | QHash<QString, QQmlJSMetaMethod> methods() const; |
235 | QList<QQmlJSMetaMethod> methods(const QString &name) const; |
236 | QList<QQmlJSMetaMethod> methods(const QString &name, QQmlJSMetaMethodType type) const; |
237 | |
238 | void addOwnEnumeration(const QQmlJSMetaEnum &enumeration) { m_enumerations.insert(key: enumeration.name(), value: enumeration); } |
239 | QHash<QString, QQmlJSMetaEnum> ownEnumerations() const { return m_enumerations; } |
240 | QQmlJSMetaEnum ownEnumeration(const QString &name) const { return m_enumerations.value(key: name); } |
241 | bool hasOwnEnumeration(const QString &name) const { return m_enumerations.contains(key: name); } |
242 | |
243 | bool hasEnumeration(const QString &name) const; |
244 | bool hasEnumerationKey(const QString &name) const; |
245 | bool hasOwnEnumerationKey(const QString &name) const; |
246 | QQmlJSMetaEnum enumeration(const QString &name) const; |
247 | QHash<QString, QQmlJSMetaEnum> enumerations() const; |
248 | |
249 | void setAnnotations(const QList<QQmlJSAnnotation> &annotation) { m_annotations = std::move(annotation); } |
250 | const QList<QQmlJSAnnotation> &annotations() const { return m_annotations; } |
251 | |
252 | QString filePath() const { return m_filePath; } |
253 | void setFilePath(const QString &file) { m_filePath = file; } |
254 | |
255 | // The name the type uses to refer to itself. Either C++ class name or base name of |
256 | // QML file. isComposite tells us if this is a C++ or a QML name. |
257 | QString internalName() const { return m_internalName; } |
258 | void setInternalName(const QString &internalName) { m_internalName = internalName; } |
259 | QString augmentedInternalName() const; |
260 | |
261 | // This returns a more user readable version of internalName / baseTypeName |
262 | static QString prettyName(QAnyStringView name); |
263 | |
264 | bool isComponentRootElement() const; |
265 | |
266 | void setAliases(const QStringList &aliases) { m_aliases = aliases; } |
267 | QStringList aliases() const { return m_aliases; } |
268 | |
269 | void setInterfaceNames(const QStringList& interfaces) { m_interfaceNames = interfaces; } |
270 | QStringList interfaceNames() const { return m_interfaceNames; } |
271 | |
272 | bool hasInterface(const QString &name) const; |
273 | bool hasOwnInterface(const QString &name) const { return m_interfaceNames.contains(str: name); } |
274 | |
275 | void setOwnDeferredNames(const QStringList &names) { m_ownDeferredNames = names; } |
276 | QStringList ownDeferredNames() const { return m_ownDeferredNames; } |
277 | void setOwnImmediateNames(const QStringList &names) { m_ownImmediateNames = names; } |
278 | QStringList ownImmediateNames() const { return m_ownImmediateNames; } |
279 | |
280 | bool isNameDeferred(const QString &name) const; |
281 | |
282 | // If isComposite(), this is the QML/JS name of the prototype. Otherwise it's the |
283 | // relevant base class (in the hierarchy starting from QObject) of a C++ type. |
284 | void setBaseTypeName(const QString &baseTypeName); |
285 | QString baseTypeName() const; |
286 | |
287 | QQmlJSScope::ConstPtr baseType() const { return m_baseType.scope; } |
288 | QTypeRevision baseTypeRevision() const { return m_baseType.revision; } |
289 | |
290 | QString moduleName() const; |
291 | QString ownModuleName() const { return m_moduleName; } |
292 | void setOwnModuleName(const QString &moduleName) { m_moduleName = moduleName; } |
293 | |
294 | void clearBaseType() { m_baseType = {}; } |
295 | void setBaseTypeError(const QString &baseTypeError); |
296 | QString baseTypeError() const; |
297 | |
298 | void addOwnProperty(const QQmlJSMetaProperty &prop) { m_properties.insert(key: prop.propertyName(), value: prop); } |
299 | QHash<QString, QQmlJSMetaProperty> ownProperties() const { return m_properties; } |
300 | QQmlJSMetaProperty ownProperty(const QString &name) const { return m_properties.value(key: name); } |
301 | bool hasOwnProperty(const QString &name) const { return m_properties.contains(key: name); } |
302 | |
303 | bool hasProperty(const QString &name) const; |
304 | QQmlJSMetaProperty property(const QString &name) const; |
305 | QHash<QString, QQmlJSMetaProperty> properties() const; |
306 | |
307 | void setPropertyLocallyRequired(const QString &name, bool isRequired); |
308 | bool isPropertyRequired(const QString &name) const; |
309 | bool isPropertyLocallyRequired(const QString &name) const; |
310 | |
311 | void addOwnPropertyBinding( |
312 | const QQmlJSMetaPropertyBinding &binding, |
313 | BindingTargetSpecifier specifier = BindingTargetSpecifier::SimplePropertyTarget); |
314 | QMultiHash<QString, QQmlJSMetaPropertyBinding> ownPropertyBindings() const; |
315 | QPair<QMultiHash<QString, QQmlJSMetaPropertyBinding>::const_iterator, |
316 | QMultiHash<QString, QQmlJSMetaPropertyBinding>::const_iterator> |
317 | ownPropertyBindings(const QString &name) const; |
318 | QList<QQmlJSMetaPropertyBinding> ownPropertyBindingsInQmlIROrder() const; |
319 | bool hasOwnPropertyBindings(const QString &name) const; |
320 | |
321 | bool hasPropertyBindings(const QString &name) const; |
322 | QList<QQmlJSMetaPropertyBinding> propertyBindings(const QString &name) const; |
323 | |
324 | struct AnnotatedScope; // defined later |
325 | static AnnotatedScope ownerOfProperty(const QQmlJSScope::ConstPtr &self, const QString &name); |
326 | |
327 | bool isResolved() const; |
328 | bool isFullyResolved() const; |
329 | |
330 | QString ownDefaultPropertyName() const { return m_defaultPropertyName; } |
331 | void setOwnDefaultPropertyName(const QString &name) { m_defaultPropertyName = name; } |
332 | QString defaultPropertyName() const; |
333 | |
334 | QString ownParentPropertyName() const { return m_parentPropertyName; } |
335 | void setOwnParentPropertyName(const QString &name) { m_parentPropertyName = name; } |
336 | QString parentPropertyName() const; |
337 | |
338 | QString ownAttachedTypeName() const { return m_attachedTypeName; } |
339 | void setOwnAttachedTypeName(const QString &name) { m_attachedTypeName = name; } |
340 | QQmlJSScope::ConstPtr ownAttachedType() const { return m_attachedType; } |
341 | |
342 | QString attachedTypeName() const; |
343 | QQmlJSScope::ConstPtr attachedType() const; |
344 | |
345 | QString extensionTypeName() const { return m_extensionTypeName; } |
346 | void setExtensionTypeName(const QString &name) { m_extensionTypeName = name; } |
347 | enum ExtensionKind { |
348 | NotExtension, |
349 | ExtensionType, |
350 | ExtensionJavaScript, |
351 | ExtensionNamespace, |
352 | }; |
353 | struct AnnotatedScope |
354 | { |
355 | QQmlJSScope::ConstPtr scope; |
356 | ExtensionKind extensionSpecifier = NotExtension; |
357 | }; |
358 | AnnotatedScope extensionType() const; |
359 | |
360 | QString valueTypeName() const { return m_valueTypeName; } |
361 | void setValueTypeName(const QString &name) { m_valueTypeName = name; } |
362 | QQmlJSScope::ConstPtr valueType() const { return m_valueType; } |
363 | QQmlJSScope::ConstPtr listType() const { return m_listType; } |
364 | QQmlJSScope::Ptr listType() { return m_listType; } |
365 | |
366 | void addOwnRuntimeFunctionIndex(QQmlJSMetaMethod::AbsoluteFunctionIndex index); |
367 | QQmlJSMetaMethod::AbsoluteFunctionIndex |
368 | ownRuntimeFunctionIndex(QQmlJSMetaMethod::RelativeFunctionIndex index) const; |
369 | |
370 | |
371 | /*! |
372 | * \internal |
373 | * |
374 | * Returns true for objects defined from Qml, and false for objects declared from C++. |
375 | */ |
376 | bool isComposite() const { return m_flags.testFlag(flag: Composite); } |
377 | void setIsComposite(bool v) { m_flags.setFlag(flag: Composite, on: v); } |
378 | |
379 | /*! |
380 | * \internal |
381 | * |
382 | * Returns true for JavaScript types, false for QML and C++ types. |
383 | */ |
384 | bool isJavaScriptBuiltin() const { return m_flags.testFlag(flag: JavaScriptBuiltin); } |
385 | void setIsJavaScriptBuiltin(bool v) { m_flags.setFlag(flag: JavaScriptBuiltin, on: v); } |
386 | |
387 | bool isScript() const { return m_flags.testFlag(flag: Script); } |
388 | void setIsScript(bool v) { m_flags.setFlag(flag: Script, on: v); } |
389 | |
390 | bool hasCustomParser() const { return m_flags.testFlag(flag: CustomParser); } |
391 | void setHasCustomParser(bool v) { m_flags.setFlag(flag: CustomParser, on: v); } |
392 | |
393 | bool isArrayScope() const { return m_flags.testFlag(flag: Array); } |
394 | void setIsArrayScope(bool v) { m_flags.setFlag(flag: Array, on: v); } |
395 | |
396 | bool isInlineComponent() const { return m_flags.testFlag(flag: InlineComponent); } |
397 | void setIsInlineComponent(bool v) { m_flags.setFlag(flag: InlineComponent, on: v); } |
398 | |
399 | bool isWrappedInImplicitComponent() const { return m_flags.testFlag(flag: WrappedInImplicitComponent); } |
400 | void setIsWrappedInImplicitComponent(bool v) { m_flags.setFlag(flag: WrappedInImplicitComponent, on: v); } |
401 | |
402 | bool extensionIsJavaScript() const { return m_flags.testFlag(flag: ExtensionIsJavaScript); } |
403 | void setExtensionIsJavaScript(bool v) { m_flags.setFlag(flag: ExtensionIsJavaScript, on: v); } |
404 | |
405 | bool extensionIsNamespace() const { return m_flags.testFlag(flag: ExtensionIsNamespace); } |
406 | void setExtensionIsNamespace(bool v) { m_flags.setFlag(flag: ExtensionIsNamespace, on: v); } |
407 | |
408 | bool isListProperty() const { return m_flags.testFlag(flag: IsListProperty); } |
409 | void setIsListProperty(bool v) { m_flags.setFlag(flag: IsListProperty, on: v); } |
410 | |
411 | bool isSingleton() const { return m_flags.testFlag(flag: Singleton); } |
412 | void setIsSingleton(bool v) { m_flags.setFlag(flag: Singleton, on: v); } |
413 | |
414 | bool enforcesScopedEnums() const; |
415 | void setEnforcesScopedEnumsFlag(bool v) { m_flags.setFlag(flag: EnforcesScopedEnums, on: v); } |
416 | |
417 | bool isCreatable() const; |
418 | void setCreatableFlag(bool v) { m_flags.setFlag(flag: Creatable, on: v); } |
419 | |
420 | bool isStructured() const; |
421 | void setStructuredFlag(bool v) { m_flags.setFlag(flag: Structured, on: v); } |
422 | |
423 | void setAccessSemantics(AccessSemantics semantics) { m_semantics = semantics; } |
424 | AccessSemantics accessSemantics() const { return m_semantics; } |
425 | bool isReferenceType() const { return m_semantics == QQmlJSScope::AccessSemantics::Reference; } |
426 | bool isValueType() const { return m_semantics == QQmlJSScope::AccessSemantics::Value; } |
427 | |
428 | std::optional<JavaScriptIdentifier> jsIdentifier(const QString &id) const; |
429 | std::optional<JavaScriptIdentifier> ownJSIdentifier(const QString &id) const; |
430 | |
431 | QQmlJS::ConstPtrWrapperIterator childScopesBegin() const { return m_childScopes.constBegin(); } |
432 | QQmlJS::ConstPtrWrapperIterator childScopesEnd() const { return m_childScopes.constEnd(); } |
433 | |
434 | void setInlineComponentName(const QString &inlineComponentName); |
435 | std::optional<QString> inlineComponentName() const; |
436 | InlineComponentOrDocumentRootName enclosingInlineComponentName() const; |
437 | |
438 | QVector<QQmlJSScope::Ptr> childScopes(); |
439 | |
440 | QVector<QQmlJSScope::ConstPtr> childScopes() const; |
441 | |
442 | static QTypeRevision resolveTypes( |
443 | const Ptr &self, const QQmlJS::ContextualTypes &contextualTypes, |
444 | QSet<QString> *usedTypes = nullptr); |
445 | static void resolveNonEnumTypes( |
446 | const QQmlJSScope::Ptr &self, const QQmlJS::ContextualTypes &contextualTypes, |
447 | QSet<QString> *usedTypes = nullptr); |
448 | static void resolveEnums( |
449 | const QQmlJSScope::Ptr &self, const QQmlJS::ContextualTypes &contextualTypes, |
450 | QSet<QString> *usedTypes = nullptr); |
451 | static void resolveList( |
452 | const QQmlJSScope::Ptr &self, const QQmlJSScope::ConstPtr &arrayType); |
453 | static void resolveGroup( |
454 | const QQmlJSScope::Ptr &self, const QQmlJSScope::ConstPtr &baseType, |
455 | const QQmlJS::ContextualTypes &contextualTypes, |
456 | QSet<QString> *usedTypes = nullptr); |
457 | |
458 | void setSourceLocation(const QQmlJS::SourceLocation &sourceLocation); |
459 | QQmlJS::SourceLocation sourceLocation() const; |
460 | |
461 | static QQmlJSScope::ConstPtr nonCompositeBaseType(const QQmlJSScope::ConstPtr &type); |
462 | |
463 | static QTypeRevision |
464 | nonCompositeBaseRevision(const ImportedScope<QQmlJSScope::ConstPtr> &scope); |
465 | |
466 | bool isSameType(const QQmlJSScope::ConstPtr &otherScope) const; |
467 | bool inherits(const QQmlJSScope::ConstPtr &base) const; |
468 | bool canAssign(const QQmlJSScope::ConstPtr &derived) const; |
469 | |
470 | bool isInCustomParserParent() const; |
471 | |
472 | |
473 | static ImportedScope<QQmlJSScope::ConstPtr> findType(const QString &name, |
474 | const QQmlJS::ContextualTypes &contextualTypes, |
475 | QSet<QString> *usedTypes = nullptr); |
476 | |
477 | static QQmlSA::Element createQQmlSAElement(const ConstPtr &); |
478 | static QQmlSA::Element createQQmlSAElement(ConstPtr &&); |
479 | static const QQmlJSScope::ConstPtr &scope(const QQmlSA::Element &); |
480 | static constexpr qsizetype sizeofQQmlSAElement() { return QQmlSA::Element::sizeofElement; } |
481 | |
482 | private: |
483 | /*! \internal |
484 | |
485 | Minimal information about a QQmlJSMetaPropertyBinding that allows it to |
486 | be manipulated similarly to QmlIR::Binding. |
487 | */ |
488 | template <typename T> |
489 | friend class QTypeInfo; // so that we can Q_DECLARE_TYPEINFO QmlIRCompatibilityBindingData |
490 | struct QmlIRCompatibilityBindingData |
491 | { |
492 | QmlIRCompatibilityBindingData() = default; |
493 | QmlIRCompatibilityBindingData(const QString &name, quint32 offset) |
494 | : propertyName(name), sourceLocationOffset(offset) |
495 | { |
496 | } |
497 | QString propertyName; // bound property name |
498 | quint32 sourceLocationOffset = 0; // binding's source location offset |
499 | }; |
500 | |
501 | QQmlJSScope() = default; |
502 | QQmlJSScope(const QQmlJSScope &) = default; |
503 | QQmlJSScope &operator=(const QQmlJSScope &) = default; |
504 | static QTypeRevision resolveType( |
505 | const QQmlJSScope::Ptr &self, const QQmlJS::ContextualTypes &contextualTypes, |
506 | QSet<QString> *usedTypes); |
507 | static void updateChildScope( |
508 | const QQmlJSScope::Ptr &childScope, const QQmlJSScope::Ptr &self, |
509 | const QQmlJS::ContextualTypes &contextualTypes, QSet<QString> *usedTypes); |
510 | |
511 | void addOwnPropertyBindingInQmlIROrder(const QQmlJSMetaPropertyBinding &binding, |
512 | BindingTargetSpecifier specifier); |
513 | bool hasEnforcesScopedEnumsFlag() const { return m_flags & EnforcesScopedEnums; } |
514 | bool hasCreatableFlag() const { return m_flags & Creatable; } |
515 | bool hasStructuredFlag() const { return m_flags & Structured; } |
516 | |
517 | QHash<QString, JavaScriptIdentifier> m_jsIdentifiers; |
518 | |
519 | QMultiHash<QString, QQmlJSMetaMethod> m_methods; |
520 | QHash<QString, QQmlJSMetaProperty> m_properties; |
521 | QMultiHash<QString, QQmlJSMetaPropertyBinding> m_propertyBindings; |
522 | |
523 | // a special QmlIR compatibility bindings array, ordered the same way as |
524 | // bindings in QmlIR::Object |
525 | QList<QmlIRCompatibilityBindingData> m_propertyBindingsArray; |
526 | |
527 | // same as QmlIR::Object::runtimeFunctionIndices |
528 | QList<QQmlJSMetaMethod::AbsoluteFunctionIndex> m_runtimeFunctionIndices; |
529 | |
530 | QHash<QString, QQmlJSMetaEnum> m_enumerations; |
531 | |
532 | QVector<QQmlJSAnnotation> m_annotations; |
533 | QVector<QQmlJSScope::Ptr> m_childScopes; |
534 | QQmlJSScope::WeakPtr m_parentScope; |
535 | |
536 | QString m_filePath; |
537 | QString m_internalName; |
538 | QString m_baseTypeNameOrError; |
539 | |
540 | // We only need the revision for the base type as inheritance is |
541 | // the only relation between two types where the revisions matter. |
542 | ImportedScope<QQmlJSScope::WeakConstPtr> m_baseType; |
543 | |
544 | ScopeType m_scopeType = ScopeType::QMLScope; |
545 | QStringList m_aliases; |
546 | QStringList m_interfaceNames; |
547 | QStringList m_ownDeferredNames; |
548 | QStringList m_ownImmediateNames; |
549 | |
550 | QString m_defaultPropertyName; |
551 | QString m_parentPropertyName; |
552 | /*! \internal |
553 | * The attached type name. |
554 | * This is an internal name, from a c++ type or a synthetic jsrootgen. |
555 | */ |
556 | QString m_attachedTypeName; |
557 | QStringList m_requiredPropertyNames; |
558 | QQmlJSScope::WeakConstPtr m_attachedType; |
559 | |
560 | /*! \internal |
561 | * The Value type name. |
562 | * This is an internal name, from a c++ type or a synthetic jsrootgen. |
563 | */ |
564 | QString m_valueTypeName; |
565 | QQmlJSScope::WeakConstPtr m_valueType; |
566 | QQmlJSScope::Ptr m_listType; |
567 | |
568 | /*! |
569 | The extension is provided as either a type (QML_{NAMESPACE_}EXTENDED) or as a |
570 | namespace (QML_EXTENDED_NAMESPACE). |
571 | The bool HasExtensionNamespace helps differentiating both cases, as namespaces |
572 | have a more limited lookup capaility. |
573 | This is an internal name, from a c++ type or a synthetic jsrootgen. |
574 | */ |
575 | QString m_extensionTypeName; |
576 | QQmlJSScope::WeakConstPtr m_extensionType; |
577 | |
578 | Flags m_flags = Creatable; // all types are marked as creatable by default. |
579 | AccessSemantics m_semantics = AccessSemantics::Reference; |
580 | |
581 | QQmlJS::SourceLocation m_sourceLocation; |
582 | |
583 | QString m_moduleName; |
584 | |
585 | std::optional<QString> m_inlineComponentName; |
586 | }; |
587 | |
588 | inline QQmlJSScope::Ptr QQmlJSScope::parentScope() |
589 | { |
590 | return m_parentScope.toStrongRef(); |
591 | } |
592 | |
593 | inline QQmlJSScope::ConstPtr QQmlJSScope::parentScope() const |
594 | { |
595 | QT_WARNING_PUSH |
596 | #if defined(Q_CC_GNU_ONLY) && Q_CC_GNU < 1400 && Q_CC_GNU >= 1200 |
597 | QT_WARNING_DISABLE_GCC("-Wuse-after-free") |
598 | #endif |
599 | return QQmlJSScope::WeakConstPtr(m_parentScope).toStrongRef(); |
600 | QT_WARNING_POP |
601 | } |
602 | |
603 | inline QMultiHash<QString, QQmlJSMetaPropertyBinding> QQmlJSScope::ownPropertyBindings() const |
604 | { |
605 | return m_propertyBindings; |
606 | } |
607 | |
608 | inline QPair<QMultiHash<QString, QQmlJSMetaPropertyBinding>::const_iterator, QMultiHash<QString, QQmlJSMetaPropertyBinding>::const_iterator> QQmlJSScope::ownPropertyBindings(const QString &name) const |
609 | { |
610 | return m_propertyBindings.equal_range(key: name); |
611 | } |
612 | |
613 | inline bool QQmlJSScope::hasOwnPropertyBindings(const QString &name) const |
614 | { |
615 | return m_propertyBindings.contains(key: name); |
616 | } |
617 | |
618 | inline QQmlJSMetaMethod::AbsoluteFunctionIndex QQmlJSScope::ownRuntimeFunctionIndex(QQmlJSMetaMethod::RelativeFunctionIndex index) const |
619 | { |
620 | const int i = static_cast<int>(index); |
621 | Q_ASSERT(i >= 0); |
622 | Q_ASSERT(i < int(m_runtimeFunctionIndices.size())); |
623 | return m_runtimeFunctionIndices[i]; |
624 | } |
625 | |
626 | inline void QQmlJSScope::setInlineComponentName(const QString &inlineComponentName) |
627 | { |
628 | Q_ASSERT(isInlineComponent()); |
629 | m_inlineComponentName = inlineComponentName; |
630 | } |
631 | |
632 | inline QVector<QQmlJSScope::Ptr> QQmlJSScope::childScopes() |
633 | { |
634 | return m_childScopes; |
635 | } |
636 | |
637 | inline void QQmlJSScope::setSourceLocation(const QQmlJS::SourceLocation &sourceLocation) |
638 | { |
639 | m_sourceLocation = sourceLocation; |
640 | } |
641 | |
642 | inline QQmlJS::SourceLocation QQmlJSScope::sourceLocation() const |
643 | { |
644 | return m_sourceLocation; |
645 | } |
646 | |
647 | inline QQmlJSScope::ConstPtr QQmlJSScope::nonCompositeBaseType(const ConstPtr &type) |
648 | { |
649 | for (QQmlJSScope::ConstPtr base = type; base; base = base->baseType()) { |
650 | if (!base->isComposite()) |
651 | return base; |
652 | } |
653 | return {}; |
654 | } |
655 | |
656 | Q_DECLARE_TYPEINFO(QQmlJSScope::QmlIRCompatibilityBindingData, Q_RELOCATABLE_TYPE); |
657 | |
658 | template<> |
659 | class Q_QMLCOMPILER_EXPORT QDeferredFactory<QQmlJSScope> |
660 | { |
661 | public: |
662 | using TypeReader = std::function<QList<QQmlJS::DiagnosticMessage>( |
663 | QQmlJSImporter *importer, const QString &filePath, |
664 | const QSharedPointer<QQmlJSScope> &scopeToPopulate)>; |
665 | QDeferredFactory() = default; |
666 | |
667 | QDeferredFactory(QQmlJSImporter *importer, const QString &filePath, |
668 | const TypeReader &typeReader = {}); |
669 | |
670 | bool isValid() const |
671 | { |
672 | return !m_filePath.isEmpty() && m_importer != nullptr; |
673 | } |
674 | |
675 | QString internalName() const |
676 | { |
677 | return QFileInfo(m_filePath).baseName(); |
678 | } |
679 | |
680 | QString filePath() const { return m_filePath; } |
681 | |
682 | QQmlJSImporter* importer() const { return m_importer; } |
683 | |
684 | void setIsSingleton(bool isSingleton) |
685 | { |
686 | m_isSingleton = isSingleton; |
687 | } |
688 | |
689 | void setModuleName(const QString &moduleName) { m_moduleName = moduleName; } |
690 | |
691 | private: |
692 | friend class QDeferredSharedPointer<QQmlJSScope>; |
693 | friend class QDeferredSharedPointer<const QQmlJSScope>; |
694 | friend class QDeferredWeakPointer<QQmlJSScope>; |
695 | friend class QDeferredWeakPointer<const QQmlJSScope>; |
696 | |
697 | // Should only be called when lazy-loading the type in a deferred pointer. |
698 | void populate(const QSharedPointer<QQmlJSScope> &scope) const; |
699 | |
700 | QString m_filePath; |
701 | QQmlJSImporter *m_importer = nullptr; |
702 | bool m_isSingleton = false; |
703 | QString m_moduleName; |
704 | TypeReader m_typeReader; |
705 | }; |
706 | |
707 | using QQmlJSExportedScope = QQmlJSScope::ExportedScope<QQmlJSScope::Ptr>; |
708 | using QQmlJSImportedScope = QQmlJSScope::ImportedScope<QQmlJSScope::ConstPtr>; |
709 | |
710 | QT_END_NAMESPACE |
711 | |
712 | #endif // QQMLJSSCOPE_P_H |
713 |
Definitions
- ConstPtrWrapperIterator
- ConstPtrWrapperIterator
- operator==
- operator!=
- operator*
- operator->
- operator++
- operator++
- Export
- Export
- package
- type
- version
- revision
- ExportedScope
- ImportedScope
- QQmlJSScope
- QQmlJSScope
- operator=
- Flag
- JavaScriptIdentifier
- Kind
- BindingTargetSpecifier
- create
- scopeType
- setScopeType
- addOwnMethod
- mutableOwnMethodsRange
- ownMethods
- ownMethods
- hasOwnMethod
- addOwnEnumeration
- ownEnumerations
- ownEnumeration
- hasOwnEnumeration
- setAnnotations
- annotations
- filePath
- setFilePath
- internalName
- setInternalName
- setAliases
- aliases
- setInterfaceNames
- interfaceNames
- hasOwnInterface
- setOwnDeferredNames
- ownDeferredNames
- setOwnImmediateNames
- ownImmediateNames
- baseType
- baseTypeRevision
- ownModuleName
- setOwnModuleName
- clearBaseType
- addOwnProperty
- ownProperties
- ownProperty
- hasOwnProperty
- ownDefaultPropertyName
- setOwnDefaultPropertyName
- ownParentPropertyName
- setOwnParentPropertyName
- ownAttachedTypeName
- setOwnAttachedTypeName
- ownAttachedType
- extensionTypeName
- setExtensionTypeName
- ExtensionKind
- AnnotatedScope
- valueTypeName
- setValueTypeName
- valueType
- listType
- listType
- isComposite
- setIsComposite
- isJavaScriptBuiltin
- setIsJavaScriptBuiltin
- isScript
- setIsScript
- hasCustomParser
- setHasCustomParser
- isArrayScope
- setIsArrayScope
- isInlineComponent
- setIsInlineComponent
- isWrappedInImplicitComponent
- setIsWrappedInImplicitComponent
- extensionIsJavaScript
- setExtensionIsJavaScript
- extensionIsNamespace
- setExtensionIsNamespace
- isListProperty
- setIsListProperty
- isSingleton
- setIsSingleton
- setEnforcesScopedEnumsFlag
- setCreatableFlag
- setStructuredFlag
- setAccessSemantics
- accessSemantics
- isReferenceType
- isValueType
- childScopesBegin
- childScopesEnd
- sizeofQQmlSAElement
- QmlIRCompatibilityBindingData
- QmlIRCompatibilityBindingData
- QmlIRCompatibilityBindingData
- QQmlJSScope
- QQmlJSScope
- operator=
- hasEnforcesScopedEnumsFlag
- hasCreatableFlag
- hasStructuredFlag
- parentScope
- parentScope
- ownPropertyBindings
- ownPropertyBindings
- hasOwnPropertyBindings
- ownRuntimeFunctionIndex
- setInlineComponentName
- childScopes
- setSourceLocation
- sourceLocation
- nonCompositeBaseType
- QDeferredFactory
- QDeferredFactory
- isValid
- internalName
- filePath
- importer
- setIsSingleton
Learn to use CMake with our Intro Training
Find out more