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

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