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
42class ConstPtrWrapperIterator
43{
44public:
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
90private:
91 QList<Ptr>::const_iterator m_iterator;
92 ConstPtr m_pointer;
93};
94
95class Export {
96public:
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
107private:
108 QString m_package;
109 QString m_type;
110 QTypeRevision m_version;
111 QTypeRevision m_revision;
112};
113
114template<typename Pointer>
115struct ExportedScope {
116 Pointer scope;
117 QList<Export> exports;
118};
119
120template<typename Pointer>
121struct ImportedScope {
122 Pointer scope;
123 QTypeRevision revision;
124};
125
126struct ContextualTypes;
127
128} // namespace QQmlJS
129
130class Q_QMLCOMPILER_EXPORT QQmlJSScope
131{
132 friend QQmlSA::Element;
133
134public:
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
482private:
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
588inline QQmlJSScope::Ptr QQmlJSScope::parentScope()
589{
590 return m_parentScope.toStrongRef();
591}
592
593inline 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
603inline QMultiHash<QString, QQmlJSMetaPropertyBinding> QQmlJSScope::ownPropertyBindings() const
604{
605 return m_propertyBindings;
606}
607
608inline 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
613inline bool QQmlJSScope::hasOwnPropertyBindings(const QString &name) const
614{
615 return m_propertyBindings.contains(key: name);
616}
617
618inline 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
626inline void QQmlJSScope::setInlineComponentName(const QString &inlineComponentName)
627{
628 Q_ASSERT(isInlineComponent());
629 m_inlineComponentName = inlineComponentName;
630}
631
632inline QVector<QQmlJSScope::Ptr> QQmlJSScope::childScopes()
633{
634 return m_childScopes;
635}
636
637inline void QQmlJSScope::setSourceLocation(const QQmlJS::SourceLocation &sourceLocation)
638{
639 m_sourceLocation = sourceLocation;
640}
641
642inline QQmlJS::SourceLocation QQmlJSScope::sourceLocation() const
643{
644 return m_sourceLocation;
645}
646
647inline 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
656Q_DECLARE_TYPEINFO(QQmlJSScope::QmlIRCompatibilityBindingData, Q_RELOCATABLE_TYPE);
657
658template<>
659class Q_QMLCOMPILER_EXPORT QDeferredFactory<QQmlJSScope>
660{
661public:
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
691private:
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
707using QQmlJSExportedScope = QQmlJSScope::ExportedScope<QQmlJSScope::Ptr>;
708using QQmlJSImportedScope = QQmlJSScope::ImportedScope<QQmlJSScope::ConstPtr>;
709
710QT_END_NAMESPACE
711
712#endif // QQMLJSSCOPE_P_H
713

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

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