Qt 6.x
The Qt SDK
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 : m_imports(importer->builtinInternalNames()),
24 m_trackedTypes(std::make_unique<QHash<QQmlJSScope::ConstPtr, TrackedType>>())
25{
26 const QQmlJSImporter::ImportedTypes &builtinTypes = m_imports;
27 m_voidType = builtinTypes.type(u"void"_s).scope;
29 m_nullType = builtinTypes.type(u"std::nullptr_t"_s).scope;
31 m_realType = builtinTypes.type(u"double"_s).scope;
33 m_floatType = builtinTypes.type(u"float"_s).scope;
35 m_int8Type = builtinTypes.type(u"qint8"_s).scope;
37 m_uint8Type = builtinTypes.type(u"quint8"_s).scope;
39 m_int16Type = builtinTypes.type(u"short"_s).scope;
41 m_uint16Type = builtinTypes.type(u"ushort"_s).scope;
43 m_int32Type = builtinTypes.type(u"int"_s).scope;
45 m_uint32Type = builtinTypes.type(u"uint"_s).scope;
47 m_int64Type = builtinTypes.type(u"qlonglong"_s).scope;
49 m_uint64Type = builtinTypes.type(u"qulonglong"_s).scope;
51 m_boolType = builtinTypes.type(u"bool"_s).scope;
53 m_stringType = builtinTypes.type(u"QString"_s).scope;
55 m_stringListType = builtinTypes.type(u"QStringList"_s).scope;
57 m_byteArrayType = builtinTypes.type(u"QByteArray"_s).scope;
59 m_urlType = builtinTypes.type(u"QUrl"_s).scope;
61 m_dateTimeType = builtinTypes.type(u"QDateTime"_s).scope;
63 m_dateType = builtinTypes.type(u"QDate"_s).scope;
65 m_timeType = builtinTypes.type(u"QTime"_s).scope;
67 m_variantListType = builtinTypes.type(u"QVariantList"_s).scope;
69 m_variantMapType = builtinTypes.type(u"QVariantMap"_s).scope;
71 m_varType = builtinTypes.type(u"QVariant"_s).scope;
73 m_jsValueType = builtinTypes.type(u"QJSValue"_s).scope;
75 m_listPropertyType = builtinTypes.type(u"QQmlListProperty<QObject>"_s).scope;
77 m_qObjectType = builtinTypes.type(u"QObject"_s).scope;
79 m_qObjectListType = builtinTypes.type(u"QObjectList"_s).scope;
81 m_functionType = builtinTypes.type(u"function"_s).scope;
83 m_numberPrototype = builtinTypes.type(u"NumberPrototype"_s).scope;
85 m_arrayPrototype = builtinTypes.type(u"ArrayPrototype"_s).scope;
87
89 emptyType->setAccessSemantics(QQmlJSScope::AccessSemantics::None);
91
93 jsPrimitiveType->setInternalName(u"QJSPrimitiveValue"_s);
94 jsPrimitiveType->setFilePath(u"qjsprimitivevalue.h"_s);
95 jsPrimitiveType->setAccessSemantics(QQmlJSScope::AccessSemantics::Value);
97
99 metaObjectType->setInternalName(u"const QMetaObject"_s);
100 metaObjectType->setFilePath(u"qmetaobject.h"_s);
101 metaObjectType->setAccessSemantics(QQmlJSScope::AccessSemantics::Reference);
103
104 m_jsGlobalObject = importer->jsGlobalObject();
105}
106
114{
115 m_logger = visitor->logger();
116
118 m_objectsByLocation.clear();
121
122 if (program)
123 program->accept(visitor);
124
125 m_objectsById = visitor->addressableScopes();
127 m_signalHandlers = visitor->signalHandlers();
128 m_imports = visitor->imports();
129}
130
133{
134 // #if required for standalone DOM compilation against Qt 6.2
135 qCDebug(lcTypeResolver()).nospace()
136 << "looking for object at " << location.line() << ':' << location.column();
138}
139
141 const QString &id, const QQmlJSScope::ConstPtr &referrer) const
142{
143 return m_objectsById.scope(id, referrer);
144}
145
147 const QQmlJSScope::ConstPtr &scope, const QQmlJSScope::ConstPtr &referrer) const
148{
149 return m_objectsById.id(scope, referrer);
150}
151
153{
154 const QString typeId = QmlIR::IRBuilder::asString(type->typeId);
155 if (!type->typeArgument)
156 return m_imports.type(typeId).scope;
157 if (typeId == u"list"_s) {
158 if (const QQmlJSScope::ConstPtr typeArgument = typeForName(type->typeArgument->toString()))
159 return typeArgument->listType();
160 }
161 return QQmlJSScope::ConstPtr();
162}
163
165{
167 if (value.isUndefined())
168 return voidType();
169
170 if (value.isInt32())
171 return int32Type();
172
173 if (value.isBoolean())
174 return boolType();
175
176 if (value.isDouble())
177 return realType();
178
179 if (value.isNull())
180 return nullType();
181
182 if (value.isEmpty())
183 return emptyType();
184
185 return {};
186}
187
190 const QQmlJSRegisterContent &right) const
191{
192 Q_ASSERT(left.isValid());
193 Q_ASSERT(right.isValid());
194
195 switch (oper) {
205 return globalType(boolType());
211 return builtinType(int32Type());
213 return builtinType(uint32Type());
214 case QSOperator::Op::Add: {
215 const auto leftContents = containedType(left);
216 const auto rightContents = containedType(right);
217 if (equals(leftContents, stringType()) || equals(rightContents, stringType()))
218 return builtinType(stringType());
219
220 const QQmlJSScope::ConstPtr result = merge(leftContents, rightContents);
221 if (equals(result, boolType()))
222 return builtinType(int32Type());
223 if (isNumeric(result))
224 return builtinType(realType());
225
227 }
230 case QSOperator::Op::Exp: {
233 }
236 return builtinType(realType());
238 return right;
239 default:
240 break;
241 }
242
243 return merge(left, right);
244}
245
247 UnaryOperator op, const QQmlJSRegisterContent &operand) const
248{
249 switch (op) {
251 return builtinType(boolType());
253 return builtinType(int32Type());
255 if (isIntegral(operand))
256 return operand;
258 default:
259 if (equals(containedType(operand), boolType()))
260 return builtinType(int32Type());
261 break;
262 }
263
264 return builtinType(realType());
265}
266
268{
270}
271
273{
275}
276
278{
280}
281
283{
284 // Only types of length <= 32bit count as integral
286}
287
289{
290 return isNumeric(type)
293}
294
296{
300 return false;
301 return equals(scope, m_numberPrototype);
302 });
303}
304
306{
307 // Only types of length <= 32bit count as integral
308 return equals(type, m_int8Type)
311}
312
314{
315 // Only types of length <= 32bit count as integral
316 return equals(type, m_uint8Type)
319}
320
323{
324 if (container.isType())
325 return container.type();
326 if (container.isProperty())
327 return container.property().type();
328 if (container.isEnumeration())
329 return container.enumeration().type();
330 if (container.isMethod())
331 return container.storedType(); // Methods can only be stored in QJSValue.
332 if (container.isImportNamespace()) {
333 switch (container.variant()) {
335 return container.storedType(); // We don't store scope module prefixes
337 return container.scopeType(); // We need to pass the original object through.
338 default:
339 Q_UNREACHABLE();
340 }
341 }
342 if (container.isConversion())
343 return container.conversionResult();
344
345 Q_UNREACHABLE_RETURN({});
346}
347
349{
351 return type;
352
353 // If origin is in fact an already tracked type, track the original of that one instead.
354 const auto it = m_trackedTypes->find(type);
355 QQmlJSScope::ConstPtr orig = (it == m_trackedTypes->end()) ? type : it->original;
356
358 m_trackedTypes->insert(clone, { std::move(orig), QQmlJSScope::ConstPtr(), clone });
359 return clone;
360}
361
363 const QQmlJSRegisterContent &origin,
364 QQmlJSScope::ConstPtr (QQmlJSTypeResolver::*op)(const QQmlJSScope::ConstPtr &) const) const
365{
366 if (origin.isType()) {
368 (this->*op)(origin.storedType()), (this->*op)(origin.type()),
369 origin.variant(), (this->*op)(origin.scopeType()));
370 }
371
372 if (origin.isProperty()) {
373 QQmlJSMetaProperty prop = origin.property();
374 prop.setType((this->*op)(prop.type()));
376 (this->*op)(origin.storedType()), prop,
377 origin.variant(), (this->*op)(origin.scopeType()));
378 }
379
380 if (origin.isEnumeration()) {
381 QQmlJSMetaEnum enumeration = origin.enumeration();
382 enumeration.setType((this->*op)(enumeration.type()));
384 (this->*op)(origin.storedType()), enumeration, origin.enumMember(),
385 origin.variant(), (this->*op)(origin.scopeType()));
386 }
387
388 if (origin.isMethod()) {
390 (this->*op)(origin.storedType()), origin.method(), origin.variant(),
391 (this->*op)(origin.scopeType()));
392 }
393
394 if (origin.isImportNamespace()) {
396 (this->*op)(origin.storedType()), origin.importNamespace(),
397 origin.variant(), (this->*op)(origin.scopeType()));
398 }
399
400 if (origin.isConversion()) {
402 (this->*op)(origin.storedType()), origin.conversionOrigins(),
403 (this->*op)(origin.conversionResult()),
404 origin.variant(), (this->*op)(origin.scopeType()));
405 }
406
407 Q_UNREACHABLE_RETURN({});
408}
409
411 const QString &name, const QQmlJSScope::ConstPtr &scopeType,
412 bool hasObjectModulePrefix) const
413{
415 if (!type)
416 return QQmlJSRegisterContent();
417
418 if (type->isSingleton())
421
422 if (type->isScript())
425
426 if (const auto attached = type->attachedType()) {
427 if (!genericType(attached)) {
428 m_logger->log(u"Cannot resolve generic base of attached %1"_s.arg(
429 attached->internalName()),
430 qmlCompiler, attached->sourceLocation());
431 return {};
432 } else if (type->accessSemantics() != QQmlJSScope::AccessSemantics::Reference) {
433 m_logger->log(u"Cannot retrieve attached object for non-reference type %1"_s.arg(
434 type->internalName()),
435 qmlCompiler, type->sourceLocation());
436 return {};
437 } else {
438 // We don't know yet whether we need the attached or the plain object. In direct
439 // mode, we will figure this out using the scope type and access any enums of the
440 // plain type directly. In indirect mode, we can use enum lookups.
442 storedType(attached), attached,
443 hasObjectModulePrefix
446 }
447 }
448
449 switch (type->accessSemantics()) {
450 case QQmlJSScope::AccessSemantics::None:
451 case QQmlJSScope::AccessSemantics::Reference:
452 // A plain reference to a non-singleton, non-attached type.
453 // We may still need the plain type reference for enum lookups,
454 // Store it as QMetaObject.
455 // This only works with namespaces and object types.
458 case QQmlJSScope::AccessSemantics::Sequence:
459 case QQmlJSScope::AccessSemantics::Value:
460 if (canAddressValueTypes()) {
463 }
464 // Else this is not actually a type reference. You cannot get the metaobject
465 // of a value type in QML and sequences don't even have metaobjects.
466 break;
467 }
468
469 return QQmlJSRegisterContent();
470}
471
473{
475}
476
478{
480}
481
483 const QQmlJSRegisterContent &container) const
484{
485 const QQmlJSScope::ConstPtr type = containedType(container);
486 return m_trackedTypes->contains(type) ? type : QQmlJSScope::ConstPtr();
487}
488
490 const QQmlJSRegisterContent &container) const
491{
492 return originalType(containedType(container));
493}
494
496 const QQmlJSScope::ConstPtr &tracked, const QQmlJSScope::ConstPtr &conversion) const
497{
499 return true;
500
501 const auto it = m_trackedTypes->find(tracked);
502 Q_ASSERT(it != m_trackedTypes->end());
503
504 // If we cannot convert to the new type without the help of e.g. lookupResultMetaType(),
505 // we better not change the type.
506 if (!canPrimitivelyConvertFromTo(tracked, conversion)
507 && !canPopulate(conversion, tracked, nullptr)
508 && !selectConstructor(conversion, tracked, nullptr).isValid()) {
509 return false;
510 }
511
512 it->replacement = comparableType(conversion);
513 *it->clone = std::move(*QQmlJSScope::clone(conversion));
514 return true;
515}
516
518 const QQmlJSScope::ConstPtr &tracked, const QList<QQmlJSScope::ConstPtr> &conversions) const
519{
521 return true;
522
523 const auto it = m_trackedTypes->find(tracked);
524 Q_ASSERT(it != m_trackedTypes->end());
525 QQmlJSScope::Ptr mutableTracked = it->clone;
527 for (const QQmlJSScope::ConstPtr &type : conversions)
529
530 // If we cannot convert to the new type without the help of e.g. lookupResultMetaType(),
531 // we better not change the type.
533 && !canPopulate(result, tracked, nullptr)
534 && !selectConstructor(result, tracked, nullptr).isValid()) {
535 return false;
536 }
537
538 it->replacement = comparableType(result);
539 *mutableTracked = std::move(*QQmlJSScope::clone(result));
540 return true;
541}
542
544 const QQmlJSScope::ConstPtr &tracked, const QQmlJSScope::ConstPtr &conversion) const
545{
547 return;
548
549 const auto it = m_trackedTypes->find(tracked);
550 Q_ASSERT(it != m_trackedTypes->end());
551
552 it->original = conversion;
553 *it->clone = std::move(*QQmlJSScope::clone(conversion));
554}
555
557{
559 return;
560
561 const auto it = m_trackedTypes->find(type);
562 Q_ASSERT(it != m_trackedTypes->end());
563 *it->clone = std::move(*QQmlJSScope::clone(genericType(type)));
564 if (it->replacement)
565 it->replacement = genericType(it->replacement);
566 it->original = genericType(it->original);
567}
568
570 bool useFancyName) const
571{
573
574 // Use the type proper instead of the attached type
575 switch (container.variant()) {
578 type = container.scopeType();
579 break;
580 default:
581 type = containedType(container);
582 break;
583 }
584
585 QString typeName = type->internalName().isEmpty() ? type->baseTypeName() : type->internalName();
586
587 if (useFancyName)
589
590 return typeName;
591}
592
594 const QQmlJSScope::ConstPtr &to) const
595{
596 if (canPrimitivelyConvertFromTo(from, to)
597 || canPopulate(to, from, nullptr)
598 || selectConstructor(to, from, nullptr).isValid()) {
599 return true;
600 }
601
602 // ### need a generic solution for custom cpp types:
603 // if (from->m_hasBoolOverload && equals(to, boolType))
604 // return true;
605
606 // All of these types have QString conversions that require a certain format
607 // TODO: Actually verify these strings or deprecate them.
608 // Some of those type are builtins or should be builtins. We should add code for them
609 // in QQmlJSCodeGenerator::conversion().
610 if (equals(from, m_stringType) && !to.isNull()) {
611 const QString toTypeName = to->internalName();
612 if (toTypeName == u"QPoint"_s || toTypeName == u"QPointF"_s
613 || toTypeName == u"QSize"_s || toTypeName == u"QSizeF"_s
614 || toTypeName == u"QRect"_s || toTypeName == u"QRectF"_s) {
615 return true;
616 }
617 }
618
619 return false;
620}
621
623 const QQmlJSRegisterContent &to) const
624{
626}
627
630{
631 return (a == b) ? a : QQmlJSRegisterContent::Unknown;
632}
633
635 const QQmlJSRegisterContent &b) const
636{
638 if (a.isConversion())
639 origins.append(a.conversionOrigins());
640 else
641 origins.append(containedType(a));
642
643 if (b.isConversion())
644 origins.append(b.conversionOrigins());
645 else
646 origins.append(containedType(b));
647
648 std::sort(origins.begin(), origins.end());
649 const auto erase = std::unique(origins.begin(), origins.end());
650 origins.erase(erase, origins.end());
651
653 merge(a.storedType(), b.storedType()),
654 origins,
656 mergeVariants(a.variant(), b.variant()),
657 merge(a.scopeType(), b.scopeType()));
658}
659
661 const QQmlJSScope::ConstPtr &b) const
662{
663 if (a.isNull())
664 return b;
665
666 if (b.isNull())
667 return a;
668
669 const auto commonBaseType = [this](
671 for (QQmlJSScope::ConstPtr aBase = a; aBase; aBase = aBase->baseType()) {
672 for (QQmlJSScope::ConstPtr bBase = b; bBase; bBase = bBase->baseType()) {
673 if (equals(aBase, bBase))
674 return aBase;
675 }
676 }
677
678 return QQmlJSScope::ConstPtr();
679 };
680
681
682 if (equals(a, b))
683 return a;
684
685 if (equals(a, jsValueType()) || equals(a, varType()))
686 return a;
687 if (equals(b, jsValueType()) || equals(b, varType()))
688 return b;
689
690 const auto isInt32Compatible = [&](const QQmlJSScope::ConstPtr &type) {
691 return (isIntegral(type) && !equals(type, uint32Type())) || equals(type, boolType());
692 };
693
694 if (isInt32Compatible(a) && isInt32Compatible(b))
695 return int32Type();
696
697 const auto isUInt32Compatible = [&](const QQmlJSScope::ConstPtr &type) {
699 };
700
701 if (isUInt32Compatible(a) && isUInt32Compatible(b))
702 return uint32Type();
703
704 if (isNumeric(a) && isNumeric(b))
705 return realType();
706
707 const auto isStringCompatible = [&](const QQmlJSScope::ConstPtr &type) {
708 // TODO: We can losslessly coerce more types to string. Should we?
709 return isIntegral(type) || equals(type, stringType());
710 };
711
712 if (isStringCompatible(a) && isStringCompatible(b))
713 return stringType();
714
715 if (isPrimitive(a) && isPrimitive(b))
716 return jsPrimitiveType();
717
718 if (auto commonBase = commonBaseType(a, b))
719 return commonBase;
720
721 if ((equals(a, nullType()) || equals(a, boolType())) && b->isReferenceType())
722 return b;
723
724 if ((equals(b, nullType()) || equals(b, boolType())) && a->isReferenceType())
725 return a;
726
727 return varType();
728}
729
731 const QQmlJSScope::ConstPtr &container, const QQmlJSScope::ConstPtr &contained) const
732{
733 if (equals(container, contained)
734 || equals(container, m_varType)
735 || equals(container, m_jsValueType)) {
736 return true;
737 }
738
739 if (equals(container, m_jsPrimitiveType))
740 return isPrimitive(contained);
741
742 if (equals(container, m_variantListType))
743 return contained->accessSemantics() == QQmlJSScope::AccessSemantics::Sequence;
744
745 if (equals(container, m_qObjectListType) || equals(container, m_listPropertyType)) {
746 if (contained->accessSemantics() != QQmlJSScope::AccessSemantics::Sequence)
747 return false;
748 if (QQmlJSScope::ConstPtr value = contained->valueType())
749 return value->isReferenceType();
750 return false;
751 }
752
754 container, [&](const QQmlJSScope::ConstPtr &base) {
755 return equals(base, contained);
756 })) {
757 return true;
758 }
759
760 if (container->isReferenceType()) {
762 contained, [&](const QQmlJSScope::ConstPtr &base) {
763 return equals(base, container);
764 })) {
765 return true;
766 }
767 }
768
769 return false;
770}
771
772
774{
775 const auto canBeUndefined = [this](const QQmlJSScope::ConstPtr &type) {
778 };
779
780 if (!canBeUndefined(content.storedType()))
781 return false;
782
783 if (!content.isConversion())
784 return canBeUndefined(containedType(content));
785
786 const auto origins = content.conversionOrigins();
787 for (const auto &origin : origins) {
788 if (canBeUndefined(origin))
789 return true;
790 }
791
792 return false;
793}
794
797 ComponentIsGeneric allowComponent) const
798{
799 if (type->isScript())
800 return m_jsValueType;
801
803 return m_metaObjectType;
804
805 if (type->accessSemantics() == QQmlJSScope::AccessSemantics::Reference) {
806 QString unresolvedBaseTypeName;
807 for (auto base = type; base;) {
808 // QObject and QQmlComponent are the two required base types.
809 // Any QML type system has to define those, or use the ones from builtins.
810 // As QQmlComponent is derived from QObject, we can restrict ourselves to the latter.
811 // This results in less if'ery when retrieving a QObject* from somewhere and deciding
812 // what it is.
813 if (base->internalName() == u"QObject"_s) {
814 return base;
815 } else if (allowComponent == ComponentIsGeneric::Yes
816 && base->internalName() == u"QQmlComponent"_s) {
817 return base;
818 }
819
820 if (auto baseBase = base->baseType()) {
821 base = baseBase;
822 } else {
823 unresolvedBaseTypeName = base->baseTypeName();
824 break;
825 }
826 }
827
828 m_logger->log(u"Object type %1 is not derived from QObject or QQmlComponent. "
829 "You may need to fully qualify all names in C++ so that moc can see them. "
830 "You may also need to add qt_extract_metatypes(<target containing %2>)."_s
831 .arg(type->internalName(), unresolvedBaseTypeName),
832 qmlCompiler, type->sourceLocation());
833
834 // Reference types that are not QObject or QQmlComponent are likely JavaScript objects.
835 // We don't want to deal with those, but m_jsValueType is the best generic option.
836 return m_jsValueType;
837 }
838
839 if (type->isListProperty())
840 return m_listPropertyType;
841
842 if (type->scopeType() == QQmlSA::ScopeType::EnumScope)
843 return type->baseType();
844
845 if (isPrimitive(type))
846 return type;
847
848 for (const QQmlJSScope::ConstPtr &builtin : {
855 if (equals(type, builtin) || equals(type, builtin->listType()))
856 return type;
857 }
858
859 return m_varType;
860}
861
863{
866}
867
869{
871}
872
874 bool isMethod)
875{
876 switch (mode) {
883 break;
884 }
885 Q_UNREACHABLE_RETURN(QQmlJSRegisterContent::Unknown);
886}
887
888static bool isRevisionAllowed(int memberRevision, const QQmlJSScope::ConstPtr &scope)
889{
890 Q_ASSERT(scope->isComposite());
891 const QTypeRevision revision = QTypeRevision::fromEncodedVersion(memberRevision);
892
893 // If the memberRevision is either invalid or 0.0, then everything is allowed.
894 if (!revision.isValid() || revision == QTypeRevision::zero())
895 return true;
896
898 {scope->baseType(), scope->baseTypeRevision()});
899
900 // If the revision is not valid, we haven't found a non-composite base type.
901 // There is nothing we can say about the property then.
902 return typeRevision.isValid() && typeRevision >= revision;
903}
904
906 const QString &name) const
907{
908 const auto isAssignedToDefaultProperty = [this](const QQmlJSScope::ConstPtr &parent,
910 const QString defaultPropertyName = parent->defaultPropertyName();
911 if (defaultPropertyName.isEmpty()) // no reason to search for bindings
912 return false;
913
914 const QList<QQmlJSMetaPropertyBinding> defaultPropBindings =
915 parent->propertyBindings(defaultPropertyName);
916 for (const QQmlJSMetaPropertyBinding &binding : defaultPropBindings) {
917 if (binding.bindingType() == QQmlSA::BindingType::Object
918 && equals(binding.objectType(), child)) {
919 return true;
920 }
921 }
922 return false;
923 };
924
925 if (QQmlJSScope::ConstPtr identified = scopeForId(name, scope)) {
926 return QQmlJSRegisterContent::create(storedType(identified), identified,
928 }
929
934 if (mode == QQmlJSScope::ExtensionNamespace) // no use for it here
935 return false;
936 if (found->hasOwnProperty(name)) {
937 QQmlJSMetaProperty prop = found->ownProperty(name);
938 if (!isRevisionAllowed(prop.revision(), scope))
939 return false;
940 if (m_parentMode == UseDocumentParent
941 && name == base->parentPropertyName()) {
942 QQmlJSScope::ConstPtr baseParent = base->parentScope();
943 if (baseParent && baseParent->inherits(prop.type())
944 && isAssignedToDefaultProperty(baseParent, base)) {
945 prop.setType(baseParent);
946 }
947 }
949 storedType(prop.type()),
950 prop, scopeContentVariant(mode, false), scope);
951 return true;
952 }
953
954 if (found->hasOwnMethod(name)) {
955 auto methods = found->ownMethods(name);
956 for (auto it = methods.begin(); it != methods.end();) {
957 if (!isRevisionAllowed(it->revision(), scope))
958 it = methods.erase(it);
959 else
960 ++it;
961 }
962 if (methods.isEmpty())
963 return false;
965 jsValueType(), methods, scopeContentVariant(mode, true), scope);
966 return true;
967 }
968
969 // Unqualified enums are not allowed
970
971 return false;
972 })) {
973 return result;
974 }
975 }
976
977 QQmlJSRegisterContent result = registerContentForName(name);
978
979 if (result.isValid())
980 return result;
981
982 if (m_jsGlobalObject->hasProperty(name)) {
983 return QQmlJSRegisterContent::create(jsValueType(), m_jsGlobalObject->property(name),
985 m_jsGlobalObject);
986 } else if (m_jsGlobalObject->hasMethod(name)) {
987 return QQmlJSRegisterContent::create(jsValueType(), m_jsGlobalObject->methods(name),
989 m_jsGlobalObject);
990 }
991
992 return {};
993}
994
998{
999 // You can't have lower case enum names in QML, even if we know the enums here.
1000 if (name.isEmpty() || !name.at(0).isUpper())
1001 return false;
1002
1003 const bool inExtension =
1005
1006 const auto enums = scope->ownEnumerations();
1007 for (const auto &enumeration : enums) {
1008 if (enumeration.name() == name) {
1010 storedType(enumeration.type()), enumeration, QString(),
1013 scope);
1014 return true;
1015 }
1016
1017 if (enumeration.hasKey(name)) {
1019 storedType(enumeration.type()), enumeration, name,
1022 scope);
1023 return true;
1024 }
1025 }
1026
1027 return false;
1028}
1029
1031 const QQmlJSScope::ConstPtr &type, const QQmlJSScope::ConstPtr &passedArgumentType,
1032 bool *isExtension) const
1033{
1034 // TODO: We could allow QVariantMap and QVariantHash to be populated, but that needs extra
1035 // code in the code generator.
1036
1037 if (type.isNull()
1038 || canHold(passedArgumentType, type)
1039 || isPrimitive(passedArgumentType)
1040 || type->accessSemantics() != QQmlJSScope::AccessSemantics::Value
1041 || !type->isStructured()) {
1042 return false;
1043 }
1044
1045 if (isExtension)
1046 *isExtension = !type->extensionType().scope.isNull();
1047
1048 return true;
1049}
1050
1052 const QQmlJSScope::ConstPtr &type, const QQmlJSScope::ConstPtr &passedArgumentType,
1053 bool *isExtension) const
1054{
1055 // If the "from" type can hold the target type, we should not try to coerce
1056 // it to any constructor argument.
1057 if (type.isNull()
1058 || canHold(passedArgumentType, type)
1059 || type->accessSemantics() != QQmlJSScope::AccessSemantics::Value
1060 || !type->isCreatable()) {
1061 return QQmlJSMetaMethod();
1062 }
1063
1064 auto doSelectConstructor = [&](const QQmlJSScope::ConstPtr &type) {
1065 QQmlJSMetaMethod candidate;
1066
1067 const auto ownMethods = type->ownMethods();
1068 for (const QQmlJSMetaMethod &method : ownMethods) {
1069 if (!method.isConstructor())
1070 continue;
1071
1072 const auto index = method.constructorIndex();
1074
1075 const auto methodArguments = method.parameters();
1076 if (methodArguments.size() != 1)
1077 continue;
1078
1079 const QQmlJSScope::ConstPtr methodArgumentType = methodArguments[0].type();
1080
1081 if (equals(passedArgumentType, methodArgumentType))
1082 return method;
1083
1084 // Do not select further ctors here. We don't want to do multi-step construction as that
1085 // is confusing and easily leads to infinite recursion.
1086 if (!candidate.isValid()
1087 && canPrimitivelyConvertFromTo(passedArgumentType, methodArgumentType)) {
1088 candidate = method;
1089 }
1090 }
1091
1092 return candidate;
1093 };
1094
1095 if (QQmlJSScope::ConstPtr extension = type->extensionType().scope) {
1096 const QQmlJSMetaMethod ctor = doSelectConstructor(extension);
1097 if (ctor.isValid()) {
1098 if (isExtension)
1099 *isExtension = true;
1100 return ctor;
1101 }
1102 }
1103
1104 if (isExtension)
1105 *isExtension = false;
1106
1107 return doSelectConstructor(type);
1108}
1109
1111 const QQmlJSScope::ConstPtr &a, const QQmlJSScope::ConstPtr &b) const
1112{
1113 const QQmlJSScope::ConstPtr equivalentLists[2][2] = {
1116 };
1117
1118 for (const auto eq : equivalentLists) {
1119 if ((equals(a, eq[0]) && equals(b, eq[1])) || (equals(a, eq[1]) && equals(b, eq[0])))
1120 return true;
1121 }
1122
1123 return false;
1124}
1125
1127{
1128 // pointers are trivially copyable
1129 if (type->isReferenceType())
1130 return true;
1131
1132 // Enum values are trivially copyable
1133 if (type->scopeType() == QQmlSA::ScopeType::EnumScope)
1134 return true;
1135
1136 for (const QQmlJSScope::ConstPtr &trivial : {
1144 if (equals(type, trivial))
1145 return true;
1146 }
1147
1148 return false;
1149}
1150
1152 const QQmlJSScope::ConstPtr &from, const QQmlJSScope::ConstPtr &to) const
1153{
1154 if (equals(from, to))
1155 return true;
1156 if (equals(from, m_varType) || equals(to, m_varType))
1157 return true;
1158 if (equals(from, m_jsValueType) || equals(to, m_jsValueType))
1159 return true;
1160 if (isNumeric(from) && isNumeric(to))
1161 return true;
1162 if (isNumeric(from) && equals(to, m_boolType))
1163 return true;
1164 if (from->accessSemantics() == QQmlJSScope::AccessSemantics::Reference
1165 && (equals(to, m_boolType) || equals(to, m_stringType))) {
1166 return true;
1167 }
1168
1169 // Yes, our String has number constructors.
1170 if (isNumeric(from) && equals(to, m_stringType))
1171 return true;
1172
1173 // We can convert strings to numbers, but not to enums
1174 if (equals(from, m_stringType) && isNumeric(to))
1175 return to->scopeType() != QQmlJSScope::ScopeType::EnumScope;
1176
1177 // We can always convert between strings and urls.
1178 if ((equals(from, m_stringType) && equals(to, m_urlType))
1179 || (equals(from, m_urlType) && equals(to, m_stringType))) {
1180 return true;
1181 }
1182
1183 // We can always convert between strings and byte arrays.
1184 if ((equals(from, m_stringType) && equals(to, m_byteArrayType))
1185 || (equals(from, m_byteArrayType) && equals(to, m_stringType))) {
1186 return true;
1187 }
1188
1189 if (equals(from, m_voidType) || equals(to, m_voidType))
1190 return true;
1191
1192 if (to.isNull())
1193 return false;
1194
1196 for (const auto &originType : types) {
1197 if (!equals(from, originType))
1198 continue;
1199
1200 for (const auto &targetType : types) {
1201 if (equals(to, targetType))
1202 return true;
1203 }
1204
1205 break;;
1206 }
1207
1208 if (equals(from, m_nullType)
1209 && to->accessSemantics() == QQmlJSScope::AccessSemantics::Reference) {
1210 return true;
1211 }
1212
1213 if (equals(from, m_jsPrimitiveType)) {
1214 // You can cast any primitive to a nullptr
1215 return isPrimitive(to) || to->accessSemantics() == QQmlJSScope::AccessSemantics::Reference;
1216 }
1217
1218 if (equals(to, m_jsPrimitiveType))
1219 return isPrimitive(from);
1220
1221 if (equals(from, m_variantListType))
1222 return to->accessSemantics() == QQmlJSScope::AccessSemantics::Sequence;
1223
1224 const bool matchByName = !to->isComposite();
1225 Q_ASSERT(!matchByName || !to->internalName().isEmpty());
1226 for (auto baseType = from; baseType; baseType = baseType->baseType()) {
1227 if (equals(baseType, to))
1228 return true;
1229 if (matchByName && baseType->internalName() == to->internalName())
1230 return true;
1231 }
1232
1233 // We can convert anything that fits into QJSPrimitiveValue
1235 return true;
1236
1237 // We can convert everything to bool.
1238 if (equals(to, m_boolType))
1239 return true;
1240
1241 if (areEquivalentLists(from, to))
1242 return true;
1243
1244 if (from->isListProperty()
1245 && to->accessSemantics() == QQmlJSScope::AccessSemantics::Sequence
1246 && canConvertFromTo(from->valueType(), to->valueType())) {
1247 return true;
1248 }
1249
1250 return false;
1251}
1252
1254 bool isWritable, const QQmlJSScope::ConstPtr &scope) const
1255{
1256 QQmlJSMetaProperty prop;
1257 prop.setPropertyName(u"length"_s);
1258 prop.setTypeName(u"int"_s);
1259 prop.setType(int32Type());
1260 prop.setIsWritable(isWritable);
1262}
1263
1265 const QString &name) const
1266{
1268
1269 // If we got a plain type reference we have to check the enums of the _scope_.
1270 if (equals(type, metaObjectType()))
1271 return {};
1272
1273 if (equals(type, variantMapType())) {
1274 QQmlJSMetaProperty prop;
1275 prop.setPropertyName(name);
1276 prop.setTypeName(u"QVariant"_s);
1277 prop.setType(varType());
1278 prop.setIsWritable(true);
1281 }
1282
1283 if (equals(type, jsValueType())) {
1284 QQmlJSMetaProperty prop;
1285 prop.setPropertyName(name);
1286 prop.setTypeName(u"QJSValue"_s);
1287 prop.setType(jsValueType());
1288 prop.setIsWritable(true);
1291 }
1292
1293 if ((equals(type, stringType())
1294 || type->accessSemantics() == QQmlJSScope::AccessSemantics::Sequence)
1295 && name == u"length"_s) {
1297 }
1298
1299 const auto check = [&](const QQmlJSScope::ConstPtr &scope, QQmlJSScope::ExtensionKind mode) {
1301 if (scope->hasOwnProperty(name)) {
1302 const auto prop = scope->ownProperty(name);
1304 storedType(prop.type()),
1305 prop,
1309 scope);
1310 return true;
1311 }
1312
1313 if (scope->hasOwnMethod(name)) {
1314 const auto methods = scope->ownMethods(name);
1320 scope);
1321 return true;
1322 }
1323
1324 if (std::optional<QQmlJSScope::JavaScriptIdentifier> identifier =
1325 scope->findJSIdentifier(name);
1326 identifier.has_value()) {
1327 QQmlJSMetaProperty prop;
1328 prop.setPropertyName(name);
1329 prop.setTypeName(u"QJSValue"_s);
1330 prop.setType(jsValueType());
1331 prop.setIsWritable(!identifier->isConst);
1332
1335 return true;
1336 }
1337 }
1338
1339 return checkEnums(scope, name, &result, mode);
1340 };
1341
1343 return result;
1344
1345 if (QQmlJSScope::ConstPtr attachedBase = typeForName(name)) {
1346 if (QQmlJSScope::ConstPtr attached = attachedBase->attachedType()) {
1347 if (!genericType(attached)) {
1348 m_logger->log(u"Cannot resolve generic base of attached %1"_s.arg(
1349 attached->internalName()),
1350 qmlCompiler, attached->sourceLocation());
1351 return {};
1352 } else if (type->accessSemantics() != QQmlJSScope::AccessSemantics::Reference) {
1353 m_logger->log(u"Cannot retrieve attached object for non-reference type %1"_s.arg(
1354 type->internalName()),
1355 qmlCompiler, type->sourceLocation());
1356 return {};
1357 } else {
1358 return QQmlJSRegisterContent::create(storedType(attached), attached,
1360 attachedBase);
1361 }
1362 }
1363 }
1364
1365 return {};
1366}
1367
1369 const QString &name) const
1370{
1372
1375 return checkEnums(scope, name, &result, mode);
1376 })) {
1377 return result;
1378 }
1379
1380 return {};
1381}
1382
1384 const QString &name) const
1385{
1386 if (type.isType()) {
1387 const auto content = type.type();
1388 const auto result = memberType(content, name);
1389 if (result.isValid())
1390 return result;
1391
1392 // If we didn't find anything and it's an attached type,
1393 // we might have an enum of the attaching type.
1394 return memberEnumType(type.scopeType(), name);
1395 }
1396 if (type.isProperty())
1397 return memberType(type.property().type(), name);
1398 if (type.isEnumeration()) {
1399 const auto enumeration = type.enumeration();
1400 if (!type.enumMember().isEmpty() || !enumeration.hasKey(name))
1401 return {};
1402 return QQmlJSRegisterContent::create(storedType(enumeration.type()), enumeration, name,
1404 }
1405 if (type.isMethod()) {
1406 QQmlJSMetaProperty prop;
1407 prop.setTypeName(u"QJSValue"_s);
1408 prop.setPropertyName(name);
1409 prop.setType(jsValueType());
1410 prop.setIsWritable(true);
1413 }
1414 if (type.isImportNamespace()) {
1415 if (type.scopeType()->accessSemantics() != QQmlJSScope::AccessSemantics::Reference) {
1416 m_logger->log(u"Cannot use a non-QObject type %1 to access prefixed import"_s.arg(
1417 type.scopeType()->internalName()),
1418 qmlPrefixedImportType, type.scopeType()->sourceLocation());
1419 return {};
1420 }
1421
1423 name, type.scopeType(),
1425 }
1426 if (type.isConversion()) {
1427 if (const auto result = memberType(type.conversionResult(), name); result.isValid())
1428 return result;
1429 if (const auto result = memberEnumType(type.scopeType(), name); result.isValid())
1430 return result;
1431
1432 // If the conversion consists of only undefined and one actual type,
1433 // we can produce the members of that one type.
1434 // If the value is then actually undefined, the result is an exception.
1435
1436 auto origins = type.conversionOrigins();
1437 const auto begin = origins.begin();
1438 const auto end = std::remove_if(begin, origins.end(),
1439 [this](const QQmlJSScope::ConstPtr &origin) {
1440 return equals(origin, m_voidType);
1441 });
1442
1443 // If the conversion cannot hold the original type, it loses information.
1444 return (end - begin == 1 && canHold(type.conversionResult(), *begin))
1445 ? memberType(*begin, name)
1447 }
1448
1449 Q_UNREACHABLE_RETURN({});
1450}
1451
1453{
1456
1457 auto valueType = [this](const QQmlJSScope::ConstPtr &scope) {
1458 if (scope->accessSemantics() == QQmlJSScope::AccessSemantics::Sequence)
1459 return scope->valueType();
1460 else if (equals(scope, m_jsValueType) || equals(scope, m_varType))
1461 return m_jsValueType;
1462 else if (equals(scope, m_stringType))
1463 return m_stringType;
1464 return QQmlJSScope::ConstPtr();
1465 };
1466
1467 if (list.isType()) {
1468 scope = list.type();
1469 value = valueType(scope);
1470 } else if (list.isConversion()) {
1471 value = valueType(list.conversionResult());
1472 } else if (list.isProperty()) {
1473 const auto prop = list.property();
1474 scope = prop.type();
1475 value = valueType(scope);
1476 }
1477
1478 if (value.isNull())
1479 return {};
1480
1482 property.setPropertyName(u"[]"_s);
1483 property.setTypeName(value->internalName());
1484 property.setType(value);
1485
1488}
1489
1492 const QQmlJSScope::ConstPtr &scope) const
1493{
1497}
1498
1500 const QQmlJSRegisterContent &reg, const QQmlJSScope::ConstPtr &type) const
1501{
1502 return equals(reg.storedType(), type);
1503}
1504
1506 const QQmlJSScope::ConstPtr &type) const
1507{
1508 if (reg.isType())
1509 return equals(reg.type(), type);
1510 if (reg.isConversion())
1511 return equals(reg.conversionResult(), type);
1512 if (reg.isProperty())
1513 return equals(type, reg.property().type());
1514 if (reg.isEnumeration())
1515 return equals(type, reg.enumeration().type());
1516 if (reg.isMethod())
1517 return equals(type, jsValueType());
1518 return false;
1519}
1520
1522{
1523 if (type.isNull())
1524 return {};
1525 if (equals(type, voidType()))
1526 return type;
1527 if (type->isScript())
1528 return jsValueType();
1529 if (type->isComposite()) {
1531 return nonComposite;
1532
1533 // If we can't find the non-composite base, we really don't know what it is.
1534 return genericType(type);
1535 }
1536 if (type->filePath().isEmpty())
1537 return genericType(type);
1538 return type;
1539}
1540
1542{
1543 const auto it = m_trackedTypes->find(type);
1544 return it == m_trackedTypes->end() ? type : it->original;
1545}
1546
1556{
1557 return comparableType(a) == comparableType(b);
1558}
1559
1561 const QQmlJSRegisterContent &from, const QQmlJSRegisterContent &to) const
1562{
1563 if (from.isConversion()) {
1565 to.storedType(), from.conversionOrigins(), containedType(to), from.variant(),
1566 from.scopeType());
1567 }
1568
1570 to.storedType(), QList<QQmlJSScope::ConstPtr>{containedType(from)},
1571 containedType(to), from.variant(), from.scopeType());
1572}
1573
1575{
1576 const auto it = m_trackedTypes->constFind(type);
1577 if (it == m_trackedTypes->constEnd())
1578 return type;
1579 return it->replacement ? it->replacement : it->original;
1580}
1581
static JNINativeMethod methods[]
\inmodule QtCore
Definition qhash.h:818
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:949
Definition qlist.h:74
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)
QQmlJSScope::ConstPtr conversionResult() const
QQmlJSMetaProperty property() const
QQmlJSScope::ConstPtr scopeType() const
static QQmlJSRegisterContent create(const QQmlJSScope::ConstPtr &storedType, const QQmlJSScope::ConstPtr &type, ContentVariant variant, const QQmlJSScope::ConstPtr &scope={})
QList< QQmlJSScope::ConstPtr > conversionOrigins() const
ContentVariant variant() const
QQmlJSScope::ConstPtr type() const
QQmlJSScope::ConstPtr storedType() const
QQmlJSMetaEnum enumeration() const
QList< QQmlJSMetaMethod > method() const
Tracks the types for the QmlCompiler.
QQmlJSMetaProperty ownProperty(const QString &name) const
bool isComposite() const
static QQmlJSScope::Ptr create()
void setAccessSemantics(AccessSemantics semantics)
QHash< QString, QQmlJSMetaEnum > ownEnumerations() const
ScopeType scopeType() const
void setInternalName(const QString &internalName)
QString internalName() const
bool isReferenceType() const
static QQmlJSScope::ConstPtr nonCompositeBaseType(const QQmlJSScope::ConstPtr &type)
AccessSemantics accessSemantics() const
bool isListProperty() const
QQmlJSScope::ConstPtr listType() const
static QTypeRevision nonCompositeBaseRevision(const ImportedScope< QQmlJSScope::ConstPtr > &scope)
QQmlJSScope::ConstPtr attachedType() const
static QQmlJSScope::Ptr clone(const QQmlJSScope::ConstPtr &origin)
QDeferredSharedPointer< const QQmlJSScope > ConstPtr
std::optional< JavaScriptIdentifier > findJSIdentifier(const QString &id) const
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
QString id(const QQmlJSScope::ConstPtr &scope, const QQmlJSScope::ConstPtr &referrer) const
QQmlJSScope::ConstPtr scope(const QString &id, const QQmlJSScope::ConstPtr &referrer) 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
QQmlJSRegisterContent memberType(const QQmlJSRegisterContent &type, const QString &name) const
QQmlJSMetaMethod selectConstructor(const QQmlJSScope::ConstPtr &type, const QQmlJSScope::ConstPtr &argument, bool *isExtension) const
QString idForScope(const QQmlJSScope::ConstPtr &scope, const QQmlJSScope::ConstPtr &referrer) 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
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 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
QQmlJSScope::ConstPtr scopeForId(const QString &id, const QQmlJSScope::ConstPtr &referrer) const
QQmlJSRegisterContent lengthProperty(bool isWritable, const QQmlJSScope::ConstPtr &scope) const
QQmlJSScope::ConstPtr boolType() const
QQmlJSScope::ConstPtr trackedType(const QQmlJSScope::ConstPtr &type) const
QQmlJSScope::ConstPtr m_jsPrimitiveType
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
bool registerContains(const QQmlJSRegisterContent &reg, const QQmlJSScope::ConstPtr &type) 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
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
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
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
QQmlJSScope::ConstPtr m_nullType
QQmlJSScope::ConstPtr voidType() const
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)
QQmlJSScope::ConstPtr m_timeType
QQmlJSScope::ConstPtr m_boolType
QQmlJSScope::ConstPtr metaObjectType() const
QQmlJSScope::ConstPtr m_metaObjectType
QQmlJSScope::ConstPtr realType() 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
QQmlJSScope::ConstPtr m_variantListType
QQmlJSScope::ConstPtr typeForName(const QString &name) const
QQmlJSRegisterContent scopedType(const QQmlJSScope::ConstPtr &scope, const QString &name) 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
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:1083
\inmodule QtCore
static constexpr QTypeRevision fromEncodedVersion(Integer value)
Produces a QTypeRevision from the given value.
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.
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:695
#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 QQmlJS::LoggerWarningId qmlPrefixedImportType
const QQmlJS::LoggerWarningId qmlCompiler
static bool isRevisionAllowed(int memberRevision, const QQmlJSScope::ConstPtr &scope)
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)
const char property[13]
Definition qwizard.cpp:101
QList< int > list
[14]
if(qFloatDistance(a, b)<(1<< 7))
[0]
QVariant variant
[1]
QLayoutItem * child
[0]
ImportedScope< ConstPtr > type(const QString &name) const
static bool searchBaseAndExtensionTypes(QQmlJSScopePtr type, const Action &check)
static constexpr Value fromReturnedValue(ReturnedValue val)
Definition qv4value_p.h:165
static QString asString(QQmlJS::AST::UiQualifiedId *node)
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent