Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qqmlexpression.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qqmlexpression.h"
5#include "qqmlexpression_p.h"
6
7#include "qqmlengine_p.h"
9#include "qqmlbinding_p.h"
10#include <private/qqmlsourcecoordinate_p.h>
11#include <private/qv4qmlcontext_p.h>
12
13#include <QtCore/qdebug.h>
14
16
19 expressionFunctionValid(true),
20 line(0), column(0)
21{
22}
23
27
28void QQmlExpressionPrivate::init(const QQmlRefPointer<QQmlContextData> &ctxt, const QString &expr,
29 QObject *me)
30{
31 expression = expr;
32
36}
37
38void QQmlExpressionPrivate::init(const QQmlRefPointer<QQmlContextData> &ctxt,
39 QV4::Function *runtimeFunction, QObject *me)
40{
42 QV4::ExecutionEngine *engine = ctxt->engine()->handle();
43 QV4::Scope scope(engine);
45 setupFunction(qmlContext, runtimeFunction);
46
49}
50
90
101: QObject(*new QQmlExpressionPrivate, parent)
102{
103 Q_D(QQmlExpression);
104 if (ctxt && !ctxt->isValid())
105 return;
106
107 const QQmlScriptStringPrivate *scriptPrivate = script.d.data();
108 if (!scriptPrivate) {
109 // A null QQmlScriptStringPrivate is an empty expression without context.
110 // We may still want the explicitly passed context, though.
111 if (ctxt)
112 d->init(QQmlContextData::get(ctxt), QString(), scope);
113 return;
114 }
115
116 if (!ctxt && (!scriptPrivate->context || !scriptPrivate->context->isValid()))
117 return;
118
119 QQmlRefPointer<QQmlContextData> evalCtxtData
120 = QQmlContextData::get(ctxt ? ctxt : scriptPrivate->context);
121 QObject *scopeObject = scope ? scope : scriptPrivate->scope;
122 QV4::Function *runtimeFunction = nullptr;
123
124 if (scriptPrivate->context) {
125 QQmlRefPointer<QQmlContextData> ctxtdata = QQmlContextData::get(scriptPrivate->context);
126 QQmlEnginePrivate *engine = QQmlEnginePrivate::get(scriptPrivate->context->engine());
127 if (engine
128 && ctxtdata
129 && !ctxtdata->urlString().isEmpty()
130 && ctxtdata->typeCompilationUnit()) {
131 d->url = ctxtdata->urlString();
132 d->line = scriptPrivate->lineNumber;
133 d->column = scriptPrivate->columnNumber;
134
135 if (scriptPrivate->bindingId != QQmlBinding::Invalid)
136 runtimeFunction = ctxtdata->typeCompilationUnit()->runtimeFunctions.at(scriptPrivate->bindingId);
137 }
138 }
139
140 if (runtimeFunction) {
141 d->expression = scriptPrivate->script;
142 d->init(evalCtxtData, runtimeFunction, scopeObject);
143 } else
144 d->init(evalCtxtData, scriptPrivate->script, scopeObject);
145}
146
155 QObject *parent)
156: QObject(*new QQmlExpressionPrivate, parent)
157{
158 Q_D(QQmlExpression);
159 d->init(QQmlContextData::get(ctxt), expression, scope);
160}
161
166{
167// Q_D(QQmlExpression);
168// d->init(QQmlContextData::get(ctxt), expression, scope);
169}
170
177
183{
184 Q_D(const QQmlExpression);
185 return d->engine();
186}
187
193{
194 Q_D(const QQmlExpression);
195 return d->publicContext();
196}
197
202{
203 Q_D(const QQmlExpression);
204 return d->expression;
205}
206
211{
212 Q_D(QQmlExpression);
213
214 d->resetNotifyOnValueChanged();
215 d->expression = expression;
216 d->expressionFunctionValid = false;
217}
218
219// Must be called with a valid handle scope
221{
225 if (hasError()) {
226 if (isUndefined)
227 *isUndefined = true;
228 return QV4::Encode::undefined();
229 }
230 }
231
232 return evaluate(isUndefined);
233}
234
236{
237 Q_Q(QQmlExpression);
238
239 if (!hasValidContext()) {
240 qWarning("QQmlExpression: Attempted to evaluate an expression in an invalid context");
241 return QVariant();
242 }
243
244 QQmlEngine *engine = q->engine();
246 QVariant rv;
247
248 ep->referenceScarceResources(); // "hold" scarce resources in memory during evaluation.
249
250 {
251 QV4::Scope scope(engine->handle());
252 QV4::ScopedValue result(scope, v4value(isUndefined));
253 if (!hasError())
255 }
256
257 ep->dereferenceScarceResources(); // "release" scarce resources if top-level expression evaluation is complete.
258
259 return rv;
260}
261
271QVariant QQmlExpression::evaluate(bool *valueIsUndefined)
272{
273 Q_D(QQmlExpression);
274 return d->value(valueIsUndefined);
275}
276
282{
283 Q_D(const QQmlExpression);
284 return d->notifyOnValueChanged();
285}
286
304{
305 Q_D(QQmlExpression);
306 d->setNotifyOnValueChanged(notifyOnChange);
307}
308
314{
315 Q_D(const QQmlExpression);
316 return d->url;
317}
318
324{
325 Q_D(const QQmlExpression);
327}
328
334{
335 Q_D(const QQmlExpression);
337}
338
350
358{
359 Q_D(const QQmlExpression);
360 return d->scopeObject();
361}
362
370{
371 Q_D(const QQmlExpression);
372 return d->hasError();
373}
374
382{
383 Q_D(QQmlExpression);
384 d->clearError();
385}
386
395{
396 Q_D(const QQmlExpression);
397 return d->error(engine());
398}
399
409{
410 Q_Q(QQmlExpression);
411 emit q->valueChanged();
412}
413
418
420
421#include <moc_qqmlexpression.cpp>
QV4::ExecutionEngine * handle() const
Definition qjsengine.h:298
\inmodule QtCore
Definition qmetatype.h:341
\inmodule QtCore
Definition qobject.h:103
static QQmlRefPointer< QQmlContextData > get(QQmlContext *context)
The QQmlContext class defines a context within a QML engine.
Definition qqmlcontext.h:25
bool isValid() const
Returns whether the context is valid.
static QQmlEnginePrivate * get(QQmlEngine *e)
void referenceScarceResources()
void dereferenceScarceResources()
The QQmlEngine class provides an environment for instantiating QML components.
Definition qqmlengine.h:57
QQmlContext * rootContext() const
Returns the engine's root context.
The QQmlError class encapsulates a QML error.
Definition qqmlerror.h:18
void expressionChanged() override
QV4::ReturnedValue v4value(bool *isUndefined=nullptr)
void init(const QQmlRefPointer< QQmlContextData > &, const QString &, QObject *)
QVariant value(bool *isUndefined=nullptr)
QString expressionIdentifier() const override
~QQmlExpressionPrivate() override
The QQmlExpression class evaluates JavaScript in a QML context.
QString sourceFile() const
Returns the source file URL for this expression.
~QQmlExpression() override
Destroy the QQmlExpression instance.
bool notifyOnValueChanged() const
Returns true if the valueChanged() signal is emitted when the expression's evaluated value changes.
QQmlContext * context() const
Returns the QQmlContext this expression is associated with, or \nullptr if there is no association or...
void clearError()
Clear any expression errors.
void setSourceLocation(const QString &fileName, int line, int column=0)
Set the location of this expression to line and column of url.
QString expression() const
Returns the expression string.
int columnNumber() const
Returns the source file column number for this expression.
int lineNumber() const
Returns the source file line number for this expression.
QQmlError error() const
Return any error from the last call to evaluate().
QQmlExpression()
Create an invalid QQmlExpression.
bool hasError() const
Returns true if the last call to evaluate() resulted in an error, otherwise false.
void setExpression(const QString &)
Set the expression to expression.
QVariant evaluate(bool *valueIsUndefined=nullptr)
Evaulates the expression, returning the result of the evaluation, or an invalid QVariant if the expre...
void setNotifyOnValueChanged(bool)
Sets whether the valueChanged() signal is emitted when the expression's evaluated value changes.
QQmlEngine * engine() const
Returns the QQmlEngine this expression is associated with, or \nullptr if there is no association or ...
QObject * scopeObject() const
Returns the expression's scope object, if provided, otherwise 0.
void setupFunction(QV4::ExecutionContext *qmlContext, QV4::Function *f)
void createQmlBinding(const QQmlRefPointer< QQmlContextData > &ctxt, QObject *scope, const QString &code, const QString &filename, quint16 line)
void setContext(const QQmlRefPointer< QQmlContextData > &context)
QQmlRefPointer< QQmlContextData > context() const
The QQmlScriptString class encapsulates a script and its context.
T * data()
Returns a pointer to the shared data object.
Definition qshareddata.h:47
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
\inmodule QtCore
Definition qvariant.h:65
Combined button and popup list for selecting options.
quint64 ReturnedValue
#define qWarning
Definition qlogging.h:166
GLenum GLenum GLsizei void GLsizei void * column
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLuint64EXT * result
[6]
QQmlContext * qmlContext(const QObject *obj)
Definition qqml.cpp:75
quint16 qmlConvertSourceCoordinate< int, quint16 >(int n)
int qmlConvertSourceCoordinate< quint16, int >(quint16 n)
#define emit
QUrl url("example.com")
[constructor-url-reference]
QObject::connect nullptr
engine evaluate("var myObject = new MyObject()")
[8]
\inmodule QtCore \reentrant
Definition qchar.h:18
static constexpr ReturnedValue undefined()
static QVariant toVariant(const QV4::Value &value, QMetaType typeHint, bool createJSValueForObjectsAndSymbols=true)
static Heap::QmlContext * create(QV4::ExecutionContext *parent, QQmlRefPointer< QQmlContextData > context, QObject *scopeObject)