37 static QQmlRefPointer<QQmlContextData> createRefCounted(
38 const QQmlRefPointer<QQmlContextData> &parent)
40 return QQmlRefPointer<QQmlContextData>(
new QQmlContextData(RefCounted,
nullptr, parent),
41 QQmlRefPointer<QQmlContextData>::Adopt);
45 static QQmlRefPointer<QQmlContextData> createChild(
46 const QQmlRefPointer<QQmlContextData> &parent)
48 Q_ASSERT(!parent.isNull());
49 return QQmlRefPointer<QQmlContextData>(
new QQmlContextData(OwnedByParent,
nullptr, parent));
52 void addref()
const { ++m_refCount; }
53 void release()
const {
if (--m_refCount == 0)
delete this; }
54 int count()
const {
return m_refCount; }
55 int refCount()
const {
return m_refCount; }
57 QQmlRefPointer<QV4::ExecutableCompilationUnit> typeCompilationUnit()
const
59 return m_typeCompilationUnit;
61 void setTypeCompilationUnit(
const QQmlRefPointer<QV4::ExecutableCompilationUnit> &unit);
63 void initFromTypeCompilationUnit(
const QQmlRefPointer<QV4::ExecutableCompilationUnit> &unit,
64 int subComponentIndex);
66 static QQmlRefPointer<QQmlContextData> get(QQmlContext *context) {
67 return QQmlContextPrivate::get(context)->m_data;
70 void emitDestruction();
71 void clearExpressions();
72 void clearContextRecursively();
73 void clearChildrenAndSiblings();
74 void clearImportedScripts();
75 void clearOwnedObjects();
76 void clearContextGuards();
82 return m_engine && (!m_isInternal || !m_contextObject
83 || !QObjectPrivate::get(m_contextObject)->wasDeleted);
86 bool isInternal()
const {
return m_isInternal; }
87 void setInternal(
bool isInternal) { m_isInternal = isInternal; }
89 bool isJSContext()
const {
return m_isJSContext; }
90 void setJSContext(
bool isJSContext) { m_isJSContext = isJSContext; }
92 bool isPragmaLibraryContext()
const {
return m_isPragmaLibraryContext; }
93 void setPragmaLibraryContext(
bool library) { m_isPragmaLibraryContext = library; }
95 QQmlRefPointer<QQmlContextData> parent()
const {
return m_parent; }
102 if (m_ownedByParent) {
103 m_ownedByParent =
false;
108 void refreshExpressions();
110 void addOwnedObject(QQmlData *ownedObject);
111 QQmlData *ownedObjects()
const {
return m_ownedObjects; }
112 void setOwnedObjects(QQmlData *ownedObjects) { m_ownedObjects = ownedObjects; }
118 void installContext(QQmlData *ddata, QmlObjectKind kind);
120 QUrl resolvedUrl(
const QUrl &)
const;
124 QQmlContext *asQQmlContext()
126 if (!m_publicContext)
127 m_publicContext =
new QQmlContext(*
new QQmlContextPrivate(
this));
128 return m_publicContext;
131 QQmlContextPrivate *asQQmlContextPrivate()
133 return QQmlContextPrivate::get(asQQmlContext());
136 QObject *contextObject()
const {
return m_contextObject; }
137 void setContextObject(QObject *contextObject) { m_contextObject = contextObject; }
139 template<
typename HandleSelf,
typename HandleLinked>
140 void deepClearContextObject(
141 QObject *contextObject, HandleSelf &&handleSelf, HandleLinked &&handleLinked) {
142 for (QQmlContextData *lc = m_linkedContext.data(); lc; lc = lc->m_linkedContext.data()) {
144 if (lc->m_contextObject == contextObject)
145 lc->m_contextObject =
nullptr;
149 if (m_contextObject == contextObject)
150 m_contextObject =
nullptr;
153 void deepClearContextObject(QObject *contextObject)
155 deepClearContextObject(
157 [](QQmlContextData *self) { self->emitDestruction(); },
158 [](QQmlContextData *){});
161 QQmlEngine *engine()
const {
return m_engine; }
162 void setEngine(QQmlEngine *engine) { m_engine = engine; }
164 QQmlContext *publicContext()
const {
return m_publicContext; }
165 void clearPublicContext()
167 if (!m_publicContext)
170 m_publicContext =
nullptr;
171 if (m_ownedByPublicContext) {
172 m_ownedByPublicContext =
false;
177 int propertyIndex(
const QString &name)
const
179 ensurePropertyNames();
180 return m_propertyNameCache.value(name);
183 int propertyIndex(QV4::Heap::String *name)
const
185 ensurePropertyNames();
186 return m_propertyNameCache.value(name);
189 QString propertyName(
int index)
const
191 ensurePropertyNames();
192 return m_propertyNameCache.key<QString>(index);
195 void addPropertyNameAndIndex(
const QString &name,
int index)
197 Q_ASSERT(m_propertyNameCache.isValid());
198 m_propertyNameCache.add(name, index);
201 void setExpressions(QQmlJavaScriptExpression *expressions) { m_expressions = expressions; }
202 QQmlJavaScriptExpression *expressions()
const {
return m_expressions; }
203 QQmlJavaScriptExpression *takeExpressions()
205 QQmlJavaScriptExpression *expressions = m_expressions;
206 m_expressions =
nullptr;
210 void setChildContexts(
const QQmlRefPointer<QQmlContextData> &childContexts)
212 m_childContexts = childContexts.data();
214 QQmlRefPointer<QQmlContextData> childContexts()
const {
return m_childContexts; }
215 QQmlRefPointer<QQmlContextData> takeChildContexts()
217 QQmlRefPointer<QQmlContextData> childContexts = m_childContexts;
218 m_childContexts =
nullptr;
219 return childContexts;
221 QQmlRefPointer<QQmlContextData> nextChild()
const {
return m_nextChild; }
223 int numIdValues()
const {
return m_idValueCount; }
224 void setIdValue(
int index, QObject *idValue);
225 bool isIdValueSet(
int index)
const {
return m_idValues[index].wasSet(); }
226 QQmlNotifier *idValueBindings(
int index)
const {
return m_idValues[index].bindings(); }
227 QObject *idValue(
int index)
const {
return m_idValues[index].data(); }
230 QString findObjectId(
const QObject *obj)
const;
238 QString urlString()
const;
240 void setBaseUrlString(
const QString &baseUrlString) { m_baseUrlString = baseUrlString; }
241 QString baseUrlString()
const
243 for (
const QQmlContextData *data =
this; data; data = data->m_parent) {
244 if (!data->m_baseUrlString.isEmpty())
245 return data->m_baseUrlString;
246 if (data->m_typeCompilationUnit)
247 return data->m_typeCompilationUnit->finalUrlString();
252 void setBaseUrl(
const QUrl &baseUrl) { m_baseUrl = baseUrl; }
255 for (
const QQmlContextData *data =
this; data; data = data->m_parent) {
256 if (!data->m_baseUrl.isEmpty())
257 return data->m_baseUrl;
258 if (data->m_typeCompilationUnit)
259 return data->m_typeCompilationUnit->finalUrl();
264 QQmlRefPointer<QQmlTypeNameCache> imports()
const {
return m_imports; }
265 void setImports(
const QQmlRefPointer<QQmlTypeNameCache> &imports) { m_imports = imports; }
267 QQmlIncubatorPrivate *incubator()
const {
return m_hasExtraObject ?
nullptr : m_incubator; }
268 void setIncubator(QQmlIncubatorPrivate *incubator)
270 Q_ASSERT(!m_hasExtraObject || m_extraObject ==
nullptr);
271 m_hasExtraObject =
false;
272 m_incubator = incubator;
275 QObject *extraObject()
const {
return m_hasExtraObject ? m_extraObject :
nullptr; }
276 void setExtraObject(QObject *extraObject)
278 Q_ASSERT(m_hasExtraObject || m_incubator ==
nullptr);
279 m_hasExtraObject =
true;
280 m_extraObject = extraObject;
283 bool isRootObjectInCreation()
const {
return m_isRootObjectInCreation; }
284 void setRootObjectInCreation(
bool rootInCreation) { m_isRootObjectInCreation = rootInCreation; }
286 QV4::ReturnedValue importedScripts()
const
288 if (m_hasWeakImportedScripts)
289 return m_weakImportedScripts.value();
291 return m_importedScripts.value();
293 void setImportedScripts(QV4::ExecutionEngine *engine, QV4::Value scripts) {
295 Q_ASSERT(!m_hasWeakImportedScripts);
296 m_importedScripts.set(engine, scripts);
300
301
302
303
304 void setImportedScripts(QV4::ExecutionEngine *engine, QV4::ReturnedValue scripts) {
306 Q_ASSERT(!m_hasWeakImportedScripts);
307 m_importedScripts.set(engine, scripts);
310 QQmlRefPointer<QQmlContextData> linkedContext()
const {
return m_linkedContext; }
311 void setLinkedContext(
const QQmlRefPointer<QQmlContextData> &context) { m_linkedContext = context; }
313 bool hasUnresolvedNames()
const {
return m_unresolvedNames; }
314 void setUnresolvedNames(
bool hasUnresolvedNames) { m_unresolvedNames = hasUnresolvedNames; }
316 QQmlComponentAttached *componentAttacheds()
const {
return m_componentAttacheds; }
317 void addComponentAttached(QQmlComponentAttached *attached);
319 void addExpression(QQmlJavaScriptExpression *expression);
321 bool valueTypesAreAddressable()
const {
322 return m_typeCompilationUnit && m_typeCompilationUnit->valueTypesAreAddressable();
325 bool valueTypesAreAssertable()
const {
326 return m_typeCompilationUnit && m_typeCompilationUnit->valueTypesAreAssertable();
330 friend class QQmlGuardedContextData;
331 friend class QQmlContextPrivate;
340 struct ContextGuard :
public QQmlGuard<QObject>
347 inline ContextGuard() : QQmlGuard<QObject>(&ContextGuard::objectDestroyedImpl,
nullptr), m_context(
nullptr) {}
348 inline ContextGuard &operator=(QObject *obj);
350 inline bool wasSet()
const;
352 QQmlNotifier *bindings() {
return &m_bindings; }
353 void setContext(
const QQmlRefPointer<QQmlContextData> &context)
355 m_context = context.data();
359 inline static void objectDestroyedImpl(QQmlGuardImpl *);
361 QTaggedPointer<QQmlContextData, Tag> m_context;
362 QQmlNotifier m_bindings;
368 Ownership ownership, QQmlContext *publicContext,
369 const QQmlRefPointer<QQmlContextData> &parent, QQmlEngine *engine =
nullptr)
370 : m_parent(parent.data()),
371 m_engine(engine ? engine : (parent.isNull() ?
nullptr : parent->engine())),
372 m_isInternal(
false), m_isJSContext(
false), m_isPragmaLibraryContext(
false),
373 m_unresolvedNames(
false), m_hasEmittedDestruction(
false), m_isRootObjectInCreation(
false),
374 m_ownedByParent(ownership == OwnedByParent),
375 m_ownedByPublicContext(ownership == OwnedByPublicContext), m_hasExtraObject(
false),
376 m_hasWeakImportedScripts(
false), m_dummy(0), m_publicContext(publicContext), m_incubator(
nullptr)
378 Q_ASSERT(!m_ownedByParent || !m_ownedByPublicContext);
382 m_nextChild = m_parent->m_childContexts;
384 m_nextChild->m_prevChild = &m_nextChild;
385 m_prevChild = &m_parent->m_childContexts;
386 m_parent->m_childContexts =
this;
391 bool hasExpressionsToRun(
bool isGlobalRefresh)
const
393 return m_expressions && (!isGlobalRefresh || m_unresolvedNames);
396 void refreshExpressionsRecursive(
bool isGlobal);
397 void refreshExpressionsRecursive(QQmlJavaScriptExpression *);
398 void initPropertyNames()
const;
400 void ensurePropertyNames()
const
402 if (!m_propertyNameCache.isValid())
404 Q_ASSERT(m_propertyNameCache.isValid());
408 QQmlContextData *m_parent =
nullptr;
409 QQmlEngine *m_engine =
nullptr;
411 mutable quint32 m_refCount = 1;
412 quint32 m_isInternal:1;
413 quint32 m_isJSContext:1;
414 quint32 m_isPragmaLibraryContext:1;
415 quint32 m_unresolvedNames:1;
416 quint32 m_hasEmittedDestruction:1;
417 quint32 m_isRootObjectInCreation:1;
418 quint32 m_ownedByParent:1;
419 quint32 m_ownedByPublicContext:1;
420 quint32 m_hasExtraObject:1;
421 quint32 m_hasWeakImportedScripts:1;
422 Q_DECL_UNUSED_MEMBER quint32 m_dummy:22;
423 QQmlContext *m_publicContext =
nullptr;
427 QQmlIncubatorPrivate *m_incubator;
429 QObject *m_extraObject;
433 QQmlRefPointer<QV4::ExecutableCompilationUnit> m_typeCompilationUnit;
436 int m_componentObjectIndex = -1;
439 mutable QV4::IdentifierHash m_propertyNameCache;
442 QObject *m_contextObject =
nullptr;
447
448
449
450 QV4::PersistentValue m_importedScripts = {};
451 QV4::WeakValue m_weakImportedScripts;
455 QString m_baseUrlString;
458 QQmlRefPointer<QQmlTypeNameCache> m_imports;
461 QQmlContextData *m_childContexts =
nullptr;
464 QQmlContextData *m_nextChild =
nullptr;
465 QQmlContextData **m_prevChild =
nullptr;
468 QQmlJavaScriptExpression *m_expressions =
nullptr;
471 QQmlData *m_ownedObjects =
nullptr;
474 QQmlGuardedContextData *m_contextGuards =
nullptr;
476 ContextGuard *m_idValues =
nullptr;
477 int m_idValueCount = 0;
480 QQmlRefPointer<QQmlContextData> m_linkedContext;
483 QQmlComponentAttached *m_componentAttacheds =
nullptr;