1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
42 #include "qdeclarativeexpression.h"
43 #include "private/qdeclarativeexpression_p.h"
45 #include "private/qdeclarativeengine_p.h"
46 #include "private/qdeclarativecontext_p.h"
47 #include "private/qdeclarativerewrite_p.h"
48 #include "private/qdeclarativecompiler_p.h"
49 #include "private/qdeclarativeglobalscriptclass_p.h"
51 #include <QtCore/qdebug.h>
52 #include <QtScript/qscriptprogram.h>
54 #include <private/qscriptdeclarativeclass_p.h>
58 bool QDeclarativeDelayedError::addError(QDeclarativeEnginePrivate *e)
62 if (e->inProgressCreations == 0) return false; // Not in construction
64 if (prevError) return true; // Already in error chain
66 prevError = &e->erroredBindings;
67 nextError = e->erroredBindings;
68 e->erroredBindings = this;
69 if (nextError) nextError->prevError = &nextError;
74 QDeclarativeQtScriptExpression::QDeclarativeQtScriptExpression()
75 : dataRef(0), expressionFunctionMode(ExplicitContext), scopeObject(0), trackChange(false),
76 guardList(0), guardListLength(0), guardObject(0), guardObjectNotifyIndex(-1), deleted(0)
80 QDeclarativeQtScriptExpression::~QDeclarativeQtScriptExpression()
82 if (guardList) { delete [] guardList; guardList = 0; }
83 if (dataRef) dataRef->release();
84 if (deleted) *deleted = true;
87 QDeclarativeExpressionPrivate::QDeclarativeExpressionPrivate()
88 : expressionFunctionValid(true), line(-1)
92 QDeclarativeExpressionPrivate::~QDeclarativeExpressionPrivate()
96 void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, const QString &expr,
101 QDeclarativeAbstractExpression::setContext(ctxt);
103 expressionFunctionValid = false;
106 void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, const QScriptValue &func,
109 expression = func.toString();
111 QDeclarativeAbstractExpression::setContext(ctxt);
114 expressionFunction = func;
115 expressionFunctionMode = ExplicitContext;
116 expressionFunctionValid = true;
119 void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, void *expr,
120 QDeclarativeRefCount *rc,
121 QObject *me, const QString &srcUrl, int lineNumber)
126 if (dataRef) dataRef->release();
128 if (dataRef) dataRef->addref();
130 quint32 *exprData = (quint32 *)expr;
131 QDeclarativeCompiledData *dd = (QDeclarativeCompiledData *)rc;
133 expression = QString::fromRawData((QChar *)(exprData + 2), exprData[1]);
135 int progIdx = *(exprData);
136 bool isSharedProgram = progIdx & 0x80000000;
137 progIdx &= 0x7FFFFFFF;
139 QDeclarativeEngine *engine = ctxt->engine;
140 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
141 QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
143 if (isSharedProgram) {
145 if (!dd->cachedClosures.at(progIdx)) {
146 QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine);
147 scriptContext->pushScope(ep->contextClass->newSharedContext());
148 scriptContext->pushScope(ep->globalClass->staticGlobalObject());
149 dd->cachedClosures[progIdx] = new QScriptValue(scriptEngine->evaluate(expression, url, line));
150 scriptEngine->popContext();
153 expressionFunction = *dd->cachedClosures.at(progIdx);
154 expressionFunctionMode = SharedContext;
155 expressionFunctionValid = true;
159 if (!dd->cachedPrograms.at(progIdx)) {
160 dd->cachedPrograms[progIdx] = new QScriptProgram(expression, url, line);
163 expressionFunction = evalInObjectScope(ctxt, me, *dd->cachedPrograms.at(progIdx),
166 expressionFunctionMode = ExplicitContext;
167 expressionFunctionValid = true;
170 QDeclarativeAbstractExpression::setContext(ctxt);
174 QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContextData *context, QObject *object,
175 const QString &program, const QString &fileName,
176 int lineNumber, QScriptValue *contextObject)
178 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine);
179 QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(&ep->scriptEngine);
181 *contextObject = ep->contextClass->newContext(context, object);
182 scriptContext->pushScope(*contextObject);
184 scriptContext->pushScope(ep->contextClass->newContext(context, object));
186 scriptContext->pushScope(ep->globalClass->staticGlobalObject());
187 QScriptValue rv = ep->scriptEngine.evaluate(program, fileName, lineNumber);
188 ep->scriptEngine.popContext();
192 QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContextData *context, QObject *object,
193 const QScriptProgram &program,
194 QScriptValue *contextObject)
196 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine);
197 QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(&ep->scriptEngine);
199 *contextObject = ep->contextClass->newContext(context, object);
200 scriptContext->pushScope(*contextObject);
202 scriptContext->pushScope(ep->contextClass->newContext(context, object));
204 scriptContext->pushScope(ep->globalClass->staticGlobalObject());
205 QScriptValue rv = ep->scriptEngine.evaluate(program);
206 ep->scriptEngine.popContext();
211 \class QDeclarativeExpression
213 \brief The QDeclarativeExpression class evaluates JavaScript in a QML context.
215 For example, given a file \c main.qml like this:
221 width: 200; height: 200
225 The following code evaluates a JavaScript expression in the context of the
229 QDeclarativeEngine *engine = new QDeclarativeEngine;
230 QDeclarativeComponent component(engine, QUrl::fromLocalFile("main.qml"));
232 QObject *myObject = component.create();
233 QDeclarativeExpression *expr = new QDeclarativeExpression(engine->rootContext(), myObject, "width * 2");
234 int result = expr->evaluate().toInt(); // result = 400
238 static int QDeclarativeExpression_notifyIdx = -1;
241 Create an invalid QDeclarativeExpression.
243 As the expression will not have an associated QDeclarativeContext, this will be a
244 null expression object and its value will always be an invalid QVariant.
246 QDeclarativeExpression::QDeclarativeExpression()
247 : QObject(*new QDeclarativeExpressionPrivate, 0)
249 Q_D(QDeclarativeExpression);
251 if (QDeclarativeExpression_notifyIdx == -1)
252 QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()");
253 d->setNotifyObject(this, QDeclarativeExpression_notifyIdx);
257 QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, void *expr,
258 QDeclarativeRefCount *rc, QObject *me,
259 const QString &url, int lineNumber,
260 QDeclarativeExpressionPrivate &dd)
263 Q_D(QDeclarativeExpression);
264 d->init(ctxt, expr, rc, me, url, lineNumber);
266 if (QDeclarativeExpression_notifyIdx == -1)
267 QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()");
268 d->setNotifyObject(this, QDeclarativeExpression_notifyIdx);
272 Create a QDeclarativeExpression object that is a child of \a parent.
274 The \a expression JavaScript will be executed in the \a ctxt QDeclarativeContext.
275 If specified, the \a scope object's properties will also be in scope during
276 the expression's execution.
278 QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContext *ctxt,
280 const QString &expression,
282 : QObject(*new QDeclarativeExpressionPrivate, parent)
284 Q_D(QDeclarativeExpression);
285 d->init(QDeclarativeContextData::get(ctxt), expression, scope);
287 if (QDeclarativeExpression_notifyIdx == -1)
288 QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()");
289 d->setNotifyObject(this, QDeclarativeExpression_notifyIdx);
295 QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, QObject *scope,
296 const QString &expression)
297 : QObject(*new QDeclarativeExpressionPrivate, 0)
299 Q_D(QDeclarativeExpression);
300 d->init(ctxt, expression, scope);
302 if (QDeclarativeExpression_notifyIdx == -1)
303 QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()");
304 d->setNotifyObject(this, QDeclarativeExpression_notifyIdx);
308 QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, QObject *scope,
309 const QString &expression, QDeclarativeExpressionPrivate &dd)
312 Q_D(QDeclarativeExpression);
313 d->init(ctxt, expression, scope);
315 if (QDeclarativeExpression_notifyIdx == -1)
316 QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()");
317 d->setNotifyObject(this, QDeclarativeExpression_notifyIdx);
321 QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, QObject *scope, const QScriptValue &func,
322 QDeclarativeExpressionPrivate &dd)
325 Q_D(QDeclarativeExpression);
326 d->init(ctxt, func, scope);
328 if (QDeclarativeExpression_notifyIdx == -1)
329 QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()");
330 d->setNotifyObject(this, QDeclarativeExpression_notifyIdx);
334 Destroy the QDeclarativeExpression instance.
336 QDeclarativeExpression::~QDeclarativeExpression()
341 Returns the QDeclarativeEngine this expression is associated with, or 0 if there
342 is no association or the QDeclarativeEngine has been destroyed.
344 QDeclarativeEngine *QDeclarativeExpression::engine() const
346 Q_D(const QDeclarativeExpression);
347 return d->context()?d->context()->engine:0;
351 Returns the QDeclarativeContext this expression is associated with, or 0 if there
352 is no association or the QDeclarativeContext has been destroyed.
354 QDeclarativeContext *QDeclarativeExpression::context() const
356 Q_D(const QDeclarativeExpression);
357 QDeclarativeContextData *data = d->context();
358 return data?data->asQDeclarativeContext():0;
362 Returns the expression string.
364 QString QDeclarativeExpression::expression() const
366 Q_D(const QDeclarativeExpression);
367 return d->expression;
371 Set the expression to \a expression.
373 void QDeclarativeExpression::setExpression(const QString &expression)
375 Q_D(QDeclarativeExpression);
377 d->resetNotifyOnChange();
378 d->expression = expression;
379 d->expressionFunctionValid = false;
380 d->expressionFunction = QScriptValue();
383 void QDeclarativeExpressionPrivate::exceptionToError(QScriptEngine *scriptEngine,
384 QDeclarativeError &error)
386 if (scriptEngine->hasUncaughtException() &&
387 scriptEngine->uncaughtException().isError()) {
390 int lineNumber = scriptEngine->uncaughtExceptionLineNumber();
392 QScriptValue exception = scriptEngine->uncaughtException();
393 QLatin1String fileNameProp("fileName");
395 if (!exception.property(fileNameProp).toString().isEmpty()){
396 fileName = exception.property(fileNameProp).toString();
398 fileName = QLatin1String("<Unknown File>");
401 error.setUrl(QUrl(fileName));
402 error.setLine(lineNumber);
404 error.setDescription(exception.toString());
406 error = QDeclarativeError();
410 bool QDeclarativeQtScriptExpression::notifyOnValueChange() const
415 void QDeclarativeQtScriptExpression::setNotifyOnValueChange(bool notify)
417 trackChange = notify;
418 if (!notify && guardList)
422 void QDeclarativeQtScriptExpression::resetNotifyOnChange()
427 void QDeclarativeQtScriptExpression::setNotifyObject(QObject *object, int notifyIndex)
429 if (guardList) clearGuards();
431 if (!object || notifyIndex == -1) {
435 guardObject = object;
436 guardObjectNotifyIndex = notifyIndex;
441 void QDeclarativeQtScriptExpression::setEvaluateFlags(EvaluateFlags flags)
446 QDeclarativeQtScriptExpression::EvaluateFlags QDeclarativeQtScriptExpression::evaluateFlags() const
451 QScriptValue QDeclarativeQtScriptExpression::scriptValue(QObject *secondaryScope, bool *isUndefined)
453 Q_ASSERT(context() && context()->engine);
454 Q_ASSERT(!trackChange || (guardObject && guardObjectNotifyIndex != -1));
456 if (!expressionFunction.isValid()) {
457 if (isUndefined) *isUndefined = true;
458 return QScriptValue();
461 DeleteWatcher watcher(this);
463 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context()->engine);
465 bool lastCaptureProperties = ep->captureProperties;
466 QPODVector<QDeclarativeEnginePrivate::CapturedProperty> lastCapturedProperties;
467 ep->captureProperties = trackChange;
468 ep->capturedProperties.copyAndClear(lastCapturedProperties);
470 QScriptValue value = eval(secondaryScope, isUndefined);
472 if (!watcher.wasDeleted() && trackChange) {
473 if (ep->capturedProperties.count() == 0) {
475 if (guardList) clearGuards();
479 updateGuards(ep->capturedProperties);
484 lastCapturedProperties.copyAndClear(ep->capturedProperties);
485 ep->captureProperties = lastCaptureProperties;
490 QScriptValue QDeclarativeQtScriptExpression::eval(QObject *secondaryScope, bool *isUndefined)
492 Q_ASSERT(context() && context()->engine);
494 DeleteWatcher watcher(this);
496 QDeclarativeEngine *engine = context()->engine;
497 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
499 QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
501 QDeclarativeContextData *oldSharedContext = 0;
502 QObject *oldSharedScope = 0;
503 QObject *oldOverride = 0;
504 bool isShared = (expressionFunctionMode == SharedContext);
507 oldSharedContext = ep->sharedContext;
508 oldSharedScope = ep->sharedScope;
509 ep->sharedContext = context();
510 ep->sharedScope = scopeObject;
512 oldOverride = ep->contextClass->setOverrideObject(expressionContext, secondaryScope);
515 QScriptValue thisObject;
516 if (evalFlags & RequiresThisObject)
517 thisObject = ep->objectClass->newQObject(scopeObject);
518 QScriptValue svalue = expressionFunction.call(thisObject); // This could cause this c++ object to be deleted
521 ep->sharedContext = oldSharedContext;
522 ep->sharedScope = oldSharedScope;
523 } else if (!watcher.wasDeleted()) {
524 ep->contextClass->setOverrideObject(expressionContext, oldOverride);
528 *isUndefined = svalue.isUndefined() || scriptEngine->hasUncaughtException();
531 if (scriptEngine->hasUncaughtException()) {
532 if (!watcher.wasDeleted())
533 QDeclarativeExpressionPrivate::exceptionToError(scriptEngine, error);
535 scriptEngine->clearExceptions();
536 return QScriptValue();
538 if (!watcher.wasDeleted())
539 error = QDeclarativeError();
545 void QDeclarativeQtScriptExpression::updateGuards(const QPODVector<QDeclarativeEnginePrivate::CapturedProperty> &properties)
547 Q_ASSERT(guardObject);
548 Q_ASSERT(guardObjectNotifyIndex != -1);
550 if (properties.count() != guardListLength) {
551 QDeclarativeNotifierEndpoint *newGuardList = new QDeclarativeNotifierEndpoint[properties.count()];
553 for (int ii = 0; ii < qMin(guardListLength, properties.count()); ++ii)
554 guardList[ii].copyAndClear(newGuardList[ii]);
557 guardList = newGuardList;
558 guardListLength = properties.count();
561 bool outputWarningHeader = false;
562 bool noChanges = true;
563 for (int ii = 0; ii < properties.count(); ++ii) {
564 QDeclarativeNotifierEndpoint &guard = guardList[ii];
565 const QDeclarativeEnginePrivate::CapturedProperty &property = properties.at(ii);
567 guard.target = guardObject;
568 guard.targetMethod = guardObjectNotifyIndex;
570 if (property.notifier != 0) {
572 if (!noChanges && guard.isConnected(property.notifier)) {
578 bool existing = false;
579 for (int jj = 0; !existing && jj < ii; ++jj)
580 if (guardList[jj].isConnected(property.notifier))
587 guard.connect(property.notifier);
592 } else if (property.notifyIndex != -1) {
594 if (!noChanges && guard.isConnected(property.object, property.notifyIndex)) {
600 bool existing = false;
601 for (int jj = 0; !existing && jj < ii; ++jj)
602 if (guardList[jj].isConnected(property.object, property.notifyIndex))
609 guard.connect(property.object, property.notifyIndex);
614 if (!outputWarningHeader) {
615 outputWarningHeader = true;
616 qWarning() << "QDeclarativeExpression: Expression" << expression
617 << "depends on non-NOTIFYable properties:";
620 const QMetaObject *metaObj = property.object->metaObject();
621 QMetaProperty metaProp = metaObj->property(property.coreIndex);
623 qWarning().nospace() << " " << metaObj->className() << "::" << metaProp.name();
628 QScriptValue QDeclarativeExpressionPrivate::scriptValue(QObject *secondaryScope, bool *isUndefined)
630 if (!expressionFunctionValid) {
631 QDeclarativeEngine *engine = context()->engine;
632 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
634 QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
636 QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine);
637 expressionContext = ep->contextClass->newContext(context(), scopeObject);
638 scriptContext->pushScope(expressionContext);
639 scriptContext->pushScope(ep->globalClass->staticGlobalObject());
641 QDeclarativeRewrite::RewriteBinding rewriteBinding;
642 rewriteBinding.setName(name);
644 const QString code = rewriteBinding(expression, &ok);
646 expressionFunction = scriptEngine->evaluate(code, url, line);
648 scriptEngine->popContext();
649 expressionFunctionMode = ExplicitContext;
650 expressionFunctionValid = true;
653 return QDeclarativeQtScriptExpression::scriptValue(secondaryScope, isUndefined);
656 QVariant QDeclarativeExpressionPrivate::value(QObject *secondaryScope, bool *isUndefined)
658 Q_Q(QDeclarativeExpression);
660 if (!context() || !context()->isValid()) {
661 qWarning("QDeclarativeExpression: Attempted to evaluate an expression in an invalid context");
665 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(q->engine());
667 return ep->scriptValueToVariant(scriptValue(secondaryScope, isUndefined), qMetaTypeId<QList<QObject*> >());
671 Evaulates the expression, returning the result of the evaluation,
672 or an invalid QVariant if the expression is invalid or has an error.
674 \a valueIsUndefined is set to true if the expression resulted in an
677 \sa hasError(), error()
679 QVariant QDeclarativeExpression::evaluate(bool *valueIsUndefined)
681 Q_D(QDeclarativeExpression);
682 return d->value(0, valueIsUndefined);
686 Returns true if the valueChanged() signal is emitted when the expression's evaluated
689 bool QDeclarativeExpression::notifyOnValueChanged() const
691 Q_D(const QDeclarativeExpression);
692 return d->notifyOnValueChange();
696 Sets whether the valueChanged() signal is emitted when the
697 expression's evaluated value changes.
699 If \a notifyOnChange is true, the QDeclarativeExpression will
700 monitor properties involved in the expression's evaluation, and emit
701 QDeclarativeExpression::valueChanged() if they have changed. This
702 allows an application to ensure that any value associated with the
703 result of the expression remains up to date.
705 If \a notifyOnChange is false (default), the QDeclarativeExpression
706 will not montitor properties involved in the expression's
707 evaluation, and QDeclarativeExpression::valueChanged() will never be
708 emitted. This is more efficient if an application wants a "one off"
709 evaluation of the expression.
711 void QDeclarativeExpression::setNotifyOnValueChanged(bool notifyOnChange)
713 Q_D(QDeclarativeExpression);
714 d->setNotifyOnValueChange(notifyOnChange);
718 Returns the source file URL for this expression. The source location must
719 have been previously set by calling setSourceLocation().
721 QString QDeclarativeExpression::sourceFile() const
723 Q_D(const QDeclarativeExpression);
728 Returns the source file line number for this expression. The source location
729 must have been previously set by calling setSourceLocation().
731 int QDeclarativeExpression::lineNumber() const
733 Q_D(const QDeclarativeExpression);
738 Set the location of this expression to \a line of \a url. This information
739 is used by the script engine.
741 void QDeclarativeExpression::setSourceLocation(const QString &url, int line)
743 Q_D(QDeclarativeExpression);
749 Returns the expression's scope object, if provided, otherwise 0.
751 In addition to data provided by the expression's QDeclarativeContext, the scope
752 object's properties are also in scope during the expression's evaluation.
754 QObject *QDeclarativeExpression::scopeObject() const
756 Q_D(const QDeclarativeExpression);
757 return d->scopeObject;
761 Returns true if the last call to evaluate() resulted in an error,
764 \sa error(), clearError()
766 bool QDeclarativeExpression::hasError() const
768 Q_D(const QDeclarativeExpression);
769 return d->error.isValid();
773 Clear any expression errors. Calls to hasError() following this will
776 \sa hasError(), error()
778 void QDeclarativeExpression::clearError()
780 Q_D(QDeclarativeExpression);
781 d->error = QDeclarativeError();
785 Return any error from the last call to evaluate(). If there was no error,
786 this returns an invalid QDeclarativeError instance.
788 \sa hasError(), clearError()
791 QDeclarativeError QDeclarativeExpression::error() const
793 Q_D(const QDeclarativeExpression);
798 void QDeclarativeExpressionPrivate::_q_notify()
803 void QDeclarativeQtScriptExpression::clearGuards()
811 \fn void QDeclarativeExpression::valueChanged()
813 Emitted each time the expression value changes from the last time it was
814 evaluated. The expression must have been evaluated at least once (by
815 calling QDeclarativeExpression::evaluate()) before this signal will be emitted.
818 void QDeclarativeExpressionPrivate::emitValueChanged()
820 Q_Q(QDeclarativeExpression);
821 emit q->valueChanged();
824 QDeclarativeAbstractExpression::QDeclarativeAbstractExpression()
825 : m_context(0), m_prevExpression(0), m_nextExpression(0)
829 QDeclarativeAbstractExpression::~QDeclarativeAbstractExpression()
831 if (m_prevExpression) {
832 *m_prevExpression = m_nextExpression;
833 if (m_nextExpression)
834 m_nextExpression->m_prevExpression = m_prevExpression;
838 QDeclarativeContextData *QDeclarativeAbstractExpression::context() const
843 void QDeclarativeAbstractExpression::setContext(QDeclarativeContextData *context)
845 if (m_prevExpression) {
846 *m_prevExpression = m_nextExpression;
847 if (m_nextExpression)
848 m_nextExpression->m_prevExpression = m_prevExpression;
849 m_prevExpression = 0;
850 m_nextExpression = 0;
856 m_nextExpression = m_context->expressions;
857 if (m_nextExpression)
858 m_nextExpression->m_prevExpression = &m_nextExpression;
859 m_prevExpression = &context->expressions;
860 m_context->expressions = this;
864 void QDeclarativeAbstractExpression::refresh()
868 bool QDeclarativeAbstractExpression::isValid() const
870 return m_context != 0;
875 #include <moc_qdeclarativeexpression.cpp>