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

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

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