Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qqmljsscope_p.h
Go to the documentation of this file.
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// Qt-Security score:significant
4
5#ifndef QQMLJSSCOPE_P_H
6#define QQMLJSSCOPE_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17
18#include <qtqmlcompilerexports.h>
19
24#include "qqmlsa_p.h"
25
26#include <QtQml/private/qqmljssourcelocation_p.h>
27
28#include <QtCore/qfileinfo.h>
29#include <QtCore/qhash.h>
30#include <QtCore/qset.h>
31#include <QtCore/qstring.h>
32
34
35#include <QtCore/qtyperevision.h>
36
37#include <optional>
38
39QT_BEGIN_NAMESPACE
40
41class QQmlJSImporter;
42
43namespace QQmlJS {
44
46
47class Export {
48public:
49 Export() = default;
50 Export(QString package, QString type, QTypeRevision version, QTypeRevision revision);
51
52 bool isValid() const;
53
54 QString package() const { return m_package; }
55 QString type() const { return m_type; }
56 QTypeRevision version() const { return m_version; }
57 QTypeRevision revision() const { return m_revision; }
58
59private:
60 QString m_package;
61 QString m_type;
62 QTypeRevision m_version;
63 QTypeRevision m_revision;
64};
65
66template<typename Pointer>
68 Pointer scope;
70};
71
72template<typename Pointer>
77
78struct ContextualTypes;
79
80} // namespace QQmlJS
81
82class Q_QMLCOMPILER_EXPORT QQmlJSScope
83{
84 friend QQmlSA::Element;
85
86public:
87 using Ptr = QDeferredSharedPointer<QQmlJSScope>;
88 using WeakPtr = QDeferredWeakPointer<QQmlJSScope>;
89 using ConstPtr = QDeferredSharedPointer<const QQmlJSScope>;
90 using WeakConstPtr = QDeferredWeakPointer<const QQmlJSScope>;
91
92 using AccessSemantics = QQmlSA::AccessSemantics;
93 using ScopeType = QQmlSA::ScopeType;
94
95 using InlineComponentNameType = QString;
96 using RootDocumentNameType = std::monostate; // an empty type that has std::hash
97 /*!
98 * A Hashable type to differentiate document roots from different inline components.
99 */
100 using InlineComponentOrDocumentRootName =
101 std::variant<InlineComponentNameType, RootDocumentNameType>;
102
103 enum Flag {
104 Creatable = 0x1,
105 Composite = 0x2,
106 JavaScriptBuiltin = 0x4,
107 Singleton = 0x8,
108 Script = 0x10,
109 CustomParser = 0x20,
110 Array = 0x40,
111 InlineComponent = 0x80,
112 WrappedInImplicitComponent = 0x100,
113 HasBaseTypeError = 0x200,
114 ExtensionIsNamespace = 0x400,
115 IsListProperty = 0x800,
116 Structured = 0x1000,
117 ExtensionIsJavaScript = 0x2000,
118 EnforcesScopedEnums = 0x4000,
119 FileRootComponent = 0x8000,
120 AssignedToUnknownProperty = 0x10000,
121 };
122 Q_DECLARE_FLAGS(Flags, Flag)
123
124 using Export = QQmlJS::Export;
125 template <typename Pointer>
126 using ImportedScope = QQmlJS::ImportedScope<Pointer>;
127 template <typename Pointer>
128 using ExportedScope = QQmlJS::ExportedScope<Pointer>;
129
130 struct JavaScriptIdentifier
131 {
132 enum Kind {
133 Parameter,
134 FunctionScoped,
135 LexicalScoped,
136 Injected
137 };
138
139 Kind kind = FunctionScoped;
140 QQmlJS::SourceLocation location;
141 std::optional<QString> typeName;
142 bool isConst = false;
143 QQmlJSScope::WeakConstPtr scope = {};
144 };
145
146 enum BindingTargetSpecifier {
147 SimplePropertyTarget, // e.g. `property int p: 42`
148 ListPropertyTarget, // e.g. `property list<Item> pList: [ Text {} ]`
149 UnnamedPropertyTarget // default property bindings, where property name is unspecified
150 };
151
152 template <typename Key, typename Value>
153 using QMultiHashRange = std::pair<typename QMultiHash<Key, Value>::iterator,
154 typename QMultiHash<Key, Value>::iterator>;
155
156 static QQmlJSScope::Ptr create() { return QSharedPointer<QQmlJSScope>(new QQmlJSScope); }
157 static QQmlJSScope::Ptr clone(const QQmlJSScope::ConstPtr &origin);
158 static QQmlJSScope::Ptr resetForReparse(QQmlJSScope::Ptr &&scope);
159
160 static void cloneInto(QQmlJSScope::Ptr &origin,
161 const QQmlJSScope::Ptr &target)
162 {
163 *target = std::move(*clone(origin));
164 }
165
166 static QQmlJSScope::ConstPtr findCurrentQMLScope(const QQmlJSScope::ConstPtr &scope);
167
168 QQmlJSScope::Ptr parentScope();
169 QQmlJSScope::ConstPtr parentScope() const;
170 static void reparent(const QQmlJSScope::Ptr &parentScope, const QQmlJSScope::Ptr &childScope);
171
172 void insertJSIdentifier(const QString &name, const JavaScriptIdentifier &identifier);
173 QHash<QString, JavaScriptIdentifier> ownJSIdentifiers() const;
174 void insertPropertyIdentifier(const QQmlJSMetaProperty &prop);
175
176 ScopeType scopeType() const { return m_scopeType; }
177 void setScopeType(ScopeType type) { m_scopeType = type; }
178
179 void addOwnMethod(const QQmlJSMetaMethod &method) { m_methods.insert(method.methodName(), method); }
180 QMultiHashRange<QString, QQmlJSMetaMethod> mutableOwnMethodsRange(const QString &name)
181 {
182 return m_methods.equal_range(name);
183 }
184 QMultiHash<QString, QQmlJSMetaMethod> ownMethods() const { return m_methods; }
185 QList<QQmlJSMetaMethod> ownMethods(const QString &name) const { return m_methods.values(name); }
186 bool hasOwnMethod(const QString &name) const { return m_methods.contains(name); }
187
188 bool hasMethod(const QString &name) const;
189 QHash<QString, QQmlJSMetaMethod> methods() const;
190 QList<QQmlJSMetaMethod> methods(const QString &name) const;
191 QList<QQmlJSMetaMethod> methods(const QString &name, QQmlJSMetaMethodType type) const;
192
193 void addOwnEnumeration(const QQmlJSMetaEnum &enumeration) { m_enumerations.insert(enumeration.name(), enumeration); }
194 QHash<QString, QQmlJSMetaEnum> ownEnumerations() const { return m_enumerations; }
195 QQmlJSMetaEnum ownEnumeration(const QString &name) const { return m_enumerations.value(name); }
196 bool hasOwnEnumeration(const QString &name) const { return m_enumerations.contains(name); }
197
198 bool hasEnumeration(const QString &name) const;
199 bool hasEnumerationKey(const QString &name) const;
200 bool hasOwnEnumerationKey(const QString &name) const;
201 QQmlJSMetaEnum enumeration(const QString &name) const;
202 QHash<QString, QQmlJSMetaEnum> enumerations() const;
203
204 void setAnnotations(const QList<QQmlJSAnnotation> &annotation) { m_annotations = std::move(annotation); }
205 const QList<QQmlJSAnnotation> &annotations() const { return m_annotations; }
206
207 QString filePath() const { return m_filePath; }
208 void setFilePath(const QString &file) { m_filePath = file; }
209
210 quint32 lineNumber() const { return m_sourceLocation.startLine; }
211 void setLineNumber(quint32 lineNumber);
212
213 // The name the type uses to refer to itself. Either C++ class name or base name of
214 // QML file. isComposite tells us if this is a C++ or a QML name.
215 QString internalName() const { return m_internalName; }
216 void setInternalName(const QString &internalName) { m_internalName = internalName; }
217 QString augmentedInternalName() const;
218
219 // This returns a more user readable version of internalName / baseTypeName
220 static QString prettyName(QAnyStringView name);
221
222 enum class IsComponentRoot : quint8 { No = 0, Yes, Maybe };
223 IsComponentRoot componentRootStatus() const;
224
225 void setAliases(const QStringList &aliases) { m_aliases = aliases; }
226 QStringList aliases() const { return m_aliases; }
227
228 void setInterfaceNames(const QStringList& interfaces) { m_interfaceNames = interfaces; }
229 QStringList interfaceNames() const { return m_interfaceNames; }
230
231 bool hasInterface(const QString &name) const;
232 bool hasOwnInterface(const QString &name) const { return m_interfaceNames.contains(name); }
233
234 void setOwnDeferredNames(const QStringList &names) { m_ownDeferredNames = names; }
235 QStringList ownDeferredNames() const { return m_ownDeferredNames; }
236 void setOwnImmediateNames(const QStringList &names) { m_ownImmediateNames = names; }
237 QStringList ownImmediateNames() const { return m_ownImmediateNames; }
238
239 bool isNameDeferred(const QString &name) const;
240
241 // If isComposite(), this is the QML/JS name of the prototype. Otherwise it's the
242 // relevant base class (in the hierarchy starting from QObject) of a C++ type.
243 void setBaseTypeName(const QString &baseTypeName);
244 QString baseTypeName() const;
245
246 QQmlJSScope::ConstPtr baseType() const { return m_baseType.scope; }
247 QTypeRevision baseTypeRevision() const { return m_baseType.revision; }
248
249 QString moduleName() const;
250 QString ownModuleName() const { return m_moduleName; }
251 void setOwnModuleName(const QString &moduleName) { m_moduleName = moduleName; }
252
253 void clearBaseType() { m_baseType = {}; }
254 void setBaseTypeError(const QString &baseTypeError);
255 QString baseTypeError() const;
256
257 void addOwnProperty(const QQmlJSMetaProperty &prop) { m_properties.insert(prop.propertyName(), prop); }
258 QHash<QString, QQmlJSMetaProperty> ownProperties() const { return m_properties; }
259 QQmlJSMetaProperty ownProperty(const QString &name) const { return m_properties.value(name); }
260 bool hasOwnProperty(const QString &name) const { return m_properties.contains(name); }
261
262 bool hasProperty(const QString &name) const;
263 QQmlJSMetaProperty property(const QString &name) const;
264 QHash<QString, QQmlJSMetaProperty> properties() const;
265
266 void setPropertyLocallyRequired(const QString &name, bool isRequired);
267 bool isPropertyRequired(const QString &name) const;
268 bool isPropertyLocallyRequired(const QString &name) const;
269
270 void addOwnPropertyBinding(
271 const QQmlJSMetaPropertyBinding &binding,
272 BindingTargetSpecifier specifier = BindingTargetSpecifier::SimplePropertyTarget);
273 QMultiHash<QString, QQmlJSMetaPropertyBinding> ownPropertyBindings() const;
274 std::pair<QMultiHash<QString, QQmlJSMetaPropertyBinding>::const_iterator,
275 QMultiHash<QString, QQmlJSMetaPropertyBinding>::const_iterator>
276 ownPropertyBindings(const QString &name) const;
277 QList<QQmlJSMetaPropertyBinding> ownPropertyBindingsInQmlIROrder() const;
278 bool hasOwnPropertyBindings(const QString &name) const;
279
280 bool hasPropertyBindings(const QString &name) const;
281 QList<QQmlJSMetaPropertyBinding> propertyBindings(const QString &name) const;
282
283 struct AnnotatedScope; // defined later
284 static AnnotatedScope ownerOfProperty(const QQmlJSScope::ConstPtr &self, const QString &name);
285 static AnnotatedScope ownerOfMethod(const QQmlJSScope::ConstPtr &self, const QString &name);
286
287 bool isResolved() const;
288 bool isFullyResolved() const;
289
290 QString ownDefaultPropertyName() const { return m_defaultPropertyName; }
291 void setOwnDefaultPropertyName(const QString &name) { m_defaultPropertyName = name; }
292 QString defaultPropertyName() const;
293
294 QString ownParentPropertyName() const { return m_parentPropertyName; }
295 void setOwnParentPropertyName(const QString &name) { m_parentPropertyName = name; }
296 QString parentPropertyName() const;
297
298 QString ownAttachedTypeName() const { return m_attachedTypeName; }
299 void setOwnAttachedTypeName(const QString &name) { m_attachedTypeName = name; }
300 QQmlJSScope::ConstPtr ownAttachedType() const { return m_attachedType; }
301
302 QString attachedTypeName() const;
303 QQmlJSScope::ConstPtr attachedType() const;
304
305 QString extensionTypeName() const { return m_extensionTypeName; }
306 void setExtensionTypeName(const QString &name) { m_extensionTypeName = name; }
307 enum ExtensionKind {
308 NotExtension,
309 ExtensionType,
310 ExtensionJavaScript,
311 ExtensionNamespace,
312 };
313 struct AnnotatedScope
314 {
315 QQmlJSScope::ConstPtr scope;
316 ExtensionKind extensionSpecifier = NotExtension;
317 };
318 AnnotatedScope extensionType() const;
319
320 QString elementTypeName() const { return m_elementTypeName; }
321 void setElementTypeName(const QString &name) { m_elementTypeName = name; }
322 QQmlJSScope::ConstPtr elementType() const { return m_elementType; }
323 QQmlJSScope::ConstPtr listType() const { return m_listType; }
324 QQmlJSScope::Ptr listType() { return m_listType; }
325
326 void addOwnRuntimeFunctionIndex(QQmlJSMetaMethod::AbsoluteFunctionIndex index);
327 QQmlJSMetaMethod::AbsoluteFunctionIndex
328 ownRuntimeFunctionIndex(QQmlJSMetaMethod::RelativeFunctionIndex index) const;
329
330
331 /*!
332 * \internal
333 *
334 * Returns true for objects defined from Qml, and false for objects declared from C++.
335 */
336 bool isComposite() const { return m_flags.testFlag(Composite); }
337 void setIsComposite(bool v) { m_flags.setFlag(Composite, v); }
338
339 /*!
340 * \internal
341 *
342 * Returns true for JavaScript types, false for QML and C++ types.
343 */
344 bool isJavaScriptBuiltin() const { return m_flags.testFlag(JavaScriptBuiltin); }
345 void setIsJavaScriptBuiltin(bool v) { m_flags.setFlag(JavaScriptBuiltin, v); }
346
347 bool isScript() const { return m_flags.testFlag(Script); }
348 void setIsScript(bool v) { m_flags.setFlag(Script, v); }
349
350 bool hasCustomParser() const { return m_flags.testFlag(CustomParser); }
351 void setHasCustomParser(bool v) { m_flags.setFlag(CustomParser, v); }
352
353 bool isArrayScope() const { return m_flags.testFlag(Array); }
354 void setIsArrayScope(bool v) { m_flags.setFlag(Array, v); }
355
356 bool isInlineComponent() const { return m_flags.testFlag(InlineComponent); }
357 void setIsInlineComponent(bool v) { m_flags.setFlag(InlineComponent, v); }
358
359 bool isWrappedInImplicitComponent() const { return m_flags.testFlag(WrappedInImplicitComponent); }
360 void setIsWrappedInImplicitComponent(bool v) { m_flags.setFlag(WrappedInImplicitComponent, v); }
361
362 bool isAssignedToUnknownProperty() const { return m_flags.testFlag(AssignedToUnknownProperty); }
363 void setAssignedToUnknownProperty(bool v) { m_flags.setFlag(AssignedToUnknownProperty, v); }
364
365 bool extensionIsJavaScript() const { return m_flags.testFlag(ExtensionIsJavaScript); }
366 void setExtensionIsJavaScript(bool v) { m_flags.setFlag(ExtensionIsJavaScript, v); }
367
368 bool extensionIsNamespace() const { return m_flags.testFlag(ExtensionIsNamespace); }
369 void setExtensionIsNamespace(bool v) { m_flags.setFlag(ExtensionIsNamespace, v); }
370
371 bool isListProperty() const { return m_flags.testFlag(IsListProperty); }
372 void setIsListProperty(bool v) { m_flags.setFlag(IsListProperty, v); }
373
374 bool isSingleton() const { return m_flags.testFlag(Singleton); }
375 void setIsSingleton(bool v) { m_flags.setFlag(Singleton, v); }
376
377 bool enforcesScopedEnums() const;
378 void setEnforcesScopedEnumsFlag(bool v) { m_flags.setFlag(EnforcesScopedEnums, v); }
379
380 bool isCreatable() const;
381 void setCreatableFlag(bool v) { m_flags.setFlag(Creatable, v); }
382
383 bool isStructured() const;
384 void setStructuredFlag(bool v) { m_flags.setFlag(Structured, v); }
385
386 bool isFileRootComponent() const { return m_flags.testFlag(FileRootComponent); }
387 void setIsRootFileComponentFlag(bool v) { m_flags.setFlag(FileRootComponent, v); }
388
389 void setAccessSemantics(AccessSemantics semantics) { m_semantics = semantics; }
390 AccessSemantics accessSemantics() const { return m_semantics; }
391 bool isReferenceType() const { return m_semantics == QQmlJSScope::AccessSemantics::Reference; }
392 bool isValueType() const { return m_semantics == QQmlJSScope::AccessSemantics::Value; }
393
394 std::optional<JavaScriptIdentifier> jsIdentifier(const QString &id) const;
395 std::optional<JavaScriptIdentifier> ownJSIdentifier(const QString &id) const;
396
397 QQmlJS::ChildScopesIterator childScopesBegin() const { return m_childScopes.constBegin(); }
398 QQmlJS::ChildScopesIterator childScopesEnd() const { return m_childScopes.constEnd(); }
399
400 void setInlineComponentName(const QString &inlineComponentName);
401 std::optional<QString> inlineComponentName() const;
402 InlineComponentOrDocumentRootName enclosingInlineComponentName() const;
403
404 QList<QQmlJSScope::Ptr> childScopes();
405
406 QList<QQmlJSScope::ConstPtr> childScopes() const;
407
408 static QTypeRevision resolveTypes(
409 const Ptr &self, const QQmlJS::ContextualTypes &contextualTypes,
410 QSet<QString> *usedTypes = nullptr);
411 static void resolveNonEnumTypes(
412 const QQmlJSScope::Ptr &self, const QQmlJS::ContextualTypes &contextualTypes,
413 QSet<QString> *usedTypes = nullptr);
414 static void resolveEnums(
415 const QQmlJSScope::Ptr &self, const QQmlJS::ContextualTypes &contextualTypes,
416 QSet<QString> *usedTypes = nullptr);
417 static void resolveList(
418 const QQmlJSScope::Ptr &self, const QQmlJSScope::ConstPtr &arrayType);
419 static void resolveGroup(
420 const QQmlJSScope::Ptr &self, const QQmlJSScope::ConstPtr &baseType,
421 const QQmlJS::ContextualTypes &contextualTypes,
422 QSet<QString> *usedTypes = nullptr);
423
424 void setSourceLocation(const QQmlJS::SourceLocation &sourceLocation);
425 QQmlJS::SourceLocation sourceLocation() const;
426
427 void setIdSourceLocation(const QQmlJS::SourceLocation &sourceLocation);
428 QQmlJS::SourceLocation idSourceLocation() const;
429
430 static QQmlJSScope::ConstPtr nonCompositeBaseType(const QQmlJSScope::ConstPtr &type);
431
432 static QTypeRevision
433 nonCompositeBaseRevision(const ImportedScope<QQmlJSScope::ConstPtr> &scope);
434
435 bool isSameType(const QQmlJSScope::ConstPtr &otherScope) const;
436 bool inherits(const QQmlJSScope::ConstPtr &base) const;
437 bool canAssign(const QQmlJSScope::ConstPtr &derived) const;
438
439 bool isInCustomParserParent() const;
440
441
442 static ImportedScope<QQmlJSScope::ConstPtr> findType(const QString &name,
443 const QQmlJS::ContextualTypes &contextualTypes,
444 QSet<QString> *usedTypes = nullptr);
445
446 static QQmlSA::Element createQQmlSAElement(const ConstPtr &);
447 static QQmlSA::Element createQQmlSAElement(ConstPtr &&);
448 static const QQmlJSScope::ConstPtr &scope(const QQmlSA::Element &);
449 static constexpr qsizetype sizeofQQmlSAElement() { return QQmlSA::Element::sizeofElement; }
450
451private:
452 // the way to construct a QQmlJSScope is via create
453 explicit QQmlJSScope(const QString &internalName);
454 QQmlJSScope(QQmlJSScope &&) = default;
455 QQmlJSScope &operator=(QQmlJSScope &&) = default;
456 /*! \internal
457
458 Minimal information about a QQmlJSMetaPropertyBinding that allows it to
459 be manipulated similarly to QmlIR::Binding.
460 */
461 template <typename T>
462 friend class QTypeInfo; // so that we can Q_DECLARE_TYPEINFO QmlIRCompatibilityBindingData
463 struct QmlIRCompatibilityBindingData
464 {
465 QmlIRCompatibilityBindingData() = default;
466 QmlIRCompatibilityBindingData(const QString &name, quint32 offset)
467 : propertyName(name), sourceLocationOffset(offset)
468 {
469 }
470 QString propertyName; // bound property name
471 quint32 sourceLocationOffset = 0; // binding's source location offset
472 };
473
474 QQmlJSScope() = default;
475 QQmlJSScope(const QQmlJSScope &) = default;
476 QQmlJSScope &operator=(const QQmlJSScope &) = default;
477 static QTypeRevision resolveType(
478 const QQmlJSScope::Ptr &self, const QQmlJS::ContextualTypes &contextualTypes,
479 QSet<QString> *usedTypes);
480 static void updateChildScope(
481 const QQmlJSScope::Ptr &childScope, const QQmlJSScope::Ptr &self,
482 const QQmlJS::ContextualTypes &contextualTypes, QSet<QString> *usedTypes);
483
484 void addOwnPropertyBindingInQmlIROrder(const QQmlJSMetaPropertyBinding &binding,
485 BindingTargetSpecifier specifier);
486 bool hasEnforcesScopedEnumsFlag() const { return m_flags & EnforcesScopedEnums; }
487 bool hasCreatableFlag() const { return m_flags & Creatable; }
488 bool hasStructuredFlag() const { return m_flags & Structured; }
489
490 QHash<QString, JavaScriptIdentifier> m_jsIdentifiers;
491
492 QMultiHash<QString, QQmlJSMetaMethod> m_methods;
493 QHash<QString, QQmlJSMetaProperty> m_properties;
494 QMultiHash<QString, QQmlJSMetaPropertyBinding> m_propertyBindings;
495
496 // a special QmlIR compatibility bindings array, ordered the same way as
497 // bindings in QmlIR::Object
498 QList<QmlIRCompatibilityBindingData> m_propertyBindingsArray;
499
500 // same as QmlIR::Object::runtimeFunctionIndices
501 QList<QQmlJSMetaMethod::AbsoluteFunctionIndex> m_runtimeFunctionIndices;
502
503 QHash<QString, QQmlJSMetaEnum> m_enumerations;
504
505 QList<QQmlJSAnnotation> m_annotations;
506 QList<QQmlJSScope::Ptr> m_childScopes;
507 QQmlJSScope::WeakPtr m_parentScope;
508
509 QString m_filePath;
510 QString m_internalName;
511 QString m_baseTypeNameOrError;
512
513 // We only need the revision for the base type as inheritance is
514 // the only relation between two types where the revisions matter.
515 ImportedScope<QQmlJSScope::WeakConstPtr> m_baseType;
516
517 ScopeType m_scopeType = ScopeType::QMLScope;
518 QStringList m_aliases;
519 QStringList m_interfaceNames;
520 QStringList m_ownDeferredNames;
521 QStringList m_ownImmediateNames;
522
523 QString m_defaultPropertyName;
524 QString m_parentPropertyName;
525 /*! \internal
526 * The attached type name.
527 * This is an internal name, from a c++ type or a synthetic jsrootgen.
528 */
529 QString m_attachedTypeName;
530 QStringList m_requiredPropertyNames;
531 QQmlJSScope::WeakConstPtr m_attachedType;
532
533 /*! \internal
534 * The type name of the list element in case this is a sequence type.
535 * This is an internal name, from a c++ type or a synthetic jsrootgen.
536 */
537 QString m_elementTypeName;
538 QQmlJSScope::WeakConstPtr m_elementType;
539 QQmlJSScope::Ptr m_listType;
540
541 /*!
542 The extension is provided as either a type (QML_{NAMESPACE_}EXTENDED) or as a
543 namespace (QML_EXTENDED_NAMESPACE).
544 The bool HasExtensionNamespace helps differentiating both cases, as namespaces
545 have a more limited lookup capaility.
546 This is an internal name, from a c++ type or a synthetic jsrootgen.
547 */
548 QString m_extensionTypeName;
549 QQmlJSScope::WeakConstPtr m_extensionType;
550
551 Flags m_flags = Creatable; // all types are marked as creatable by default.
552 AccessSemantics m_semantics = AccessSemantics::Reference;
553
554 QQmlJS::SourceLocation m_sourceLocation;
555 QQmlJS::SourceLocation m_idSourceLocation;
556
557 QString m_moduleName;
558
559 std::optional<QString> m_inlineComponentName;
560};
561
562inline QQmlJSScope::Ptr QQmlJSScope::parentScope()
563{
564 return m_parentScope.toStrongRef();
565}
566
567inline QQmlJSScope::ConstPtr QQmlJSScope::parentScope() const
568{
569 QT_WARNING_PUSH
570#if defined(Q_CC_GNU_ONLY) && Q_CC_GNU < 1400 && Q_CC_GNU >= 1200
571 QT_WARNING_DISABLE_GCC("-Wuse-after-free")
572#endif
573 return QQmlJSScope::WeakConstPtr(m_parentScope).toStrongRef();
574 QT_WARNING_POP
575}
576
577inline QMultiHash<QString, QQmlJSMetaPropertyBinding> QQmlJSScope::ownPropertyBindings() const
578{
579 return m_propertyBindings;
580}
581
582inline std::pair<QMultiHash<QString, QQmlJSMetaPropertyBinding>::const_iterator, QMultiHash<QString, QQmlJSMetaPropertyBinding>::const_iterator> QQmlJSScope::ownPropertyBindings(const QString &name) const
583{
584 return m_propertyBindings.equal_range(name);
585}
586
587inline bool QQmlJSScope::hasOwnPropertyBindings(const QString &name) const
588{
589 return m_propertyBindings.contains(name);
590}
591
592inline QQmlJSMetaMethod::AbsoluteFunctionIndex QQmlJSScope::ownRuntimeFunctionIndex(QQmlJSMetaMethod::RelativeFunctionIndex index) const
593{
594 const int i = static_cast<int>(index);
595 Q_ASSERT(i >= 0);
596 Q_ASSERT(i < int(m_runtimeFunctionIndices.size()));
597 return m_runtimeFunctionIndices[i];
598}
599
600inline void QQmlJSScope::setInlineComponentName(const QString &inlineComponentName)
601{
602 Q_ASSERT(isInlineComponent());
603 m_inlineComponentName = inlineComponentName;
604}
605
606inline QList<QQmlJSScope::Ptr> QQmlJSScope::childScopes()
607{
608 return m_childScopes;
609}
610
611inline void QQmlJSScope::setSourceLocation(const QQmlJS::SourceLocation &sourceLocation)
612{
613 m_sourceLocation = sourceLocation;
614}
615
616inline QQmlJS::SourceLocation QQmlJSScope::sourceLocation() const
617{
618 return m_sourceLocation;
619}
620
621inline void QQmlJSScope::setIdSourceLocation(const QQmlJS::SourceLocation &sourceLocation)
622{
623 Q_ASSERT(m_scopeType == QQmlSA::ScopeType::QMLScope);
624 m_idSourceLocation = sourceLocation;
625}
626
627inline QQmlJS::SourceLocation QQmlJSScope::idSourceLocation() const
628{
629 Q_ASSERT(m_scopeType == QQmlSA::ScopeType::QMLScope);
630 return m_idSourceLocation;
631}
632
633inline QQmlJSScope::ConstPtr QQmlJSScope::nonCompositeBaseType(const ConstPtr &type)
634{
635 for (QQmlJSScope::ConstPtr base = type; base; base = base->baseType()) {
636 if (!base->isComposite())
637 return base;
638 }
639 return {};
640}
641
643
644template<>
645class Q_QMLCOMPILER_EXPORT QDeferredFactory<QQmlJSScope>
646{
647public:
648 using TypeReader = std::function<QList<QQmlJS::DiagnosticMessage>(
649 QQmlJSImporter *importer, const QString &filePath,
650 const QSharedPointer<QQmlJSScope> &scopeToPopulate)>;
651 QDeferredFactory() = default;
652
653 QDeferredFactory(QQmlJSImporter *importer, const TypeReader &typeReader,
654 const QString &filePath, const QString &moduleName, bool isSingleton);
655
656 bool isValid() const
657 {
658 return !m_filePath.isEmpty() && m_importer != nullptr;
659 }
660
661 QString internalName() const
662 {
663 return QFileInfo(m_filePath).baseName();
664 }
665
666 QString filePath() const { return m_filePath; }
667
668 QQmlJSImporter* importer() const { return m_importer; }
669 QString moduleName() const { return m_moduleName; }
670 bool isSingleton() const { return m_isSingleton; }
671
672 void setIsSingleton(bool isSingleton)
673 {
674 m_isSingleton = isSingleton;
675 }
676
677 void setModuleName(const QString &moduleName) { m_moduleName = moduleName; }
678
679private:
680 friend class QDeferredSharedPointer<QQmlJSScope>;
681 friend class QDeferredSharedPointer<const QQmlJSScope>;
682 friend class QDeferredWeakPointer<QQmlJSScope>;
683 friend class QDeferredWeakPointer<const QQmlJSScope>;
684
685 // Should only be called when lazy-loading the type in a deferred pointer.
686 void populate(const QSharedPointer<QQmlJSScope> &scope) const;
687
688 QQmlJSImporter *m_importer = nullptr;
689 TypeReader m_typeReader;
690 QString m_filePath;
691 QString m_moduleName;
692 bool m_isSingleton = false;
693};
694
695using QQmlJSExportedScope = QQmlJSScope::ExportedScope<QQmlJSScope::Ptr>;
696using QQmlJSImportedScope = QQmlJSScope::ImportedScope<QQmlJSScope::ConstPtr>;
697
698namespace QQmlSA {
699constexpr inline bool isFunctionScope(ScopeType type)
700{
701 switch (type) {
705 return true;
706 default:
707 return false;
708 }
709}
710
711}
712
713template <typename T>
714static void resetFactory(QDeferredSharedPointer<T> &pointer,
715 QQmlJSImporter *importer,
716 const typename QDeferredFactory<std::remove_const_t<T>>::TypeReader &typeReader,
717 const QString &filePath)
718{
719 const auto &factory = pointer.factory();
720 QDeferredFactory<std::remove_const_t<T>> newFactory(importer,
721 typeReader, filePath,
722 factory ? factory->moduleName() : QString(),
723 factory ? factory->isSingleton() : false);
724 return resetFactoryImpl(pointer, std::move(newFactory));
725}
726
727template<typename T, typename U>
728void resetFactoryImpl(QDeferredSharedPointer<T> &pointer, U&& factory)
729{
730 pointer.m_data.reset();
731 *pointer.m_factory = std::forward<U>(factory);
732}
733
734
735QT_END_NAMESPACE
736
737#endif // QQMLJSSCOPE_P_H
friend bool operator==(const QByteArray::FromBase64Result &lhs, const QByteArray::FromBase64Result &rhs) noexcept
Returns true if lhs and rhs are equal, otherwise returns false.
Definition qbytearray.h:803
friend bool operator!=(const QByteArray::FromBase64Result &lhs, const QByteArray::FromBase64Result &rhs) noexcept
Returns true if lhs and rhs are different, otherwise returns false.
Definition qbytearray.h:814
QString fileName() const
If the currently assigned device is a QFile, or if setFileName() has been called, this function retur...
void setFileName(const QString &fileName)
Sets the file name of QImageReader to fileName.
virtual Type type() const =0
Reimplement this function to return the paint engine \l{Type}.
virtual bool isValid() const
virtual QString location() const
QString typeName() const
void setIsFlag(bool isFlag)
void setLineNumber(int lineNumber)
friend bool operator!=(const QQmlJSMetaEnum &a, const QQmlJSMetaEnum &b)
void setName(const QString &name)
QQmlJSMetaEnum()=default
int lineNumber() const
friend size_t qHash(const QQmlJSMetaEnum &e, size_t seed=0)
friend bool operator==(const QQmlJSMetaEnum &a, const QQmlJSMetaEnum &b)
void setTypeName(const QString &typeName)
bool hasKey(const QString &key) const
void setIsScoped(bool v)
void setType(const QSharedPointer< const QQmlJSScope > &type)
QSharedPointer< const QQmlJSScope > type() const
int value(const QString &key) const
bool isQml() const
void setIsQml(bool v)
void addValue(int value)
bool isScoped() const
QList< int > values() const
bool isFlag() const
QString alias() const
QStringList keys() const
bool isValid() const
void addKey(const QString &key)
void setAlias(const QString &alias)
QString name() const
QQmlJSMetaEnum(QString name)
bool hasValues() const
QQmlJSMetaReturnType returnValue() const
QQmlJSMetaMethod()=default
void setReturnType(QWeakPointer< const QQmlJSScope > type)
void setSourceLocation(QQmlJS::SourceLocation location)
QQmlJS::SourceLocation sourceLocation() const
QString methodName() const
QQmlJSMetaMethodType MethodType
void setMethodName(const QString &name)
void setReturnTypeName(const QString &typeName)
QString returnTypeName() const
QQmlJSMetaMethod(QString name, QString returnType=QString())
QList< QQmlJSMetaParameter > parameters() const
void setReturnValue(const QQmlJSMetaReturnType returnValue)
QSharedPointer< const QQmlJSScope > returnType() const
void setIsPointer(bool isPointer)
void setType(QWeakPointer< const QQmlJSScope > type)
void setIsList(bool isList)
friend bool operator!=(const QQmlJSMetaParameter &a, const QQmlJSMetaParameter &b)
friend size_t qHash(const QQmlJSMetaParameter &e, size_t seed=0)
void setName(const QString &name)
void setTypeName(const QString &typeName)
void setTypeQualifier(Constness typeQualifier)
Constness typeQualifier() const
QString typeName() const
QQmlJSMetaParameter(QString name=QString(), QString typeName=QString(), Constness typeQualifier=NonConst, QWeakPointer< const QQmlJSScope > type={})
friend bool operator==(const QQmlJSMetaParameter &a, const QQmlJSMetaParameter &b)
QSharedPointer< const QQmlJSScope > type() const
\inmodule QtQmlCompiler
friend bool operator!=(const QQmlJSMetaProperty &a, const QQmlJSMetaProperty &b)
QString notify() const
QSharedPointer< const QQmlJSScope > aliasTargetScope() const
QString aliasExpression() const
friend bool operator==(const QQmlJSMetaProperty &a, const QQmlJSMetaProperty &b)
void setIsOverride(bool isOverride)
void setPropertyName(const QString &propertyName)
QString aliasTargetName() const
void setAnnotations(const QList< QQmlJSAnnotation > &annotation)
void setIsList(bool isList)
QString bindable() const
QSharedPointer< const QQmlJSScope > type() const
void setPrivateClass(const QString &privateClass)
void setRead(const QString &read)
friend size_t qHash(const QQmlJSMetaProperty &prop, size_t seed=0)
void setBindable(const QString &bindable)
void setWrite(const QString &write)
void setIsPropertyConstant(bool isPropertyConstant)
QString reset() const
void setRevision(int revision)
void setIsFinal(bool isFinal)
QString typeName() const
void setAliasTargetScope(const QSharedPointer< const QQmlJSScope > &scope)
void setSourceLocation(const QQmlJS::SourceLocation &newSourceLocation)
QString write() const
void setIsTypeConstant(bool isTypeConstant)
const QList< QQmlJSAnnotation > & annotations() const
QQmlJS::SourceLocation sourceLocation() const
void setTypeName(const QString &typeName)
QQmlJSMetaProperty()=default
void setReset(const QString &reset)
QString privateClass() const
void setIsVirtual(bool isVirtual)
void setIsWritable(bool isWritable)
void setAliasExpression(const QString &aliasString)
void setAliasTargetName(const QString &name)
void setIndex(int index)
void setNotify(const QString &notify)
bool isPropertyConstant() const
bool isTypeConstant() const
void setType(const QSharedPointer< const QQmlJSScope > &type)
QString propertyName() const
void setIsPointer(bool isPointer)
QQmlJSRegisterContent createMethod(const QList< QQmlJSMetaMethod > &methods, const QQmlJSScope::ConstPtr &methodType, ContentVariant variant, QQmlJSRegisterContent scope)
QQmlJSRegisterContent createImportNamespace(uint importNamespaceStringId, const QQmlJSScope::ConstPtr &importNamespaceType, ContentVariant variant, QQmlJSRegisterContent scope)
QQmlJSRegisterContent createProperty(const QQmlJSMetaProperty &property, int baseLookupIndex, int resultLookupIndex, ContentVariant variant, QQmlJSRegisterContent scope)
void adjustType(QQmlJSRegisterContent content, const QQmlJSScope::ConstPtr &adjusted)
void generalizeType(QQmlJSRegisterContent content, const QQmlJSScope::ConstPtr &generalized)
void storeType(QQmlJSRegisterContent content, const QQmlJSScope::ConstPtr &stored)
QQmlJSRegisterContent castTo(QQmlJSRegisterContent content, const QQmlJSScope::ConstPtr &newContainedType)
QQmlJSRegisterContent createEnumeration(const QQmlJSMetaEnum &enumeration, const QString &enumMember, ContentVariant variant, QQmlJSRegisterContent scope)
void setAllocationMode(AllocationMode mode)
QQmlJSRegisterContent storedIn(QQmlJSRegisterContent content, const QQmlJSScope::ConstPtr &newStoredType)
QQmlJSRegisterContent clone(QQmlJSRegisterContent from)
QQmlJSRegisterContent createType(const QQmlJSScope::ConstPtr &type, int resultLookupIndex, ContentVariant variant, QQmlJSRegisterContent scope={})
QQmlJSRegisterContent createConversion(const QList< QQmlJSRegisterContent > &origins, const QQmlJSScope::ConstPtr &conversion, QQmlJSRegisterContent conversionScope, ContentVariant variant, QQmlJSRegisterContent scope)
QQmlJSRegisterContent createMethodCall(const QQmlJSMetaMethod &method, const QQmlJSScope::ConstPtr &returnType, QQmlJSRegisterContent scope)
Tracks the types for the QmlCompiler.
QTypeRevision revision() const
QString type() const
QTypeRevision version() const
bool isValid() const
QString package() const
Export()=default
Export(QString package, QString type, QTypeRevision version, QTypeRevision revision)
virtual QQmlSourceLocation sourceLocation() const
\inmodule QtQmlCompiler
Definition qqmlsa.h:53
Element attachedType() const
Returns the attached type if the content type of this binding is AttachedProperty,...
Definition qqmlsa.cpp:384
BindingType bindingType() const
Returns the type of this binding.
Definition qqmlsa.cpp:350
Element bindingScope() const
Returns the Element scope in which the binding is defined.
Definition qqmlsa.cpp:342
friend bool operator!=(const Binding &lhs, const Binding &rhs)
Returns true if lhs and rhs are not equal, and false otherwise.
Definition qqmlsa.h:107
bool hasUndefinedScriptValue() const
Returns whether this binding has script value type undefined like when it is assigned undefined.
Definition qqmlsa.cpp:451
Binding(const Binding &)
Creates a copy of other.
Definition qqmlsa.cpp:254
Binding & operator=(const Binding &)
Assigns other to this Binding instance.
Definition qqmlsa.cpp:266
bool isAttached() const
Returns true if this type is attached to another one, false otherwise.
Definition qqmlsa.cpp:375
bool hasObject() const
Returns true if this binding has an objects, otherwise returns false.
Definition qqmlsa.cpp:432
friend bool operator==(const Binding &lhs, const Binding &rhs)
Returns true if lhs and rhs are equal, and false otherwise.
Definition qqmlsa.h:103
static bool isLiteralBinding(BindingType)
Returns true if bindingType is a literal type, and false otherwise.
Definition qqmlsa.cpp:475
QString propertyName() const
Returns the name of the property bound with this binding.
Definition qqmlsa.cpp:367
Binding()
Constructs a new Binding object.
Definition qqmlsa.cpp:247
QString stringValue() const
Returns the associated string literal if the content type of this binding is StringLiteral,...
Definition qqmlsa.cpp:359
Element objectType() const
Returns the type of the associated object if the content type of this binding is Object,...
Definition qqmlsa.cpp:441
Binding & operator=(Binding &&) noexcept
Move-assigns other to this Binding instance.
Definition qqmlsa.cpp:282
QQmlSA::SourceLocation sourceLocation() const
Returns the location in the QML code where this binding is defined.
Definition qqmlsa.cpp:405
ScriptBindingKind scriptKind() const
Returns the kind of the associated script if the content type of this binding is Script,...
Definition qqmlsa.cpp:424
double numberValue() const
Returns the associated number if the content type of this binding is NumberLiteral,...
Definition qqmlsa.cpp:415
Element groupType() const
Returns the type of the property of this binding if it is a group property, otherwise returns an inva...
Definition qqmlsa.cpp:334
bool hasFunctionScriptValue() const
Returns whether this binding has script value type function like when it is assigned a (lambda) metho...
Definition qqmlsa.cpp:464
\inmodule QtQmlCompiler
Definition qqmlsa.h:378
QString replacement() const
Returns the replacement string of the edit.
Definition qqmlsa.cpp:2123
QString filename() const
Returns the file this edit applies to.
Definition qqmlsa.cpp:2105
DocumentEdit(const DocumentEdit &)
Creates a copy of other.
Definition qqmlsa.cpp:2058
\inmodule QtQmlCompiler
Definition qqmlsa.h:369
\inmodule QtQmlCompiler
Definition qqmlsa.h:203
\inmodule QtQmlCompiler
Definition qqmlsa.h:406
FixSuggestion(const QString &description, const QQmlSA::SourceLocation &location, const QList< DocumentEdit > &documentEdits={})
Creates a FixSuggestion object.
Definition qqmlsa.cpp:2214
void addDocumentEdit(const DocumentEdit &)
Adds a document edit to the list of edits for this fix.
Definition qqmlsa.cpp:2286
FixSuggestion(const FixSuggestion &)
Creates a copy of other.
Definition qqmlsa.cpp:2223
QString description() const
Returns the description of the fix.
Definition qqmlsa.cpp:2268
bool isAutoApplicable() const
Returns whether this suggested fix can be applied automatically.
Definition qqmlsa.cpp:2330
void setAutoApplicable(bool autoApplicable=true)
Sets autoApplicable to determine whether this suggested fix can be applied automatically.
Definition qqmlsa.cpp:2321
QList< DocumentEdit > documentEdits() const
Returns the list of document edits that applying this fix would make.
Definition qqmlsa.cpp:2295
\inmodule QtQmlCompiler
Definition qqmlsa.h:284
void emitWarning(QAnyStringView diagnostic, LoggerWarningId id)
Emits a warning message diagnostic about an issue of type id.
Definition qqmlsa.cpp:1269
Element resolveLiteralType(const Binding &binding)
Returns the element representing the type of literal in binding.
Definition qqmlsa.cpp:1382
void emitWarning(QAnyStringView diagnostic, LoggerWarningId id, QQmlSA::SourceLocation srcLocation, const QQmlSA::FixSuggestion &fix)
Emits a warning message diagnostic about an issue of type id located at srcLocation and with suggeste...
Definition qqmlsa.cpp:1292
void emitWarning(QAnyStringView diagnostic, LoggerWarningId id, QQmlSA::SourceLocation srcLocation)
Emits warning message diagnostic about an issue of type id located at srcLocation.
Definition qqmlsa.cpp:1278
Element resolveBuiltinType(QAnyStringView typeName) const
Returns the type of the built-in type identified by typeName.
Definition qqmlsa.cpp:1354
Element resolveAttached(QAnyStringView moduleName, QAnyStringView typeName)
Returns the attached type of typeName defined in module moduleName.
Definition qqmlsa.cpp:1372
QString resolveElementToId(const Element &element, const Element &context)
Returns the id of element in a given context.
Definition qqmlsa.cpp:1405
Element resolveTypeInFileScope(QAnyStringView typeName)
Returns the type corresponding to typeName inside the currently analysed file.
Definition qqmlsa.cpp:1307
QString sourceCode(QQmlSA::SourceLocation location)
Returns the source code located within location.
Definition qqmlsa.cpp:1417
Element resolveAttachedInFileScope(QAnyStringView typeName)
Returns the attached type corresponding to typeName used inside the currently analysed file.
Definition qqmlsa.cpp:1319
Element resolveIdToElement(QAnyStringView id, const Element &context)
Returns the element in context that has id id.
Definition qqmlsa.cpp:1393
Element resolveType(QAnyStringView moduleName, QAnyStringView typeName)
Returns the type of typeName defined in module moduleName.
Definition qqmlsa.cpp:1337
\inmodule QtQmlCompiler
Definition qqmlsa.h:341
\inmodule QtQmlCompiler
Definition qqmlsa.h:121
Method & operator=(Method &&) noexcept
Move-assigns other to this Method instance.
Definition qqmlsa.cpp:624
MethodType methodType() const
Returns the type of this method.
Definition qqmlsa.cpp:651
Method(const Method &)
Creates a copy of other.
Definition qqmlsa.cpp:598
Method()
Constructs a new Method object.
Definition qqmlsa.cpp:593
Method & operator=(const Method &)
Assigns other to this Method instance.
Definition qqmlsa.cpp:611
QString methodName() const
Returns the name of the this method.
Definition qqmlsa.cpp:642
\inmodule QtQmlCompiler
Definition qqmlsa.h:315
void analyze(const Element &root)
Runs the element passes over root and all its children.
Definition qqmlsa.cpp:1607
bool isCategoryEnabled(LoggerWarningId category) const
Returns true if warnings of category are enabled, false otherwise.
Definition qqmlsa.cpp:1718
bool registerPropertyPass(std::shared_ptr< PropertyPass > pass, QAnyStringView moduleName, QAnyStringView typeName, QAnyStringView propertyName=QAnyStringView(), bool allowInheritance=true)
Registers a static analysis pass for properties.
Definition qqmlsa.cpp:1509
std::unordered_map< quint32, Binding > bindingsByLocation() const
Returns bindings by their source location.
Definition qqmlsa.cpp:1948
bool hasImportedModule(QAnyStringView name) const
Returns true if the module named module has been imported by the QML to be analyzed,...
Definition qqmlsa.cpp:1710
\inmodule QtQmlCompiler
Definition qqmlsa.h:352
\inmodule QtQmlCompiler
Definition qqmlsa.h:170
Property(const Property &)
Creates a copy of other.
Definition qqmlsa.cpp:779
QString typeName() const
Returns the name of the type of this property.
Definition qqmlsa.cpp:824
bool isReadonly() const
Returns true if this property is read-only, false otherwise.
Definition qqmlsa.cpp:842
\inmodule QtQmlCompiler
MethodType
Definition qqmlsa.h:49
constexpr bool isFunctionScope(ScopeType type)
AccessSemantics
Definition qqmlsa.h:50
Combined button and popup list for selecting options.
Q_DECLARE_TYPEINFO(QDateTime::Data, Q_RELOCATABLE_TYPE)
Q_DECLARE_INTERFACE(QNetworkAccessBackendFactory, QNetworkAccessBackendFactory_iid)
static QString toNumericString(double value)
static QString messageTypeForMethod(const QString &method)
static QString derefContentPointer(const QString &contentPointer)
static bool canTypeBeAffectedBySideEffects(const QQmlJSTypeResolver *typeResolver, const QQmlJSRegisterContent &baseType)
#define BYTECODE_UNIMPLEMENTED()
#define INJECT_TRACE_INFO(function)
#define REJECT
static QString registerName(int registerIndex, int offset)
static QString minExpression(int argc)
static QString maxExpression(int argc)
static bool isTypeStorable(const QQmlJSTypeResolver *resolver, const QQmlJSScope::ConstPtr &type)
QQmlSA::MethodType QQmlJSMetaMethodType
QQmlJSMetaParameter QQmlJSMetaReturnType
ScriptBindingValueType
@ ScriptValue_Function
@ ScriptValue_Unknown
@ ScriptValue_Undefined
static void resetFactory(QDeferredSharedPointer< T > &pointer, QQmlJSImporter *importer, const typename QDeferredFactory< std::remove_const_t< T > >::TypeReader &typeReader, const QString &filePath)
void resetFactoryImpl(QDeferredSharedPointer< T > &pointer, U &&factory)
#define QmlLintPluginInterface_iid
Definition qqmlsa.h:450
QList< Export > exports
QTypeRevision revision