6#include <private/qqmlengine_p.h>
7#include <private/qqmlvmemetaobject_p.h>
8#include <private/qv4function_p.h>
9#include <private/qv4functionobject_p.h>
10#include <private/qv4qobjectwrapper_p.h>
11#include <private/qqmlbinding_p.h>
12#include <private/qqmlstringconverters_p.h>
13#include <private/qqmlboundsignal_p.h>
14#include <private/qqmlcomponentattached_p.h>
15#include <private/qqmlcomponent_p.h>
16#include <private/qqmlcustomparser_p.h>
17#include <private/qqmlscriptstring_p.h>
18#include <private/qqmlpropertyvalueinterceptor_p.h>
19#include <private/qqmlvaluetypeproxybinding_p.h>
20#include <private/qqmldebugconnector_p.h>
21#include <private/qqmldebugserviceinterfaces_p.h>
22#include <private/qqmlscriptdata_p.h>
23#include <private/qqmlsourcecoordinate_p.h>
24#include <private/qjsvalue_p.h>
25#include <private/qv4generatorobject_p.h>
26#include <private/qv4resolvedtypereference_p.h>
27#include <private/qqmlpropertybinding_p.h>
28#include <private/qqmlanybinding_p.h>
29#include <QtQml/private/qqmlvme_p.h>
31#include <QScopedValueRollback>
33#include <qtqml_tracepoints_p.h>
34#include <QScopedValueRollback>
35#include <QLoggingCategory>
43"struct ExecutionEngine;
" \
44"namespace CompiledData {
" \
45"struct CompilationUnit;
" \
51Q_TRACE_POINT(qtqml, QQmlObjectCreator_createInstance_entry, const QV4::CompiledData::CompilationUnit *compilationUnit, const QV4::CompiledData::Object *object, const QUrl &url)
52Q_TRACE_POINT(qtqml, QQmlObjectCreator_createInstance_exit, const QString &typeName)
54QQmlObjectCreator::QQmlObjectCreator(
55 QQmlRefPointer<QQmlContextData> parentContext,
56 const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit,
57 const QQmlRefPointer<QQmlContextData> &creationContext,
58 QQmlIncubatorPrivate *incubator)
60 , compilationUnit(compilationUnit)
61 , propertyCaches(&compilationUnit->propertyCaches)
62 , sharedState(new QQmlObjectCreatorSharedState, QQmlRefPointer<QQmlObjectCreatorSharedState>::Adopt)
63 , topLevelCreator(true)
64 , isContextObject(true)
65 , incubator(incubator)
67 init(std::move(parentContext));
69 sharedState->componentAttached = nullptr;
70 sharedState->allCreatedBindings.allocate(compilationUnit->totalBindingsCount());
71 sharedState->allParserStatusCallbacks.allocate(compilationUnit->totalParserStatusCount());
72 sharedState->allCreatedObjects.allocate(compilationUnit->totalObjectCount());
73 sharedState->allJavaScriptObjects = nullptr;
74 sharedState->creationContext = creationContext;
75 sharedState->rootContext.reset();
76 sharedState->hadTopLevelRequiredProperties = false;
78 if (auto profiler = QQmlEnginePrivate::get(engine)->profiler) {
79 Q_QML_PROFILE_IF_ENABLED(QQmlProfilerDefinitions::ProfileCreating, profiler,
80 sharedState->profiler.init(profiler, compilationUnit->totalParserStatusCount()));
86QQmlObjectCreator::QQmlObjectCreator(QQmlRefPointer<QQmlContextData> parentContext,
87 const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit,
88 QQmlObjectCreatorSharedState *inheritedSharedState, bool isContextObject)
90 , compilationUnit(compilationUnit)
91 , propertyCaches(&compilationUnit->propertyCaches)
92 , sharedState(inheritedSharedState)
93 , topLevelCreator(false)
94 , isContextObject(isContextObject)
97 init(std::move(parentContext));
100void QQmlObjectCreator::init(QQmlRefPointer<QQmlContextData> providedParentContext)
102 parentContext = std::move(providedParentContext);
103 engine = parentContext->engine();
104 v4 = engine->handle();
106 if (compilationUnit && !compilationUnit->engine)
107 compilationUnit->linkToEngine(v4);
109 qmlUnit = compilationUnit->unitData();
111 _scopeObject = nullptr;
112 _bindingTarget = nullptr;
113 _valueTypeProperty = nullptr;
114 _compiledObject = nullptr;
115 _compiledObjectIndex = -1;
117 _vmeMetaObject = nullptr;
118 _qmlContext = nullptr;
121QQmlObjectCreator::~QQmlObjectCreator()
123 if (topLevelCreator) {
125 QQmlObjectCreatorRecursionWatcher watcher(this);
127 for (int i = 0; i < sharedState->allParserStatusCallbacks.count(); ++i) {
128 QQmlParserStatus *ps = sharedState->allParserStatusCallbacks.at(i);
132 while (sharedState->componentAttached) {
133 QQmlComponentAttached *a = sharedState->componentAttached;
139QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlInstantiationInterrupt *interrupt, int flags)
141 if (phase == CreatingObjectsPhase2) {
142 phase = ObjectsCreated;
143 return context->contextObject();
145 Q_ASSERT(phase == Startup);
146 phase = CreatingObjects;
149 bool isComponentRoot = false; // either a "real
" component of or an inline component
151 if (subComponentIndex == -1) {
152 objectToCreate = /*root object*/0;
153 isComponentRoot = true;
155 Q_ASSERT(subComponentIndex >= 0);
156 if (flags & CreationFlags::InlineComponent) {
157 if (compilationUnit->unitData()->flags & QV4::CompiledData::Unit::ComponentsBound
158 && compilationUnit != parentContext->typeCompilationUnit()) {
159 recordError({}, tr("Cannot instantiate bound
inline component in different
file"));
160 phase = ObjectsCreated;
163 objectToCreate = subComponentIndex;
164 isComponentRoot = true;
166 Q_ASSERT(flags & CreationFlags::NormalObject);
167 if (compilationUnit->unitData()->flags & QV4::CompiledData::Unit::ComponentsBound
168 && sharedState->creationContext != parentContext) {
169 recordError({}, tr("Cannot instantiate bound
component "
170 "outside its creation
context"));
171 phase = ObjectsCreated;
174 const QV4::CompiledData::Object *compObj = compilationUnit->objectAt(subComponentIndex);
175 objectToCreate = compObj->bindingTable()->value.objectIndex;
179 context = QQmlEnginePrivate::get(engine)->createInternalContext(
180 compilationUnit, parentContext, subComponentIndex, isComponentRoot);
182 if (!sharedState->rootContext) {
183 sharedState->rootContext = context;
184 sharedState->rootContext->setIncubator(incubator);
185 sharedState->rootContext->setRootObjectInCreation(true);
188 QV4::Scope scope(v4);
190 Q_ASSERT(sharedState->allJavaScriptObjects || topLevelCreator);
192 sharedState->allJavaScriptObjects = scope.alloc(compilationUnit->totalObjectCount());
194 if (!isComponentRoot && sharedState->creationContext) {
195 // otherwise QQmlEnginePrivate::createInternalContext() handles it
196 context->setImportedScripts(sharedState->creationContext->importedScripts());
199 QObject *instance = createInstance(objectToCreate, parent, /*isContextObject*/true);
201 QQmlData *ddata = QQmlData::get(instance);
203 ddata->compilationUnit = compilationUnit;
207 sharedState->allJavaScriptObjects = nullptr;
209 phase = CreatingObjectsPhase2;
211 if (interrupt && interrupt->shouldInterrupt())
214 phase = ObjectsCreated;
217 if (QQmlEngineDebugService *service
218 = QQmlDebugConnector::service<QQmlEngineDebugService>()) {
219 if (!parentContext->isInternal())
220 parentContext->asQQmlContextPrivate()->appendInstance(instance);
221 service->objectCreated(engine, instance);
222 } else if (!parentContext->isInternal() && QQmlDebugConnector::service<QV4DebugService>()) {
223 parentContext->asQQmlContextPrivate()->appendInstance(instance);
230void QQmlObjectCreator::beginPopulateDeferred(const QQmlRefPointer<QQmlContextData> &newContext)
232 context = newContext;
233 sharedState->rootContext = newContext;
235 Q_ASSERT(topLevelCreator);
236 Q_ASSERT(!sharedState->allJavaScriptObjects);
238 QV4::Scope valueScope(v4);
239 sharedState->allJavaScriptObjects = valueScope.alloc(compilationUnit->totalObjectCount());
242void QQmlObjectCreator::populateDeferred(QObject *instance, int deferredIndex,
243 const QQmlPropertyPrivate *qmlProperty,
244 const QV4::CompiledData::Binding *binding)
246 doPopulateDeferred(instance, deferredIndex, [this, qmlProperty, binding]() {
247 Q_ASSERT(qmlProperty);
248 Q_ASSERT(binding->hasFlag(QV4::CompiledData::Binding::IsDeferredBinding));
250 QQmlListProperty<void> savedList;
251 qSwap(_currentList, savedList);
253 const QQmlPropertyData &property = qmlProperty->core;
255 if (property.propType().flags().testFlag(QMetaType::IsQmlList)) {
256 void *argv[1] = { (void*)&_currentList };
257 QMetaObject::metacall(_qobject, QMetaObject::ReadProperty, property.coreIndex(), argv);
258 } else if (_currentList.object) {
259 _currentList = QQmlListProperty<void>();
262 setPropertyBinding(&property, binding);
264 qSwap(_currentList, savedList);
268void QQmlObjectCreator::populateDeferred(QObject *instance, int deferredIndex)
270 doPopulateDeferred(instance, deferredIndex, [this]() { setupBindings(ApplyDeferred); });
273bool QQmlObjectCreator::populateDeferredProperties(QObject *instance,
274 const QQmlData::DeferredData *deferredData)
276 beginPopulateDeferred(deferredData->context);
277 populateDeferred(instance, deferredData->deferredIdx);
278 finalizePopulateDeferred();
279 return errors.isEmpty();
282void QQmlObjectCreator::populateDeferredBinding(const QQmlProperty &qmlProperty, int deferredIndex,
283 const QV4::CompiledData::Binding *binding)
286 populateDeferred(qmlProperty.object(), deferredIndex, QQmlPropertyPrivate::get(qmlProperty),
289 populateDeferred(qmlProperty.object(), deferredIndex);
293void QQmlObjectCreator::finalizePopulateDeferred()
295 phase = ObjectsCreated;
298void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const QV4::CompiledData::Binding *binding)
300 QQmlPropertyData::WriteFlags propertyWriteFlags = QQmlPropertyData::BypassInterceptor | QQmlPropertyData::RemoveBindingOnAliasWrite;
301 QV4::Scope scope(v4);
303 QMetaType propertyType = property->propType();
305 if (property->isEnum()) {
306 if (binding->hasFlag(QV4::CompiledData::Binding::IsResolvedEnum)) {
307 propertyType = QMetaType::fromType<int>();
309 // ### This should be resolved earlier at compile time and the binding value should be changed accordingly.
310 QVariant value = compilationUnit->bindingValueAsString(binding);
311 bool ok = QQmlPropertyPrivate::write(_qobject, *property, value, context);
318 auto assertOrNull = [&](bool ok)
320 Q_ASSERT(ok || binding->type() == QV4::CompiledData::Binding::Type_Null);
324 auto assertType = [&](QV4::CompiledData::Binding::Type type)
326 Q_ASSERT(binding->type()== type || binding->type() == QV4::CompiledData::Binding::Type_Null);
330 if (property->isQObject()) {
331 if (binding->type() == QV4::CompiledData::Binding::Type_Null) {
332 QObject *value = nullptr;
333 const bool ok = property->writeProperty(_qobject, &value, propertyWriteFlags);
340 switch (propertyType.id()) {
341 case QMetaType::QVariant: {
342 if (binding->type() == QV4::CompiledData::Binding::Type_Number) {
343 double n = compilationUnit->bindingValueAsNumber(binding);
344 if (double(int(n)) == n) {
345 if (property->isVarProperty()) {
346 _vmeMetaObject->setVMEProperty(property->coreIndex(), QV4::Value::fromInt32(int(n)));
350 property->writeProperty(_qobject, &value, propertyWriteFlags);
353 if (property->isVarProperty()) {
354 _vmeMetaObject->setVMEProperty(property->coreIndex(), QV4::Value::fromDouble(n));
357 property->writeProperty(_qobject, &value, propertyWriteFlags);
360 } else if (binding->type() == QV4::CompiledData::Binding::Type_Boolean) {
361 if (property->isVarProperty()) {
362 _vmeMetaObject->setVMEProperty(property->coreIndex(), QV4::Value::fromBoolean(binding->valueAsBoolean()));
364 QVariant value(binding->valueAsBoolean());
365 property->writeProperty(_qobject, &value, propertyWriteFlags);
367 } else if (binding->type() == QV4::CompiledData::Binding::Type_Null) {
368 if (property->isVarProperty()) {
369 _vmeMetaObject->setVMEProperty(property->coreIndex(), QV4::Value::nullValue());
371 QVariant nullValue = QVariant::fromValue(nullptr);
372 property->writeProperty(_qobject, &nullValue, propertyWriteFlags);
375 QString stringValue = compilationUnit->bindingValueAsString(binding);
376 if (property->isVarProperty()) {
377 QV4::ScopedString s(scope, v4->newString(stringValue));
378 _vmeMetaObject->setVMEProperty(property->coreIndex(), s);
380 QVariant value = stringValue;
381 property->writeProperty(_qobject, &value, propertyWriteFlags);
386 case QMetaType::QString: {
387 assertOrNull(binding->evaluatesToString());
388 QString value = compilationUnit->bindingValueAsString(binding);
389 property->writeProperty(_qobject, &value, propertyWriteFlags);
392 case QMetaType::QStringList: {
393 assertOrNull(binding->evaluatesToString());
394 QStringList value(compilationUnit->bindingValueAsString(binding));
395 property->writeProperty(_qobject, &value, propertyWriteFlags);
398 case QMetaType::QByteArray: {
399 assertType(QV4::CompiledData::Binding::Type_String);
400 QByteArray value(compilationUnit->bindingValueAsString(binding).toUtf8());
401 property->writeProperty(_qobject, &value, propertyWriteFlags);
404 case QMetaType::QUrl: {
405 assertType(QV4::CompiledData::Binding::Type_String);
406 const QString string = compilationUnit->bindingValueAsString(binding);
407 QUrl value = (!string.isEmpty() && QQmlPropertyPrivate::resolveUrlsOnAssignment())
408 ? compilationUnit->finalUrl().resolved(QUrl(string))
410 property->writeProperty(_qobject, &value, propertyWriteFlags);
413 case QMetaType::UInt: {
414 assertType(QV4::CompiledData::Binding::Type_Number);
415 double d = compilationUnit->bindingValueAsNumber(binding);
416 uint value = uint(d);
417 property->writeProperty(_qobject, &value, propertyWriteFlags);
421 case QMetaType::Int: {
422 assertType(QV4::CompiledData::Binding::Type_Number);
423 double d = compilationUnit->bindingValueAsNumber(binding);
425 property->writeProperty(_qobject, &value, propertyWriteFlags);
429 case QMetaType::Float: {
430 assertType(QV4::CompiledData::Binding::Type_Number);
431 float value = float(compilationUnit->bindingValueAsNumber(binding));
432 property->writeProperty(_qobject, &value, propertyWriteFlags);
435 case QMetaType::Double: {
436 assertType(QV4::CompiledData::Binding::Type_Number);
437 double value = compilationUnit->bindingValueAsNumber(binding);
438 property->writeProperty(_qobject, &value, propertyWriteFlags);
441 case QMetaType::QColor: {
442 QVariant data = QQmlValueTypeProvider::createValueType(
443 compilationUnit->bindingValueAsString(binding), propertyType);
444 if (data.isValid()) {
445 property->writeProperty(_qobject, data.data(), propertyWriteFlags);
449#if QT_CONFIG(datestring)
450 case QMetaType::QDate: {
452 QDate value = QQmlStringConverters::dateFromString(compilationUnit->bindingValueAsString(binding), &ok);
454 property->writeProperty(_qobject, &value, propertyWriteFlags);
457 case QMetaType::QTime: {
459 QTime value = QQmlStringConverters::timeFromString(compilationUnit->bindingValueAsString(binding), &ok);
461 property->writeProperty(_qobject, &value, propertyWriteFlags);
464 case QMetaType::QDateTime: {
466 QDateTime value = QQmlStringConverters::dateTimeFromString(
467 compilationUnit->bindingValueAsString(binding), &ok);
469 property->writeProperty(_qobject, &value, propertyWriteFlags);
473 case QMetaType::QPoint: {
475 QPoint value = QQmlStringConverters::pointFFromString(compilationUnit->bindingValueAsString(binding), &ok).toPoint();
477 property->writeProperty(_qobject, &value, propertyWriteFlags);
480 case QMetaType::QPointF: {
482 QPointF value = QQmlStringConverters::pointFFromString(compilationUnit->bindingValueAsString(binding), &ok);
484 property->writeProperty(_qobject, &value, propertyWriteFlags);
487 case QMetaType::QSize: {
489 QSize value = QQmlStringConverters::sizeFFromString(compilationUnit->bindingValueAsString(binding), &ok).toSize();
491 property->writeProperty(_qobject, &value, propertyWriteFlags);
494 case QMetaType::QSizeF: {
496 QSizeF value = QQmlStringConverters::sizeFFromString(compilationUnit->bindingValueAsString(binding), &ok);
498 property->writeProperty(_qobject, &value, propertyWriteFlags);
501 case QMetaType::QRect: {
503 QRect value = QQmlStringConverters::rectFFromString(compilationUnit->bindingValueAsString(binding), &ok).toRect();
505 property->writeProperty(_qobject, &value, propertyWriteFlags);
508 case QMetaType::QRectF: {
510 QRectF value = QQmlStringConverters::rectFFromString(compilationUnit->bindingValueAsString(binding), &ok);
512 property->writeProperty(_qobject, &value, propertyWriteFlags);
515 case QMetaType::Bool: {
516 assertType(QV4::CompiledData::Binding::Type_Boolean);
517 bool value = binding->valueAsBoolean();
518 property->writeProperty(_qobject, &value, propertyWriteFlags);
521 case QMetaType::QVector2D:
522 case QMetaType::QVector3D:
523 case QMetaType::QVector4D:
524 case QMetaType::QQuaternion: {
525 QVariant result = QQmlValueTypeProvider::createValueType(
526 compilationUnit->bindingValueAsString(binding), propertyType);
527 assertOrNull(result.isValid());
528 property->writeProperty(_qobject, result.data(), propertyWriteFlags);
532 // generate single literal value assignment to a list property if required
533 if (propertyType == QMetaType::fromType<QList<qreal>>()) {
534 assertType(QV4::CompiledData::Binding::Type_Number);
536 value.append(compilationUnit->bindingValueAsNumber(binding));
537 property->writeProperty(_qobject, &value, propertyWriteFlags);
539 } else if (propertyType == QMetaType::fromType<QList<int>>()) {
540 assertType(QV4::CompiledData::Binding::Type_Number);
541 double n = compilationUnit->bindingValueAsNumber(binding);
543 value.append(int(n));
544 property->writeProperty(_qobject, &value, propertyWriteFlags);
546 } else if (propertyType == QMetaType::fromType<QList<bool>>()) {
547 assertType(QV4::CompiledData::Binding::Type_Boolean);
549 value.append(binding->valueAsBoolean());
550 property->writeProperty(_qobject, &value, propertyWriteFlags);
552 } else if (propertyType == QMetaType::fromType<QList<QUrl>>()) {
553 assertType(QV4::CompiledData::Binding::Type_String);
554 const QUrl url(compilationUnit->bindingValueAsString(binding));
556 QQmlPropertyPrivate::resolveUrlsOnAssignment()
557 ? compilationUnit->finalUrl().resolved(url)
560 property->writeProperty(_qobject, &value, propertyWriteFlags);
562 } else if (propertyType == QMetaType::fromType<QList<QString>>()) {
563 assertOrNull(binding->evaluatesToString());
564 QList<QString> value;
565 value.append(compilationUnit->bindingValueAsString(binding));
566 property->writeProperty(_qobject, &value, propertyWriteFlags);
568 } else if (propertyType == QMetaType::fromType<QJSValue>()) {
570 switch (binding->type()) {
571 case QV4::CompiledData::Binding::Type_Boolean:
572 value = QJSValue(binding->valueAsBoolean());
574 case QV4::CompiledData::Binding::Type_Number: {
575 const double n = compilationUnit->bindingValueAsNumber(binding);
576 if (double(int(n)) == n)
577 value = QJSValue(int(n));
582 case QV4::CompiledData::Binding::Type_Null:
583 value = QJSValue::NullValue;
586 value = QJSValue(compilationUnit->bindingValueAsString(binding));
589 property->writeProperty(_qobject, &value, propertyWriteFlags);
593 switch (binding->type()) {
594 case QV4::CompiledData::Binding::Type_Boolean:
595 source = binding->valueAsBoolean();
597 case QV4::CompiledData::Binding::Type_Number: {
598 const double n = compilationUnit->bindingValueAsNumber(binding);
599 if (double(int(n)) == n)
605 case QV4::CompiledData::Binding::Type_Null:
606 source = QVariant::fromValue<std::nullptr_t>(nullptr);
608 case QV4::CompiledData::Binding::Type_Invalid:
611 source = compilationUnit->bindingValueAsString(binding);
615 QVariant target = QQmlValueTypeProvider::createValueType(source, propertyType);
616 if (target.isValid()) {
617 property->writeProperty(_qobject, target.data(), propertyWriteFlags);
622 // string converters are not exposed, so ending up here indicates an error
623 QString stringValue = compilationUnit->bindingValueAsString(binding);
624 QMetaProperty metaProperty = _qobject->metaObject()->property(property->coreIndex());
625 recordError(binding->location, tr("Cannot assign
value %1 to
property"
626" %2
").arg(stringValue, QString::fromUtf8(metaProperty.name())));
632static QQmlType qmlTypeForObject(QObject *object)
635 const QMetaObject *mo = object->metaObject();
636 while (mo && !type.isValid()) {
637 type = QQmlMetaType::qmlType(mo);
638 mo = mo->superClass();
643void QQmlObjectCreator::setupBindings(BindingSetupFlags mode)
645 QQmlListProperty<void> savedList;
646 qSwap(_currentList, savedList);
648 const QV4::BindingPropertyData &propertyData = compilationUnit->bindingPropertyDataPerObject.at(_compiledObjectIndex);
650 if (_compiledObject->idNameIndex) {
651 const QQmlPropertyData *idProperty = propertyData.last();
652 Q_ASSERT(!idProperty || !idProperty->isValid() || idProperty->name(_qobject) == QLatin1String("id"));
653 if (idProperty && idProperty->isValid() && idProperty->isWritable() && idProperty->propType().id() == QMetaType::QString) {
654 QV4::CompiledData::Binding idBinding;
655 idBinding.propertyNameIndex = 0; // Not used
656 idBinding.clearFlags();
657 idBinding.setType(QV4::CompiledData::Binding::Type_String);
658 idBinding.stringIndex = _compiledObject->idNameIndex;
659 idBinding.location = _compiledObject->location; // ###
660 idBinding.value.nullMarker = 0; // zero the value field to make codechecker happy
661 setPropertyValue(idProperty, &idBinding);
665 // ### this is best done through type-compile-time binding skip lists.
666 if (_valueTypeProperty) {
667 QQmlAbstractBinding *binding = QQmlPropertyPrivate::binding(_bindingTarget, QQmlPropertyIndex(_valueTypeProperty->coreIndex()));
669 if (binding && binding->kind() != QQmlAbstractBinding::ValueTypeProxy) {
670 QQmlPropertyPrivate::removeBinding(_bindingTarget, QQmlPropertyIndex(_valueTypeProperty->coreIndex()));
671 } else if (binding) {
672 QQmlValueTypeProxyBinding *proxy = static_cast<QQmlValueTypeProxyBinding *>(binding);
674 if (qmlTypeForObject(_bindingTarget).isValid()) {
675 quint32 bindingSkipList = 0;
677 const QQmlPropertyData *defaultProperty = _compiledObject->indexOfDefaultPropertyOrAlias != -1 ? _propertyCache->parent()->defaultProperty() : _propertyCache->defaultProperty();
679 const QV4::CompiledData::Binding *binding = _compiledObject->bindingTable();
680 for (quint32 i = 0; i < _compiledObject->nBindings; ++i, ++binding) {
681 const QQmlPropertyData *property = binding->propertyNameIndex != 0
682 ? _propertyCache->property(stringAt(binding->propertyNameIndex),
686 bindingSkipList |= (1 << property->coreIndex());
689 proxy->removeBindings(bindingSkipList);
694 int currentListPropertyIndex = -1;
696 const QV4::CompiledData::Binding *binding = _compiledObject->bindingTable();
697 for (quint32 i = 0; i < _compiledObject->nBindings; ++i, ++binding) {
698 const QQmlPropertyData *const property = propertyData.at(i);
700 const QQmlPropertyData *targetProperty = property;
701 if (targetProperty->isAlias()) {
703 QQmlPropertyIndex originalIndex(targetProperty->coreIndex(), _valueTypeProperty ? _valueTypeProperty->coreIndex() : -1);
704 auto [targetObject, targetIndex] = QQmlPropertyPrivate::findAliasTarget(_bindingTarget, originalIndex);
705 QQmlData *data = QQmlData::get(targetObject);
706 Q_ASSERT(data && data->propertyCache);
707 targetProperty = data->propertyCache->property(targetIndex.coreIndex());
708 sharedState->requiredProperties.remove({targetObject, targetProperty});
710 sharedState->requiredProperties.remove({_bindingTarget, property});
714 if (binding->hasFlag(QV4::CompiledData::Binding::IsCustomParserBinding))
717 if (binding->hasFlag(QV4::CompiledData::Binding::IsDeferredBinding)) {
718 if (!(mode & ApplyDeferred))
720 } else if (!(mode & ApplyImmediate)) {
724 if (property && property->propType().flags().testFlag(QMetaType::IsQmlList)) {
725 if (property->coreIndex() != currentListPropertyIndex) {
726 void *argv[1] = { (void*)&_currentList };
727 QMetaObject::metacall(_qobject, QMetaObject::ReadProperty, property->coreIndex(), argv);
728 currentListPropertyIndex = property->coreIndex();
730 // manage override behavior
731 const QMetaObject *const metaobject = _qobject->metaObject();
732 const int qmlListBehavorClassInfoIndex = metaobject->indexOfClassInfo("QML.ListPropertyAssignBehavior
");
733 if (qmlListBehavorClassInfoIndex != -1) { // QML.ListPropertyAssignBehavior class info is set
734 const char *overrideBehavior =
735 metaobject->classInfo(qmlListBehavorClassInfoIndex).value();
736 if (!strcmp(overrideBehavior,
738 if (_currentList.clear) {
739 _currentList.clear(&_currentList);
742 bool isDefaultProperty =
743 (property->name(_qobject)
744 == QString::fromUtf8(
746 ->classInfo(metaobject->indexOfClassInfo(
749 if (!isDefaultProperty
750 && (!strcmp(overrideBehavior,
751 "ReplaceIfNotDefault
"))) {
752 if (_currentList.clear) {
753 _currentList.clear(&_currentList);
759 } else if (_currentList.object) {
760 _currentList = QQmlListProperty<void>();
761 currentListPropertyIndex = -1;
764 if (!setPropertyBinding(property, binding))
768 qSwap(_currentList, savedList);
771bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProperty, const QV4::CompiledData::Binding *binding)
773 const QV4::CompiledData::Binding::Type bindingType = binding->type();
774 if (bindingType == QV4::CompiledData::Binding::Type_AttachedProperty) {
775 Q_ASSERT(stringAt(compilationUnit->objectAt(binding->value.objectIndex)->inheritedTypeNameIndex).isEmpty());
776 QV4::ResolvedTypeReference *tr = resolvedType(binding->propertyNameIndex);
778 QQmlType attachedType = tr->type();
779 if (!attachedType.isValid()) {
780 QQmlTypeNameCache::Result res = context->imports()->query(
781 stringAt(binding->propertyNameIndex));
783 attachedType = res.type;
787 QObject *qmlObject = qmlAttachedPropertiesObject(
788 _qobject, attachedType.attachedPropertiesFunction(QQmlEnginePrivate::get(engine)));
790 recordError(binding->location,
792 .arg(QString::fromUtf8(attachedType.typeName())));
796 if (!populateInstance(binding->value.objectIndex, qmlObject, qmlObject,
797 /*value type property*/ nullptr, binding))
802 // ### resolve this at compile time
803 if (bindingProperty && bindingProperty->propType() == QMetaType::fromType<QQmlScriptString>()) {
804 QQmlScriptString ss(compilationUnit->bindingValueAsScriptString(binding),
805 context->asQQmlContext(), _scopeObject);
806 ss.d.data()->bindingId = bindingType == QV4::CompiledData::Binding::Type_Script ? binding->value.compiledScriptIndex : (quint32)QQmlBinding::Invalid;
807 ss.d.data()->lineNumber = binding->location.line();
808 ss.d.data()->columnNumber = binding->location.column();
809 ss.d.data()->isStringLiteral = bindingType == QV4::CompiledData::Binding::Type_String;
810 ss.d.data()->isNumberLiteral = bindingType == QV4::CompiledData::Binding::Type_Number;
811 ss.d.data()->numberValue = compilationUnit->bindingValueAsNumber(binding);
813 QQmlPropertyData::WriteFlags propertyWriteFlags = QQmlPropertyData::BypassInterceptor |
814 QQmlPropertyData::RemoveBindingOnAliasWrite;
815 int propertyWriteStatus = -1;
816 void *argv[] = { &ss, nullptr, &propertyWriteStatus, &propertyWriteFlags };
817 QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, bindingProperty->coreIndex(), argv);
821 QObject *createdSubObject = nullptr;
822 if (bindingType == QV4::CompiledData::Binding::Type_Object) {
823 createdSubObject = createInstance(binding->value.objectIndex, _bindingTarget);
824 if (!createdSubObject)
828 if (bindingType == QV4::CompiledData::Binding::Type_GroupProperty) {
829 const QV4::CompiledData::Object *obj = compilationUnit->objectAt(binding->value.objectIndex);
830 if (stringAt(obj->inheritedTypeNameIndex).isEmpty()) {
832 QObject *groupObject = nullptr;
833 QQmlGadgetPtrWrapper *valueType = nullptr;
834 const QQmlPropertyData *valueTypeProperty = nullptr;
835 QObject *bindingTarget = _bindingTarget;
836 int groupObjectIndex = binding->value.objectIndex;
838 if (!bindingProperty) {
839 for (int i = 0, end = compilationUnit->objectCount(); i != end; ++i) {
840 const QV4::CompiledData::Object *external = compilationUnit->objectAt(i);
841 if (external->idNameIndex == binding->propertyNameIndex) {
842 bindingTarget = groupObject = context->idValue(external->objectId());
848 } else if (QQmlMetaType::isValueType(bindingProperty->propType())) {
849 valueType = QQmlGadgetPtrWrapper::instance(engine, bindingProperty->propType());
851 recordError(binding->location, tr("Cannot
set properties on %1 as
it is null
").arg(stringAt(binding->propertyNameIndex)));
855 valueType->read(_qobject, bindingProperty->coreIndex());
857 groupObject = valueType;
858 valueTypeProperty = bindingProperty;
860 void *argv[1] = { &groupObject };
861 QMetaObject::metacall(_qobject, QMetaObject::ReadProperty, bindingProperty->coreIndex(), argv);
863 QQmlPropertyIndex index(bindingProperty->coreIndex());
864 auto anyBinding = QQmlAnyBinding::ofProperty(_qobject, index);
866 // if there is a binding, try to force-evaluate it now
867 // this might instantiate a necessary part of a grouped property
868 anyBinding.refresh();
869 QMetaObject::metacall(_qobject, QMetaObject::ReadProperty, bindingProperty->coreIndex(), argv);
872 recordError(binding->location, tr("Cannot
set properties on %1 as
it is null
").arg(stringAt(binding->propertyNameIndex)));
877 bindingTarget = groupObject;
880 if (!populateInstance(groupObjectIndex, groupObject, bindingTarget, valueTypeProperty,
886 valueType->write(_qobject, bindingProperty->coreIndex(), QQmlPropertyData::BypassInterceptor);
892 if (!bindingProperty) // ### error
895 const QV4::CompiledData::Binding::Flags bindingFlags = binding->flags();
896 const bool allowedToRemoveBinding
897 = !(bindingFlags & QV4::CompiledData::Binding::IsSignalHandlerExpression)
898 && !(bindingFlags & QV4::CompiledData::Binding::IsOnAssignment)
899 && !(bindingFlags & QV4::CompiledData::Binding::IsPropertyObserver)
900 && !_valueTypeProperty;
902 if (_ddata->hasBindingBit(bindingProperty->coreIndex()) && allowedToRemoveBinding) {
903 QQmlPropertyPrivate::removeBinding(_bindingTarget, QQmlPropertyIndex(bindingProperty->coreIndex()));
904 } else if (bindingProperty->isBindable() && allowedToRemoveBinding) {
905 removePendingBinding(_bindingTarget, bindingProperty->coreIndex());
908 if (bindingType == QV4::CompiledData::Binding::Type_Script || binding->isTranslationBinding()) {
909 if (bindingFlags & QV4::CompiledData::Binding::IsSignalHandlerExpression
910 || bindingFlags & QV4::CompiledData::Binding::IsPropertyObserver) {
911 QV4::Function *runtimeFunction = compilationUnit->runtimeFunctions[binding->value.compiledScriptIndex];
912 int signalIndex = _propertyCache->methodIndexToSignalIndex(bindingProperty->coreIndex());
913 QQmlBoundSignalExpression *expr = new QQmlBoundSignalExpression(
914 _bindingTarget, signalIndex, context,
915 _scopeObject, runtimeFunction, currentQmlContext());
917 if (bindingProperty->isBindable()) {
918 auto target = _bindingTarget;
919 if (bindingProperty->isAlias()) {
920 // If the property is an alias, we cannot obtain the bindable interface directly with qt_metacall
921 // so instead, we resolve the alias to obtain the actual target
922 // This should be faster than doing a detour through the metaobject of the target, and relying on
923 // QMetaObject::metacall doing the correct resolution
924 QQmlPropertyIndex originalIndex(bindingProperty->coreIndex(), _valueTypeProperty ? _valueTypeProperty->coreIndex() : -1);
925 auto [aliasTargetObject, aliasTargetIndex] = QQmlPropertyPrivate::findAliasTarget(target, originalIndex);
926 target = aliasTargetObject;
927 QQmlData *data = QQmlData::get(target);
928 Q_ASSERT(data && data->propertyCache);
929 bindingProperty = data->propertyCache->property(aliasTargetIndex.coreIndex());
931 auto &observer = QQmlData::get(_scopeObject)->propertyObservers.emplace_back(expr);
932 QUntypedBindable bindable;
933 void *argv[] = { &bindable };
934 target->qt_metacall(QMetaObject::BindableProperty, bindingProperty->coreIndex(), argv);
935 Q_ASSERT(bindable.isValid());
936 bindable.observe(&observer);
938 QQmlBoundSignal *bs = new QQmlBoundSignal(_bindingTarget, signalIndex, _scopeObject, engine);
939 bs->takeExpression(expr);
941 } else if (bindingProperty->isBindable()) {
942 QUntypedPropertyBinding qmlBinding;
943 if (binding->isTranslationBinding()) {
944 qmlBinding = QQmlTranslationPropertyBinding::create(bindingProperty, compilationUnit, binding);
946 QV4::Function *runtimeFunction = compilationUnit->runtimeFunctions[binding->value.compiledScriptIndex];
947 QQmlPropertyIndex index(bindingProperty->coreIndex(), -1);
948 qmlBinding = QQmlPropertyBinding::create(bindingProperty, runtimeFunction, _scopeObject, context, currentQmlContext(), _bindingTarget, index);
950 sharedState.data()->allQPropertyBindings.push_back(DeferredQPropertyBinding {_bindingTarget, bindingProperty->coreIndex(), qmlBinding });
952 // When writing bindings to grouped properties implemented as value types,
953 // such as point.x: { someExpression; }, then the binding is installed on
954 // the point property (_qobjectForBindings) and after evaluating the expression,
955 // the result is written to a value type virtual property, that contains the sub-index
956 // of the "x" property.
957 QQmlBinding::Ptr qmlBinding;
958 const QQmlPropertyData *targetProperty = bindingProperty;
959 const QQmlPropertyData *subprop = nullptr;
960 if (_valueTypeProperty) {
961 targetProperty = _valueTypeProperty;
962 subprop = bindingProperty;
964 if (binding->isTranslationBinding()) {
965 qmlBinding = QQmlBinding::createTranslationBinding(
966 compilationUnit, binding, _scopeObject, context);
968 QV4::Function *runtimeFunction = compilationUnit->runtimeFunctions[binding->value.compiledScriptIndex];
969 qmlBinding = QQmlBinding::create(targetProperty, runtimeFunction, _scopeObject,
970 context, currentQmlContext());
973 auto bindingTarget = _bindingTarget;
974 auto valueTypeProperty = _valueTypeProperty;
975 auto assignBinding = [qmlBinding, bindingTarget, targetProperty, subprop, bindingProperty, valueTypeProperty](QQmlObjectCreatorSharedState *sharedState) mutable -> bool {
976 if (!qmlBinding->setTarget(bindingTarget, *targetProperty, subprop) && targetProperty->isAlias())
979 sharedState->allCreatedBindings.push(qmlBinding);
981 if (bindingProperty->isAlias()) {
982 QQmlPropertyPrivate::setBinding(qmlBinding.data(), QQmlPropertyPrivate::DontEnable);
984 qmlBinding->addToObject();
986 if (!valueTypeProperty) {
987 QQmlData *targetDeclarativeData = QQmlData::get(bindingTarget);
988 Q_ASSERT(targetDeclarativeData);
989 targetDeclarativeData->setPendingBindingBit(bindingTarget, bindingProperty->coreIndex());
995 if (!assignBinding(sharedState.data()))
996 pendingAliasBindings.push_back(assignBinding);
1001 if (bindingType == QV4::CompiledData::Binding::Type_Object) {
1002 if (bindingFlags & QV4::CompiledData::Binding::IsOnAssignment) {
1003 // ### determine value source and interceptor casts ahead of time.
1004 QQmlType type = qmlTypeForObject(createdSubObject);
1005 Q_ASSERT(type.isValid());
1007 int valueSourceCast = type.propertyValueSourceCast();
1008 if (valueSourceCast != -1) {
1009 QQmlPropertyValueSource *vs = reinterpret_cast<QQmlPropertyValueSource *>(reinterpret_cast<char *>(createdSubObject) + valueSourceCast);
1010 QObject *target = createdSubObject->parent();
1012 if (_valueTypeProperty) {
1013 prop = QQmlPropertyPrivate::restore(target, *_valueTypeProperty,
1014 bindingProperty, context);
1016 prop = QQmlPropertyPrivate::restore(target, *bindingProperty, nullptr, context);
1018 vs->setTarget(prop);
1021 int valueInterceptorCast = type.propertyValueInterceptorCast();
1022 if (valueInterceptorCast != -1) {
1023 QQmlPropertyValueInterceptor *vi = reinterpret_cast<QQmlPropertyValueInterceptor *>(reinterpret_cast<char *>(createdSubObject) + valueInterceptorCast);
1024 QObject *target = createdSubObject->parent();
1026 QQmlPropertyIndex propertyIndex;
1027 if (bindingProperty->isAlias()) {
1028 QQmlPropertyIndex originalIndex(bindingProperty->coreIndex(), _valueTypeProperty ? _valueTypeProperty->coreIndex() : -1);
1029 auto aliasTarget = QQmlPropertyPrivate::findAliasTarget(target, originalIndex);
1030 target = aliasTarget.targetObject;
1031 QQmlData *data = QQmlData::get(target);
1032 if (!data || !data->propertyCache) {
1033 qWarning() << "can
't resolve property alias for 'on
' assignment";
1037 // we can't have aliasses on subproperties of
value types, so:
1038 QQmlPropertyData targetPropertyData = *
data->propertyCache->property(aliasTarget.targetIndex.coreIndex());
1041 vi->setTarget(prop);
1045 if (_valueTypeProperty) {
1052 vi->setTarget(prop);
1059 mo->registerInterceptor(propertyIndex, vi);
1067 if (!bindingProperty->isFunction()) {
1068 recordError(binding->valueLocation,
tr(
"Cannot assign an object to signal property %1").
arg(bindingProperty->name(_qobject)));
1073 recordError(binding->valueLocation,
tr(
"Cannot assign object type %1 with no default method").
arg(
QString::fromLatin1(createdSubObject->metaObject()->className())));
1076 qCWarning(lcQmlDefaultMethod) <<
"Assigning an object to a signal handler is deprecated."
1077 "Instead, create the object, give it an id, and call the desired slot from the signal handler."
1080 QMetaMethod signalMethod = _qobject->metaObject()->method(bindingProperty->coreIndex());
1082 recordError(binding->valueLocation,
1083 tr(
"Cannot connect mismatched signal/slot %1 vs %2")
1095 int propertyWriteStatus = -1;
1096 void *argv[] = {
nullptr,
nullptr, &propertyWriteStatus, &propertyWriteFlags };
1099 void *
ptr = createdSubObject->qt_metacast(iid);
1104 recordError(binding->location,
tr(
"Cannot assign object to interface property"));
1107 }
else if (bindingProperty->propType() == QMetaType::fromType<QVariant>()) {
1108 if (bindingProperty->isVarProperty()) {
1111 _vmeMetaObject->setVMEProperty(bindingProperty->coreIndex(), wrappedObject);
1117 }
else if (bindingProperty->propType() == QMetaType::fromType<QJSValue>()) {
1120 if (bindingProperty->isVarProperty()) {
1121 _vmeMetaObject->setVMEProperty(bindingProperty->coreIndex(), wrappedObject);
1131 void *itemToAdd = createdSubObject;
1137 itemToAdd = createdSubObject->qt_metacast(iid);
1140 if (_currentList.append)
1141 _currentList.append(&_currentList, itemToAdd);
1143 recordError(binding->location,
tr(
"Cannot assign object to read only list"));
1149 argv[0] = &createdSubObject;
1155 if (bindingProperty->isQList()) {
1156 recordError(binding->location,
tr(
"Cannot assign primitives to lists"));
1160 setPropertyValue(bindingProperty, binding);
1164void QQmlObjectCreator::setupFunctions()
1190 error.setUrl(compilationUnit->
url());
1193 error.setDescription(description);
1199 if (
object->objectId() >= 0)
1213 bool isComponent =
false;
1218 bool installPropertyCache =
true;
1231 if (
type.isValid() && !
type.isInlineComponentType()) {
1234 instance =
type.createWithQQmlData();
1236 recordError(
obj->location,
tr(
"Unable to create object of type %1").
arg(stringAt(
obj->inheritedTypeNameIndex)));
1240 const int finalizerCast =
type.finalizerCast();
1241 if (finalizerCast != -1) {
1242 auto hook =
reinterpret_cast<QQmlFinalizerHook *
>(
reinterpret_cast<char *
>(instance) + finalizerCast);
1245 const int parserStatusCast =
type.parserStatusCast();
1246 if (parserStatusCast != -1)
1247 parserStatus =
reinterpret_cast<QQmlParserStatus*
>(
reinterpret_cast<char *
>(instance) + parserStatusCast);
1249 customParser =
type.customParser();
1265 recordError(
obj->location,
tr(
"Composite Singleton Type %1 is not creatable").
arg(stringAt(
obj->inheritedTypeNameIndex)));
1269 if (!
type.isInlineComponentType()) {
1272 instance = subCreator.create();
1274 errors += subCreator.errors;
1280 subObjectName =
type.elementName();
1281 std::swap(*compilationUnit->
icRootName, subObjectName);
1283 compilationUnit->
icRootName = std::make_unique<QString>(
type.elementName());
1290 std::swap(*compilationUnit->
icRootName, subObjectName);
1295 instance = subCreator.create(
1299 errors += subCreator.errors;
1328 const bool documentRoot =
static_cast<quint32>(
index) == 0
1345 if (isContextObject)
1346 context->setContextObject(instance);
1357 bindings << binding;
1359 customParser->
applyBindings(instance, compilationUnit, bindings);
1361 customParser->engine =
nullptr;
1366 registerObjectWithContextById(
obj, instance);
1372 if (installPropertyCache)
1375 QObject *scopeObject = instance;
1376 qSwap(_scopeObject, scopeObject);
1387 bool ok = populateInstance(
index, instance, instance,
nullptr);
1389 if (isContextObject && !pendingAliasBindings.empty()) {
1390 bool processedAtLeastOneBinding =
false;
1392 processedAtLeastOneBinding =
false;
1393 for (std::vector<PendingAliasBinding>::iterator
it = pendingAliasBindings.begin();
1394 it != pendingAliasBindings.end(); ) {
1395 if ((*
it)(sharedState.
data())) {
1396 it = pendingAliasBindings.erase(
it);
1397 processedAtLeastOneBinding =
true;
1402 }
while (processedAtLeastOneBinding && pendingAliasBindings.empty());
1403 Q_ASSERT(pendingAliasBindings.empty());
1407 pendingAliasBindings.clear();
1411 qSwap(_scopeObject, scopeObject);
1413 return ok ? instance :
nullptr;
1418 Q_ASSERT(phase == ObjectsCreated || phase == Finalizing);
1441 if (!
b->isAddedToObject())
1445 data->clearPendingBindingBit(
b->targetPropertyIndex().coreIndex());
1463 void *argv[] = { &bindable };
1466 const bool success = bindable.
setBinding(qmlBinding);
1476 const bool canRemove = !qmlBinding.
error().hasError()
1477 && !qmlBindingPriv->hasDependencies()
1478 && !jsExpression->hasUnresolvedNames();
1493 if (status && status->d) {
1494 status->d =
nullptr;
1504 hook->componentFinalized();
1516 d->context->addComponentAttached(
a);
1518 emit a->completed();
1531 if (phase == Done || phase == Finalizing || phase == Startup)
1550bool QQmlObjectCreator::populateInstance(
int index,
QObject *instance,
QObject *bindingTarget,
1557 qSwap(_qobject, instance);
1558 qSwap(_valueTypeProperty, valueTypeProperty);
1562 qSwap(_ddata, declarativeData);
1563 qSwap(_bindingTarget, bindingTarget);
1581 registerObjectWithContextById(_compiledObject, _qobject);
1584 qSwap(_vmeMetaObject, vmeMetaObject);
1593 postHocRequired.
insert(stringAt(
it->nameIndex));
1594 bool hadInheritedRequiredProperties = !postHocRequired.
empty();
1596 for (
int propertyIndex = 0; propertyIndex != _compiledObject->
propertyCount(); ++propertyIndex) {
1598 const QQmlPropertyData *propertyData = _propertyCache->property(_propertyCache->propertyOffset() + propertyIndex);
1600 auto postHocIt = postHocRequired.
isEmpty() ? postHocRequired.
end() : postHocRequired.
find(stringAt(
property->nameIndex));
1601 if (!
property->isRequired() && postHocRequired.
end() == postHocIt)
1603 if (postHocIt != postHocRequired.
end())
1604 postHocRequired.
erase(postHocIt);
1605 if (isContextObject)
1612 const auto getPropertyCacheRange = [&]() -> std::pair<int, int> {
1634 return { 0, _propertyCache->propertyCount() };
1636 return { 0, _propertyCache->propertyOffset() + 1 };
1640 if (
type.isValid() && !
type.isInlineComponentType()) {
1641 return { 0, _propertyCache->propertyCount() };
1644 return { _propertyCache->propertyOffset(), _propertyCache->propertyCount() };
1646 const auto [
offset,
count] = getPropertyCacheRange();
1648 const QQmlPropertyData *propertyData = _propertyCache->maybeUnresolvedProperty(
i);
1657 auto postHocIt = postHocRequired.
find(
name);
1658 if (!propertyData->
isRequired() && postHocRequired.
end() == postHocIt )
1661 if (postHocIt != postHocRequired.
end())
1662 postHocRequired.
erase(postHocIt);
1664 if (isContextObject)
1667 {_qobject, propertyData},
1676 QLatin1String(
"Attached property has required properties. This is not supported"));
1683 if (!postHocRequired.
isEmpty()) {
1686 const QQmlPropertyData *propertyData = _propertyCache->maybeUnresolvedProperty(
i);
1690 auto postHocIt = postHocRequired.
find(
name);
1691 if (postHocRequired.
end() == postHocIt)
1693 postHocRequired.
erase(postHocIt);
1695 if (isContextObject)
1698 {_qobject, propertyData},
1704 if (!postHocRequired.
isEmpty() && hadInheritedRequiredProperties)
1705 recordError({},
QLatin1String(
"Property %1 was marked as required but does not exist").
arg(*postHocRequired.
begin()));
1710 ? BindingMode::ApplyAll
1711 : BindingMode::ApplyImmediate);
1713 for (
int aliasIndex = 0; aliasIndex != _compiledObject->
aliasCount(); ++aliasIndex) {
1715 const auto originalAlias = alias;
1719 if (!
context->isIdValueSet(0))
1729 if (!targetProperty)
1733 it->aliasesToRequired.push_back(
1735 compilationUnit->
stringAt(originalAlias->nameIndex()),
1740 qSwap(_vmeMetaObject, vmeMetaObject);
1741 qSwap(_bindingTarget, bindingTarget);
1742 qSwap(_ddata, declarativeData);
1745 qSwap(_valueTypeProperty, valueTypeProperty);
1746 qSwap(_qobject, instance);
1767 : sharedState(
creator->sharedState)
static void(* setWidgetParent)(QObject *, QObject *)
qsizetype size() const noexcept
Returns the number of items in the hash.
iterator find(const Key &key)
Returns an iterator pointing to the item with the key in the hash.
iterator end() noexcept
Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item after the last ...
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
QV4::ExecutionEngine * handle() const
static ObjectOwnership objectOwnership(QObject *)
Returns the ownership of object.
static void setValue(QJSValue *jsval, const QV4::Value &v)
The QJSValue class acts as a container for Qt/JavaScript data types.
QString arg(Args &&...args) const
bool isEmpty() const noexcept
void push_back(parameter_type t)
void pop_front() noexcept
bool isWidgetType() const
Returns true if the object is a widget; otherwise returns false.
static QPropertyBindingPrivate * get(const QUntypedPropertyBinding &binding)
void removeFromObject()
Remove the binding from the object.
virtual bool hasDependencies() const
static QQmlComponentPrivate * get(QQmlComponent *c)
QQmlGuardedContextData creationContext
The QQmlComponent class encapsulates a QML component definition.
void setRootObjectInCreation(bool rootInCreation)
bool isRootObjectInCreation() const
The QQmlCustomParser class allows you to add new arbitrary types to QML.
virtual void applyBindings(QObject *, const QQmlRefPointer< QV4::ExecutableCompilationUnit > &, const QList< const QV4::CompiledData::Binding * > &)=0
QQmlRefPointer< QV4::ExecutableCompilationUnit > compilationUnit
QQmlPropertyCache::ConstPtr propertyCache
static QQmlData * get(QObjectPrivate *priv, bool create)
void deferData(int objectIndex, const QQmlRefPointer< QV4::ExecutableCompilationUnit > &, const QQmlRefPointer< QQmlContextData > &)
void setImplicitDestructible()
quint32 rootObjectInCreation
static QQmlEnginePrivate * get(QQmlEngine *e)
The QQmlEngine class provides an environment for instantiating QML components.
The QQmlError class encapsulates a QML error.
bool shouldInterrupt() const
bool hasUnresolvedNames() const
QQmlError error(QQmlEngine *) const
bool finalize(QQmlInstantiationInterrupt &interrupt)
static QQmlComponent * createComponent(QQmlEngine *engine, QV4::ExecutableCompilationUnit *compilationUnit, int index, QObject *parent, const QQmlRefPointer< QQmlContextData > &context)
QList< QQmlError > errors
The QQmlParserStatus class provides updates on the QML parser state.
virtual void classBegin()=0
Invoked after class creation, but before any properties have been set.
virtual void componentComplete()=0
Invoked after the root component that caused this instantiation has completed construction.
QQmlPropertyBindingJS * jsExpression()
bool needsVMEMetaObject(int index) const
QQmlPropertyCache::ConstPtr at(int index) const
@ RemoveBindingOnAliasWrite
QString name(QObject *) const
static QQmlPropertyIndex fromEncoded(qint32 encodedIndex)
static QQmlProperty restore(QObject *, const QQmlPropertyData &, const QQmlPropertyData *, const QQmlRefPointer< QQmlContextData > &)
static QQmlPropertyIndex propertyIndex(const QQmlProperty &that)
static bool connect(const QObject *sender, int signal_index, const QObject *receiver, int method_index, int type=0, int *types=nullptr)
Connect sender signal_index to receiver method_index with the specified type and types.
The QQmlProperty class abstracts accessing properties on objects created from QML.
static bool componentCompleteEnabled()
iterator erase(const_iterator i)
iterator find(const T &value)
iterator insert(const T &value)
\macro QT_RESTRICTED_CAST_FROM_ASCII
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
QUntypedPropertyBinding takeBinding()
Removes the currently set binding from the property and returns it.
bool setBinding(const QUntypedPropertyBinding &binding)
Sets the underlying property's binding to binding.
const CompiledObject * objectAt(int index) const
std::unique_ptr< QString > icRootName
QVector< QV4::Function * > runtimeFunctions
int inlineComponentId(const QString &inlineComponentName) const
QQmlRefPointer< QQmlTypeNameCache > typeNameCache
QQmlRefPointer< QV4::ExecutableCompilationUnit > compilationUnit()
bool isFullyDynamicType() const
ReturnedValue value() const
static auto fromValue(T &&value) noexcept(std::is_nothrow_copy_constructible_v< T > &&Private::CanUseInternalSpace< T >) -> std::enable_if_t< std::conjunction_v< std::is_copy_constructible< T >, std::is_destructible< T > >, QVariant >
QCache< int, Employee > cache
[0]
QSet< QString >::iterator it
\qmltype Particle \inqmlmodule QtQuick.Particles
static const QCssKnownValue properties[NumProperties - 1]
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction function
DBusConnection const char DBusError * error
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]
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
static ControlElement< T > * ptr(QWidget *widget)
GLboolean GLboolean GLboolean b
GLint GLint GLint GLint GLint x
[0]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLsizei GLenum GLenum * types
GLenum GLenum GLsizei count
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLuint GLintptr offset
static qreal component(const QPointF &point, unsigned int i)
QQmlContext * qmlContext(const QObject *obj)
void QQml_setParent_noEvent(QObject *object, QObject *parent)
Makes the object a child of parent.
#define Q_QML_OC_PROFILE(member, Code)
int qmlConvertSourceCoordinate< quint32, int >(quint32 n)
QScopeGuard< typename std::decay< F >::type > qScopeGuard(F &&f)
[qScopeGuard]
QLatin1StringView QLatin1String
#define QStringLiteral(str)
#define Q_TRACE_PREFIX(provider, prefix)
#define Q_TRACE_EXIT(x,...)
QFuture< QSet< QChar > > set
[10]
QFutureWatcher< int > watcher
QItemEditorCreatorBase * creator
QQmlObjectCreatorRecursionWatcher(QQmlObjectCreator *creator)
QList< DeferredQPropertyBinding > allQPropertyBindings
QFiniteStack< QQmlAbstractBinding::Ptr > allCreatedBindings
QQmlRefPointer< QQmlContextData > rootContext
QV4::Value * allJavaScriptObjects
QQmlComponentAttached * componentAttached
QFiniteStack< QQmlGuard< QObject > > allCreatedObjects
RequiredProperties requiredProperties
QFiniteStack< QQmlParserStatus * > allParserStatusCallbacks
QList< QQmlFinalizerHook * > finalizeHooks
bool hadTopLevelRequiredProperties
static const quintptr profiler
void push(const QV4::CompiledData::Object *)
qint32_le encodedMetaPropertyIndex
quint32 targetObjectId() const
bool hasFlag(Flag flag) const
bool isAliasToLocalAlias() const
quint32_le localAliasIndex
bool isAttachedProperty() const
bool hasFlag(Flag flag) const
bool isGroupProperty() const
QString stringAt(uint index) const
const Unit * unitData() const
int propertyCount() const
RequiredPropertyExtraDataIterator requiredPropertyExtraDataEnd() const
quint32_le inheritedTypeNameIndex
bool hasFlag(Flag flag) const
@ HasCustomParserBindings
const Property * propertiesBegin() const
const quint32_le * functionOffsetTable() const
RequiredPropertyExtraDataIterator requiredPropertyExtraDataBegin() const
const Alias * aliasesBegin() const
static Heap::FunctionObject * createScriptFunction(ExecutionContext *scope, Function *function)
Heap::String * name() const
static Heap::FunctionObject * create(ExecutionContext *scope, Function *function)
QString toQString() const
static ReturnedValue wrap(ExecutionEngine *engine, QObject *object)
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent