Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qqmljsscope.cpp
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
5#include "qqmljsscope_p.h"
7#include "qqmljsimporter_p.h"
8#include "qqmljsutils_p.h"
9#include "qqmlsa.h"
10#include "qqmlsa_p.h"
11
12#include <QtCore/qqueue.h>
13#include <QtCore/qsharedpointer.h>
14
15#include <private/qduplicatetracker_p.h>
16
17#include <algorithm>
18#include <type_traits>
19
21
34using namespace Qt::StringLiterals;
35
37{
38 m_internalName = internalName;
39}
40
42{
43 return QSharedPointer<QQmlJSScope>(new QQmlJSScope(internalName));
44}
45
46void QQmlJSScope::reparent(const QQmlJSScope::Ptr &parentScope, const QQmlJSScope::Ptr &childScope)
47{
48 if (const QQmlJSScope::Ptr parent = childScope->m_parentScope.toStrongRef())
49 parent->m_childScopes.removeOne(childScope);
50 if (parentScope)
51 parentScope->m_childScopes.append(childScope);
52 childScope->m_parentScope = parentScope;
53}
54
56{
57 if (origin.isNull())
58 return QQmlJSScope::Ptr();
59 QQmlJSScope::Ptr cloned = create();
60 *cloned = *origin;
61 if (QQmlJSScope::Ptr parent = cloned->parentScope())
62 parent->m_childScopes.append(cloned);
63 return cloned;
64}
65
70QHash<QString, QQmlJSScope::JavaScriptIdentifier> QQmlJSScope::ownJSIdentifiers() const
71{
72 return m_jsIdentifiers;
73}
74
76{
80 || m_scopeType == QQmlSA::ScopeType::JSFunctionScope) {
81 m_jsIdentifiers.insert(name, identifier);
82 } else {
83 auto targetScope = parentScope();
84 while (targetScope->m_scopeType != QQmlSA::ScopeType::JSFunctionScope)
85 targetScope = targetScope->parentScope();
86 targetScope->m_jsIdentifiers.insert(name, identifier);
87 }
88}
89
91{
95 method.setMethodType(QQmlJSMetaMethodType::Signal);
96 method.setIsImplicitQmlPropertyChangeSignal(true);
98}
99
101{
105 return false;
106 return scope->m_methods.contains(name);
107 });
108}
109
119QHash<QString, QQmlJSMetaMethod> QQmlJSScope::methods() const
120{
121 QHash<QString, QQmlJSMetaMethod> results;
125 return false;
126 for (auto it = scope->m_methods.constBegin(); it != scope->m_methods.constEnd();
127 it++) {
128 if (!results.contains(it.key()))
129 results.insert(it.key(), it.value());
130 }
131 return false;
132 });
133
134 return results;
135}
136
137QList<QQmlJSMetaMethod> QQmlJSScope::methods(const QString &name) const
138{
139 QList<QQmlJSMetaMethod> results;
140
144 return false;
145 results.append(scope->ownMethods(name));
146 return false;
147 });
148 return results;
149}
150
151QList<QQmlJSMetaMethod> QQmlJSScope::methods(const QString &name, QQmlJSMetaMethodType type) const
152{
153 QList<QQmlJSMetaMethod> results;
154
158 return false;
159 const auto ownMethods = scope->ownMethods(name);
160 for (const auto &method : ownMethods) {
161 if (method.methodType() == type)
163 }
164 return false;
165 });
166 return results;
167}
168
170{
172 this, [&](const QQmlJSScope *scope) { return scope->m_enumerations.contains(name); });
173}
174
176{
177 for (const auto &e : m_enumerations) {
178 if (e.keys().contains(name))
179 return true;
180 }
181 return false;
182}
183
185{
187 this, [&](const QQmlJSScope *scope) { return scope->hasOwnEnumerationKey(name); });
188}
189
191{
193
195 const auto it = scope->m_enumerations.find(name);
196 if (it == scope->m_enumerations.end())
197 return false;
198 result = *it;
199 return true;
200 });
201
202 return result;
203}
204
205QHash<QString, QQmlJSMetaEnum> QQmlJSScope::enumerations() const
206{
207 QHash<QString, QQmlJSMetaEnum> results;
208
210 for (auto it = scope->m_enumerations.constBegin(); it != scope->m_enumerations.constEnd();
211 it++) {
212 if (!results.contains(it.key()))
213 results.insert(it.key(), it.value());
214 }
215 return false;
216 });
217
218 return results;
219}
220
222{
223 using namespace Qt::StringLiterals;
224
225 switch (m_semantics) {
226 case AccessSemantics::Reference:
227 return m_internalName + " *"_L1;
228 case AccessSemantics::Value:
229 case AccessSemantics::Sequence:
230 break;
231 case AccessSemantics::None:
232 // If we got a namespace, it might still be a regular type, exposed as namespace.
233 // We may need to travel the inheritance chain all the way up to QObject to
234 // figure this out, since all other types may be exposed the same way.
235 for (QQmlJSScope::ConstPtr base = baseType(); base; base = base->baseType()) {
236 switch (base->accessSemantics()) {
237 case AccessSemantics::Reference:
238 return m_internalName + " *"_L1;
239 case AccessSemantics::Value:
240 case AccessSemantics::Sequence:
241 return m_internalName;
242 case AccessSemantics::None:
243 break;
244 }
245 }
246 break;
247 }
248 return m_internalName;
249}
250
252{
253 const auto internal = "$internal$."_L1;
254 const QString anonymous = "$anonymous$."_L1;
255
256 QString pretty = name.toString();
257
258 if (pretty.startsWith(internal))
259 pretty = pretty.mid(internal.size());
260 else if (pretty.startsWith(anonymous))
261 pretty = pretty.mid(anonymous.size());
262
263 if (pretty == u"std::nullptr_t")
264 return u"null"_s;
265
266 if (pretty == u"void")
267 return u"undefined"_s;
268
269 return pretty;
270}
271
283 if (m_flags.testFlag(WrappedInImplicitComponent))
284 return true;
285
286 auto base = nonCompositeBaseType(parentScope()); // handles null parentScope()
287 if (!base)
288 return false;
289 return base->internalName() == u"QQmlComponent";
290}
291
292std::optional<QQmlJSScope::JavaScriptIdentifier>
294{
295 for (const auto *scope = this; scope; scope = scope->parentScope().data()) {
296 if (scope->m_scopeType == QQmlSA::ScopeType::JSFunctionScope
297 || scope->m_scopeType == QQmlSA::ScopeType::JSLexicalScope) {
298 auto it = scope->m_jsIdentifiers.find(id);
299 if (it != scope->m_jsIdentifiers.end())
300 return *it;
301 }
302 }
303
304 return std::optional<JavaScriptIdentifier>{};
305}
306
307std::optional<QQmlJSScope::JavaScriptIdentifier> QQmlJSScope::ownJSIdentifier(const QString &id) const
308{
309 auto it = m_jsIdentifiers.find(id);
310 if (it != m_jsIdentifiers.end())
311 return *it;
312
313 return std::optional<JavaScriptIdentifier>{};
314}
315
318{
319 const int separatorIndex = typeName.lastIndexOf(u'.');
320 // do not crash in typeName.sliced() when it starts or ends with an '.'.
321 if (separatorIndex < 1 || separatorIndex >= typeName.size() - 1)
322 return {};
323
324 const auto parentIt = contextualTypes.types().constFind(typeName.first(separatorIndex).toString());
325 if (parentIt == contextualTypes.types().constEnd())
326 return {};
327
328 auto inlineComponentParent = *parentIt;
329
330 // find the inline components using BFS, as inline components defined in childrens are also
331 // accessible from other qml documents. Same for inline components defined in a base class of
332 // the parent. Use BFS over DFS as the inline components are probably not deeply-nested.
333
334 QStringView inlineComponentName = typeName.sliced(separatorIndex + 1);
335 QQueue<QQmlJSScope::ConstPtr> candidatesForInlineComponents;
336 candidatesForInlineComponents.enqueue(inlineComponentParent.scope);
337 while (candidatesForInlineComponents.size()) {
338 QQmlJSScope::ConstPtr current = candidatesForInlineComponents.dequeue();
339 if (!current) // if some type was not resolved, ignore it instead of crashing
340 continue;
341 if (current->isInlineComponent() && current->inlineComponentName() == inlineComponentName) {
342 return { current, inlineComponentParent.revision };
343 }
344 // check alternatively the inline components at layer 1 in current and basetype, then at
345 // layer 2, etc...
346 candidatesForInlineComponents.append(current->childScopes());
347 if (const auto base = current->baseType())
348 candidatesForInlineComponents.enqueue(base);
349 }
350 return {};
351}
352
362 const QString &name, const QQmlJS::ContextualTypes &contextualTypes,
363 QSet<QString> *usedTypes)
364{
365 const auto useType = [&]() {
366 if (usedTypes != nullptr)
367 usedTypes->insert(name);
368 };
369
370 auto type = contextualTypes.types().constFind(name);
371
372 if (type != contextualTypes.types().constEnd()) {
373 useType();
374 return *type;
375 }
376
377 const auto findListType = [&](const QString &prefix, const QString &postfix)
378 -> ImportedScope<ConstPtr> {
379 if (name.startsWith(prefix) && name.endsWith(postfix)) {
380 const qsizetype prefixLength = prefix.length();
381 const QString &elementName
382 = name.mid(prefixLength, name.length() - prefixLength - postfix.length());
383 const ImportedScope<ConstPtr> element
384 = findType(elementName, contextualTypes, usedTypes);
385 if (element.scope) {
386 useType();
387 return { element.scope->listType(), element.revision };
388 }
389 }
390
391 return {};
392 };
393
394 switch (contextualTypes.context()) {
396 if (const auto listType = findListType(u"QList<"_s, u">"_s);
397 listType.scope && !listType.scope->isReferenceType()) {
398 return listType;
399 }
400
401 if (const auto listType = findListType(u"QQmlListProperty<"_s, u">"_s);
402 listType.scope && listType.scope->isReferenceType()) {
403 return listType;
404 }
405
406 // look for c++ namescoped enums!
407 const auto colonColon = name.lastIndexOf(QStringLiteral("::"));
408 if (colonColon == -1)
409 break;
410
411 const QString outerTypeName = name.left(colonColon);
412 const auto outerType = contextualTypes.types().constFind(outerTypeName);
413 if (outerType == contextualTypes.types().constEnd())
414 break;
415
416 for (const auto &innerType : std::as_const(outerType->scope->m_childScopes)) {
417 if (innerType->m_internalName == name) {
418 useType();
419 return { innerType, outerType->revision };
420 }
421 }
422
423 break;
424 }
426 // look after inline components
427 const auto inlineComponent = qFindInlineComponents(name, contextualTypes);
428 if (inlineComponent.scope) {
429 useType();
430 return inlineComponent;
431 }
432
433 if (const auto listType = findListType(u"list<"_s, u">"_s); listType.scope)
434 return listType;
435
436 break;
437 }
438 }
439 return {};
440}
441
442QTypeRevision QQmlJSScope::resolveType(
444 QSet<QString> *usedTypes)
445{
446 if (self->accessSemantics() == AccessSemantics::Sequence
447 && self->internalName().startsWith(u"QQmlListProperty<"_s)) {
448 self->setIsListProperty(true);
449 }
450
451 const QString baseTypeName = self->baseTypeName();
452 const auto baseType = findType(baseTypeName, context, usedTypes);
453 if (!self->m_baseType.scope && !baseTypeName.isEmpty())
454 self->m_baseType = { baseType.scope, baseType.revision };
455
456 if (!self->m_attachedType && !self->m_attachedTypeName.isEmpty())
457 self->m_attachedType = findType(self->m_attachedTypeName, context, usedTypes).scope;
458
459 if (!self->m_valueType && !self->m_valueTypeName.isEmpty())
460 self->m_valueType = findType(self->m_valueTypeName, context, usedTypes).scope;
461
462 if (!self->m_extensionType) {
463 if (self->m_extensionTypeName.isEmpty()) {
464 if (self->accessSemantics() == AccessSemantics::Sequence) {
465 // All sequence types are implicitly extended by JS Array.
466 self->setExtensionTypeName(u"Array"_s);
467 self->setExtensionIsJavaScript(true);
468 self->m_extensionType = context.arrayType();
469 }
470 } else {
471 self->m_extensionType = findType(self->m_extensionTypeName, context, usedTypes).scope;
472 }
473 }
474
475
476 for (auto it = self->m_properties.begin(), end = self->m_properties.end(); it != end; ++it) {
477 const QString typeName = it->typeName();
478 if (it->type() || typeName.isEmpty())
479 continue;
480
481 if (const auto type = findType(typeName, context, usedTypes); type.scope) {
482 it->setType(it->isList() ? type.scope->listType() : type.scope);
483 continue;
484 }
485
486 const auto enumeration = self->m_enumerations.find(typeName);
487 if (enumeration != self->m_enumerations.end()) {
488 it->setType(it->isList()
491 }
492 }
493
494 const auto resolveParameter = [&](QQmlJSMetaParameter &parameter) {
495 if (const QString typeName = parameter.typeName();
496 !parameter.type() && !typeName.isEmpty()) {
497 auto type = findType(typeName, context, usedTypes);
498 if (type.scope && parameter.isList()) {
499 type.scope = type.scope->listType();
500 parameter.setIsList(false);
501 parameter.setIsPointer(false);
502 parameter.setTypeName(type.scope ? type.scope->internalName() : QString());
503 } else if (type.scope && type.scope->isReferenceType()) {
504 parameter.setIsPointer(true);
505 }
506 parameter.setType({ type.scope });
507 }
508 };
509
510 for (auto it = self->m_methods.begin(), end = self->m_methods.end(); it != end; ++it) {
511 auto returnValue = it->returnValue();
512 resolveParameter(returnValue);
513 it->setReturnValue(returnValue);
514
515 auto parameters = it->parameters();
516 for (int i = 0, length = parameters.size(); i < length; ++i)
517 resolveParameter(parameters[i]);
518 it->setParameters(parameters);
519 }
520
521 for (auto it = self->m_jsIdentifiers.begin(); it != self->m_jsIdentifiers.end(); ++it) {
522 if (it->typeName)
523 it->scope = findType(it->typeName.value(), context, usedTypes).scope;
524 }
525
526 return baseType.revision;
527}
528
529void QQmlJSScope::updateChildScope(
530 const QQmlJSScope::Ptr &childScope, const QQmlJSScope::Ptr &self,
531 const QQmlJS::ContextualTypes &contextualTypes, QSet<QString> *usedTypes)
532{
533 switch (childScope->scopeType()) {
537 if (mode == QQmlJSScope::ExtensionNamespace)
538 return false;
539 const auto propertyIt = type->m_properties.find(childScope->internalName());
540 if (propertyIt != type->m_properties.end()) {
541 childScope->m_baseType.scope = QQmlJSScope::ConstPtr(propertyIt->type());
542 if (propertyIt->type())
543 childScope->m_semantics = propertyIt->type()->accessSemantics();
544 childScope->setBaseTypeName(propertyIt->typeName());
545 return true;
546 }
547 return false;
548 });
549 break;
551 if (const auto attachedBase = findType(
552 childScope->internalName(), contextualTypes, usedTypes).scope) {
553 childScope->m_baseType.scope = attachedBase->attachedType();
554 childScope->setBaseTypeName(attachedBase->attachedTypeName());
555 }
556 break;
557 default:
558 break;
559 }
560}
561
562template<typename Resolver, typename ChildScopeUpdater>
564 Resolver resolve, ChildScopeUpdater update, const QQmlJSScope::Ptr &self,
565 const QQmlJS::ContextualTypes &contextualTypes, QSet<QString> *usedTypes)
566{
567 const QTypeRevision revision = resolve(self, contextualTypes, usedTypes);
568 // NB: constness ensures no detach
569 const auto childScopes = self->childScopes();
570 for (auto it = childScopes.begin(), end = childScopes.end(); it != end; ++it) {
571 const auto childScope = *it;
572 update(childScope, self, contextualTypes, usedTypes);
573 resolveTypesInternal(resolve, update, childScope, contextualTypes, usedTypes); // recursion
574 }
575 return revision;
576}
577
579 const QQmlJSScope::Ptr &self, const QQmlJS::ContextualTypes &contextualTypes,
580 QSet<QString> *usedTypes)
581{
582 const auto resolveAll = [](const QQmlJSScope::Ptr &self,
583 const QQmlJS::ContextualTypes &contextualTypes,
584 QSet<QString> *usedTypes) {
585 resolveEnums(self, contextualTypes, usedTypes);
586 resolveList(self, contextualTypes.arrayType());
587 return resolveType(self, contextualTypes, usedTypes);
588 };
589 return resolveTypesInternal(resolveAll, updateChildScope, self, contextualTypes, usedTypes);
590}
591
593 const QQmlJSScope::Ptr &self, const QQmlJS::ContextualTypes &contextualTypes,
594 QSet<QString> *usedTypes)
595{
596 resolveTypesInternal(resolveType, updateChildScope, self, contextualTypes, usedTypes);
597}
598
599static QString flagStorage(const QString &underlyingType)
600{
601 // All numeric types are builtins. Therefore we can exhaustively check the internal names.
602
603 if (underlyingType == u"uint"
604 || underlyingType == u"quint8"
605 || underlyingType == u"ushort"
606 || underlyingType == u"ulonglong") {
607 return u"uint"_s;
608 }
609
610 if (underlyingType == u"int"
611 || underlyingType == u"qint8"
612 || underlyingType == u"short"
613 || underlyingType == u"longlong") {
614 return u"int"_s;
615 }
616
617 // Will fail to resolve and produce an error on usage.
618 // It's harmless if you never use the enum.
619 return QString();
620}
621
634 const QQmlJSScope::Ptr &self, const QQmlJS::ContextualTypes &contextualTypes,
635 QSet<QString> *usedTypes)
636{
637 // temporary hash to avoid messing up m_enumerations while iterators are active on it
638 QHash<QString, QQmlJSMetaEnum> toBeAppended;
639 for (auto it = self->m_enumerations.begin(), end = self->m_enumerations.end(); it != end; ++it) {
640 if (it->type())
641 continue;
643 reparent(self, enumScope);
644 enumScope->m_scopeType = QQmlSA::ScopeType::EnumScope;
645
646 QString typeName = it->typeName();
647 if (typeName.isEmpty())
648 typeName = QStringLiteral("int");
649 else if (it->isFlag())
651 enumScope->setBaseTypeName(typeName);
652 const auto type = findType(typeName, contextualTypes, usedTypes);
653 enumScope->m_baseType = { type.scope, type.revision };
654
655 enumScope->m_semantics = AccessSemantics::Value;
656 enumScope->m_internalName = self->internalName() + QStringLiteral("::") + it->name();
657 if (QString alias = it->alias(); !alias.isEmpty()
658 && self->m_enumerations.constFind(alias) == self->m_enumerations.constEnd()) {
659 auto aliasScope = QQmlJSScope::clone(enumScope);
660 aliasScope->m_internalName = self->internalName() + QStringLiteral("::") + alias;
661 QQmlJSMetaEnum cpy(*it);
662 cpy.setType(QQmlJSScope::ConstPtr(aliasScope));
663 toBeAppended.insert(alias, cpy);
664 }
665 it->setType(QQmlJSScope::ConstPtr(enumScope));
666 }
667 // no more iterators active on m_enumerations, so it can be changed safely now
668 self->m_enumerations.insert(toBeAppended);
669}
670
672{
673 if (self->listType() || self->accessSemantics() == AccessSemantics::Sequence)
674 return;
675
676 Q_ASSERT(!arrayType.isNull());
678 listType->setAccessSemantics(AccessSemantics::Sequence);
679 listType->setValueTypeName(self->internalName());
680
681 if (self->isComposite()) {
682 // There is no internalName for this thing. Just set the value type right away
683 listType->setInternalName(u"QQmlListProperty<>"_s);
684 listType->m_valueType = QQmlJSScope::ConstPtr(self);
685 } else if (self->isReferenceType()) {
686 listType->setInternalName(u"QQmlListProperty<%2>"_s.arg(self->internalName()));
687 // Do not set a filePath on the list type, so that we have to generalize it
688 // even in direct mode.
689 } else {
690 listType->setInternalName(u"QList<%2>"_s.arg(self->internalName()));
691 listType->setFilePath(self->filePath());
692 }
693
694 const QQmlJSImportedScope element = {self, QTypeRevision()};
695 const QQmlJSImportedScope array = {arrayType, QTypeRevision()};
696 QQmlJS::ContextualTypes contextualTypes(
697 QQmlJS::ContextualTypes::INTERNAL, { { self->internalName(), element }, },
698 arrayType);
699 QQmlJSScope::resolveTypes(listType, contextualTypes);
700
701 Q_ASSERT(listType->valueType() == self);
702 self->m_listType = listType;
703}
704
706 const Ptr &self, const ConstPtr &baseType,
707 const QQmlJS::ContextualTypes &contextualTypes, QSet<QString> *usedTypes)
708{
710 // Generalized group properties are always composite,
711 // which means we expect contextualTypes to be QML names.
712 Q_ASSERT(self->isComposite());
713
714 self->m_baseType.scope = baseType;
715 self->m_semantics = baseType->accessSemantics();
716 resolveNonEnumTypes(self, contextualTypes, usedTypes);
717}
718
720{
721 auto qmlScope = scope;
722 while (qmlScope && qmlScope->m_scopeType != QQmlSA::ScopeType::QMLScope)
723 qmlScope = qmlScope->parentScope();
724 return qmlScope;
725}
726
728{
732 return false;
733 return scope->m_properties.contains(name);
734 });
735}
736
738{
743 return false;
744 const auto it = scope->m_properties.find(name);
745 if (it == scope->m_properties.end())
746 return false;
747 prop = *it;
748 return true;
749 });
750 return prop;
751}
752
760QHash<QString, QQmlJSMetaProperty> QQmlJSScope::properties() const
761{
762 QHash<QString, QQmlJSMetaProperty> results;
766 return false;
767 for (auto it = scope->m_properties.constBegin();
768 it != scope->m_properties.constEnd(); it++) {
769 if (!results.contains(it.key()))
770 results.insert(it.key(), it.value());
771 }
772 return false;
773 });
774 return results;
775}
776
778 const QString &name)
779{
784 return false;
785 if (scope->hasOwnProperty(name)) {
786 owner = { scope, mode };
787 return true;
788 }
789 return false;
790 });
791 return owner;
792}
793
795{
796 if (!isRequired)
797 m_requiredPropertyNames.removeOne(name);
798 else if (!m_requiredPropertyNames.contains(name))
799 m_requiredPropertyNames.append(name);
800}
801
803{
804 bool isRequired = false;
807 if (scope->isPropertyLocallyRequired(name)) {
808 isRequired = true;
809 return true;
810 }
811
812 // the hasOwnProperty() below only makes sense if our scope is
813 // not an extension namespace
815 return false;
816
817 // If it has a property of that name, and that is not required, then none of the
818 // base types matter. You cannot make a derived type's property required with
819 // a "required" specification in a base type.
820 return scope->hasOwnProperty(name);
821 });
822 return isRequired;
823}
824
826{
827 return m_requiredPropertyNames.contains(name);
828}
829
831{
832 Q_ASSERT(binding.sourceLocation().isValid());
833 m_propertyBindings.insert(binding.propertyName(), binding);
834
835 // NB: insert() prepends \a binding to the list of bindings, but we need
836 // append, so rotate
838 QPair<iter, iter> r = m_propertyBindings.equal_range(binding.propertyName());
839 std::rotate(r.first, std::next(r.first), r.second);
840
841 // additionally store bindings in the QmlIR compatible order
842 addOwnPropertyBindingInQmlIROrder(binding, specifier);
843 Q_ASSERT(m_propertyBindings.size() == m_propertyBindingsArray.size());
844}
845
846void QQmlJSScope::addOwnPropertyBindingInQmlIROrder(const QQmlJSMetaPropertyBinding &binding,
847 BindingTargetSpecifier specifier)
848{
849 // the order:
850 // * ordinary bindings are prepended to the binding array
851 // * list bindings are properly ordered within each other, so basically
852 // prepended "in bulk"
853 // * bindings to default properties (which are not explicitly mentioned in
854 // binding expression) are inserted by source location's offset
855
857 "We really want T to be relocatable as it improves QList<T> performance");
858
859 switch (specifier) {
861 m_propertyBindingsArray.emplaceFront(binding.propertyName(),
862 binding.sourceLocation().offset);
863 break;
864 }
866 const auto bindingOnTheSameProperty =
867 [&](const QQmlJSScope::QmlIRCompatibilityBindingData &x) {
868 return x.propertyName == binding.propertyName();
869 };
870 // fake "prepend in bulk" by appending a list binding to the sequence of
871 // bindings to the same property. there's an implicit QML language
872 // guarantee that such sequence does not contain arbitrary in-between
873 // bindings that do not belong to the same list property
874 auto pos = std::find_if_not(m_propertyBindingsArray.begin(), m_propertyBindingsArray.end(),
875 bindingOnTheSameProperty);
876 Q_ASSERT(pos == m_propertyBindingsArray.begin()
877 || std::prev(pos)->propertyName == binding.propertyName());
878 m_propertyBindingsArray.emplace(pos, binding.propertyName(),
879 binding.sourceLocation().offset);
880 break;
881 }
883 // see QmlIR::PoolList<>::findSortedInsertionPoint()
884 const auto findInsertionPoint = [this](const QQmlJSMetaPropertyBinding &x) {
885 qsizetype pos = -1;
886 for (auto it = m_propertyBindingsArray.cbegin(); it != m_propertyBindingsArray.cend();
887 ++it) {
888 if (!(it->sourceLocationOffset <= x.sourceLocation().offset))
889 break;
890 ++pos;
891 }
892 return pos;
893 };
894
895 // see QmlIR::PoolList<>::insertAfter()
896 const auto insertAfter = [this](qsizetype pos, const QQmlJSMetaPropertyBinding &x) {
897 if (pos == -1) {
898 m_propertyBindingsArray.emplaceFront(x.propertyName(), x.sourceLocation().offset);
899 } else if (pos == m_propertyBindingsArray.size()) {
900 m_propertyBindingsArray.emplaceBack(x.propertyName(), x.sourceLocation().offset);
901 } else {
902 // since we insert *after*, use (pos + 1) as insertion point
903 m_propertyBindingsArray.emplace(pos + 1, x.propertyName(),
904 x.sourceLocation().offset);
905 }
906 };
907
908 const qsizetype insertionPos = findInsertionPoint(binding);
909 insertAfter(insertionPos, binding);
910 break;
911 }
912 default: {
913 Q_UNREACHABLE();
914 break;
915 }
916 }
917}
918
919QList<QQmlJSMetaPropertyBinding> QQmlJSScope::ownPropertyBindingsInQmlIROrder() const
920{
921 QList<QQmlJSMetaPropertyBinding> qmlIrOrdered;
922 qmlIrOrdered.reserve(m_propertyBindingsArray.size());
923
924 for (const auto &data : m_propertyBindingsArray) {
925 const auto [first, last] = m_propertyBindings.equal_range(data.propertyName);
926 Q_ASSERT(first != last);
927 auto binding = std::find_if(first, last, [&](const QQmlJSMetaPropertyBinding &x) {
928 return x.sourceLocation().offset == data.sourceLocationOffset;
929 });
930 Q_ASSERT(binding != last);
931 qmlIrOrdered.append(*binding);
932 }
933
934 return qmlIrOrdered;
935}
936
938{
942 Q_ASSERT(!scope->hasOwnPropertyBindings(name));
943 return false;
944 }
945 return scope->hasOwnPropertyBindings(name);
946 });
947}
948
949QList<QQmlJSMetaPropertyBinding> QQmlJSScope::propertyBindings(const QString &name) const
950{
951 QList<QQmlJSMetaPropertyBinding> bindings;
955 Q_ASSERT(!scope->hasOwnPropertyBindings(name));
956 return false;
957 }
958 const auto range = scope->ownPropertyBindings(name);
959 for (auto it = range.first; it != range.second; ++it)
960 bindings.append(*it);
961 return false;
962 });
963 return bindings;
964}
965
967{
971 return false;
972 return scope->m_interfaceNames.contains(name);
973 });
974}
975
977{
978 bool isDeferred = false;
979
981 const QStringList immediate = scope->ownImmediateNames();
982 if (!immediate.isEmpty()) {
983 isDeferred = !immediate.contains(name);
984 return true;
985 }
986 const QStringList deferred = scope->ownDeferredNames();
987 if (!deferred.isEmpty()) {
988 isDeferred = deferred.contains(name);
989 return true;
990 }
991 return false;
992 });
993
994 return isDeferred;
995}
996
997void QQmlJSScope::setBaseTypeName(const QString &baseTypeName)
998{
999 m_flags.setFlag(HasBaseTypeError, false);
1000 m_baseTypeNameOrError = baseTypeName;
1001}
1002
1004{
1005 return m_flags.testFlag(HasBaseTypeError) ? QString() : m_baseTypeNameOrError;
1006}
1007
1008void QQmlJSScope::setBaseTypeError(const QString &baseTypeError)
1009{
1010 m_flags.setFlag(HasBaseTypeError);
1011 m_baseTypeNameOrError = baseTypeError;
1012}
1013
1021{
1022 for (const QQmlJSScope *it = this; it; it = it->parentScope().get()) {
1023 const QString name = it->ownModuleName();
1024 if (!name.isEmpty())
1025 return name;
1026 }
1027 return {};
1028}
1029
1031{
1032 return m_flags.testFlag(HasBaseTypeError) ? m_baseTypeNameOrError : QString();
1033}
1034
1036{
1037 QString name;
1041 return false;
1042 if (scope->ownAttachedType().isNull())
1043 return false;
1044 name = scope->ownAttachedTypeName();
1045 return true;
1046 });
1047
1048 return name;
1049}
1050
1052{
1057 return false;
1058 if (scope->ownAttachedType().isNull())
1059 return false;
1060 ptr = scope->ownAttachedType();
1061 return true;
1062 });
1063
1064 return ptr;
1065}
1066
1068{
1069 if (!m_extensionType)
1070 return { m_extensionType, NotExtension };
1071 if (m_flags & ExtensionIsJavaScript)
1072 return { m_extensionType, ExtensionJavaScript };
1073 if (m_flags & ExtensionIsNamespace)
1074 return { m_extensionType, ExtensionNamespace };
1075 return { m_extensionType, ExtensionType };
1076}
1077
1082
1084{
1085 const bool nameIsEmpty = (m_scopeType == ScopeType::AttachedPropertyScope
1086 || m_scopeType == ScopeType::GroupedPropertyScope)
1087 ? m_internalName.isEmpty()
1088 : m_baseTypeNameOrError.isEmpty();
1089 if (nameIsEmpty)
1090 return true;
1091 if (m_baseType.scope.isNull())
1092 return false;
1094 return false;
1095 return true;
1096}
1097
1099{
1100 QString name;
1102 name = scope->ownDefaultPropertyName();
1103 return !name.isEmpty();
1104 });
1105 return name;
1106}
1107
1109{
1110 QString name;
1112 name = scope->ownParentPropertyName();
1113 return !name.isEmpty();
1114 });
1115 return name;
1116}
1117
1119{
1120 bool baseResolved = true;
1122 if (!scope->isResolved()) {
1123 baseResolved = false;
1124 return true;
1125 }
1126 return false;
1127 });
1128
1129 return baseResolved;
1130}
1131
1133 QString package, QString type, QTypeRevision version, QTypeRevision revision)
1134 : m_package(std::move(package))
1135 , m_type(std::move(type))
1136 , m_version(std::move(version))
1137 , m_revision(std::move(revision))
1138{
1139}
1140
1142{
1143 return m_version.isValid() || !m_package.isEmpty() || !m_type.isEmpty();
1144}
1145
1146void QDeferredFactory<QQmlJSScope>::populate(const QSharedPointer<QQmlJSScope> &scope) const
1147{
1148 scope->setOwnModuleName(m_moduleName);
1149 QQmlJSTypeReader typeReader(m_importer, m_filePath);
1150 typeReader(scope);
1151 m_importer->m_globalWarnings.append(typeReader.errors());
1152 scope->setInternalName(internalName());
1153 QQmlJSScope::resolveEnums(scope, m_importer->builtinInternalNames());
1154 QQmlJSScope::resolveList(scope, m_importer->builtinInternalNames().arrayType());
1155
1156 if (m_isSingleton && !scope->isSingleton()) {
1157 m_importer->m_globalWarnings.append(
1159 "Type %1 declared as singleton in qmldir but missing pragma Singleton")
1160 .arg(scope->internalName()),
1162 scope->setIsSingleton(true);
1163 } else if (!m_isSingleton && scope->isSingleton()) {
1164 m_importer->m_globalWarnings.append(
1165 { QStringLiteral("Type %1 not declared as singleton in qmldir "
1166 "but using pragma Singleton")
1167 .arg(scope->internalName()),
1169 scope->setIsSingleton(false);
1170 }
1171}
1172
1183{
1184 if (!derived)
1185 return false;
1186
1187 // expect this and derived types to have non-composite bases
1188 Q_ASSERT(!isComposite() || nonCompositeBaseType(baseType()));
1189 Q_ASSERT(nonCompositeBaseType(derived));
1190
1191 // the logic with isBaseComponent (as well as the way we set this flag)
1192 // feels wrong - QTBUG-101940
1193 const bool isBaseComponent = [this]() {
1194 if (internalName() == u"QQmlComponent")
1195 return true;
1196 else if (isComposite())
1197 return false;
1198 for (auto cppBase = nonCompositeBaseType(baseType()); cppBase;
1199 cppBase = cppBase->baseType()) {
1200 if (cppBase->internalName() == u"QQmlAbstractDelegateComponent")
1201 return true;
1202 }
1203 return false;
1204 }();
1205
1206 QDuplicateTracker<QQmlJSScope::ConstPtr> seen;
1207 for (auto scope = derived; !scope.isNull() && !seen.hasSeen(scope);
1208 scope = scope->baseType()) {
1209 if (isSameType(scope))
1210 return true;
1211 if (isBaseComponent && scope->internalName() == u"QObject"_s)
1212 return true;
1213 }
1214
1215 if (internalName() == u"QVariant"_s || internalName() == u"QJSValue"_s)
1216 return true;
1217
1218 return isListProperty() && valueType()->canAssign(derived);
1219}
1220
1226{
1227 for (const auto *scope = this; scope; scope = scope->parentScope().get()) {
1228 if (!scope->baseType().isNull() && scope->baseType()->hasCustomParser())
1229 return true;
1230 }
1231
1232 return false;
1233}
1234
1240std::optional<QString> QQmlJSScope::inlineComponentName() const
1241{
1242 Q_ASSERT(isInlineComponent() == m_inlineComponentName.has_value());
1243 return m_inlineComponentName;
1244}
1245
1252{
1253 for (auto *type = this; type; type = type->parentScope().get()) {
1254 if (type->isInlineComponent())
1255 return *type->inlineComponentName();
1256 }
1257 return RootDocumentNameType();
1258}
1259
1260QVector<QQmlJSScope::ConstPtr> QQmlJSScope::childScopes() const
1261{
1262 QVector<QQmlJSScope::ConstPtr> result;
1263 result.reserve(m_childScopes.size());
1264 for (const auto &child : m_childScopes)
1265 result.append(child);
1266 return result;
1267}
1268
1285{
1286 auto isCreatableNonRecursive = [](const QQmlJSScope *scope) {
1287 return scope->hasCreatableFlag() && !scope->isSingleton()
1288 && scope->scopeType() == QQmlSA::ScopeType::QMLScope;
1289 };
1290
1291 for (const QQmlJSScope* scope = this; scope; scope = scope->baseType().get()) {
1292 if (!scope->isComposite()) {
1293 // just check the first nonComposite (c++) base for isCreatableNonRecursive() and then stop
1294 return isCreatableNonRecursive(scope);
1295 } else {
1296 // check all composite (qml) bases for isCreatableNonRecursive().
1297 if (isCreatableNonRecursive(scope))
1298 return true;
1299 }
1300 }
1301 // no uncreatable bases found
1302 return false;
1303}
1304
1306{
1307 for (const QQmlJSScope *scope = this; scope; scope = scope->baseType().get()) {
1308 if (!scope->isComposite())
1309 return scope->hasStructuredFlag();
1310 }
1311 return false;
1312}
1313
1315{
1316 QQmlSA::Element element;
1317 *reinterpret_cast<QQmlJSScope::ConstPtr *>(element.m_data) = ptr;
1318 return element;
1319}
1320
1322{
1323 QQmlSA::Element element;
1324 *reinterpret_cast<QQmlJSScope::ConstPtr *>(element.m_data) = std::move(ptr);
1325 return element;
1326}
1327
1329{
1330 return *reinterpret_cast<const QQmlJSScope::ConstPtr *>(element.m_data);
1331}
1332
1334QQmlJSScope::nonCompositeBaseRevision(const ImportedScope<QQmlJSScope::ConstPtr> &scope)
1335{
1336 for (auto base = scope; base.scope;
1337 base = { base.scope->m_baseType.scope, base.scope->m_baseType.revision }) {
1338 if (!base.scope->isComposite())
1339 return base.revision;
1340 }
1341 return {};
1342}
1343
1351bool QQmlJSScope::isSameType(const ConstPtr &otherScope) const
1352{
1353 return this == otherScope.get()
1354 || (!this->internalName().isEmpty()
1355 && this->internalName() == otherScope->internalName());
1356}
1357
1359{
1360 for (const QQmlJSScope *scope = this; scope; scope = scope->baseType().get()) {
1361 if (scope->isSameType(base))
1362 return true;
1363 }
1364 return false;
1365}
1366
1367
\inmodule QtCore
QSharedPointer< T > toStrongRef() const
qsizetype size() const noexcept
Definition qlist.h:397
reference emplaceFront(Args &&... args)
Definition qlist.h:852
iterator insert(qsizetype i, parameter_type t)
Definition qlist.h:488
iterator end()
Definition qlist.h:626
reference emplaceBack(Args &&... args)
Definition qlist.h:882
iterator begin()
Definition qlist.h:625
iterator emplace(const_iterator before, Args &&... args)
Definition qlist.h:530
const_iterator cend() const noexcept
Definition qlist.h:631
void append(parameter_type t)
Definition qlist.h:458
const_iterator cbegin() const noexcept
Definition qlist.h:630
\inmodule QtCore
Definition qhash.h:1788
std::pair< iterator, iterator > equal_range(const Key &key)
Definition qhash.h:2266
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition qhash.h:2034
qsizetype size() const noexcept
Definition qhash.h:1567
QSharedPointer< const QQmlJSScope > type() const
const QQmlJS::SourceLocation & sourceLocation() const
Tracks the types for the QmlCompiler.
QHash< QString, QQmlJSMetaProperty > properties() const
Returns all properties visible from this scope including those of base types and extensions.
QString attachedTypeName() const
QList< QQmlJSMetaPropertyBinding > propertyBindings(const QString &name) const
bool isComposite() const
bool isStructured() const
void insertJSIdentifier(const QString &name, const JavaScriptIdentifier &identifier)
QDeferredSharedPointer< QQmlJSScope > Ptr
bool isNameDeferred(const QString &name) const
QHash< QString, QQmlJSMetaMethod > methods() const
Returns all methods visible from this scope including those of base types and extensions.
InlineComponentOrDocumentRootName enclosingInlineComponentName() const
QString defaultPropertyName() const
bool isInCustomParserParent() const
bool hasPropertyBindings(const QString &name) const
static QQmlJSScope::Ptr create()
bool isSameType(const QQmlJSScope::ConstPtr &otherScope) const
void setAccessSemantics(AccessSemantics semantics)
std::monostate RootDocumentNameType
static AnnotatedScope ownerOfProperty(const QQmlJSScope::ConstPtr &self, const QString &name)
bool isComponentRootElement() const
bool isResolved() const
AnnotatedScope extensionType() const
QQmlJSScope::Ptr parentScope()
ScopeType scopeType() const
static void resolveNonEnumTypes(const QQmlJSScope::Ptr &self, const QQmlJS::ContextualTypes &contextualTypes, QSet< QString > *usedTypes=nullptr)
void setInternalName(const QString &internalName)
QString baseTypeName() const
QString internalName() const
std::variant< InlineComponentNameType, RootDocumentNameType > InlineComponentOrDocumentRootName
A Hashable type to differentiate document roots from different inline components.
static ImportedScope< QQmlJSScope::ConstPtr > findType(const QString &name, const QQmlJS::ContextualTypes &contextualTypes, QSet< QString > *usedTypes=nullptr)
bool isReferenceType() const
void addOwnProperty(const QQmlJSMetaProperty &prop)
QString parentPropertyName() const
static void resolveList(const QQmlJSScope::Ptr &self, const QQmlJSScope::ConstPtr &arrayType)
QHash< QString, QQmlJSMetaEnum > enumerations() const
static QTypeRevision resolveTypes(const Ptr &self, const QQmlJS::ContextualTypes &contextualTypes, QSet< QString > *usedTypes=nullptr)
@ WrappedInImplicitComponent
QString moduleName() const
bool isInlineComponent() const
void insertPropertyIdentifier(const QQmlJSMetaProperty &prop)
AccessSemantics accessSemantics() const
static QQmlSA::Element createQQmlSAElement(const ConstPtr &)
bool hasEnumeration(const QString &name) const
QVector< QQmlJSScope::Ptr > childScopes()
bool hasEnumerationKey(const QString &name) const
void setBaseTypeName(const QString &baseTypeName)
bool isFullyResolved() const
bool hasInterface(const QString &name) const
static void resolveEnums(const QQmlJSScope::Ptr &self, const QQmlJS::ContextualTypes &contextualTypes, QSet< QString > *usedTypes=nullptr)
QQmlJSMetaEnum enumeration(const QString &name) const
QList< QQmlJSMetaPropertyBinding > ownPropertyBindingsInQmlIROrder() const
void addOwnPropertyBinding(const QQmlJSMetaPropertyBinding &binding, BindingTargetSpecifier specifier=BindingTargetSpecifier::SimplePropertyTarget)
bool isCreatable() const
QQmlJSScope(const QString &internalName)
std::optional< JavaScriptIdentifier > jsIdentifier(const QString &id) const
bool hasMethod(const QString &name) const
std::optional< JavaScriptIdentifier > ownJSIdentifier(const QString &id) const
QQmlJSScope::ConstPtr listType() const
static const QQmlJSScope::ConstPtr & scope(const QQmlSA::Element &)
bool isPropertyRequired(const QString &name) const
void setValueTypeName(const QString &name)
static QQmlJSScope::ConstPtr nonCompositeBaseType(const QQmlJSScope::ConstPtr &type)
QString augmentedInternalName() const
QQmlJSScope::ConstPtr attachedType() const
bool inherits(const QQmlJSScope::ConstPtr &base) const
static QQmlJSScope::Ptr clone(const QQmlJSScope::ConstPtr &origin)
QDeferredSharedPointer< const QQmlJSScope > ConstPtr
QQmlJSMetaProperty property(const QString &name) const
bool hasOwnEnumerationKey(const QString &name) const
static QTypeRevision nonCompositeBaseRevision(const ImportedScope< QQmlJSScope::ConstPtr > &scope)
static QString prettyName(QAnyStringView name)
bool canAssign(const QQmlJSScope::ConstPtr &derived) const
QQmlJSScope::ConstPtr baseType() const
void addOwnMethod(const QQmlJSMetaMethod &method)
bool isPropertyLocallyRequired(const QString &name) const
std::optional< QString > inlineComponentName() const
void addOwnRuntimeFunctionIndex(QQmlJSMetaMethod::AbsoluteFunctionIndex index)
bool hasProperty(const QString &name) const
QHash< QString, JavaScriptIdentifier > ownJSIdentifiers() const
static void reparent(const QQmlJSScope::Ptr &parentScope, const QQmlJSScope::Ptr &childScope)
static QQmlJSScope::ConstPtr findCurrentQMLScope(const QQmlJSScope::ConstPtr &scope)
QString baseTypeError() const
static void resolveGeneralizedGroup(const QQmlJSScope::Ptr &self, const QQmlJSScope::ConstPtr &baseType, const QQmlJS::ContextualTypes &contextualTypes, QSet< QString > *usedTypes=nullptr)
void setFilePath(const QString &file)
QMultiHash< QString, QQmlJSMetaMethod > ownMethods() const
QQmlJSScope::ConstPtr valueType() const
void setPropertyLocallyRequired(const QString &name, bool isRequired)
void setBaseTypeError(const QString &baseTypeError)
bool isValid() const
Export()=default
\inmodule QtQmlCompiler
Definition qqmlsa.h:193
static QString propertyNameToChangedSignalName(QStringView property)
iterator begin()
Definition qset.h:136
\inmodule QtCore
\inmodule QtCore
Definition qstringview.h:78
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
QString left(qsizetype n) const &
Definition qstring.h:363
iterator begin()
Returns an \l{STL-style iterators}{STL-style iterator} pointing to the first character in the string.
Definition qstring.h:1349
const_iterator constEnd() const
Returns a const \l{STL-style iterators}{STL-style iterator} pointing just after the last character in...
Definition qstring.h:1363
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
Definition qstring.cpp:5455
QString mid(qsizetype position, qsizetype n=-1) const &
Definition qstring.cpp:5300
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
iterator end()
Returns an \l{STL-style iterators}{STL-style iterator} pointing just after the last character in the ...
Definition qstring.h:1357
QString & insert(qsizetype i, QChar c)
Definition qstring.cpp:3132
QChar * data()
Returns a pointer to the data stored in the QString.
Definition qstring.h:1240
qsizetype length() const noexcept
Returns the number of characters in this string.
Definition qstring.h:191
\inmodule QtCore
QSet< QString >::iterator it
MethodType
Definition qqmlsa.h:49
Combined button and popup list for selecting options.
QString self
Definition language.cpp:58
static void * context
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter * iter
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char * method
static QDBusError::ErrorType get(const char *name)
@ QtCriticalMsg
Definition qlogging.h:32
static ControlElement< T > * ptr(QWidget *widget)
const char * typeName
GLint GLint GLint GLint GLint x
[0]
GLenum mode
GLuint index
[2]
GLboolean r
[2]
GLuint GLuint end
GLenum GLuint GLenum GLsizei length
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLsizei range
GLenum type
GLenum GLuint GLintptr offset
GLuint name
GLint first
GLenum array
GLuint64EXT * result
[6]
static bool isComposite(const QQmlJSScope::ConstPtr &scope)
static QString internalName(const QQmlJSScope::ConstPtr &scope)
static QQmlJSScope::ImportedScope< QQmlJSScope::ConstPtr > qFindInlineComponents(QStringView typeName, const QQmlJS::ContextualTypes &contextualTypes)
static QString flagStorage(const QString &underlyingType)
static QTypeRevision resolveTypesInternal(Resolver resolve, ChildScopeUpdater update, const QQmlJSScope::Ptr &self, const QQmlJS::ContextualTypes &contextualTypes, QSet< QString > *usedTypes)
static const QQmlJSScope * resolve(const QQmlJSScope *current, const QStringList &names)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define QStringLiteral(str)
ptrdiff_t qsizetype
Definition qtypes.h:165
static const uint base
Definition qurlidna.cpp:20
const char property[13]
Definition qwizard.cpp:101
if(qFloatDistance(a, b)<(1<< 7))
[0]
QExplicitlySharedDataPointer< Derived > derived(base)
QLayoutItem * child
[0]
bool contains(const AT &t) const noexcept
Definition qlist.h:45
static bool searchBaseAndExtensionTypes(QQmlJSScopePtr type, const Action &check)