6#include <private/qqmlbinding_p.h>
7#include <private/qqmlglobal_p.h>
8#include <private/qqmlscriptstring_p.h>
9#include <private/qv4functionobject_p.h>
10#include <private/qv4jscall_p.h>
11#include <private/qv4qmlcontext_p.h>
13#include <QtQml/qqmlinfo.h>
15#include <QtCore/qloggingcategory.h>
24 QObject *
obj,
const QQmlRefPointer<QQmlContextData> &ctxt,
33 const QQmlRefPointer<QQmlContextData> &ctxt,
40 TargetData::WithoutBoundFunction);
42 Q_ASSERT(binding->jsExpression() == js);
43 Q_ASSERT(js->asBinding() == binding);
45 binding->jsExpression()->setNotifyOnValueChanged(
true);
46 binding->jsExpression()->setContext(ctxt);
47 binding->jsExpression()->setScopeObject(
obj);
48 binding->jsExpression()->setupFunction(scope, function);
58 Q_ASSERT(binding->jsExpression() == js);
59 Q_ASSERT(js->asBinding() == binding);
61 binding->jsExpression()->setNotifyOnValueChanged(
true);
62 binding->jsExpression()->setContext(ctxt);
63 binding->jsExpression()->createQmlBinding(ctxt,
obj,
str,
url, lineNumber);
71 if (!ctxt && (!scriptPrivate->context || !scriptPrivate->context->isValid())) {
75 auto scopeObject =
obj ?
obj : scriptPrivate->scope;
81 if (
engine && ctxtdata && !ctxtdata->urlString().isEmpty() && ctxtdata->typeCompilationUnit()) {
82 url = ctxtdata->urlString();
84 runtimeFunction = ctxtdata->typeCompilationUnit()->runtimeFunctions.at(scriptPrivate->bindingId);
94 Q_ASSERT(binding->jsExpression() == js);
95 Q_ASSERT(js->asBinding() == binding);
101 js->setupFunction(
qmlContext, runtimeFunction);
111 Q_ASSERT(binding->jsExpression() == js);
112 Q_ASSERT(js->asBinding() == binding);
114 binding->jsExpression()->setNotifyOnValueChanged(
true);
115 binding->jsExpression()->setContext(ctxt);
116 binding->jsExpression()->setScopeObject(
obj);
117 binding->jsExpression()->setupFunction(scope, function->function());
118 js->m_boundFunction.set(function->engine(), *function);
136 auto binding = asBinding();
137 if (!binding->propertyDataPtr)
149 err.
setDescription(asBinding()->createBindingLoopErrorDescription());
158 binding->evaluateRecursive(bindingObservers);
159 binding->notifyNonRecursive(bindingObservers);
168 static_assert (std::is_trivially_destructible_v<TargetData>);
171 const auto state = hasBoundFunction ? TargetData::HasBoundFunction : TargetData::WithoutBoundFunction;
172 new (&declarativeExtraData) TargetData {
target, targetIndex,
state};
173 errorCallBack = bindingErrorCallback;
187 std::byte *qpropertyPointer =
reinterpret_cast<std::byte *
>(dataPtr);
188 qpropertyPointer +=
type.sizeOf();
194void QQmlPropertyBinding::handleUndefinedAssignment(
QQmlEnginePrivate *ep,
void *dataPtr)
203 propertyData =
data->propertyCache->property(targetIndex().coreIndex());
205 Q_ASSERT(!targetIndex().hasValueTypeIndex());
214 metaType.destruct(dataPtr);
227 bindingData->d_ref() = 0;
229 bindingDataPointer.setObservers(firstObserver.ptr);
231 Q_ASSERT(!bindingData->hasBinding());
232 setIsUndefined(
true);
248 qCWarning(lcQQPropertyBinding) <<
"Resetting " << prop.
name() <<
"due to the binding becoming undefined caused a new binding to be installed\n"
249 <<
"The old binding binding will be abandoned";
254 firstObserver = bindingDataPointer.firstObserver();
261 qmlError.setColumn(
location.column);
265 qmlError.setDescription(description);
266 qmlError.setObject(target());
271QString QQmlPropertyBinding::createBindingLoopErrorDescription()
280 propertyData =
data->propertyCache->property(targetIndex().coreIndex());
282 Q_ASSERT(!targetIndex().hasValueTypeIndex());
290 auto target = This->target();
295 auto error = This->bindingError();
297 auto location = This->jsExpression()->sourceLocation();
301 auto description =
error.description();
303 description = This->createBindingLoopErrorDescription();
305 qmlError.setDescription(description);
306 qmlError.setObject(
target);
310template<
typename TranslateWithUnit>
312 const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit,
313 TranslateWithUnit &&translateWithUnit)
315 return [compilationUnit, translateWithUnit](
QMetaType metaType,
void *dataPtr) ->
bool {
319 QVariant resultVariant(translateWithUnit(compilationUnit));
320 if (metaType != QMetaType::fromType<QString>())
321 resultVariant.convert(metaType);
323 const bool hasChanged = !metaType.equals(resultVariant.constData(), dataPtr);
324 metaType.destruct(dataPtr);
325 metaType.construct(dataPtr, resultVariant.constData());
332 const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit,
337 [binding](
const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit) {
338 return compilationUnit->bindingValueAsString(binding);
347 const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit,
353 const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit) {
355 return translationData.translate();
370 QV4::Heap::MemberData *
args =
b->boundArgs();
375 thisObject = &
b->d()->boundThis;
QV4::ExecutionEngine * handle() const
qsizetype size() const noexcept
friend class QPropertyBindingPrivatePtr
QMetaType valueMetaType() const
QPropertyObserverPointer takeObservers()
static constexpr size_t getSizeEnsuringAlignment()
void prependObserver(QPropertyObserverPointer observer)
QUntypedPropertyData * propertyDataPtr
static QQmlRefPointer< QQmlContextData > get(QQmlContext *context)
The QQmlContext class defines a context within a QML engine.
static QQmlData * get(QObjectPrivate *priv, bool create)
void warning(const QQmlError &)
static QQmlEnginePrivate * get(QQmlEngine *e)
The QQmlEngine class provides an environment for instantiating QML components.
The QQmlError class encapsulates a QML error.
void setObject(QObject *)
Sets the nearest object where this error occurred.
void setColumn(int)
Sets the error column number.
void setLine(int)
Sets the error line number.
void setDescription(const QString &)
Sets the error description.
void setUrl(const QUrl &)
Sets the url for the file that caused this error.
QObject * scopeObject() const
QV4::ReturnedValue evaluate(bool *isUndefined)
QQmlEngine * engine() const
QQmlRefPointer< QQmlContextData > context() const
virtual QQmlSourceLocation sourceLocation() const
QTaggedPointer< QQmlDelayedError, Tag > m_error
QV4::ReturnedValue evaluate(bool *isUndefined)
QV4::PersistentValue m_boundFunction
void expressionChanged() override
friend class QQmlPropertyBindingJS
static QUntypedPropertyBinding createFromBoundFunction(const QQmlPropertyData *pd, QV4::BoundFunction *function, QObject *obj, const QQmlRefPointer< QQmlContextData > &ctxt, QV4::ExecutionContext *scope, QObject *target, QQmlPropertyIndex targetIndex)
static QUntypedPropertyBinding createFromCodeString(const QQmlPropertyData *property, const QString &str, QObject *obj, const QQmlRefPointer< QQmlContextData > &ctxt, const QString &url, quint16 lineNumber, QObject *target, QQmlPropertyIndex targetIndex)
QQmlPropertyBindingJS * jsExpression()
static QUntypedPropertyBinding create(const QQmlPropertyData *pd, QV4::Function *function, QObject *obj, const QQmlRefPointer< QQmlContextData > &ctxt, QV4::ExecutionContext *scope, QObject *target, QQmlPropertyIndex targetIndex)
static QUntypedPropertyBinding createFromScriptString(const QQmlPropertyData *property, const QQmlScriptString &script, QObject *obj, QQmlContext *ctxt, QObject *target, QQmlPropertyIndex targetIndex)
QMetaType propType() const
static QQmlProperty restore(QObject *, const QQmlPropertyData &, const QQmlPropertyData *, const QQmlRefPointer< QQmlContextData > &)
The QQmlProperty class abstracts accessing properties on objects created from QML.
QMetaType propertyMetaType() const
Returns the metatype of the property.
bool isResettable() const
Returns true if the property is resettable, otherwise false.
bool reset() const
Resets the property and returns true if the property is resettable.
The QQmlScriptString class encapsulates a script and its context.
static QUntypedPropertyBinding Q_QML_EXPORT create(const QQmlPropertyData *pd, const QQmlRefPointer< QV4::ExecutableCompilationUnit > &compilationUnit, const QV4::CompiledData::Binding *binding)
T * data()
Returns a pointer to the shared data object.
\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 constexpr quintptr BindingBit
Combined button and popup list for selecting options.
BindingEvaluationState * suspendCurrentBindingStatus()
void restoreBindingStatus(BindingEvaluationState *status)
DBusConnection const char DBusError * error
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
const QBindingStorage * qGetBindingStorage(const QObject *o)
GLboolean GLboolean GLboolean b
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
QQmlEngine * qmlEngine(const QObject *obj)
QQmlContext * qmlContext(const QObject *obj)
Q_QML_EXPORT QQmlInfo qmlWarning(const QObject *me)
static QtPrivate::QPropertyBindingData * bindingDataFromPropertyData(QUntypedPropertyData *dataPtr, QMetaType type)
auto qQmlTranslationPropertyBindingCreateBinding(const QQmlRefPointer< QV4::ExecutableCompilationUnit > &compilationUnit, TranslateWithUnit &&translateWithUnit)
const QtPrivate::BindingFunctionVTable * bindingFunctionVTableForQQmlPropertyBinding(QMetaType type)
Int aligned(Int v, Int byteAlign)
#define QStringLiteral(str)
QUrl url("example.com")
[constructor-url-reference]
obj metaObject() -> className()
ExecutionContext * rootContext() const
static Heap::QmlContext * create(QV4::ExecutionContext *parent, QQmlRefPointer< QQmlContextData > context, QObject *scopeObject)