7#include <private/qjsvalue_p.h>
8#include <private/qqmlanybinding_p.h>
9#include <private/qqmlbinding_p.h>
10#include <private/qqmlboundsignal_p.h>
11#include <private/qqmlcomponent_p.h>
12#include <private/qqmlcomponentattached_p.h>
13#include <private/qqmlcustomparser_p.h>
14#include <private/qqmldebugconnector_p.h>
15#include <private/qqmldebugserviceinterfaces_p.h>
16#include <private/qqmlengine_p.h>
17#include <private/qqmlpropertybinding_p.h>
18#include <private/qqmlpropertyvalueinterceptor_p.h>
19#include <private/qqmlscriptdata_p.h>
20#include <private/qqmlscriptstring_p.h>
21#include <private/qqmlsourcecoordinate_p.h>
22#include <private/qqmlstringconverters_p.h>
23#include <private/qqmlvaluetypeproxybinding_p.h>
24#include <private/qqmlvme_p.h>
25#include <private/qqmlvmemetaobject_p.h>
26#include <private/qv4function_p.h>
27#include <private/qv4functionobject_p.h>
28#include <private/qv4generatorobject_p.h>
29#include <private/qv4qobjectwrapper_p.h>
30#include <private/qv4referenceobject_p.h>
31#include <private/qv4resolvedtypereference_p.h>
33#include <qtqml_tracepoints_p.h>
35#include <QtCore/qscopedvaluerollback.h>
36#include <QtCore/qloggingcategory.h>
44"struct ExecutionEngine;"\
45"class ExecutableCompilationUnit;"\
46"namespace CompiledData {"\
47"struct Object;"\
48"}}"\
49"class QQmlEngine;"
52Q_TRACE_POINT(qtqml, QQmlObjectCreator_createInstance_entry,
const QV4::ExecutableCompilationUnit *compilationUnit,
const QV4::CompiledData::Object *object,
const QUrl &url)
53Q_TRACE_POINT(qtqml, QQmlObjectCreator_createInstance_exit,
const QString &typeName)
55QQmlObjectCreator::QQmlObjectCreator(
56 const QQmlRefPointer<QQmlContextData> &parentContext,
57 const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit,
58 const QQmlRefPointer<QQmlContextData> &creationContext,
59 const QString &inlineComponentName,
60 QQmlIncubatorPrivate *incubator)
62 , m_inlineComponentName(inlineComponentName)
63 , compilationUnit(compilationUnit)
64 , propertyCaches(compilationUnit->propertyCachesPtr())
65 , sharedState(
new QQmlObjectCreatorSharedState, QQmlRefPointer<QQmlObjectCreatorSharedState>::Adopt)
66 , topLevelCreator(
true)
67 , isContextObject(
true)
68 , incubator(incubator)
72 sharedState->componentAttached =
nullptr;
73 sharedState->allJavaScriptObjects = ObjectInCreationGCAnchorList();
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));
86QQmlObjectCreator::QQmlObjectCreator(
const QQmlRefPointer<QQmlContextData> &parentContext,
87 const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit,
const QString inlineComponentName,
88 QQmlObjectCreatorSharedState *inheritedSharedState,
bool isContextObject)
90 , m_inlineComponentName(inlineComponentName)
91 , compilationUnit(compilationUnit)
92 , propertyCaches(compilationUnit->propertyCachesPtr())
93 , sharedState(inheritedSharedState)
94 , topLevelCreator(
false)
95 , isContextObject(isContextObject)
101void QQmlObjectCreator::init(
const QQmlRefPointer<QQmlContextData> &providedParentContext)
103 parentContext = providedParentContext;
104 engine = parentContext->engine();
105 v4 = engine->handle();
107 Q_ASSERT(compilationUnit);
108 Q_ASSERT(compilationUnit->engine == v4);
109 if (!compilationUnit->runtimeStrings)
110 compilationUnit->populate();
112 qmlUnit = compilationUnit->unitData();
114 _scopeObject =
nullptr;
115 _bindingTarget =
nullptr;
116 _valueTypeProperty =
nullptr;
117 _compiledObject =
nullptr;
118 _compiledObjectIndex = -1;
120 _vmeMetaObject =
nullptr;
121 _qmlContext =
nullptr;
124QQmlObjectCreator::~QQmlObjectCreator()
126 if (topLevelCreator) {
130 QQmlObjectCreatorRecursionWatcher watcher(
this);
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;
151 if (subComponentIndex == -1) {
153 isComponentRoot =
true;
155 Q_ASSERT(subComponentIndex >= 0);
156 if (flags & CreationFlags::InlineComponent) {
157 if (compilationUnit->componentsAreBound()
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->componentsAreBound()
168 && sharedState->creationContext != parentContext) {
169 recordError({}, tr(
"Cannot instantiate bound component "
170 "outside its creation context"));
171 phase = ObjectsCreated;
174 if (subComponentIndex < compilationUnit->objectCount()) {
175 const QV4::CompiledData::Object *compObj
176 = compilationUnit->objectAt(subComponentIndex);
177 objectToCreate = compObj->bindingTable()->value.objectIndex;
181 objectToCreate = compilationUnit->resolvedIndex(subComponentIndex);
186 context = QQmlEnginePrivate::get(engine)->createInternalContext(
187 compilationUnit, parentContext, subComponentIndex, isComponentRoot);
189 if (!sharedState->rootContext) {
190 sharedState->rootContext = context;
191 sharedState->rootContext->setIncubator(incubator);
192 sharedState->rootContext->setRootObjectInCreation(
true);
195 QV4::Scope scope(v4);
197 Q_ASSERT(sharedState->allJavaScriptObjects.canTrack() || topLevelCreator);
199 sharedState->allJavaScriptObjects = ObjectInCreationGCAnchorList(scope);
201 if (!isComponentRoot && sharedState->creationContext) {
203 QV4::ScopedValue scripts(scope, sharedState->creationContext->importedScripts());
204 context->setImportedScripts(v4, scripts);
207 QObject *instance = createInstance(objectToCreate, parent,
true);
209 QQmlData *ddata = QQmlData::get(instance);
211 ddata->compilationUnit = compilationUnit;
215 sharedState->allJavaScriptObjects = ObjectInCreationGCAnchorList();
217 phase = CreatingObjectsPhase2;
219 if (interrupt && interrupt->shouldInterrupt())
222 phase = ObjectsCreated;
225 if (QQmlEngineDebugService *service
226 = QQmlDebugConnector::service<QQmlEngineDebugService>()) {
227 if (!parentContext->isInternal())
228 parentContext->asQQmlContextPrivate()->appendInstance(instance);
229 service->objectCreated(engine, instance);
230 }
else if (!parentContext->isInternal() && QQmlDebugConnector::service<QV4DebugService>()) {
231 parentContext->asQQmlContextPrivate()->appendInstance(instance);
238void QQmlObjectCreator::beginPopulateDeferred(
const QQmlRefPointer<QQmlContextData> &newContext)
240 context = newContext;
241 sharedState->rootContext = newContext;
243 Q_ASSERT(topLevelCreator);
244 Q_ASSERT(!sharedState->allJavaScriptObjects.canTrack());
247 QV4::Scope valueScope(v4);
248 sharedState->allJavaScriptObjects = ObjectInCreationGCAnchorList(valueScope);
251void QQmlObjectCreator::populateDeferred(QObject *instance,
int deferredIndex,
252 const QQmlPropertyPrivate *qmlProperty,
253 const QV4::CompiledData::Binding *binding)
255 doPopulateDeferred(instance, deferredIndex, [
this, qmlProperty, binding]() {
256 Q_ASSERT(qmlProperty);
257 Q_ASSERT(binding->hasFlag(QV4::CompiledData::Binding::IsDeferredBinding));
259 QQmlListProperty<QObject> savedList;
260 qSwap(_currentList, savedList);
262 const QQmlPropertyData &property = qmlProperty->core;
264 if (property.propType().flags().testFlag(QMetaType::IsQmlList)) {
265 void *argv[1] = { (
void*)&_currentList };
266 QMetaObject::metacall(_qobject, QMetaObject::ReadProperty, property.coreIndex(), argv);
267 }
else if (_currentList.object) {
268 _currentList = QQmlListProperty<QObject>();
271 setPropertyBinding(&property, binding);
273 qSwap(_currentList, savedList);
277void QQmlObjectCreator::populateDeferred(QObject *instance,
int deferredIndex)
279 doPopulateDeferred(instance, deferredIndex, [
this]() { setupBindings(ApplyDeferred); });
282bool QQmlObjectCreator::populateDeferredProperties(QObject *instance,
283 const QQmlData::DeferredData *deferredData)
285 beginPopulateDeferred(deferredData->context);
286 populateDeferred(instance, deferredData->deferredIdx);
287 finalizePopulateDeferred();
288 return errors.isEmpty();
291void QQmlObjectCreator::populateDeferredBinding(
const QQmlProperty &qmlProperty,
int deferredIndex,
292 const QV4::CompiledData::Binding *binding)
295 populateDeferred(qmlProperty.object(), deferredIndex, QQmlPropertyPrivate::get(qmlProperty),
298 populateDeferred(qmlProperty.object(), deferredIndex);
302void QQmlObjectCreator::populateDeferredInstance(
303 QObject *outerObject,
int deferredIndex,
int index, QObject *instance,
304 QObject *bindingTarget,
const QQmlPropertyData *valueTypeProperty,
305 const QV4::CompiledData::Binding *binding)
307 doPopulateDeferred(outerObject, deferredIndex, [&]() {
308 populateInstance(index, instance, bindingTarget, valueTypeProperty, binding);
312void QQmlObjectCreator::finalizePopulateDeferred()
314 phase = ObjectsCreated;
317void QQmlObjectCreator::setPropertyValue(
const QQmlPropertyData *property,
const QV4::CompiledData::Binding *binding)
319 QQmlPropertyData::WriteFlags propertyWriteFlags = QQmlPropertyData::BypassInterceptor | QQmlPropertyData::RemoveBindingOnAliasWrite;
320 QV4::Scope scope(v4);
322 QMetaType propertyType = property->propType();
324 if (property->isEnum()) {
325 if (binding->hasFlag(QV4::CompiledData::Binding::IsResolvedEnum) ||
328 (property->isAlias() && binding->isNumberBinding())) {
329 propertyType = property->propType().underlyingType();
332 QVariant value = compilationUnit->bindingValueAsString(binding);
333 bool ok = QQmlPropertyPrivate::write(_qobject, *property, value, context);
340 auto assertOrNull = [&](
bool ok)
342 Q_ASSERT(ok || binding->type() == QV4::CompiledData::Binding::Type_Null);
346 auto assertType = [&](QV4::CompiledData::Binding::Type type)
348 Q_ASSERT(binding->type()== type || binding->type() == QV4::CompiledData::Binding::Type_Null);
352 if (property->isQObject()) {
353 if (binding->type() == QV4::CompiledData::Binding::Type_Null) {
354 QObject *value =
nullptr;
355 const bool ok = property->writeProperty(_qobject, &value, propertyWriteFlags);
362 switch (propertyType.id()) {
363 case QMetaType::QVariant: {
364 if (binding->type() == QV4::CompiledData::Binding::Type_Number) {
365 double n = compilationUnit->bindingValueAsNumber(binding);
366 if (
double(
int(n)) == n) {
367 if (property->isVarProperty()) {
368 _vmeMetaObject->setVMEProperty(property->coreIndex(), QV4::Value::fromInt32(
int(n)));
372 property->writeProperty(_qobject, &value, propertyWriteFlags);
375 if (property->isVarProperty()) {
376 _vmeMetaObject->setVMEProperty(property->coreIndex(), QV4::Value::fromDouble(n));
379 property->writeProperty(_qobject, &value, propertyWriteFlags);
382 }
else if (binding->type() == QV4::CompiledData::Binding::Type_Boolean) {
383 if (property->isVarProperty()) {
384 _vmeMetaObject->setVMEProperty(property->coreIndex(), QV4::Value::fromBoolean(binding->valueAsBoolean()));
386 QVariant value(binding->valueAsBoolean());
387 property->writeProperty(_qobject, &value, propertyWriteFlags);
389 }
else if (binding->type() == QV4::CompiledData::Binding::Type_Null) {
390 if (property->isVarProperty()) {
391 _vmeMetaObject->setVMEProperty(property->coreIndex(), QV4::Value::nullValue());
393 QVariant nullValue = QVariant::fromValue(
nullptr);
394 property->writeProperty(_qobject, &nullValue, propertyWriteFlags);
397 QString stringValue = compilationUnit->bindingValueAsString(binding);
398 if (property->isVarProperty()) {
399 QV4::ScopedString s(scope, v4->newString(stringValue));
400 _vmeMetaObject->setVMEProperty(property->coreIndex(), s);
402 QVariant value = stringValue;
403 property->writeProperty(_qobject, &value, propertyWriteFlags);
408 case QMetaType::QString: {
409 assertOrNull(binding->evaluatesToString());
410 QString value = compilationUnit->bindingValueAsString(binding);
411 property->writeProperty(_qobject, &value, propertyWriteFlags);
414 case QMetaType::QStringList: {
415 assertOrNull(binding->evaluatesToString());
416 QStringList value(compilationUnit->bindingValueAsString(binding));
417 property->writeProperty(_qobject, &value, propertyWriteFlags);
420 case QMetaType::QByteArray: {
421 assertType(QV4::CompiledData::Binding::Type_String);
422 QByteArray value(compilationUnit->bindingValueAsString(binding).toUtf8());
423 property->writeProperty(_qobject, &value, propertyWriteFlags);
426 case QMetaType::QUrl: {
427 assertType(QV4::CompiledData::Binding::Type_String);
428 const QString string = compilationUnit->bindingValueAsString(binding);
429 QUrl value = (!string.isEmpty() && QQmlPropertyPrivate::resolveUrlsOnAssignment())
430 ? compilationUnit->finalUrl().resolved(QUrl(string))
432 property->writeProperty(_qobject, &value, propertyWriteFlags);
435 case QMetaType::UInt: {
436 assertType(QV4::CompiledData::Binding::Type_Number);
437 double d = compilationUnit->bindingValueAsNumber(binding);
438 uint value = uint(d);
439 property->writeProperty(_qobject, &value, propertyWriteFlags);
443 case QMetaType::Int: {
444 assertType(QV4::CompiledData::Binding::Type_Number);
445 double d = compilationUnit->bindingValueAsNumber(binding);
447 property->writeProperty(_qobject, &value, propertyWriteFlags);
451 case QMetaType::SChar: {
452 assertType(QV4::CompiledData::Binding::Type_Number);
453 double d = compilationUnit->bindingValueAsNumber(binding);
454 qint8 value = qint8(d);
455 property->writeProperty(_qobject, &value, propertyWriteFlags);
458 case QMetaType::UChar: {
459 assertType(QV4::CompiledData::Binding::Type_Number);
460 double d = compilationUnit->bindingValueAsNumber(binding);
461 quint8 value = quint8(d);
462 property->writeProperty(_qobject, &value, propertyWriteFlags);
465 case QMetaType::Short: {
466 assertType(QV4::CompiledData::Binding::Type_Number);
467 double d = compilationUnit->bindingValueAsNumber(binding);
468 qint16 value = qint16(d);
469 property->writeProperty(_qobject, &value, propertyWriteFlags);
472 case QMetaType::UShort: {
473 assertType(QV4::CompiledData::Binding::Type_Number);
474 double d = compilationUnit->bindingValueAsNumber(binding);
475 quint16 value = quint16(d);
476 property->writeProperty(_qobject, &value, propertyWriteFlags);
479 case QMetaType::LongLong: {
480 assertType(QV4::CompiledData::Binding::Type_Number);
481 double d = compilationUnit->bindingValueAsNumber(binding);
482 qint64 value = qint64(d);
483 property->writeProperty(_qobject, &value, propertyWriteFlags);
486 case QMetaType::ULongLong: {
487 assertType(QV4::CompiledData::Binding::Type_Number);
488 double d = compilationUnit->bindingValueAsNumber(binding);
489 quint64 value = quint64(d);
490 property->writeProperty(_qobject, &value, propertyWriteFlags);
494 case QMetaType::Float: {
495 assertType(QV4::CompiledData::Binding::Type_Number);
496 float value =
float(compilationUnit->bindingValueAsNumber(binding));
497 property->writeProperty(_qobject, &value, propertyWriteFlags);
500 case QMetaType::Double: {
501 assertType(QV4::CompiledData::Binding::Type_Number);
502 double value = compilationUnit->bindingValueAsNumber(binding);
503 property->writeProperty(_qobject, &value, propertyWriteFlags);
506 case QMetaType::QColor: {
508 QVariant data = QQmlStringConverters::colorFromString(
509 compilationUnit->bindingValueAsString(binding), &ok);
511 property->writeProperty(_qobject, data.data(), propertyWriteFlags);
514#if QT_CONFIG(datestring)
515 case QMetaType::QDate: {
517 QDate value = QQmlStringConverters::dateFromString(compilationUnit->bindingValueAsString(binding), &ok);
519 property->writeProperty(_qobject, &value, propertyWriteFlags);
522 case QMetaType::QTime: {
524 QTime value = QQmlStringConverters::timeFromString(compilationUnit->bindingValueAsString(binding), &ok);
526 property->writeProperty(_qobject, &value, propertyWriteFlags);
529 case QMetaType::QDateTime: {
531 QDateTime value = QQmlStringConverters::dateTimeFromString(
532 compilationUnit->bindingValueAsString(binding), &ok);
534 property->writeProperty(_qobject, &value, propertyWriteFlags);
538 case QMetaType::QPoint: {
540 QPoint value = QQmlStringConverters::pointFFromString(compilationUnit->bindingValueAsString(binding), &ok).toPoint();
542 property->writeProperty(_qobject, &value, propertyWriteFlags);
545 case QMetaType::QPointF: {
547 QPointF value = QQmlStringConverters::pointFFromString(compilationUnit->bindingValueAsString(binding), &ok);
549 property->writeProperty(_qobject, &value, propertyWriteFlags);
552 case QMetaType::QSize: {
554 QSize value = QQmlStringConverters::sizeFFromString(compilationUnit->bindingValueAsString(binding), &ok).toSize();
556 property->writeProperty(_qobject, &value, propertyWriteFlags);
559 case QMetaType::QSizeF: {
561 QSizeF value = QQmlStringConverters::sizeFFromString(compilationUnit->bindingValueAsString(binding), &ok);
563 property->writeProperty(_qobject, &value, propertyWriteFlags);
566 case QMetaType::QRect: {
568 QRect value = QQmlStringConverters::rectFFromString(compilationUnit->bindingValueAsString(binding), &ok).toRect();
570 property->writeProperty(_qobject, &value, propertyWriteFlags);
573 case QMetaType::QRectF: {
575 QRectF value = QQmlStringConverters::rectFFromString(compilationUnit->bindingValueAsString(binding), &ok);
577 property->writeProperty(_qobject, &value, propertyWriteFlags);
580 case QMetaType::Bool: {
581 assertType(QV4::CompiledData::Binding::Type_Boolean);
582 bool value = binding->valueAsBoolean();
583 property->writeProperty(_qobject, &value, propertyWriteFlags);
586 case QMetaType::QVector2D:
587 case QMetaType::QVector3D:
588 case QMetaType::QVector4D:
589 case QMetaType::QQuaternion: {
590 QVariant result = QQmlValueTypeProvider::createValueType(
591 compilationUnit->bindingValueAsString(binding), propertyType);
592 assertOrNull(result.isValid());
593 property->writeProperty(_qobject, result.data(), propertyWriteFlags);
598 if (propertyType == QMetaType::fromType<QList<qreal>>()) {
599 assertType(QV4::CompiledData::Binding::Type_Number);
601 value.append(compilationUnit->bindingValueAsNumber(binding));
602 property->writeProperty(_qobject, &value, propertyWriteFlags);
604 }
else if (propertyType == QMetaType::fromType<QList<
int>>()) {
605 assertType(QV4::CompiledData::Binding::Type_Number);
606 double n = compilationUnit->bindingValueAsNumber(binding);
608 value.append(
int(n));
609 property->writeProperty(_qobject, &value, propertyWriteFlags);
611 }
else if (propertyType == QMetaType::fromType<QList<
bool>>()) {
612 assertType(QV4::CompiledData::Binding::Type_Boolean);
614 value.append(binding->valueAsBoolean());
615 property->writeProperty(_qobject, &value, propertyWriteFlags);
617 }
else if (propertyType == QMetaType::fromType<QList<QUrl>>()) {
618 assertType(QV4::CompiledData::Binding::Type_String);
619 const QUrl url(compilationUnit->bindingValueAsString(binding));
621 QQmlPropertyPrivate::resolveUrlsOnAssignment()
622 ? compilationUnit->finalUrl().resolved(url)
625 property->writeProperty(_qobject, &value, propertyWriteFlags);
627 }
else if (propertyType == QMetaType::fromType<QList<QString>>()) {
628 assertOrNull(binding->evaluatesToString());
629 QList<QString> value;
630 value.append(compilationUnit->bindingValueAsString(binding));
631 property->writeProperty(_qobject, &value, propertyWriteFlags);
633 }
else if (propertyType == QMetaType::fromType<QJSValue>()) {
635 switch (binding->type()) {
636 case QV4::CompiledData::Binding::Type_Boolean:
637 value = QJSValue(binding->valueAsBoolean());
639 case QV4::CompiledData::Binding::Type_Number: {
640 const double n = compilationUnit->bindingValueAsNumber(binding);
641 if (
double(
int(n)) == n)
642 value = QJSValue(
int(n));
647 case QV4::CompiledData::Binding::Type_Null:
648 value = QJSValue::NullValue;
651 value = QJSValue(compilationUnit->bindingValueAsString(binding));
654 property->writeProperty(_qobject, &value, propertyWriteFlags);
658 switch (binding->type()) {
659 case QV4::CompiledData::Binding::Type_Boolean:
660 source = binding->valueAsBoolean();
662 case QV4::CompiledData::Binding::Type_Number: {
663 const double n = compilationUnit->bindingValueAsNumber(binding);
664 if (
double(
int(n)) == n)
670 case QV4::CompiledData::Binding::Type_Null:
671 source = QVariant::fromValue<std::nullptr_t>(
nullptr);
673 case QV4::CompiledData::Binding::Type_Invalid:
676 source = compilationUnit->bindingValueAsString(binding);
680 QVariant target = QQmlValueTypeProvider::createValueType(
681 source, propertyType, engine->handle());
682 if (target.isValid()) {
683 property->writeProperty(_qobject, target.data(), propertyWriteFlags);
689 QString stringValue = compilationUnit->bindingValueAsString(binding);
690 QMetaProperty metaProperty = _qobject->metaObject()->property(property->coreIndex());
691 recordError(binding->location, tr(
"Cannot assign value %1 to property"
692" %2").arg(stringValue, QString::fromUtf8(metaProperty.name())));
701 const QMetaObject *mo = object->metaObject();
702 while (mo && !type.isValid()) {
703 type = QQmlMetaType::qmlType(mo);
704 mo = mo->superClass();
709void QQmlObjectCreator::setupBindings(BindingSetupFlags mode)
711 QQmlListProperty<QObject> savedList;
712 qSwap(_currentList, savedList);
714 const QV4::CompiledData::BindingPropertyData *propertyData
715 = compilationUnit->bindingPropertyDataPerObjectAt(_compiledObjectIndex);
717 if (_compiledObject->idNameIndex) {
718 const QQmlPropertyData *idProperty = propertyData->last();
719 Q_ASSERT(!idProperty || !idProperty->isValid() || idProperty->name(_qobject) == QLatin1String(
"id"));
720 if (idProperty && idProperty->isValid() && idProperty->isWritable() && idProperty->propType().id() == QMetaType::QString) {
721 QV4::CompiledData::Binding idBinding;
722 idBinding.propertyNameIndex = 0;
723 idBinding.clearFlags();
724 idBinding.setType(QV4::CompiledData::Binding::Type_String);
725 idBinding.stringIndex = _compiledObject->idNameIndex;
726 idBinding.location = _compiledObject->location;
727 idBinding.value.nullMarker = 0;
728 setPropertyValue(idProperty, &idBinding);
733 if (_valueTypeProperty) {
734 QQmlAbstractBinding *binding = QQmlPropertyPrivate::binding(_bindingTarget, QQmlPropertyIndex(_valueTypeProperty->coreIndex()));
736 if (binding && binding->kind() != QQmlAbstractBinding::ValueTypeProxy) {
737 QQmlPropertyPrivate::removeBinding(
738 _bindingTarget, QQmlPropertyIndex(_valueTypeProperty->coreIndex()),
739 QQmlPropertyPrivate::OverrideSticky);
740 }
else if (binding) {
741 QQmlValueTypeProxyBinding *proxy =
static_cast<QQmlValueTypeProxyBinding *>(binding);
743 if (qmlTypeForObject(_bindingTarget).isValid()) {
744 quint32 bindingSkipList = 0;
746 const QQmlPropertyData *defaultProperty = _compiledObject->indexOfDefaultPropertyOrAlias != -1 ? _propertyCache->parent()->defaultProperty() : _propertyCache->defaultProperty();
748 const QV4::CompiledData::Binding *binding = _compiledObject->bindingTable();
749 for (quint32 i = 0; i < _compiledObject->nBindings; ++i, ++binding) {
750 const QQmlPropertyData *property = binding->propertyNameIndex != 0
751 ? _propertyCache->property(stringAt(binding->propertyNameIndex),
755 bindingSkipList |= (1 << property->coreIndex());
758 proxy->removeBindings(bindingSkipList);
763 const QQmlPropertyData *defaultProperty = _compiledObject->indexOfDefaultPropertyOrAlias != -1
764 ? _propertyCache->parent()->defaultProperty()
765 : _propertyCache->defaultProperty();
767 int currentListPropertyIndex = -1;
770 const auto applyBinding = [&](
const QQmlPropertyData *property,
771 const QV4::CompiledData::Binding *binding) ->
bool {
772 if (property && property->propType().flags().testFlag(QMetaType::IsQmlList)) {
773 if (property->coreIndex() != currentListPropertyIndex) {
774 void *argv[1] = { (
void*)&_currentList };
775 QMetaObject::metacall(_qobject, QMetaObject::ReadProperty, property->coreIndex(), argv);
776 currentListPropertyIndex = property->coreIndex();
779 const QMetaObject *
const metaobject = _qobject->metaObject();
780 const int qmlListBehavorClassInfoIndex = metaobject->indexOfClassInfo(
"QML.ListPropertyAssignBehavior");
781 if (qmlListBehavorClassInfoIndex != -1) {
782 const char *overrideBehavior =
783 metaobject->classInfo(qmlListBehavorClassInfoIndex).value();
784 if (!strcmp(overrideBehavior,
786 if (_currentList.clear) {
787 _currentList.clear(&_currentList);
790 bool isDefaultProperty =
791 (property->name(_qobject)
792 == QString::fromUtf8(
794 ->classInfo(metaobject->indexOfClassInfo(
797 if (!isDefaultProperty
798 && (!strcmp(overrideBehavior,
799 "ReplaceIfNotDefault"))) {
800 if (_currentList.clear) {
801 _currentList.clear(&_currentList);
807 }
else if (_currentList.object) {
808 _currentList = QQmlListProperty<QObject>();
809 currentListPropertyIndex = -1;
812 return setPropertyBinding(property, binding);
820 const QV4::CompiledData::Binding *explicitDefaultPropertyBindings =
nullptr;
821 quint32 numExplicitDefaultPropertyBindings = 0;
823 const auto applyExplicitDefaultPropertyBindings = [&]() ->
bool {
824 for (; numExplicitDefaultPropertyBindings > 0; --numExplicitDefaultPropertyBindings) {
825 if (!applyBinding(defaultProperty, explicitDefaultPropertyBindings++))
831 const QV4::CompiledData::Binding *binding = _compiledObject->bindingTable();
832 for (quint32 i = 0; i < _compiledObject->nBindings; ++i, ++binding) {
833 const QQmlPropertyData *
const property = propertyData->at(i);
835 const QQmlPropertyData *targetProperty = property;
836 if (targetProperty->isAlias()) {
838 QQmlPropertyIndex originalIndex(targetProperty->coreIndex(),
839 _valueTypeProperty ? _valueTypeProperty->coreIndex()
841 auto [targetObject, targetIndex] =
842 QQmlPropertyPrivate::findAliasTarget(_bindingTarget, originalIndex);
843 QQmlData *data = QQmlData::get(targetObject);
844 Q_ASSERT(data && data->propertyCache);
845 targetProperty = data->propertyCache->property(targetIndex.coreIndex());
846 sharedState->requiredProperties.remove({ targetObject, targetProperty });
848 sharedState->requiredProperties.remove({ _bindingTarget, property });
851 if (binding->hasFlag(QV4::CompiledData::Binding::IsCustomParserBinding))
854 if (binding->hasFlag(QV4::CompiledData::Binding::IsDeferredBinding)) {
855 if (!(mode & ApplyDeferred))
857 }
else if (!(mode & ApplyImmediate)) {
863 if (binding->propertyNameIndex != quint32(0)
865 && property == defaultProperty) {
866 if (++numExplicitDefaultPropertyBindings == 1)
867 explicitDefaultPropertyBindings = binding;
873 if (binding->propertyNameIndex == quint32(0)
874 && numExplicitDefaultPropertyBindings > 0
875 && !(binding->location < explicitDefaultPropertyBindings->location)) {
876 if (!applyExplicitDefaultPropertyBindings())
880 if (!applyBinding(property, binding))
885 if (!applyExplicitDefaultPropertyBindings())
887 qSwap(_currentList, savedList);
890bool QQmlObjectCreator::setPropertyBinding(
const QQmlPropertyData *bindingProperty,
const QV4::CompiledData::Binding *binding)
892 const QV4::CompiledData::Binding::Type bindingType = binding->type();
893 if (bindingType == QV4::CompiledData::Binding::Type_AttachedProperty) {
894 const QV4::CompiledData::Object *obj = compilationUnit->objectAt(binding->value.objectIndex);
895 QQmlObjectCreationProfiler profiler(sharedState->profiler.profiler, obj);
897 Q_ASSERT(stringAt(obj->inheritedTypeNameIndex).isEmpty());
898 QV4::ResolvedTypeReference *tr = resolvedType(binding->propertyNameIndex);
900 QQmlType attachedType = tr->type();
901 QQmlTypeLoader *typeLoader = QQmlTypeLoader::get(engine);
902 if (!attachedType.isValid()) {
903 QQmlTypeNameCache::Result res
904 = context->imports()->query(stringAt(binding->propertyNameIndex), typeLoader);
906 attachedType = res.type;
912 sharedState->profiler,
913 profiler.update(compilationUnit.data(), obj, attachedType.qmlTypeName(),
916 QObject *qmlObject = qmlAttachedPropertiesObject(
917 _qobject, attachedType.attachedPropertiesFunction(typeLoader));
919 recordError(binding->location,
920 QStringLiteral(
"Could not create attached properties object '%1'")
921 .arg(QString::fromUtf8(attachedType.typeName())));
925 const size_t objectIndex = sharedState->allCreatedObjects.size();
926 sharedState->allCreatedObjects.push_back(qmlObject);
927 const QQmlType attachedObjectType
928 = QQmlMetaType::qmlType(attachedType.attachedPropertiesType(typeLoader));
929 const int parserStatusCast = attachedObjectType.parserStatusCast();
930 QQmlParserStatus *parserStatus =
nullptr;
931 if (parserStatusCast != -1)
932 parserStatus =
reinterpret_cast<QQmlParserStatus*>(
reinterpret_cast<
char *>(qmlObject) + parserStatusCast);
934 parserStatus->classBegin();
936 sharedState->allParserStatusCallbacks.push_back({objectIndex, parserStatusCast});
939 if (!populateInstance(binding->value.objectIndex, qmlObject, qmlObject,
946 if (bindingProperty && bindingProperty->propType() == QMetaType::fromType<QQmlScriptString>()) {
947 QQmlScriptString ss(compilationUnit->bindingValueAsScriptString(binding),
948 context->asQQmlContext(), _scopeObject);
949 ss.d.data()->bindingId = bindingType == QV4::CompiledData::Binding::Type_Script ? binding->value.compiledScriptIndex : (quint32)QQmlBinding::Invalid;
950 ss.d.data()->lineNumber = binding->location.line();
951 ss.d.data()->columnNumber = binding->location.column();
952 ss.d.data()->isStringLiteral = bindingType == QV4::CompiledData::Binding::Type_String;
953 ss.d.data()->isNumberLiteral = bindingType == QV4::CompiledData::Binding::Type_Number;
954 ss.d.data()->numberValue = compilationUnit->bindingValueAsNumber(binding);
956 QQmlPropertyData::WriteFlags propertyWriteFlags = QQmlPropertyData::BypassInterceptor |
957 QQmlPropertyData::RemoveBindingOnAliasWrite;
958 int propertyWriteStatus = -1;
959 void *argv[] = { &ss,
nullptr, &propertyWriteStatus, &propertyWriteFlags };
960 QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, bindingProperty->coreIndex(), argv);
964 QObject *createdSubObject =
nullptr;
965 if (bindingType == QV4::CompiledData::Binding::Type_Object) {
968 QScopedValueRollback topLevelRequired(sharedState->hadTopLevelRequiredProperties);
969 int objectIndex = binding->value.objectIndex;
970 if (
const int wrapperIdx = compilationUnit->implicitComponentForObject(objectIndex);
973 objectIndex = wrapperIdx;
975 createdSubObject = createInstance(objectIndex, _bindingTarget);
976 if (!createdSubObject)
980 if (bindingType == QV4::CompiledData::Binding::Type_GroupProperty) {
981 const QV4::CompiledData::Object *obj = compilationUnit->objectAt(binding->value.objectIndex);
982 if (stringAt(obj->inheritedTypeNameIndex).isEmpty()) {
984 QObject *groupObject =
nullptr;
985 QQmlGadgetPtrWrapper *valueType =
nullptr;
986 const QQmlPropertyData *valueTypeProperty =
nullptr;
987 QObject *bindingTarget = _bindingTarget;
988 int groupObjectIndex = binding->value.objectIndex;
990 if (!bindingProperty) {
991 for (
int i = 0, end = compilationUnit->objectCount(); i != end; ++i) {
992 const QV4::CompiledData::Object *external = compilationUnit->objectAt(i);
993 if (external->idNameIndex == binding->propertyNameIndex) {
994 bindingTarget = groupObject = context->idValue(external->objectId());
1000 }
else if (QQmlMetaType::isValueType(bindingProperty->propType())) {
1001 valueType = QQmlGadgetPtrWrapper::instance(engine, bindingProperty->propType());
1003 recordError(binding->location, tr(
"Cannot set properties on %1 as it is null").arg(stringAt(binding->propertyNameIndex)));
1007 valueType->read(_qobject, bindingProperty->coreIndex());
1009 groupObject = valueType;
1010 valueTypeProperty = bindingProperty;
1011 }
else if (bindingProperty->propType().flags() & QMetaType::PointerToQObject) {
1012 void *argv[1] = { &groupObject };
1013 QMetaObject::metacall(_qobject, QMetaObject::ReadProperty, bindingProperty->coreIndex(), argv);
1015 QQmlPropertyIndex index(bindingProperty->coreIndex());
1016 auto anyBinding = QQmlAnyBinding::ofProperty(_qobject, index);
1020 anyBinding.refresh();
1021 QMetaObject::metacall(_qobject, QMetaObject::ReadProperty, bindingProperty->coreIndex(), argv);
1024 recordError(binding->location, tr(
"Cannot set properties on %1 as it is null").arg(stringAt(binding->propertyNameIndex)));
1029 bindingTarget = groupObject;
1033 tr(
"Using grouped property syntax on %1 which has no properties")
1034 .arg(stringAt(binding->propertyNameIndex)));
1038 if (!populateInstance(groupObjectIndex, groupObject, bindingTarget, valueTypeProperty,
1045 _qobject, bindingProperty->coreIndex(),
1046 QQmlPropertyData::BypassInterceptor,
1047 QV4::ReferenceObject::AllProperties);
1054 if (!bindingProperty)
1057 const QV4::CompiledData::Binding::Flags bindingFlags = binding->flags();
1058 const bool allowedToRemoveBinding
1059 = !(bindingFlags & QV4::CompiledData::Binding::IsSignalHandlerExpression)
1060 && !(bindingFlags & QV4::CompiledData::Binding::IsOnAssignment)
1061 && !(bindingFlags & QV4::CompiledData::Binding::IsPropertyObserver)
1062 && !_valueTypeProperty;
1064 if (allowedToRemoveBinding) {
1065 if (bindingProperty->acceptsQBinding()) {
1066 removePendingBinding(_bindingTarget, bindingProperty->coreIndex());
1068 QQmlPropertyPrivate::removeBinding(
1069 _bindingTarget, QQmlPropertyIndex(bindingProperty->coreIndex()),
1070 QQmlPropertyPrivate::OverrideSticky);
1074 if (bindingType == QV4::CompiledData::Binding::Type_Script || binding->isTranslationBinding()) {
1075 if (bindingFlags & QV4::CompiledData::Binding::IsSignalHandlerExpression
1076 || bindingFlags & QV4::CompiledData::Binding::IsPropertyObserver) {
1077 QV4::Function *runtimeFunction = compilationUnit->runtimeFunctions[binding->value.compiledScriptIndex];
1078 int signalIndex = _propertyCache->methodIndexToSignalIndex(bindingProperty->coreIndex());
1079 QQmlBoundSignalExpression *expr =
new QQmlBoundSignalExpression(
1080 _bindingTarget, signalIndex, context,
1081 _scopeObject, runtimeFunction, currentQmlContext());
1083 if (bindingProperty->notifiesViaBindable()) {
1084 auto target = _bindingTarget;
1085 if (bindingProperty->isAlias()) {
1090 QQmlPropertyIndex originalIndex(bindingProperty->coreIndex(), _valueTypeProperty ? _valueTypeProperty->coreIndex() : -1);
1091 auto [aliasTargetObject, aliasTargetIndex] = QQmlPropertyPrivate::findAliasTarget(target, originalIndex);
1092 target = aliasTargetObject;
1093 QQmlData *data = QQmlData::get(target);
1094 Q_ASSERT(data && data->propertyCache);
1095 bindingProperty = data->propertyCache->property(aliasTargetIndex.coreIndex());
1097 auto &observer = QQmlData::get(_scopeObject)->propertyObservers.emplace_back(expr);
1098 QUntypedBindable bindable;
1099 void *argv[] = { &bindable };
1100 target->qt_metacall(QMetaObject::BindableProperty, bindingProperty->coreIndex(), argv);
1101 Q_ASSERT(bindable.isValid());
1102 bindable.observe(&observer);
1104 QQmlBoundSignal *bs =
new QQmlBoundSignal(_bindingTarget, signalIndex, _scopeObject, engine);
1105 bs->takeExpression(expr);
1107 }
else if (bindingProperty->acceptsQBinding()) {
1108 QUntypedPropertyBinding qmlBinding;
1109 if (binding->isTranslationBinding()) {
1110 qmlBinding = QQmlTranslationPropertyBinding::create(bindingProperty, compilationUnit, binding);
1112 QV4::Function *runtimeFunction = compilationUnit->runtimeFunctions[binding->value.compiledScriptIndex];
1113 QQmlPropertyIndex index(bindingProperty->coreIndex(), -1);
1114 qmlBinding = QQmlPropertyBinding::create(bindingProperty, runtimeFunction, _scopeObject, context, currentQmlContext(), _bindingTarget, index);
1116 sharedState.data()->allQPropertyBindings.push_back(DeferredQPropertyBinding {_bindingTarget, bindingProperty->coreIndex(), qmlBinding });
1118 QQmlData *data = QQmlData::get(_bindingTarget,
true);
1119 data->setBindingBit(_bindingTarget, bindingProperty->coreIndex());
1126 QQmlBinding::Ptr qmlBinding;
1127 const QQmlPropertyData *targetProperty = bindingProperty;
1128 const QQmlPropertyData *subprop =
nullptr;
1129 if (_valueTypeProperty) {
1130 targetProperty = _valueTypeProperty;
1131 subprop = bindingProperty;
1133 if (binding->isTranslationBinding()) {
1134 qmlBinding = QQmlBinding::createTranslationBinding(
1135 compilationUnit, binding, _scopeObject, context);
1137 QV4::Function *runtimeFunction = compilationUnit->runtimeFunctions[binding->value.compiledScriptIndex];
1138 qmlBinding = QQmlBinding::create(targetProperty, runtimeFunction, _scopeObject,
1139 context, currentQmlContext());
1142 auto bindingTarget = _bindingTarget;
1143 auto valueTypeProperty = _valueTypeProperty;
1144 auto assignBinding = [qmlBinding, bindingTarget, targetProperty, subprop, bindingProperty, valueTypeProperty](QQmlObjectCreatorSharedState *sharedState)
mutable ->
bool {
1145 if (!qmlBinding->setTarget(bindingTarget, *targetProperty, subprop) && targetProperty->isAlias())
1148 sharedState->allCreatedBindings.push_back(qmlBinding);
1150 if (bindingProperty->isAlias()) {
1151 QQmlPropertyPrivate::setBinding(qmlBinding.data(), QQmlPropertyPrivate::DontEnable);
1153 qmlBinding->addToObject();
1155 if (!valueTypeProperty) {
1156 QQmlData *targetDeclarativeData = QQmlData::get(bindingTarget);
1157 Q_ASSERT(targetDeclarativeData);
1158 targetDeclarativeData->setPendingBindingBit(bindingTarget, bindingProperty->coreIndex());
1164 if (!assignBinding(sharedState.data()))
1165 pendingAliasBindings.push_back(assignBinding);
1170 if (bindingType == QV4::CompiledData::Binding::Type_Object) {
1171 if (bindingFlags & QV4::CompiledData::Binding::IsOnAssignment) {
1173 QQmlType type = qmlTypeForObject(createdSubObject);
1174 Q_ASSERT(type.isValid());
1176 int valueSourceCast = type.propertyValueSourceCast();
1177 if (valueSourceCast != -1) {
1178 QQmlPropertyValueSource *vs =
reinterpret_cast<QQmlPropertyValueSource *>(
reinterpret_cast<
char *>(createdSubObject) + valueSourceCast);
1179 QObject *target = createdSubObject->parent();
1181 if (_valueTypeProperty) {
1182 prop = QQmlPropertyPrivate::restore(target, *_valueTypeProperty,
1183 bindingProperty, context);
1185 prop = QQmlPropertyPrivate::restore(target, *bindingProperty,
nullptr, context);
1187 vs->setTarget(prop);
1190 int valueInterceptorCast = type.propertyValueInterceptorCast();
1191 if (valueInterceptorCast != -1) {
1192 QQmlPropertyValueInterceptor *vi =
reinterpret_cast<QQmlPropertyValueInterceptor *>(
reinterpret_cast<
char *>(createdSubObject) + valueInterceptorCast);
1193 QObject *target = createdSubObject->parent();
1195 QQmlPropertyIndex propertyIndex;
1196 if (bindingProperty->isAlias()) {
1197 QQmlPropertyIndex originalIndex(bindingProperty->coreIndex(), _valueTypeProperty ? _valueTypeProperty->coreIndex() : -1);
1198 auto aliasTarget = QQmlPropertyPrivate::findAliasTarget(target, originalIndex);
1199 target = aliasTarget.targetObject;
1200 QQmlData *data = QQmlData::get(target);
1201 if (!data || !data->propertyCache) {
1202 qWarning() <<
"can't resolve property alias for 'on' assignment";
1207 QQmlPropertyData targetPropertyData = *data->propertyCache->property(aliasTarget.targetIndex.coreIndex());
1208 auto prop = QQmlPropertyPrivate::restore(
1209 target, targetPropertyData,
nullptr, context);
1210 vi->setTarget(prop);
1211 propertyIndex = QQmlPropertyPrivate::propertyIndex(prop);
1214 if (_valueTypeProperty) {
1215 prop = QQmlPropertyPrivate::restore(
1216 target, *_valueTypeProperty, bindingProperty, context);
1218 prop = QQmlPropertyPrivate::restore(
1219 target, *bindingProperty,
nullptr, context);
1221 vi->setTarget(prop);
1222 propertyIndex = QQmlPropertyPrivate::propertyIndex(prop);
1225 QQmlInterceptorMetaObject *mo = QQmlInterceptorMetaObject::get(target);
1227 mo =
new QQmlInterceptorMetaObject(target, QQmlData::get(target)->propertyCache);
1228 mo->registerInterceptor(propertyIndex, vi);
1235 if (bindingFlags & QV4::CompiledData::Binding::IsSignalHandlerObject) {
1236 if (!bindingProperty->isFunction()) {
1237 recordError(binding->valueLocation, tr(
"Cannot assign an object to signal property %1").arg(bindingProperty->name(_qobject)));
1240 QMetaMethod method = QQmlMetaType::defaultMethod(createdSubObject);
1241 if (!method.isValid()) {
1242 recordError(binding->valueLocation, tr(
"Cannot assign object type %1 with no default method").arg(QString::fromLatin1(createdSubObject->metaObject()->className())));
1245 qCWarning(lcQmlDefaultMethod) <<
"Assigning an object to a signal handler is deprecated. "
1246 "Instead, create the object, give it an id, and call the desired slot "
1247 "from the signal handler. The object is:" << createdSubObject;
1249 QMetaMethod signalMethod = _qobject->metaObject()->method(bindingProperty->coreIndex());
1250 if (!QMetaObject::checkConnectArgs(signalMethod, method)) {
1251 recordError(binding->valueLocation,
1252 tr(
"Cannot connect mismatched signal/slot %1 vs %2")
1253 .arg(QString::fromUtf8(method.methodSignature()))
1254 .arg(QString::fromUtf8(signalMethod.methodSignature())));
1258 QQmlPropertyPrivate::connect(_qobject, bindingProperty->coreIndex(), createdSubObject, method.methodIndex());
1262 QQmlPropertyData::WriteFlags propertyWriteFlags = QQmlPropertyData::BypassInterceptor |
1263 QQmlPropertyData::RemoveBindingOnAliasWrite;
1264 int propertyWriteStatus = -1;
1265 void *argv[] = {
nullptr,
nullptr, &propertyWriteStatus, &propertyWriteFlags };
1267 if (
const char *iid = QQmlMetaType::interfaceIId(bindingProperty->propType())) {
1268 void *ptr = createdSubObject->qt_metacast(iid);
1271 QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, bindingProperty->coreIndex(), argv);
1273 recordError(binding->location, tr(
"Cannot assign object to interface property"));
1276 }
else if (bindingProperty->propType() == QMetaType::fromType<QVariant>()) {
1277 if (bindingProperty->isVarProperty()) {
1278 QV4::Scope scope(v4);
1279 QV4::ScopedValue wrappedObject(scope, QV4::QObjectWrapper::wrap(engine->handle(), createdSubObject));
1280 _vmeMetaObject->setVMEProperty(bindingProperty->coreIndex(), wrappedObject);
1282 QVariant value = QVariant::fromValue(createdSubObject);
1284 QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, bindingProperty->coreIndex(), argv);
1286 }
else if (bindingProperty->propType() == QMetaType::fromType<QJSValue>()) {
1287 QV4::Scope scope(v4);
1288 QV4::ScopedValue wrappedObject(scope, QV4::QObjectWrapper::wrap(engine->handle(), createdSubObject));
1289 if (bindingProperty->isVarProperty()) {
1290 _vmeMetaObject->setVMEProperty(bindingProperty->coreIndex(), wrappedObject);
1293 QJSValuePrivate::setValue(&value, wrappedObject);
1295 QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, bindingProperty->coreIndex(), argv);
1297 }
else if (bindingProperty->propType().flags().testFlag(QMetaType::IsQmlList)) {
1298 Q_ASSERT(_currentList.object);
1300 QObject *itemToAdd = createdSubObject;
1302 QMetaType listItemType = QQmlMetaType::listValueType(bindingProperty->propType());
1303 if (listItemType.isValid()) {
1304 const char *iid = QQmlMetaType::interfaceIId(listItemType);
1306 itemToAdd =
static_cast<QObject *>(createdSubObject->qt_metacast(iid));
1309 if (_currentList.append)
1310 _currentList.append(&_currentList, itemToAdd);
1312 recordError(binding->location, tr(
"Cannot assign object to read only list"));
1315 }
else if (bindingProperty->propType().flags().testFlag(QMetaType::PointerToQObject)) {
1317 argv[0] = &createdSubObject;
1318 QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, bindingProperty->coreIndex(), argv);
1320 QVariant target = QQmlValueTypeProvider::createValueType(
1321 QVariant::fromValue(createdSubObject), bindingProperty->propType(), v4);
1322 if (target.isValid())
1323 bindingProperty->writeProperty(_qobject, target.data(), propertyWriteFlags);
1325 recordError(binding->location, tr(
"Cannot construct value type from given object"));
1330 if (bindingProperty->isQList()) {
1331 recordError(binding->location, tr(
"Cannot assign primitives to lists"));
1335 setPropertyValue(bindingProperty, binding);
1339void QQmlObjectCreator::setupFunctions()
1341 QV4::Scope scope(v4);
1342 QV4::ScopedValue function(scope);
1343 QV4::ScopedContext qmlContext(scope, currentQmlContext());
1345 const quint32_le *functionIdx = _compiledObject->functionOffsetTable();
1346 for (quint32 i = 0; i < _compiledObject->nFunctions; ++i, ++functionIdx) {
1347 QV4::Function *runtimeFunction = compilationUnit->runtimeFunctions[*functionIdx];
1348 const QString name = runtimeFunction->name()->toQString();
1350 const QQmlPropertyData *property = _propertyCache->property(name, _qobject, context);
1351 if (!property->isVMEFunction())
1354 if (runtimeFunction->isGenerator())
1355 function = QV4::GeneratorFunction::create(qmlContext, runtimeFunction);
1357 function = QV4::FunctionObject::createScriptFunction(qmlContext, runtimeFunction);
1358 _vmeMetaObject->setVmeMethod(property->coreIndex(), function);
1362void QQmlObjectCreator::recordError(
const QV4::CompiledData::Location &location,
const QString &description)
1365 error.setUrl(compilationUnit->url());
1366 error.setLine(qmlConvertSourceCoordinate<quint32,
int>(location.line()));
1367 error.setColumn(qmlConvertSourceCoordinate<quint32,
int>(location.column()));
1368 error.setDescription(description);
1372void QQmlObjectCreator::registerObjectWithContextById(
const QV4::CompiledData::Object *object, QObject *instance)
const
1374 if (object->objectId() >= 0)
1375 context->setIdValue(object->objectId(), instance);
1378QObject *QQmlObjectCreator::createInstance(
int index, QObject *parent,
bool isContextObject)
1380 const QV4::CompiledData::Object *obj = compilationUnit->objectAt(index);
1381 Q_TRACE(QQmlObjectCreator_createInstance_entry, compilationUnit.data(), obj, context->url());
1382 QQmlObjectCreationProfiler profiler(sharedState->profiler.profiler, obj);
1384 const bool isImplicitComponent = index >= compilationUnit->objectCount();
1385 const InitFlags flags = (isContextObject ? InitFlag::IsContextObject : InitFlag::None)
1386 | (index == 0 ? InitFlag::IsDocumentRoot : InitFlag::None)
1387 | (isImplicitComponent ? InitFlag::IsImplicitComponent : InitFlag::None);
1389 if (obj->hasFlag(QV4::CompiledData::Object::IsComponent) || isImplicitComponent) {
1390 Q_TRACE_EXIT(QQmlObjectCreator_createInstance_exit, QStringLiteral(
"<component>"));
1392 sharedState->profiler,
1394 compilationUnit.data(), obj, QStringLiteral(
"<component>"),
1396 return initializeComponent(
1397 obj, createComponent(engine, compilationUnit.data(), index, parent, context),
1401 const QV4::ResolvedTypeReference *typeRef = resolvedType(obj->inheritedTypeNameIndex);
1403 const QQmlType type = typeRef->type();
1404 Q_ASSERT(type.isValid());
1406 Q_TRACE_EXIT(QQmlObjectCreator_createInstance_exit, type.qmlTypeName());
1408 sharedState->profiler,
1409 profiler.update(compilationUnit.data(), obj, type.qmlTypeName(), context->url()));
1411 if (type.isCompositeSingleton()) {
1414 tr(
"Composite Singleton Type %1 is not creatable")
1415 .arg(stringAt(obj->inheritedTypeNameIndex)));
1419 if (!type.isComposite() && !type.isInlineComponentType()) {
1420 if (QObject *instance = type.createWithQQmlData())
1421 return initializeNonComposite(index, obj, typeRef, instance, parent, flags);
1424 tr(
"Unable to create object of type %1").arg(
1425 stringAt(obj->inheritedTypeNameIndex)));
1429 QQmlRefPointer<QV4::ExecutableCompilationUnit> executableCu = typeRef->isSelfReference()
1431 : engine->handle()->executableCompilationUnit(typeRef->compilationUnit());
1432 Q_ASSERT(executableCu);
1434 const bool isInlineComponent = type.isInlineComponentType();
1435 const QString inlineComponentName = isInlineComponent ? type.elementName() : QString();
1436 QQmlObjectCreator subCreator(
1437 context, executableCu, inlineComponentName, sharedState.data(),
1440 if (QObject *instance = isInlineComponent
1441 ? subCreator.create(
1442 executableCu->inlineComponentId(inlineComponentName),
nullptr,
nullptr,
1443 CreationFlags::InlineComponent)
1444 : subCreator.create()) {
1445 return initializeComposite(index, obj, typeRef, instance, parent, flags);
1448 errors += subCreator.errors;
1452void QQmlObjectCreator::initializeDData(
1453 const QV4::CompiledData::Object *obj, QObject *instance, QQmlData *ddata, InitFlags flags)
1455 ddata->lineNumber = obj->location.line();
1456 ddata->columnNumber = obj->location.column();
1457 ddata->setImplicitDestructible();
1461 const bool documentRoot = (flags & InitFlag::IsDocumentRoot)
1462 || ddata->rootObjectInCreation
1463 || obj->hasFlag(QV4::CompiledData::Object::IsInlineComponentRoot);
1465 context->installContext(
1466 ddata, documentRoot ? QQmlContextData::DocumentRoot : QQmlContextData::OrdinaryObject);
1470 if ((flags & (InitFlag::IsContextObject | InitFlag::IsImplicitComponent))
1471 == InitFlag::IsContextObject) {
1472 context->setContextObject(instance);
1476void QQmlObjectCreator::initializePropertyCache(
1477 int index, QQmlData *ddata,
const QV4::ResolvedTypeReference *typeRef)
1479 if (!typeRef->isFullyDynamicType()) {
1480 QQmlPropertyCache::ConstPtr cache = propertyCaches->at(index);
1481 Q_ASSERT(!cache.isNull());
1482 ddata->propertyCache = std::move(cache);
1486void QQmlObjectCreator::initializeParent(QObject *instance, QObject *parent)
1488 if (instance->isWidgetType()) {
1489 if (parent && parent->isWidgetType()) {
1490 QAbstractDeclarativeData::setWidgetParent(instance, parent);
1495 }
else if (parent) {
1496 QQml_setParent_noEvent(instance, parent);
1500QObject *QQmlObjectCreator::populateInstanceAndAliasBindings(
1501 int index, QObject *instance, InitFlags flags)
1503 const auto doPopulate = [&]() {
1504 if (!populateInstance(
1505 index, instance, instance,
nullptr)) {
1507 pendingAliasBindings.clear();
1511 if (!flags.testFlag(InitFlag::IsContextObject))
1514 while (!pendingAliasBindings.empty()) {
1515 for (std::vector<PendingAliasBinding>::iterator it = pendingAliasBindings.begin();
1516 it != pendingAliasBindings.end(); ) {
1517 if ((*it)(sharedState.data()))
1518 it = pendingAliasBindings.erase(it);
1527 QObject *scopeObject = instance;
1528 qSwap(_scopeObject, scopeObject);
1530 Q_ASSERT(sharedState->allJavaScriptObjects.canTrack());
1531 sharedState->allJavaScriptObjects.trackObject(v4, instance);
1533 QV4::Scope valueScope(v4);
1534 QV4::QmlContext *qmlContext =
static_cast<QV4::QmlContext *>(valueScope.constructUndefined(1));
1536 qSwap(_qmlContext, qmlContext);
1538 const bool ok = doPopulate();
1540 qSwap(_qmlContext, qmlContext);
1541 qSwap(_scopeObject, scopeObject);
1543 return ok ? instance :
nullptr;
1546QObject *QQmlObjectCreator::initializeComponent(
1547 const QV4::CompiledData::Object *obj, QObject *instance, InitFlags flags)
1552 QScopedValueRollback<QQmlObjectCreator*> ocRestore(
1553 QQmlEnginePrivate::get(engine)->activeObjectCreator,
this);
1556 initializeDData(obj, instance, QQmlData::get(instance), flags);
1558 if (!flags.testFlag(InitFlag::IsImplicitComponent))
1559 registerObjectWithContextById(obj, instance);
1563QObject *QQmlObjectCreator::initializeComposite(
1564 int index,
const QV4::CompiledData::Object *obj,
const QV4::ResolvedTypeReference *typeRef,
1565 QObject *instance, QObject *parent, InitFlags flags)
1570 QScopedValueRollback<QQmlObjectCreator*> ocRestore(
1571 QQmlEnginePrivate::get(engine)->activeObjectCreator,
this);
1573 initializeParent(instance, parent);
1574 QQmlData *ddata = QQmlData::get(instance,
true);
1575 initializeDData(obj, instance, ddata, flags);
1577 initializePropertyCache(index, ddata, typeRef);
1579 return populateInstanceAndAliasBindings(index, instance, flags);
1582QObject *QQmlObjectCreator::initializeNonComposite(
1583 int index,
const QV4::CompiledData::Object *obj,
const QV4::ResolvedTypeReference *typeRef,
1584 QObject *instance, QObject *parent, InitFlags flags)
1588 Q_ASSERT(!obj->hasFlag(QV4::CompiledData::Object::IsComponent));
1591 const QQmlType type = typeRef->type();
1592 Q_ASSERT(type.isValid());
1593 Q_ASSERT(!type.isComposite() && !type.isInlineComponentType());
1595 QScopedValueRollback<QQmlObjectCreator*> ocRestore(QQmlEnginePrivate::get(engine)->activeObjectCreator,
this);
1597 if (
const int finalizerCast = type.finalizerCast(); finalizerCast != -1) {
1598 const auto hook =
reinterpret_cast<QQmlFinalizerHook *>(
1599 reinterpret_cast<
char *>(instance) + finalizerCast);
1600 sharedState->finalizeHooks.push_back(hook);
1603 QQmlData *ddata = QQmlData::get(instance,
true);
1604 if (sharedState->rootContext && sharedState->rootContext->isRootObjectInCreation()) {
1605 ddata->rootObjectInCreation =
true;
1606 sharedState->rootContext->setRootObjectInCreation(
false);
1609 const size_t instanceIndex = sharedState->allCreatedObjects.size();
1610 sharedState->allCreatedObjects.push_back(instance);
1612 initializeParent(instance, parent);
1613 initializeDData(obj, instance, ddata, flags);
1615 if (
const int parserStatusCast = type.parserStatusCast(); parserStatusCast != -1) {
1616 if (QQmlParserStatus *parserStatus =
reinterpret_cast<QQmlParserStatus*>(
1617 reinterpret_cast<
char *>(instance) + parserStatusCast)) {
1618 parserStatus->classBegin();
1621 Q_QML_OC_PROFILE(sharedState->profiler, sharedState->profiler.push(obj));
1622 sharedState->allParserStatusCallbacks.push_back({ instanceIndex, parserStatusCast });
1626 if (QQmlCustomParser *customParser = type.customParser();
1627 customParser && obj->hasFlag(QV4::CompiledData::Object::HasCustomParserBindings)) {
1628 customParser->engine = QQmlEnginePrivate::get(engine);
1629 customParser->imports = compilationUnit->typeNameCache().data();
1631 QList<
const QV4::CompiledData::Binding *> bindings;
1632 const QV4::CompiledData::Object *obj = compilationUnit->objectAt(index);
1633 const QV4::CompiledData::Binding *binding = obj->bindingTable();
1634 for (quint32 i = 0; i < obj->nBindings; ++i, ++binding) {
1635 if (binding->hasFlag(QV4::CompiledData::Binding::IsCustomParserBinding))
1636 bindings << binding;
1638 customParser->applyBindings(instance, compilationUnit, bindings);
1640 customParser->engine =
nullptr;
1641 customParser->imports = (QQmlTypeNameCache*)
nullptr;
1644 initializePropertyCache(index, ddata, typeRef);
1645 return populateInstanceAndAliasBindings(index, instance, flags);
1648bool QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interrupt)
1650 Q_ASSERT(phase == ObjectsCreated || phase == Finalizing);
1653 QQmlObjectCreatorRecursionWatcher watcher(
this);
1654 QScopedValueRollback<QQmlObjectCreator*> ocRestore(QQmlEnginePrivate::get(engine)->activeObjectCreator,
this);
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1669 while (!sharedState->allCreatedBindings.empty()) {
1670 QQmlAbstractBinding::Ptr b = sharedState->allCreatedBindings.back();
1671 sharedState->allCreatedBindings.pop_back();
1674 if (!b->isAddedToObject())
1676 QQmlData *data = QQmlData::get(b->targetObject());
1678 data->clearPendingBindingBit(b->targetPropertyIndex().coreIndex());
1679 b->setEnabled(
true, QQmlPropertyData::BypassInterceptor |
1680 QQmlPropertyData::DontRemoveBinding);
1681 if (b->kind() == QQmlAbstractBinding::QmlBinding) {
1682 QQmlBinding *binding =
static_cast<QQmlBinding*>(b.data());
1683 if (!binding->hasError() && !binding->hasDependencies()
1684 && !binding->hasUnresolvedNames()) {
1685 b->removeFromObject();
1689 if (watcher.hasRecursed() || interrupt.shouldInterrupt())
1693 while (!sharedState->allQPropertyBindings.isEmpty()) {
1694 auto& [target, index, qmlBinding] = sharedState->allQPropertyBindings.first();
1696 QQmlData *data = QQmlData::get(target);
1697 if (!data || !data->hasBindingBit(index)) {
1699 sharedState->allQPropertyBindings.pop_front();
1703 QUntypedBindable bindable;
1704 void *argv[] = { &bindable };
1706 target->metaObject()->metacall(target, QMetaObject::BindableProperty, index, argv);
1707 const bool success = bindable.setBinding(qmlBinding);
1709 const auto bindingPrivateRefCount = QPropertyBindingPrivate::get(qmlBinding)->refCount();
1712 sharedState->allQPropertyBindings.pop_front();
1715 if (success && bindingPrivateRefCount > 1) {
1716 if (
auto priv = QPropertyBindingPrivate::get(qmlBinding); priv->hasCustomVTable()) {
1717 auto qmlBindingPriv =
static_cast<QQmlPropertyBinding *>(priv);
1718 auto jsExpression = qmlBindingPriv->jsExpression();
1719 const bool canRemove = !qmlBinding.error().hasError()
1720 && !qmlBindingPriv->hasDependencies()
1721 && !jsExpression->hasUnresolvedNames();
1723 bindable.takeBinding();
1727 if (watcher.hasRecursed() || interrupt.shouldInterrupt())
1731 if (QQmlVME::componentCompleteEnabled()) {
1732 while (!sharedState->allParserStatusCallbacks.empty()) {
1733 QQmlObjectCompletionProfiler profiler(&sharedState->profiler);
1734 const ParserStatus status = sharedState->allParserStatusCallbacks.back();
1735 sharedState->allParserStatusCallbacks.pop_back();
1737 const QQmlGuard<QObject> &instance = sharedState->allCreatedObjects[status.objectIndex];
1741 QQmlParserStatus *parserStatus
1742 =
reinterpret_cast<QQmlParserStatus *>(
1743 reinterpret_cast<
char *>(instance.data()) + status.parserStatusCast);
1744 parserStatus->componentComplete();
1746 if (watcher.hasRecursed() || interrupt.shouldInterrupt())
1751 for (QQmlFinalizerHook *hook: sharedState->finalizeHooks) {
1752 hook->componentFinalized();
1753 if (watcher.hasRecursed())
1756 sharedState->finalizeHooks.clear();
1758 while (sharedState->componentAttached) {
1759 QQmlComponentAttached *a = sharedState->componentAttached;
1760 a->removeFromList();
1761 QQmlData *d = QQmlData::get(a->parent());
1763 Q_ASSERT(d->context);
1764 d->context->addComponentAttached(a);
1765 if (QQmlVME::componentCompleteEnabled())
1766 emit a->completed();
1768 if (watcher.hasRecursed() || interrupt.shouldInterrupt())
1777void QQmlObjectCreator::clear()
1779 if (phase == Done || phase == Finalizing || phase == Startup)
1781 Q_ASSERT(phase != Startup);
1783 while (!sharedState->allCreatedObjects.empty()) {
1784 auto object = sharedState->allCreatedObjects.back();
1785 sharedState->allCreatedObjects.pop_back();
1786 if (engine->objectOwnership(object) != QQmlEngine::CppOwnership) {
1791 while (sharedState->componentAttached) {
1792 QQmlComponentAttached *a = sharedState->componentAttached;
1793 a->removeFromList();
1799void QQmlObjectCreator::registerPostHocRequiredProperties(
const QV4::CompiledData::Binding *binding)
1801 const qsizetype oldRequiredPropertiesCount = sharedState->requiredProperties.size();
1802 QSet<QString> postHocRequired;
1803 for (
auto it = _compiledObject->requiredPropertyExtraDataBegin(); it != _compiledObject->requiredPropertyExtraDataEnd(); ++it)
1804 postHocRequired.insert(stringAt(it->nameIndex));
1805 bool hadInheritedRequiredProperties = !postHocRequired.empty();
1807 for (
int propertyIndex = 0; propertyIndex != _compiledObject->propertyCount(); ++propertyIndex) {
1808 const QV4::CompiledData::Property* property = _compiledObject->propertiesBegin() + propertyIndex;
1809 const QQmlPropertyData *propertyData = _propertyCache->property(_propertyCache->propertyOffset() + propertyIndex);
1811 auto postHocIt = postHocRequired.isEmpty() ? postHocRequired.end() : postHocRequired.find(stringAt(property->nameIndex()));
1812 if (!property->isRequired() && postHocRequired.end() == postHocIt)
1814 if (postHocIt != postHocRequired.end())
1815 postHocRequired.erase(postHocIt);
1816 if (isContextObject)
1817 sharedState->hadTopLevelRequiredProperties =
true;
1818 sharedState->requiredProperties.insert({_qobject, propertyData},
1819 RequiredPropertyInfo {compilationUnit->stringAt(property->nameIndex()), compilationUnit->finalUrl(), property->location, {}});
1823 const auto getPropertyCacheRange = [&]() -> std::pair<
int,
int> {
1841 QV4::ResolvedTypeReference *typeRef = resolvedType(_compiledObject->inheritedTypeNameIndex);
1844 if (binding->isAttachedProperty())
1845 return { 0, _propertyCache->propertyCount() };
1846 Q_ASSERT(binding->isGroupProperty());
1847 return { 0, _propertyCache->propertyOffset() + 1 };
1849 Q_ASSERT(!_compiledObject->hasFlag(QV4::CompiledData::Object::IsComponent));
1850 QQmlType type = typeRef->type();
1851 if (type.isComposite() || type.isInlineComponentType())
1852 return { _propertyCache->propertyOffset(), _propertyCache->propertyCount() };
1853 return { 0, _propertyCache->propertyCount() };
1855 const auto [offset, count] = getPropertyCacheRange();
1856 for (
int i = offset; i < count; ++i) {
1857 const QQmlPropertyData *propertyData = _propertyCache->maybeUnresolvedProperty(i);
1863 if (!propertyData->isRequired() && postHocRequired.isEmpty())
1865 QString name = propertyData->name(_qobject);
1866 const auto postHocIt = postHocRequired.constFind(name);
1867 if (postHocIt == postHocRequired.constEnd()) {
1868 if (!propertyData->isRequired())
1871 postHocRequired.erase(postHocIt);
1874 if (isContextObject)
1875 sharedState->hadTopLevelRequiredProperties =
true;
1876 sharedState->requiredProperties.insert(
1877 {_qobject, propertyData},
1878 RequiredPropertyInfo {
1879 std::move(name), compilationUnit->finalUrl(), _compiledObject->location, {}
1883 if (binding && binding->isAttachedProperty()
1884 && sharedState->requiredProperties.size() != oldRequiredPropertiesCount) {
1887 QLatin1String(
"Attached property has required properties. This is not supported"));
1894 if (!postHocRequired.isEmpty()) {
1896 for (
int i = 0; i < offset; ++i) {
1897 const QQmlPropertyData *propertyData = _propertyCache->maybeUnresolvedProperty(i);
1900 QString name = propertyData->name(_qobject);
1901 const auto postHocIt = postHocRequired.constFind(name);
1902 if (postHocIt == postHocRequired.constEnd())
1904 postHocRequired.erase(postHocIt);
1906 if (isContextObject)
1907 sharedState->hadTopLevelRequiredProperties =
true;
1908 sharedState->requiredProperties.insert(
1909 {_qobject, propertyData},
1910 RequiredPropertyInfo {
1911 std::move(name), compilationUnit->finalUrl(), _compiledObject->location, {}
1916 if (!postHocRequired.isEmpty() && hadInheritedRequiredProperties)
1917 recordError({}, QLatin1String(
"Property %1 was marked as required but does not exist").arg(*postHocRequired.begin()));
1920bool QQmlObjectCreator::populateInstance(
int index, QObject *instance, QObject *bindingTarget,
1921 const QQmlPropertyData *valueTypeProperty,
1922 const QV4::CompiledData::Binding *binding)
1925 QQmlData *declarativeData = QQmlData::get(instance,
true);
1927 qSwap(_qobject, instance);
1928 qSwap(_valueTypeProperty, valueTypeProperty);
1929 qSwap(_compiledObjectIndex, index);
1930 const QV4::CompiledData::Object *obj = compilationUnit->objectAt(_compiledObjectIndex);
1931 qSwap(_compiledObject, obj);
1932 qSwap(_ddata, declarativeData);
1933 qSwap(_bindingTarget, bindingTarget);
1935 QV4::Scope valueScope(v4);
1936 QV4::ScopedValue scopeObjectProtector(valueScope);
1938 QQmlPropertyCache::ConstPtr cache = propertyCaches->at(_compiledObjectIndex);
1940 QQmlVMEMetaObject *vmeMetaObject =
nullptr;
1941 if (propertyCaches->needsVMEMetaObject(_compiledObjectIndex)) {
1942 Q_ASSERT(!cache.isNull());
1944 vmeMetaObject =
new QQmlVMEMetaObject(v4, _qobject, cache, compilationUnit, _compiledObjectIndex);
1945 _ddata->propertyCache = cache;
1946 scopeObjectProtector = _ddata->jsWrapper.value();
1948 vmeMetaObject = QQmlVMEMetaObject::get(_qobject);
1951 registerObjectWithContextById(_compiledObject, _qobject);
1953 qSwap(_propertyCache, cache);
1954 qSwap(_vmeMetaObject, vmeMetaObject);
1956 _ddata->compilationUnit = compilationUnit;
1957 if (_compiledObject->hasFlag(QV4::CompiledData::Object::HasDeferredBindings))
1958 _ddata->deferData(_compiledObjectIndex, compilationUnit, context, m_inlineComponentName);
1960 registerPostHocRequiredProperties(binding);
1962 if (_compiledObject->nFunctions > 0)
1964 setupBindings((binding && binding->hasFlag(QV4::CompiledData::Binding::IsDeferredBinding))
1965 ? BindingMode::ApplyAll
1966 : BindingMode::ApplyImmediate);
1968 for (
int aliasIndex = 0; aliasIndex != _compiledObject->aliasCount(); ++aliasIndex) {
1973 _vmeMetaObject->connectAlias(_compiledObject, aliasIndex);
1974 if (!context->isIdValueSet(0))
1976 const QQmlPropertyData *aliasProperty =
1977 _propertyCache->property(_vmeMetaObject->aliasOffset() + aliasIndex);
1980 QObject *target = context->idValue(aliasProperty->aliasTargetObjectId());
1983 QQmlData *targetDData = QQmlData::get(target,
false);
1984 if (targetDData ==
nullptr || targetDData->propertyCache.isNull())
1987 const int targetPropertyIndex = aliasProperty->aliasTarget();
1988 int coreIndex = QQmlPropertyIndex::fromEncoded(targetPropertyIndex).coreIndex();
1990 const QQmlPropertyData *
const targetProperty = targetDData->propertyCache->property(coreIndex);
1991 if (!targetProperty)
1993 auto it = sharedState->requiredProperties.find({target, targetProperty});
1994 if (it != sharedState->requiredProperties.end()) {
1995 const QV4::CompiledData::Alias* alias = _compiledObject->aliasesBegin() + aliasIndex;
1996 it->aliasesToRequired.push_back(
1997 AliasToRequiredInfo {
1998 compilationUnit->stringAt(alias->nameIndex()),
1999 compilationUnit->finalUrl()
2004 qSwap(_vmeMetaObject, vmeMetaObject);
2005 qSwap(_bindingTarget, bindingTarget);
2006 qSwap(_ddata, declarativeData);
2007 qSwap(_compiledObject, obj);
2008 qSwap(_compiledObjectIndex, index);
2009 qSwap(_valueTypeProperty, valueTypeProperty);
2010 qSwap(_qobject, instance);
2011 qSwap(_propertyCache, cache);
2013 return errors.isEmpty();
2017
2018
2019QQmlComponent *QQmlObjectCreator::createComponent(
2020 QQmlEngine *engine, QV4::ExecutableCompilationUnit *compilationUnit,
int index,
2021 QObject *parent,
const QQmlRefPointer<QQmlContextData> &context)
2023 QQmlComponent *component =
new QQmlComponent(engine, compilationUnit, index, parent);
2024 QQmlComponentPrivate::get(component)->setCreationContext(context);
2025 QQmlData::get(component,
true);
2035void ObjectInCreationGCAnchorList::trackObject(QV4::ExecutionEngine *engine, QObject *instance)
2037 QV4::Value *wrapper = allocationScope->construct(1, QV4::QObjectWrapper::wrap(engine, instance));
2041 QV4::WriteBarrier::markCustom(engine, [wrapper](QV4::MarkStack *ms) {
2042 wrapper->heapObject()->mark(ms);
QT_BEGIN_NAMESPACE Q_STATIC_LOGGING_CATEGORY(lcSynthesizedIterableAccess, "qt.iterable.synthesized", QtWarningMsg)
static QQmlType qmlTypeForObject(QObject *object)
QQmlObjectCreatorRecursionWatcher(QQmlObjectCreator *creator)