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
qqmljstyperesolver.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
5
6#include "qqmljsimporter_p.h"
8#include "qqmljslogger_p.h"
9#include "qqmljsutils_p.h"
10#include <private/qv4value_p.h>
11
12#include <private/qduplicatetracker_p.h>
13
14#include <QtCore/qloggingcategory.h>
15
17
18using namespace Qt::StringLiterals;
19
20Q_LOGGING_CATEGORY(lcTypeResolver, "qt.qml.compiler.typeresolver", QtInfoMsg);
21
23{
25 Q_ASSERT(type->extensionType().scope->internalName() == extension);
26 Q_ASSERT(type->extensionIsJavaScript());
27}
28
30 : m_imports(importer->builtinInternalNames()),
31 m_trackedTypes(std::make_unique<QHash<QQmlJSScope::ConstPtr, TrackedType>>())
32{
33 const QQmlJSImporter::ImportedTypes &builtinTypes = m_imports;
34
35 m_voidType = builtinTypes.type(u"void"_s).scope;
36 assertExtension(m_voidType, "undefined"_L1);
37
38 m_nullType = builtinTypes.type(u"std::nullptr_t"_s).scope;
40
41 m_realType = builtinTypes.type(u"double"_s).scope;
42 assertExtension(m_realType, "Number"_L1);
43
44 m_floatType = builtinTypes.type(u"float"_s).scope;
45 assertExtension(m_floatType, "Number"_L1);
46
47 m_int8Type = builtinTypes.type(u"qint8"_s).scope;
48 assertExtension(m_int8Type, "Number"_L1);
49
50 m_uint8Type = builtinTypes.type(u"quint8"_s).scope;
51 assertExtension(m_uint8Type, "Number"_L1);
52
53 m_int16Type = builtinTypes.type(u"short"_s).scope;
54 assertExtension(m_int16Type, "Number"_L1);
55
56 m_uint16Type = builtinTypes.type(u"ushort"_s).scope;
57 assertExtension(m_uint16Type, "Number"_L1);
58
59 m_int32Type = builtinTypes.type(u"int"_s).scope;
60 assertExtension(m_int32Type, "Number"_L1);
61
62 m_uint32Type = builtinTypes.type(u"uint"_s).scope;
63 assertExtension(m_uint32Type, "Number"_L1);
64
65 m_int64Type = builtinTypes.type(u"qlonglong"_s).scope;
67
68 m_uint64Type = builtinTypes.type(u"qulonglong"_s).scope;
70
71 m_sizeType = builtinTypes.type(u"qsizetype"_s).scope;
72 assertExtension(m_sizeType, "Number"_L1);
73
74 // qsizetype is either a 32bit or a 64bit signed integer. We don't want to special-case it.
76
77 m_boolType = builtinTypes.type(u"bool"_s).scope;
78 assertExtension(m_boolType, "Boolean"_L1);
79
80 m_stringType = builtinTypes.type(u"QString"_s).scope;
81 assertExtension(m_stringType, "String"_L1);
82
83 m_stringListType = builtinTypes.type(u"QStringList"_s).scope;
85
86 m_byteArrayType = builtinTypes.type(u"QByteArray"_s).scope;
87 assertExtension(m_byteArrayType, "ArrayBuffer"_L1);
88
89 m_urlType = builtinTypes.type(u"QUrl"_s).scope;
90 assertExtension(m_urlType, "URL"_L1);
91
92 m_dateTimeType = builtinTypes.type(u"QDateTime"_s).scope;
94
95 m_dateType = builtinTypes.type(u"QDate"_s).scope;
97
98 m_timeType = builtinTypes.type(u"QTime"_s).scope;
100
101 m_variantListType = builtinTypes.type(u"QVariantList"_s).scope;
103
104 m_variantMapType = builtinTypes.type(u"QVariantMap"_s).scope;
106 m_varType = builtinTypes.type(u"QVariant"_s).scope;
108
109 m_jsValueType = builtinTypes.type(u"QJSValue"_s).scope;
111
112 m_qObjectType = builtinTypes.type(u"QObject"_s).scope;
113 assertExtension(m_qObjectType, "Object"_L1);
114
115 m_qObjectListType = builtinTypes.type(u"QObjectList"_s).scope;
117
118 m_qQmlScriptStringType = builtinTypes.type(u"QQmlScriptString"_s).scope;
120
121 m_functionType = builtinTypes.type(u"function"_s).scope;
123
124 m_numberPrototype = builtinTypes.type(u"NumberPrototype"_s).scope;
126
127 m_arrayPrototype = builtinTypes.type(u"ArrayPrototype"_s).scope;
129
131 Q_ASSERT(m_listPropertyType->internalName() == u"QQmlListProperty<QObject>"_s);
132 Q_ASSERT(m_listPropertyType->accessSemantics() == QQmlJSScope::AccessSemantics::Sequence);
133 Q_ASSERT(m_listPropertyType->valueTypeName() == u"QObject"_s);
135
137 emptyType->setAccessSemantics(QQmlJSScope::AccessSemantics::None);
139
141 jsPrimitiveType->setInternalName(u"QJSPrimitiveValue"_s);
142 jsPrimitiveType->setFilePath(u"qjsprimitivevalue.h"_s);
143 jsPrimitiveType->setAccessSemantics(QQmlJSScope::AccessSemantics::Value);
145
147 metaObjectType->setInternalName(u"const QMetaObject"_s);
148 metaObjectType->setFilePath(u"qmetaobject.h"_s);
149 metaObjectType->setAccessSemantics(QQmlJSScope::AccessSemantics::Reference);
151
152 m_jsGlobalObject = importer->jsGlobalObject();
153
155 forInIteratorPtr->setAccessSemantics(QQmlJSScope::AccessSemantics::Value);
156 forInIteratorPtr->setFilePath(u"qjslist.h"_s);
157 forInIteratorPtr->setInternalName(u"QJSListForInIterator::Ptr"_s);
159
161 forOfIteratorPtr->setAccessSemantics(QQmlJSScope::AccessSemantics::Value);
162 forOfIteratorPtr->setFilePath(u"qjslist.h"_s);
163 forOfIteratorPtr->setInternalName(u"QJSListForOfIterator::Ptr"_s);
165}
166
174{
175 m_logger = visitor->logger();
176
178 m_objectsByLocation.clear();
181
182 if (program)
183 program->accept(visitor);
184
185 m_objectsById = visitor->addressableScopes();
187 m_signalHandlers = visitor->signalHandlers();
188 m_imports = visitor->imports();
189}
190
195
200
203{
204 // #if required for standalone DOM compilation against Qt 6.2
205 qCDebug(lcTypeResolver()).nospace()
206 << "looking for object at " << location.line() << ':' << location.column();
208}
209
211{
212 const QString typeId = QmlIR::IRBuilder::asString(type->typeId);
213 if (!type->typeArgument)
214 return m_imports.type(typeId).scope;
215 if (typeId == u"list"_s) {
216 if (const QQmlJSScope::ConstPtr typeArgument = typeForName(type->typeArgument->toString()))
217 return typeArgument->listType();
218 }
219 return QQmlJSScope::ConstPtr();
220}
221
223{
225 if (value.isUndefined())
226 return voidType();
227
228 if (value.isInt32())
229 return int32Type();
230
231 if (value.isBoolean())
232 return boolType();
233
234 if (value.isDouble())
235 return realType();
236
237 if (value.isNull())
238 return nullType();
239
240 if (value.isEmpty())
241 return emptyType();
242
243 return {};
244}
245
248 const QQmlJSRegisterContent &right) const
249{
250 Q_ASSERT(left.isValid());
251 Q_ASSERT(right.isValid());
252
253 switch (oper) {
263 return globalType(boolType());
269 return builtinType(int32Type());
271 return builtinType(uint32Type());
272 case QSOperator::Op::Add: {
273 const auto leftContents = containedType(left);
274 const auto rightContents = containedType(right);
275 if (equals(leftContents, stringType()) || equals(rightContents, stringType()))
276 return builtinType(stringType());
277
278 const QQmlJSScope::ConstPtr result = merge(leftContents, rightContents);
279 if (equals(result, boolType()))
280 return builtinType(int32Type());
281 if (isNumeric(result))
282 return builtinType(realType());
283
285 }
288 case QSOperator::Op::Exp: {
291 }
294 return builtinType(realType());
296 return right;
297 default:
298 break;
299 }
300
301 return merge(left, right);
302}
303
305 UnaryOperator op, const QQmlJSRegisterContent &operand) const
306{
307 switch (op) {
309 return builtinType(boolType());
311 return builtinType(int32Type());
313 if (isIntegral(operand))
314 return operand;
316 default:
317 if (equals(containedType(operand), boolType()))
318 return builtinType(int32Type());
319 break;
320 }
321
322 return builtinType(realType());
323}
324
329
334
339
341{
342 // Only types of length <= 32bit count as integral
344}
345
352
362
370
378
388
391{
392 if (container.isType())
393 return container.type();
394 if (container.isProperty())
395 return container.property().type();
396 if (container.isEnumeration())
397 return container.enumeration().type();
398 if (container.isMethod())
399 return container.storedType(); // Methods can only be stored in QJSValue.
400 if (container.isImportNamespace()) {
401 switch (container.variant()) {
403 return container.storedType(); // We don't store scope module prefixes
405 return container.scopeType(); // We need to pass the original object through.
406 default:
407 Q_UNREACHABLE();
408 }
409 }
410 if (container.isConversion())
411 return container.conversionResult();
412
413 Q_UNREACHABLE_RETURN({});
414}
415
417{
419 return type;
420
421 // If origin is in fact an already tracked type, track the original of that one instead.
422 const auto it = m_trackedTypes->find(type);
423 QQmlJSScope::ConstPtr orig = (it == m_trackedTypes->end()) ? type : it->original;
424
426 m_trackedTypes->insert(clone, { std::move(orig), QQmlJSScope::ConstPtr(), clone });
427 return clone;
428}
429
431 const QQmlJSRegisterContent &origin,
432 QQmlJSScope::ConstPtr (QQmlJSTypeResolver::*op)(const QQmlJSScope::ConstPtr &) const) const
433{
434 if (origin.isType()) {
436 (this->*op)(origin.storedType()), (this->*op)(origin.type()),
437 origin.resultLookupIndex(), origin.variant(), (this->*op)(origin.scopeType()));
438 }
439
440 if (origin.isProperty()) {
441 QQmlJSMetaProperty prop = origin.property();
442 prop.setType((this->*op)(prop.type()));
444 (this->*op)(origin.storedType()), prop, origin.baseLookupIndex(),
445 origin.resultLookupIndex(), origin.variant(), (this->*op)(origin.scopeType()));
446 }
447
448 if (origin.isEnumeration()) {
449 QQmlJSMetaEnum enumeration = origin.enumeration();
450 enumeration.setType((this->*op)(enumeration.type()));
452 (this->*op)(origin.storedType()), enumeration, origin.enumMember(),
453 origin.variant(), (this->*op)(origin.scopeType()));
454 }
455
456 if (origin.isMethod()) {
458 (this->*op)(origin.storedType()), origin.method(), origin.variant(),
459 (this->*op)(origin.scopeType()));
460 }
461
462 if (origin.isImportNamespace()) {
464 (this->*op)(origin.storedType()), origin.importNamespace(),
465 origin.variant(), (this->*op)(origin.scopeType()));
466 }
467
468 if (origin.isConversion()) {
469 // When retrieving the originals we want a deep retrieval.
470 // When tracking a new type, we don't want to re-track its originals, though.
471
472 const QList<QQmlJSScope::ConstPtr> origins = origin.conversionOrigins();
473 QList<QQmlJSScope::ConstPtr> transformedOrigins;
475 transformedOrigins = origins;
476 } else {
477 transformedOrigins.reserve(origins.length());
478 for (const QQmlJSScope::ConstPtr &origin: origins)
479 transformedOrigins.append((this->*op)(origin));
480 }
481
483 (this->*op)(origin.storedType()),
484 transformedOrigins,
485 (this->*op)(origin.conversionResult()),
486 (this->*op)(origin.conversionResultScope()),
487 origin.variant(), (this->*op)(origin.scopeType()));
488 }
489
490 Q_UNREACHABLE_RETURN({});
491}
492
494 const QString &name, const QQmlJSScope::ConstPtr &scopeType,
495 bool hasObjectModulePrefix) const
496{
498 if (!type)
499 return QQmlJSRegisterContent();
500
501 if (type->isSingleton()) {
505 }
506
507 if (type->isScript()) {
511 }
512
513 if (const auto attached = type->attachedType()) {
514 if (!genericType(attached)) {
515 m_logger->log(u"Cannot resolve generic base of attached %1"_s.arg(
516 attached->internalName()),
517 qmlCompiler, attached->sourceLocation());
518 return {};
519 } else if (type->accessSemantics() != QQmlJSScope::AccessSemantics::Reference) {
520 m_logger->log(u"Cannot retrieve attached object for non-reference type %1"_s.arg(
521 type->internalName()),
522 qmlCompiler, type->sourceLocation());
523 return {};
524 } else {
525 // We don't know yet whether we need the attached or the plain object. In direct
526 // mode, we will figure this out using the scope type and access any enums of the
527 // plain type directly. In indirect mode, we can use enum lookups.
530 hasObjectModulePrefix
533 }
534 }
535
536 switch (type->accessSemantics()) {
537 case QQmlJSScope::AccessSemantics::None:
538 case QQmlJSScope::AccessSemantics::Reference:
539 // A plain reference to a non-singleton, non-attached type.
540 // We may still need the plain type reference for enum lookups,
541 // Store it as QMetaObject.
542 // This only works with namespaces and object types.
546 case QQmlJSScope::AccessSemantics::Sequence:
547 case QQmlJSScope::AccessSemantics::Value:
548 if (canAddressValueTypes()) {
552 }
553 // Else this is not actually a type reference. You cannot get the metaobject
554 // of a value type in QML and sequences don't even have metaobjects.
555 break;
556 }
557
558 return QQmlJSRegisterContent();
559}
560
565
570
577
583
585 const QQmlJSScope::ConstPtr &tracked, const QQmlJSScope::ConstPtr &conversion) const
586{
588 return true;
589
590 const auto it = m_trackedTypes->find(tracked);
592
593 // If we cannot convert to the new type without the help of e.g. lookupResultMetaType(),
594 // we better not change the type.
595 if (!canPrimitivelyConvertFromTo(tracked, conversion)
596 && !canPopulate(conversion, tracked, nullptr)
597 && !selectConstructor(conversion, tracked, nullptr).isValid()) {
598 return false;
599 }
600
601 it->replacement = comparableType(conversion);
602 *it->clone = std::move(*QQmlJSScope::clone(conversion));
603 return true;
604}
605
607 const QQmlJSScope::ConstPtr &tracked, const QList<QQmlJSScope::ConstPtr> &conversions) const
608{
610 return true;
611
612 const auto it = m_trackedTypes->find(tracked);
614 QQmlJSScope::Ptr mutableTracked = it->clone;
616 for (const QQmlJSScope::ConstPtr &type : conversions)
618
619 // If we cannot convert to the new type without the help of e.g. lookupResultMetaType(),
620 // we better not change the type.
622 && !canPopulate(result, tracked, nullptr)
623 && !selectConstructor(result, tracked, nullptr).isValid()) {
624 return false;
625 }
626
627 it->replacement = comparableType(result);
628 *mutableTracked = std::move(*QQmlJSScope::clone(result));
629 return true;
630}
631
633 const QQmlJSScope::ConstPtr &tracked, const QQmlJSScope::ConstPtr &conversion) const
634{
636 return;
637
638 const auto it = m_trackedTypes->find(tracked);
640
641 it->original = conversion;
642 *it->clone = std::move(*QQmlJSScope::clone(conversion));
643}
644
646{
648 return;
649
650 const auto it = m_trackedTypes->find(type);
652 *it->clone = std::move(*QQmlJSScope::clone(genericType(type)));
653 if (it->replacement)
654 it->replacement = genericType(it->replacement);
655 it->original = genericType(it->original);
656}
657
659 bool useFancyName) const
660{
662
663 // Use the type proper instead of the attached type
664 switch (container.variant()) {
667 type = container.scopeType();
668 break;
669 default:
670 type = containedType(container);
671 break;
672 }
673
674 QString typeName = type->internalName().isEmpty() ? type->baseTypeName() : type->internalName();
675
676 if (useFancyName)
678
679 return typeName;
680}
681
683 const QQmlJSScope::ConstPtr &to) const
684{
685 if (canPrimitivelyConvertFromTo(from, to)
686 || canPopulate(to, from, nullptr)
687 || selectConstructor(to, from, nullptr).isValid()) {
688 return true;
689 }
690
691 // ### need a generic solution for custom cpp types:
692 // if (from->m_hasBoolOverload && equals(to, boolType))
693 // return true;
694
695 // All of these types have QString conversions that require a certain format
696 // TODO: Actually verify these strings or deprecate them.
697 // Some of those type are builtins or should be builtins. We should add code for them
698 // in QQmlJSCodeGenerator::conversion().
699 if (equals(from, m_stringType) && !to.isNull()) {
700 const QString toTypeName = to->internalName();
701 if (toTypeName == u"QPoint"_s || toTypeName == u"QPointF"_s
702 || toTypeName == u"QSize"_s || toTypeName == u"QSizeF"_s
703 || toTypeName == u"QRect"_s || toTypeName == u"QRectF"_s) {
704 return true;
705 }
706 }
707
708 return false;
709}
710
716
722
724 const QQmlJSRegisterContent &b) const
725{
726 if (a == b)
727 return a;
728
729 QList<QQmlJSScope::ConstPtr> origins;
730
731 QQmlJSScope::ConstPtr aResultScope;
732 if (a.isConversion()) {
733 origins.append(a.conversionOrigins());
734 aResultScope = a.conversionResultScope();
735 } else {
736 origins.append(containedType(a));
737 aResultScope = a.scopeType();
738 }
739
740 QQmlJSScope::ConstPtr bResultScope;
741 if (b.isConversion()) {
742 origins.append(b.conversionOrigins());
743 bResultScope = b.conversionResultScope();
744 } else {
745 origins.append(containedType(b));
746 bResultScope = b.scopeType();
747 }
748
749 std::sort(origins.begin(), origins.end());
750 const auto erase = std::unique(origins.begin(), origins.end());
751 origins.erase(erase, origins.end());
752
754 merge(a.storedType(), b.storedType()),
755 origins,
757 merge(aResultScope, bResultScope),
758 mergeVariants(a.variant(), b.variant()),
759 merge(a.scopeType(), b.scopeType()));
760}
761
763 const QQmlJSScope::ConstPtr &b) const
764{
765 if (a.isNull())
766 return b;
767
768 if (b.isNull())
769 return a;
770
771 const auto commonBaseType = [this](
773 for (QQmlJSScope::ConstPtr aBase = a; aBase; aBase = aBase->baseType()) {
774 for (QQmlJSScope::ConstPtr bBase = b; bBase; bBase = bBase->baseType()) {
775 if (equals(aBase, bBase))
776 return aBase;
777 }
778 }
779
780 return QQmlJSScope::ConstPtr();
781 };
782
783
784 if (equals(a, b))
785 return a;
786
787 if (equals(a, jsValueType()) || equals(a, varType()))
788 return a;
789 if (equals(b, jsValueType()) || equals(b, varType()))
790 return b;
791
792 const auto isInt32Compatible = [&](const QQmlJSScope::ConstPtr &type) {
793 return (isIntegral(type) && !equals(type, uint32Type())) || equals(type, boolType());
794 };
795
796 if (isInt32Compatible(a) && isInt32Compatible(b))
797 return int32Type();
798
799 const auto isUInt32Compatible = [&](const QQmlJSScope::ConstPtr &type) {
801 };
802
803 if (isUInt32Compatible(a) && isUInt32Compatible(b))
804 return uint32Type();
805
806 if (isNumeric(a) && isNumeric(b))
807 return realType();
808
809 if (isPrimitive(a) && isPrimitive(b))
810 return jsPrimitiveType();
811
812 if (auto commonBase = commonBaseType(a, b))
813 return commonBase;
814
815 if ((equals(a, nullType()) || equals(a, boolType())) && b->isReferenceType())
816 return b;
817
818 if ((equals(b, nullType()) || equals(b, boolType())) && a->isReferenceType())
819 return a;
820
821 return varType();
822}
823
825 const QQmlJSScope::ConstPtr &container, const QQmlJSScope::ConstPtr &contained) const
826{
827 if (equals(container, contained)
828 || equals(container, m_varType)
829 || equals(container, m_jsValueType)) {
830 return true;
831 }
832
833 if (equals(container, m_jsPrimitiveType))
834 return isPrimitive(contained);
835
836 if (equals(container, m_variantListType))
837 return contained->accessSemantics() == QQmlJSScope::AccessSemantics::Sequence;
838
839 if (equals(container, m_qObjectListType) || equals(container, m_listPropertyType)) {
840 if (contained->accessSemantics() != QQmlJSScope::AccessSemantics::Sequence)
841 return false;
842 if (QQmlJSScope::ConstPtr value = contained->valueType())
843 return value->isReferenceType();
844 return false;
845 }
846
848 container, [&](const QQmlJSScope::ConstPtr &base) {
849 return equals(base, contained);
850 })) {
851 return true;
852 }
853
854 if (container->isReferenceType()) {
856 contained, [&](const QQmlJSScope::ConstPtr &base) {
857 return equals(base, container);
858 })) {
859 return true;
860 }
861 }
862
863 return false;
864}
865
866
868{
869 const auto canBeUndefined = [this](const QQmlJSScope::ConstPtr &type) {
872 };
873
874 if (!canBeUndefined(content.storedType()))
875 return false;
876
877 if (!content.isConversion())
878 return canBeUndefined(containedType(content));
879
880 const auto origins = content.conversionOrigins();
881 for (const auto &origin : origins) {
882 if (canBeUndefined(origin))
883 return true;
884 }
885
886 return false;
887}
888
890{
891 if (!content.isConversion())
892 return false;
893
894 const auto origins = content.conversionOrigins();
895 if (origins.length() != 2)
896 return false;
897
898 return equals(origins[0], m_voidType) || equals(origins[1], m_voidType);
899}
900
902 const QQmlJSRegisterContent &content) const
903{
904 if (!isOptionalType(content))
905 return QQmlJSScope::ConstPtr();
906
907 const auto origins = content.conversionOrigins();
910 return result;
911}
912
915 ComponentIsGeneric allowComponent) const
916{
917 if (type->isScript())
918 return m_jsValueType;
919
921 return m_metaObjectType;
922
923 if (type->accessSemantics() == QQmlJSScope::AccessSemantics::Reference) {
924 QString unresolvedBaseTypeName;
925 for (auto base = type; base;) {
926 // QObject and QQmlComponent are the two required base types.
927 // Any QML type system has to define those, or use the ones from builtins.
928 // As QQmlComponent is derived from QObject, we can restrict ourselves to the latter.
929 // This results in less if'ery when retrieving a QObject* from somewhere and deciding
930 // what it is.
931 if (base->internalName() == u"QObject"_s) {
932 return base;
933 } else if (allowComponent == ComponentIsGeneric::Yes
934 && base->internalName() == u"QQmlComponent"_s) {
935 return base;
936 }
937
938 if (auto baseBase = base->baseType()) {
939 base = baseBase;
940 } else {
941 unresolvedBaseTypeName = base->baseTypeName();
942 break;
943 }
944 }
945
946 m_logger->log(u"Object type %1 is not derived from QObject or QQmlComponent. "
947 "You may need to fully qualify all names in C++ so that moc can see them. "
948 "You may also need to add qt_extract_metatypes(<target containing %2>)."_s
949 .arg(type->internalName(), unresolvedBaseTypeName),
950 qmlCompiler, type->sourceLocation());
951
952 // Reference types that are not QObject or QQmlComponent are likely JavaScript objects.
953 // We don't want to deal with those, but m_jsValueType is the best generic option.
954 return m_jsValueType;
955 }
956
957 if (type->isListProperty())
958 return m_listPropertyType;
959
960 if (type->scopeType() == QQmlSA::ScopeType::EnumScope)
961 return type->baseType();
962
963 if (isPrimitive(type))
964 return type;
965
966 for (const QQmlJSScope::ConstPtr &builtin : {
973 if (equals(type, builtin) || equals(type, builtin->listType()))
974 return type;
975 }
976
977 return m_varType;
978}
979
986
993
1009
1010static bool isRevisionAllowed(int memberRevision, const QQmlJSScope::ConstPtr &scope)
1011{
1012 Q_ASSERT(scope->isComposite());
1013 const QTypeRevision revision = QTypeRevision::fromEncodedVersion(memberRevision);
1014
1015 // If the memberRevision is either invalid or 0.0, then everything is allowed.
1016 if (!revision.isValid() || revision == QTypeRevision::zero())
1017 return true;
1018
1020 {scope->baseType(), scope->baseTypeRevision()});
1021
1022 // If the revision is not valid, we haven't found a non-composite base type.
1023 // There is nothing we can say about the property then.
1024 return typeRevision.isValid() && typeRevision >= revision;
1025}
1026
1028 const QString &name, int lookupIndex,
1029 QQmlJSScopesByIdOptions options) const
1030{
1031 const auto isAssignedToDefaultProperty = [this](const QQmlJSScope::ConstPtr &parent,
1033 const QString defaultPropertyName = parent->defaultPropertyName();
1034 if (defaultPropertyName.isEmpty()) // no reason to search for bindings
1035 return false;
1036
1037 const QList<QQmlJSMetaPropertyBinding> defaultPropBindings =
1038 parent->propertyBindings(defaultPropertyName);
1039 for (const QQmlJSMetaPropertyBinding &binding : defaultPropBindings) {
1040 if (binding.bindingType() == QQmlSA::BindingType::Object
1041 && equals(binding.objectType(), child)) {
1042 return true;
1043 }
1044 }
1045 return false;
1046 };
1047
1048 if (QQmlJSScope::ConstPtr identified = m_objectsById.scope(name, scope, options)) {
1049 return QQmlJSRegisterContent::create(storedType(identified), identified, lookupIndex,
1051 }
1052
1057 if (mode == QQmlJSScope::ExtensionNamespace) // no use for it here
1058 return false;
1059 if (found->hasOwnProperty(name)) {
1060 QQmlJSMetaProperty prop = found->ownProperty(name);
1061 if (!isRevisionAllowed(prop.revision(), scope))
1062 return false;
1063 if (m_parentMode == UseDocumentParent
1064 && name == base->parentPropertyName()) {
1065 QQmlJSScope::ConstPtr baseParent = base->parentScope();
1066 if (baseParent && baseParent->inherits(prop.type())
1067 && isAssignedToDefaultProperty(baseParent, base)) {
1068 prop.setType(baseParent);
1069 }
1070 }
1072 storedType(prop.type()), prop,
1074 scopeContentVariant(mode, false), scope);
1075 return true;
1076 }
1077
1078 if (found->hasOwnMethod(name)) {
1079 auto methods = found->ownMethods(name);
1080 for (auto it = methods.begin(); it != methods.end();) {
1081 if (!isRevisionAllowed(it->revision(), scope))
1082 it = methods.erase(it);
1083 else
1084 ++it;
1085 }
1086 if (methods.isEmpty())
1087 return false;
1089 jsValueType(), methods, scopeContentVariant(mode, true), scope);
1090 return true;
1091 }
1092
1093 // Unqualified enums are not allowed
1094
1095 return false;
1096 })) {
1097 return result;
1098 }
1099 }
1100
1101 QQmlJSRegisterContent result = registerContentForName(name);
1102
1103 if (result.isValid())
1104 return result;
1105
1106 if (m_jsGlobalObject->hasProperty(name)) {
1108 jsValueType(), m_jsGlobalObject->property(name),
1110 QQmlJSRegisterContent::JavaScriptGlobal, m_jsGlobalObject);
1111 } else if (m_jsGlobalObject->hasMethod(name)) {
1112 return QQmlJSRegisterContent::create(jsValueType(), m_jsGlobalObject->methods(name),
1114 m_jsGlobalObject);
1115 }
1116
1117 return {};
1118}
1119
1123{
1124 // You can't have lower case enum names in QML, even if we know the enums here.
1125 if (name.isEmpty() || !name.at(0).isUpper())
1126 return false;
1127
1128 const bool inExtension = (mode != QQmlJSScope::NotExtension);
1129
1130 const auto enums = scope->ownEnumerations();
1131 for (const auto &enumeration : enums) {
1132 if ((enumeration.isScoped() || enumeration.isQml()) && enumeration.name() == name) {
1134 storedType(enumeration.type()), enumeration, QString(),
1137 scope);
1138 return true;
1139 }
1140
1141 if (!enumeration.isScoped() && enumeration.hasKey(name)) {
1143 storedType(enumeration.type()), enumeration, name,
1146 scope);
1147 return true;
1148 }
1149 }
1150
1151 return false;
1152}
1153
1155 const QQmlJSScope::ConstPtr &type, const QQmlJSScope::ConstPtr &passedArgumentType,
1156 bool *isExtension) const
1157{
1158 // TODO: We could allow QVariantMap and QVariantHash to be populated, but that needs extra
1159 // code in the code generator.
1160
1161 if (type.isNull()
1162 || canHold(passedArgumentType, type)
1163 || isPrimitive(passedArgumentType)
1164 || type->accessSemantics() != QQmlJSScope::AccessSemantics::Value
1165 || !type->isStructured()) {
1166 return false;
1167 }
1168
1169 if (isExtension)
1170 *isExtension = !type->extensionType().scope.isNull();
1171
1172 return true;
1173}
1174
1176 const QQmlJSScope::ConstPtr &type, const QQmlJSScope::ConstPtr &passedArgumentType,
1177 bool *isExtension) const
1178{
1179 // If the "from" type can hold the target type, we should not try to coerce
1180 // it to any constructor argument.
1181 if (type.isNull()
1182 || canHold(passedArgumentType, type)
1183 || type->accessSemantics() != QQmlJSScope::AccessSemantics::Value
1184 || !type->isCreatable()) {
1185 return QQmlJSMetaMethod();
1186 }
1187
1188 auto doSelectConstructor = [&](const QQmlJSScope::ConstPtr &type) {
1189 QQmlJSMetaMethod candidate;
1190
1191 const auto ownMethods = type->ownMethods();
1192 for (const QQmlJSMetaMethod &method : ownMethods) {
1193 if (!method.isConstructor())
1194 continue;
1195
1196 const auto index = method.constructorIndex();
1198
1199 const auto methodArguments = method.parameters();
1200 if (methodArguments.size() != 1)
1201 continue;
1202
1203 const QQmlJSScope::ConstPtr methodArgumentType = methodArguments[0].type();
1204
1205 if (equals(passedArgumentType, methodArgumentType))
1206 return method;
1207
1208 // Do not select further ctors here. We don't want to do multi-step construction as that
1209 // is confusing and easily leads to infinite recursion.
1210 if (!candidate.isValid()
1211 && canPrimitivelyConvertFromTo(passedArgumentType, methodArgumentType)) {
1212 candidate = method;
1213 }
1214 }
1215
1216 return candidate;
1217 };
1218
1220 const QQmlJSMetaMethod ctor = doSelectConstructor(extension);
1221 if (ctor.isValid()) {
1222 if (isExtension)
1223 *isExtension = true;
1224 return ctor;
1225 }
1226 }
1227
1228 if (isExtension)
1229 *isExtension = false;
1230
1231 return doSelectConstructor(type);
1232}
1233
1235 const QQmlJSScope::ConstPtr &a, const QQmlJSScope::ConstPtr &b) const
1236{
1237 const QQmlJSScope::ConstPtr equivalentLists[2][2] = {
1240 };
1241
1242 for (const auto eq : equivalentLists) {
1243 if ((equals(a, eq[0]) && equals(b, eq[1])) || (equals(a, eq[1]) && equals(b, eq[0])))
1244 return true;
1245 }
1246
1247 return false;
1248}
1249
1251{
1252 // pointers are trivially copyable
1253 if (type->isReferenceType())
1254 return true;
1255
1256 // Enum values are trivially copyable
1257 if (type->scopeType() == QQmlSA::ScopeType::EnumScope)
1258 return true;
1259
1260 for (const QQmlJSScope::ConstPtr &trivial : {
1268 if (equals(type, trivial))
1269 return true;
1270 }
1271
1272 return false;
1273}
1274
1276{
1277 const bool matchByName = !base->isComposite();
1278 for (QQmlJSScope::ConstPtr derivedBase = derived; derivedBase;
1279 derivedBase = derivedBase->baseType()) {
1280 if (equals(derivedBase, base))
1281 return true;
1282 if (matchByName
1283 && !derivedBase->isComposite()
1284 && derivedBase->internalName() == base->internalName()) {
1285 return true;
1286 }
1287 }
1288 return false;
1289}
1290
1292 const QQmlJSScope::ConstPtr &from, const QQmlJSScope::ConstPtr &to) const
1293{
1294 if (equals(from, to))
1295 return true;
1296 if (equals(from, m_varType) || equals(to, m_varType))
1297 return true;
1298 if (equals(from, m_jsValueType) || equals(to, m_jsValueType))
1299 return true;
1301 return true;
1302 if (isNumeric(from) && isNumeric(to))
1303 return true;
1304 if (isNumeric(from) && equals(to, m_boolType))
1305 return true;
1306 if (from->accessSemantics() == QQmlJSScope::AccessSemantics::Reference
1307 && (equals(to, m_boolType) || equals(to, m_stringType))) {
1308 return true;
1309 }
1310
1311 // Yes, our String has number constructors.
1312 if (isNumeric(from) && equals(to, m_stringType))
1313 return true;
1314
1315 // We can convert strings to numbers, but not to enums
1316 if (equals(from, m_stringType) && isNumeric(to))
1317 return to->scopeType() != QQmlJSScope::ScopeType::EnumScope;
1318
1319 // We can always convert between strings and urls.
1320 if ((equals(from, m_stringType) && equals(to, m_urlType))
1321 || (equals(from, m_urlType) && equals(to, m_stringType))) {
1322 return true;
1323 }
1324
1325 // We can always convert between strings and byte arrays.
1326 if ((equals(from, m_stringType) && equals(to, m_byteArrayType))
1327 || (equals(from, m_byteArrayType) && equals(to, m_stringType))) {
1328 return true;
1329 }
1330
1331 if (equals(to, m_voidType))
1332 return true;
1333
1334 if (to.isNull())
1335 return equals(from, m_voidType);
1336
1338 for (const auto &originType : types) {
1339 if (!equals(from, originType))
1340 continue;
1341
1342 for (const auto &targetType : types) {
1343 if (equals(to, targetType))
1344 return true;
1345 }
1346
1347 if (equals(to, m_realType))
1348 return true;
1349
1350 break;
1351 }
1352
1353 if (equals(from, m_nullType)
1354 && to->accessSemantics() == QQmlJSScope::AccessSemantics::Reference) {
1355 return true;
1356 }
1357
1358 if (equals(from, m_jsPrimitiveType)) {
1359 // You can cast any primitive to a nullptr
1360 return isPrimitive(to) || to->accessSemantics() == QQmlJSScope::AccessSemantics::Reference;
1361 }
1362
1363 if (equals(to, m_jsPrimitiveType))
1364 return isPrimitive(from);
1365
1366 if (equals(from, m_variantListType))
1367 return to->accessSemantics() == QQmlJSScope::AccessSemantics::Sequence;
1368
1369 const bool matchByName = !to->isComposite();
1370 Q_ASSERT(!matchByName || !to->internalName().isEmpty());
1371 for (auto baseType = from; baseType; baseType = baseType->baseType()) {
1372 if (equals(baseType, to))
1373 return true;
1374 if (matchByName && baseType->internalName() == to->internalName())
1375 return true;
1376 }
1377
1378 // We can convert anything that fits into QJSPrimitiveValue
1380 return true;
1381
1382 // We can convert everything to bool.
1383 if (equals(to, m_boolType))
1384 return true;
1385
1386 if (areEquivalentLists(from, to))
1387 return true;
1388
1389 if (from->isListProperty()
1390 && to->accessSemantics() == QQmlJSScope::AccessSemantics::Sequence
1391 && canConvertFromTo(from->valueType(), to->valueType())) {
1392 return true;
1393 }
1394
1395 if (equals(to, m_stringType)
1396 && from->accessSemantics() == QQmlJSScope::AccessSemantics::Sequence) {
1397 return canConvertFromTo(from->valueType(), m_stringType);
1398 }
1399
1400 return false;
1401}
1402
1404 bool isWritable, const QQmlJSScope::ConstPtr &scope) const
1405{
1406 QQmlJSMetaProperty prop;
1407 prop.setPropertyName(u"length"_s);
1408 prop.setTypeName(u"qsizetype"_s);
1409 prop.setType(sizeType());
1410 prop.setIsWritable(isWritable);
1414}
1415
1417 const QQmlJSScope::ConstPtr &type, const QString &name, int baseLookupIndex,
1418 int resultLookupIndex) const
1419{
1421
1422 // If we got a plain type reference we have to check the enums of the _scope_.
1423 if (equals(type, metaObjectType()))
1424 return {};
1425
1426 if (equals(type, variantMapType())) {
1427 QQmlJSMetaProperty prop;
1428 prop.setPropertyName(name);
1429 prop.setTypeName(u"QVariant"_s);
1430 prop.setType(varType());
1431 prop.setIsWritable(true);
1433 varType(), prop, baseLookupIndex, resultLookupIndex,
1435 }
1436
1437 if (equals(type, jsValueType())) {
1438 QQmlJSMetaProperty prop;
1439 prop.setPropertyName(name);
1440 prop.setTypeName(u"QJSValue"_s);
1441 prop.setType(jsValueType());
1442 prop.setIsWritable(true);
1444 jsValueType(), prop, baseLookupIndex, resultLookupIndex,
1446 }
1447
1448 if ((equals(type, stringType())
1449 || type->accessSemantics() == QQmlJSScope::AccessSemantics::Sequence)
1450 && name == u"length"_s) {
1452 }
1453
1454 const auto check = [&](const QQmlJSScope::ConstPtr &scope, QQmlJSScope::ExtensionKind mode) {
1456 if (scope->hasOwnProperty(name)) {
1457 const auto prop = scope->ownProperty(name);
1459 storedType(prop.type()),
1460 prop, baseLookupIndex, resultLookupIndex,
1464 scope);
1465 return true;
1466 }
1467
1468 if (scope->hasOwnMethod(name)) {
1469 const auto methods = scope->ownMethods(name);
1475 scope);
1476 return true;
1477 }
1478 }
1479
1480 return checkEnums(scope, name, &result, mode);
1481 };
1482
1484 return result;
1485
1486 for (auto scope = type;
1487 scope && (scope->scopeType() == QQmlSA::ScopeType::JSFunctionScope
1489 scope = scope->parentScope()) {
1490 if (auto ownIdentifier = scope->ownJSIdentifier(name)) {
1491 QQmlJSMetaProperty prop;
1492 prop.setPropertyName(name);
1493 prop.setTypeName(u"QJSValue"_s);
1494 prop.setType(jsValueType());
1495 prop.setIsWritable(!(ownIdentifier.value().isConst));
1496
1497 return QQmlJSRegisterContent::create(jsValueType(), prop, baseLookupIndex,
1498 resultLookupIndex,
1500 }
1501 }
1502
1503 if (QQmlJSScope::ConstPtr attachedBase = typeForName(name)) {
1504 if (QQmlJSScope::ConstPtr attached = attachedBase->attachedType()) {
1505 if (!genericType(attached)) {
1506 m_logger->log(u"Cannot resolve generic base of attached %1"_s.arg(
1507 attached->internalName()),
1508 qmlCompiler, attached->sourceLocation());
1509 return {};
1510 } else if (type->accessSemantics() != QQmlJSScope::AccessSemantics::Reference) {
1511 m_logger->log(u"Cannot retrieve attached object for non-reference type %1"_s.arg(
1512 type->internalName()),
1513 qmlCompiler, type->sourceLocation());
1514 return {};
1515 } else {
1517 storedType(attached), attached, resultLookupIndex,
1519 }
1520 }
1521 }
1522
1523 return {};
1524}
1525
1527 const QString &name) const
1528{
1530
1533 return checkEnums(scope, name, &result, mode);
1534 })) {
1535 return result;
1536 }
1537
1538 return {};
1539}
1540
1542 const QQmlJSRegisterContent &type, const QString &name, int lookupIndex) const
1543{
1544 if (type.isType()) {
1545 const auto content = type.type();
1546 const auto result = memberType(content, name, type.resultLookupIndex(), lookupIndex);
1547 if (result.isValid())
1548 return result;
1549
1550 // If we didn't find anything and it's an attached type,
1551 // we might have an enum of the attaching type.
1552 return memberEnumType(type.scopeType(), name);
1553 }
1554 if (type.isProperty())
1555 return memberType(type.property().type(), name, type.resultLookupIndex(), lookupIndex);
1556 if (type.isEnumeration()) {
1557 const auto enumeration = type.enumeration();
1558 if (!type.enumMember().isEmpty() || !enumeration.hasKey(name))
1559 return {};
1560 return QQmlJSRegisterContent::create(storedType(enumeration.type()), enumeration, name,
1562 }
1563 if (type.isMethod()) {
1564 QQmlJSMetaProperty prop;
1565 prop.setTypeName(u"QJSValue"_s);
1566 prop.setPropertyName(name);
1567 prop.setType(jsValueType());
1568 prop.setIsWritable(true);
1572 }
1573 if (type.isImportNamespace()) {
1574 if (type.scopeType()->accessSemantics() != QQmlJSScope::AccessSemantics::Reference) {
1575 m_logger->log(u"Cannot use a non-QObject type %1 to access prefixed import"_s.arg(
1576 type.scopeType()->internalName()),
1577 qmlPrefixedImportType, type.scopeType()->sourceLocation());
1578 return {};
1579 }
1580
1582 name, type.scopeType(),
1584 }
1585 if (type.isConversion()) {
1586 if (const auto result = memberType(
1587 type.conversionResult(), name, type.resultLookupIndex(), lookupIndex);
1588 result.isValid()) {
1589 return result;
1590 }
1591
1592 if (const auto result = memberEnumType(type.scopeType(), name); result.isValid())
1593 return result;
1594
1595 // If the conversion consists of only undefined and one actual type,
1596 // we can produce the members of that one type.
1597 // If the value is then actually undefined, the result is an exception.
1598
1599 auto origins = type.conversionOrigins();
1600 const auto begin = origins.begin();
1601 const auto end = std::remove_if(begin, origins.end(),
1602 [this](const QQmlJSScope::ConstPtr &origin) {
1603 return equals(origin, m_voidType);
1604 });
1605
1606 // If the conversion cannot hold the original type, it loses information.
1607 return (end - begin == 1 && canHold(type.conversionResult(), *begin))
1608 ? memberType(*begin, name, type.resultLookupIndex(), lookupIndex)
1610 }
1611
1612 Q_UNREACHABLE_RETURN({});
1613}
1614
1616{
1619
1620 auto valueType = [&](const QQmlJSScope::ConstPtr &scope) {
1621 if (scope->accessSemantics() == QQmlJSScope::AccessSemantics::Sequence)
1622 return scope->valueType();
1623
1624 if (equals(scope, m_forInIteratorPtr))
1625 return m_sizeType;
1626
1627 if (equals(scope, m_forOfIteratorPtr))
1628 return list.scopeType()->valueType();
1629
1630 if (equals(scope, m_jsValueType) || equals(scope, m_varType))
1631 return m_jsValueType;
1632
1633 if (equals(scope, m_stringType))
1634 return m_stringType;
1635
1636 return QQmlJSScope::ConstPtr();
1637 };
1638
1639 if (list.isType()) {
1640 scope = list.type();
1641 value = valueType(scope);
1642 } else if (list.isConversion()) {
1643 value = valueType(list.conversionResult());
1644 } else if (list.isProperty()) {
1645 const auto prop = list.property();
1646 scope = prop.type();
1647 value = valueType(scope);
1648 }
1649
1650 if (value.isNull())
1651 return {};
1652
1654 property.setPropertyName(u"[]"_s);
1655 property.setTypeName(value->internalName());
1656 property.setType(value);
1657
1661}
1662
1672
1696
1698 const QQmlJSRegisterContent &reg, const QQmlJSScope::ConstPtr &type) const
1699{
1700 return equals(reg.storedType(), type);
1701}
1702
1704 const QQmlJSScope::ConstPtr &type) const
1705{
1706 if (reg.isType())
1707 return equals(reg.type(), type);
1708 if (reg.isConversion())
1709 return equals(reg.conversionResult(), type);
1710 if (reg.isProperty())
1711 return equals(type, reg.property().type());
1712 if (reg.isEnumeration())
1713 return equals(type, reg.enumeration().type());
1714 if (reg.isMethod())
1715 return equals(type, jsValueType());
1716 return false;
1717}
1718
1720{
1721 if (type.isNull())
1722 return {};
1723 if (equals(type, voidType()))
1724 return type;
1725 if (type->isScript())
1726 return jsValueType();
1727 if (type->isComposite()) {
1729 return nonComposite;
1730
1731 // If we can't find the non-composite base, we really don't know what it is.
1732 return genericType(type);
1733 }
1734 if (type->filePath().isEmpty())
1735 return genericType(type);
1736 return type;
1737}
1738
1740{
1741 const auto it = m_trackedTypes->find(type);
1742 return it == m_trackedTypes->end() ? type : it->original;
1743}
1744
1757
1759 const QQmlJSRegisterContent &from, const QQmlJSRegisterContent &to) const
1760{
1761 if (from.isConversion()) {
1763 to.storedType(), from.conversionOrigins(), containedType(to),
1764 to.scopeType() ? to.scopeType() : from.conversionResultScope(),
1765 from.variant(), from.scopeType());
1766 }
1767
1769 to.storedType(), QList<QQmlJSScope::ConstPtr>{containedType(from)},
1770 containedType(to), to.scopeType(), from.variant(), from.scopeType());
1771}
1772
1774 const QQmlJSRegisterContent &from, const QQmlJSScope::ConstPtr &to) const
1775{
1776 return from.castTo(to).storedIn(storedType(to));
1777}
1778
1780{
1781 const auto it = m_trackedTypes->constFind(type);
1782 if (it == m_trackedTypes->constEnd())
1783 return type;
1784 return it->replacement ? it->replacement : it->original;
1785}
1786
static JNINativeMethod methods[]
\inmodule QtCore
Definition qhash.h:820
void clear() noexcept(std::is_nothrow_destructible< Node >::value)
Removes all items from the hash and frees up all memory used by it.
Definition qhash.h:951
QQmlJSImporter::ImportedTypes imports() const
const QQmlJSLogger * logger() const
QQmlJSScopesById addressableScopes() const
QHash< QQmlJS::SourceLocation, QQmlJSMetaSignalHandler > signalHandlers() const
QHash< QV4::CompiledData::Location, QQmlJSScope::ConstPtr > scopesBylocation() const
QQmlJSScope::ConstPtr jsGlobalObject() const
void log(const QString &message, QQmlJS::LoggerWarningId id, const QQmlJS::SourceLocation &srcLocation, bool showContext=true, bool showFileName=true, const std::optional< QQmlJSFixSuggestion > &suggestion={}, const QString overrideFileName=QString())
void setType(const QSharedPointer< const QQmlJSScope > &type)
QSharedPointer< const QQmlJSScope > type() const
void setPropertyName(const QString &propertyName)
QSharedPointer< const QQmlJSScope > type() const
void setTypeName(const QString &typeName)
void setIsWritable(bool isWritable)
void setType(const QSharedPointer< const QQmlJSScope > &type)
QQmlJSRegisterContent storedIn(const QQmlJSScope::ConstPtr &newStoredType) const
QQmlJSScope::ConstPtr conversionResult() const
QQmlJSMetaProperty property() const
QQmlJSScope::ConstPtr scopeType() const
QQmlJSScope::ConstPtr conversionResultScope() const
QList< QQmlJSScope::ConstPtr > conversionOrigins() const
ContentVariant variant() const
QQmlJSScope::ConstPtr type() const
QQmlJSScope::ConstPtr storedType() const
static QQmlJSRegisterContent create(const QQmlJSScope::ConstPtr &storedType, const QQmlJSScope::ConstPtr &type, int resultLookupIndex, ContentVariant variant, const QQmlJSScope::ConstPtr &scope={})
QQmlJSMetaEnum enumeration() const
QQmlJSRegisterContent castTo(const QQmlJSScope::ConstPtr &newContainedType) const
QList< QQmlJSMetaMethod > method() const
Tracks the types for the QmlCompiler.
QQmlJSMetaProperty ownProperty(const QString &name) const
QList< QQmlJSMetaPropertyBinding > propertyBindings(const QString &name) const
bool isComposite() const
QString defaultPropertyName() const
static QQmlJSScope::Ptr create()
void setAccessSemantics(AccessSemantics semantics)
AnnotatedScope extensionType() const
QHash< QString, QQmlJSMetaEnum > ownEnumerations() const
QQmlJSScope::Ptr parentScope()
ScopeType scopeType() const
void setInternalName(const QString &internalName)
QString internalName() const
bool isReferenceType() const
AccessSemantics accessSemantics() const
bool isListProperty() const
std::optional< JavaScriptIdentifier > ownJSIdentifier(const QString &id) const
QQmlJSScope::ConstPtr listType() const
static QQmlJSScope::ConstPtr nonCompositeBaseType(const QQmlJSScope::ConstPtr &type)
QQmlJSScope::ConstPtr attachedType() const
QString valueTypeName() const
static QQmlJSScope::Ptr clone(const QQmlJSScope::ConstPtr &origin)
QDeferredSharedPointer< const QQmlJSScope > ConstPtr
QQmlJSMetaProperty property(const QString &name) const
static QTypeRevision nonCompositeBaseRevision(const ImportedScope< QQmlJSScope::ConstPtr > &scope)
static QString prettyName(QAnyStringView name)
bool hasOwnProperty(const QString &name) const
QQmlJSScope::ConstPtr baseType() const
static QQmlJSScope::ConstPtr findCurrentQMLScope(const QQmlJSScope::ConstPtr &scope)
void setFilePath(const QString &file)
QMultiHash< QString, QQmlJSMetaMethod > ownMethods() const
QTypeRevision baseTypeRevision() const
QQmlJSScope::ConstPtr valueType() const
bool hasOwnMethod(const QString &name) const
QQmlJSScope::ConstPtr scope(const QString &id, const QQmlJSScope::ConstPtr &referrer, QQmlJSScopesByIdOptions options=Default) const
bool equals(const QQmlJSScope::ConstPtr &a, const QQmlJSScope::ConstPtr &b) const
QQmlJSRegisterContent original(const QQmlJSRegisterContent &type) const
QQmlJSScope::ConstPtr m_int8Type
QQmlJSScope::ConstPtr trackedContainedType(const QQmlJSRegisterContent &container) const
QQmlJSRegisterContent merge(const QQmlJSRegisterContent &a, const QQmlJSRegisterContent &b) const
QQmlJSMetaMethod selectConstructor(const QQmlJSScope::ConstPtr &type, const QQmlJSScope::ConstPtr &argument, bool *isExtension) const
QQmlJSScope::ConstPtr m_stringListType
QQmlJSScope::ConstPtr m_arrayPrototype
QQmlJSImporter::ImportedTypes m_imports
QQmlJSScope::ConstPtr stringType() const
QQmlJSScope::ConstPtr m_realType
QQmlJSScope::ConstPtr m_int64Type
QQmlJSScope::ConstPtr m_uint16Type
QQmlJSScope::ConstPtr storedType(const QQmlJSScope::ConstPtr &type) const
QQmlJSRegisterContent cast(const QQmlJSRegisterContent &from, const QQmlJSScope::ConstPtr &to) const
QQmlJSScope::ConstPtr nullType() const
QQmlJSRegisterContent memberEnumType(const QQmlJSScope::ConstPtr &type, const QString &name) const
QQmlJSScope::ConstPtr m_voidType
QQmlJSRegisterContent tracked(const QQmlJSRegisterContent &type) const
QQmlJSScope::ConstPtr mathObject() const
QQmlJSScope::ConstPtr genericType(const QQmlJSScope::ConstPtr &type, ComponentIsGeneric allowComponent=ComponentIsGeneric::No) const
bool areEquivalentLists(const QQmlJSScope::ConstPtr &a, const QQmlJSScope::ConstPtr &b) const
QQmlJSScope::ConstPtr emptyType() const
bool registerIsStoredIn(const QQmlJSRegisterContent &reg, const QQmlJSScope::ConstPtr &type) const
bool canPopulate(const QQmlJSScope::ConstPtr &type, const QQmlJSScope::ConstPtr &argument, bool *isExtension) const
QQmlJSScope::ConstPtr containedType(const QQmlJSRegisterContent &container) const
QQmlJSScope::ConstPtr jsPrimitiveType() const
QQmlJSRegisterContent typeForArithmeticUnaryOperation(UnaryOperator op, const QQmlJSRegisterContent &operand) const
QQmlJSScope::ConstPtr m_jsValueType
bool isNumeric(const QQmlJSRegisterContent &type) const
QQmlJSScope::ConstPtr m_int16Type
QQmlJSRegisterContent lengthProperty(bool isWritable, const QQmlJSScope::ConstPtr &scope) const
QQmlJSScope::ConstPtr consoleObject() const
QQmlJSScope::ConstPtr boolType() const
QQmlJSScope::ConstPtr trackedType(const QQmlJSScope::ConstPtr &type) const
QQmlJSScope::ConstPtr m_jsPrimitiveType
QQmlJSScope::ConstPtr jsGlobalObject() const
QQmlJSScopesById m_objectsById
bool adjustTrackedType(const QQmlJSScope::ConstPtr &tracked, const QQmlJSScope::ConstPtr &conversion) const
QQmlJSScope::ConstPtr m_qObjectListType
QQmlJSScope::ConstPtr m_varType
bool canPrimitivelyConvertFromTo(const QQmlJSScope::ConstPtr &from, const QQmlJSScope::ConstPtr &to) const
QQmlJSScope::ConstPtr m_byteArrayType
QQmlJSScope::ConstPtr m_forOfIteratorPtr
bool registerContains(const QQmlJSRegisterContent &reg, const QQmlJSScope::ConstPtr &type) const
QQmlJSScope::ConstPtr m_forInIteratorPtr
bool inherits(const QQmlJSScope::ConstPtr &derived, const QQmlJSScope::ConstPtr &base) const
bool isIntegral(const QQmlJSRegisterContent &type) const
bool canHold(const QQmlJSScope::ConstPtr &container, const QQmlJSScope::ConstPtr &contained) const
bool isPrimitive(const QQmlJSRegisterContent &type) const
QQmlJSRegisterContent builtinType(const QQmlJSScope::ConstPtr &type) const
QQmlJSScope::ConstPtr m_qQmlScriptStringType
QQmlJSRegisterContent returnType(const QQmlJSScope::ConstPtr &type, QQmlJSRegisterContent::ContentVariant variant, const QQmlJSScope::ConstPtr &scope) const
bool canConvertFromTo(const QQmlJSScope::ConstPtr &from, const QQmlJSScope::ConstPtr &to) const
QQmlJSScope::ConstPtr m_qObjectType
QString containedTypeName(const QQmlJSRegisterContent &container, bool useFancyName=false) const
QQmlJSScope::ConstPtr jsValueType() const
QQmlJSRegisterContent globalType(const QQmlJSScope::ConstPtr &type) const
QQmlJSRegisterContent convert(const QQmlJSRegisterContent &from, const QQmlJSRegisterContent &to) const
QQmlJSScope::ConstPtr originalType(const QQmlJSScope::ConstPtr &type) const
bool canHoldUndefined(const QQmlJSRegisterContent &content) const
QQmlJSScope::ConstPtr sizeType() const
void adjustOriginalType(const QQmlJSScope::ConstPtr &tracked, const QQmlJSScope::ConstPtr &conversion) const
QQmlJSRegisterContent valueType(const QQmlJSRegisterContent &list) const
QHash< QV4::CompiledData::Location, QQmlJSScope::ConstPtr > m_objectsByLocation
QQmlJSScope::ConstPtr originalContainedType(const QQmlJSRegisterContent &container) const
QQmlJSScope::ConstPtr uint32Type() const
QQmlJSScope::ConstPtr comparableType(const QQmlJSScope::ConstPtr &type) const
QQmlJSScope::ConstPtr extractNonVoidFromOptionalType(const QQmlJSRegisterContent &content) const
bool checkEnums(const QQmlJSScope::ConstPtr &scope, const QString &name, QQmlJSRegisterContent *result, QQmlJSScope::ExtensionKind mode) const
bool isTriviallyCopyable(const QQmlJSScope::ConstPtr &type) const
QQmlJSScope::ConstPtr m_urlType
QQmlJSScope::ConstPtr m_uint32Type
QQmlJSScope::ConstPtr int32Type() const
QQmlJSScope::ConstPtr m_numberPrototype
QQmlJSScope::ConstPtr m_functionType
QQmlJSScope::ConstPtr m_listPropertyType
QQmlJSScope::ConstPtr m_variantMapType
QQmlJSScope::ConstPtr m_stringType
QQmlJSRegisterContent memberType(const QQmlJSRegisterContent &type, const QString &name, int lookupIndex=QQmlJSRegisterContent::InvalidLookupIndex) const
QQmlJSScope::ConstPtr m_nullType
QQmlJSScope::ConstPtr voidType() const
QQmlJSScope::ConstPtr m_sizeType
QQmlJSScope::ConstPtr m_dateTimeType
QQmlJSScope::ConstPtr typeFromAST(QQmlJS::AST::Type *type) const
QQmlJSRegisterContent registerContentForName(const QString &name, const QQmlJSScope::ConstPtr &scopeType=QQmlJSScope::ConstPtr(), bool hasObjectModuelPrefix=false) const
QQmlJSScope::ConstPtr m_floatType
QHash< QQmlJS::SourceLocation, QQmlJSMetaSignalHandler > m_signalHandlers
QQmlJSTypeResolver(QQmlJSImporter *importer)
QQmlJSRegisterContent iteratorPointer(const QQmlJSRegisterContent &listType, QQmlJS::AST::ForEachType type, int lookupIndex) const
QQmlJSScope::ConstPtr m_timeType
QQmlJSScope::ConstPtr m_boolType
QQmlJSScope::ConstPtr forOfIteratorPtr() const
QQmlJSScope::ConstPtr metaObjectType() const
QQmlJSScope::ConstPtr forInIteratorPtr() const
QQmlJSScope::ConstPtr m_metaObjectType
QQmlJSScope::ConstPtr realType() const
bool isOptionalType(const QQmlJSRegisterContent &content) const
QQmlJSScope::ConstPtr m_jsGlobalObject
void init(QQmlJSImportVisitor *visitor, QQmlJS::AST::Node *program)
void generalizeType(const QQmlJSScope::ConstPtr &type) const
QQmlJSScope::ConstPtr m_int32Type
bool isUnsignedInteger(const QQmlJSScope::ConstPtr &type) const
QQmlJSScope::ConstPtr scopeForLocation(const QV4::CompiledData::Location &location) const
QQmlJSScope::ConstPtr m_uint64Type
QQmlJSScope::ConstPtr m_emptyType
QQmlJSScope::ConstPtr typeForConst(QV4::ReturnedValue rv) const
bool canAddressValueTypes() const
bool isSignedInteger(const QQmlJSScope::ConstPtr &type) const
QQmlJSRegisterContent transformed(const QQmlJSRegisterContent &origin, QQmlJSScope::ConstPtr(QQmlJSTypeResolver::*op)(const QQmlJSScope::ConstPtr &) const) const
std::unique_ptr< QHash< QQmlJSScope::ConstPtr, TrackedType > > m_trackedTypes
QQmlJSScope::ConstPtr m_uint8Type
QQmlJSRegisterContent scopedType(const QQmlJSScope::ConstPtr &scope, const QString &name, int lookupIndex=QQmlJSRegisterContent::InvalidLookupIndex, QQmlJSScopesByIdOptions options=Default) const
QQmlJSScope::ConstPtr m_variantListType
QQmlJSScope::ConstPtr typeForName(const QString &name) const
bool isNativeArrayIndex(const QQmlJSScope::ConstPtr &type) const
QQmlJSScope::ConstPtr varType() const
QQmlJSRegisterContent typeForBinaryOperation(QSOperator::Op oper, const QQmlJSRegisterContent &left, const QQmlJSRegisterContent &right) const
QQmlJSScope::ConstPtr m_dateType
QQmlJSScope::ConstPtr variantMapType() const
iterator end()
Definition qset.h:140
const_iterator constEnd() const noexcept
Definition qset.h:143
const_iterator constFind(const T &value) const
Definition qset.h:161
iterator find(const T &value)
Definition qset.h:159
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
\inmodule QtCore
static constexpr QTypeRevision zero()
Produces a QTypeRevision with major and minor version {0}.
constexpr bool isValid() const
Returns true if the major version or the minor version is known, otherwise false.
static constexpr QTypeRevision fromEncodedVersion(Integer value)
Produces a QTypeRevision from the given value.
void extension()
[6]
Definition dialogs.cpp:230
#define this
Definition dialogs.cpp:9
QSet< QString >::iterator it
Combined button and popup list for selecting options.
quint64 ReturnedValue
qsizetype erase(QByteArray &ba, const T &t)
Definition qbytearray.h:782
#define Q_FALLTHROUGH()
static const QCssKnownValue origins[NumKnownOrigins - 1]
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
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
@ QtInfoMsg
Definition qlogging.h:34
#define Q_LOGGING_CATEGORY(name,...)
#define qCDebug(category,...)
const char * typeName
GLint location
GLboolean GLboolean GLboolean b
GLenum mode
GLboolean GLboolean GLboolean GLboolean a
[7]
GLuint index
[2]
GLuint GLuint end
GLsizei GLenum GLenum * types
GLdouble GLdouble right
GLint left
GLenum type
GLuint program
GLuint name
GLuint64EXT * result
[6]
const QQmlSA::LoggerWarningId qmlPrefixedImportType
const QQmlSA::LoggerWarningId qmlCompiler
static bool isRevisionAllowed(int memberRevision, const QQmlJSScope::ConstPtr &scope)
static void assertExtension(const QQmlJSScope::ConstPtr &type, QLatin1String extension)
static QQmlJSRegisterContent::ContentVariant scopeContentVariant(QQmlJSScope::ExtensionKind mode, bool isMethod)
static QQmlJSRegisterContent::ContentVariant mergeVariants(QQmlJSRegisterContent::ContentVariant a, QQmlJSRegisterContent::ContentVariant b)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
SSL_CTX int void * arg
static const uint base
Definition qurlidna.cpp:20
const char property[13]
Definition qwizard.cpp:101
QList< int > list
[14]
if(qFloatDistance(a, b)<(1<< 7))
[0]
QVariant variant
[1]
QExplicitlySharedDataPointer< Derived > derived(base)
QLayoutItem * child
[0]
QQmlJSScope::ConstPtr scope
static bool searchBaseAndExtensionTypes(QQmlJSScopePtr type, const Action &check)
ImportedScope< QQmlJSScope::ConstPtr > type(const QString &name) const
static constexpr Value fromReturnedValue(ReturnedValue val)
Definition qv4value_p.h:165
static QString asString(QQmlJS::AST::UiQualifiedId *node)