Merge branch 'master' into v8
[profile/ivi/qtdeclarative.git] / src / declarative / qml / qdeclarativeexpression_p.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #ifndef QDECLARATIVEEXPRESSION_P_H
43 #define QDECLARATIVEEXPRESSION_P_H
44
45 //
46 //  W A R N I N G
47 //  -------------
48 //
49 // This file is not part of the Qt API.  It exists purely as an
50 // implementation detail.  This header file may change from version to
51 // version without notice, or even be removed.
52 //
53 // We mean it.
54 //
55
56 #include "qdeclarativeexpression.h"
57
58 #include "private/qdeclarativeengine_p.h"
59 #include "private/qdeclarativeguard_p.h"
60
61 #include <QtScript/qscriptvalue.h>
62
63 #include <private/qv8engine_p.h>
64
65 QT_BEGIN_NAMESPACE
66
67 class QDeclarativeAbstractExpression
68 {
69 public:
70     QDeclarativeAbstractExpression();
71     virtual ~QDeclarativeAbstractExpression();
72
73     bool isValid() const;
74
75     QDeclarativeContextData *context() const;
76     void setContext(QDeclarativeContextData *);
77
78     virtual void refresh();
79
80 private:
81     friend class QDeclarativeContext;
82     friend class QDeclarativeContextData;
83     friend class QDeclarativeContextPrivate;
84     QDeclarativeContextData *m_context;
85     QDeclarativeAbstractExpression **m_prevExpression;
86     QDeclarativeAbstractExpression  *m_nextExpression;
87 };
88
89 class QDeclarativeDelayedError 
90 {
91 public:
92     inline QDeclarativeDelayedError() : nextError(0), prevError(0) {}
93     inline ~QDeclarativeDelayedError() { removeError(); }
94
95     QDeclarativeError error;
96
97     bool addError(QDeclarativeEnginePrivate *);
98
99     inline void removeError() {
100         if (!prevError) return;
101         if (nextError) nextError->prevError = prevError;
102         *prevError = nextError;
103         nextError = 0;
104         prevError = 0;
105     }
106
107 private:
108     QDeclarativeDelayedError  *nextError;
109     QDeclarativeDelayedError **prevError;
110 };
111
112 class QDeclarativeQtScriptExpression : public QDeclarativeAbstractExpression, 
113                                        public QDeclarativeDelayedError
114 {
115 public:
116     enum Mode { SharedContext, ExplicitContext };
117
118     enum EvaluateFlag { RequiresThisObject = 0x01 };
119     Q_DECLARE_FLAGS(EvaluateFlags, EvaluateFlag)
120
121     QDeclarativeQtScriptExpression();
122     virtual ~QDeclarativeQtScriptExpression();
123
124     QDeclarativeRefCount *dataRef;
125
126     QString expression;
127
128     Mode expressionFunctionMode;
129     v8::Persistent<v8::Function> v8function;
130     v8::Persistent<v8::Object> v8qmlscope;
131
132     QScriptValue expressionContext; // Only used in ExplicitContext
133     QObject *scopeObject;           // Only used in SharedContext
134
135     bool notifyOnValueChange() const;
136     void setNotifyOnValueChange(bool);
137     void resetNotifyOnChange();
138     void setNotifyObject(QObject *, int );
139
140     void setEvaluateFlags(EvaluateFlags flags);
141     EvaluateFlags evaluateFlags() const;
142
143     v8::Local<v8::Value> v8value(QObject *secondaryScope, bool *isUndefined);
144
145     class DeleteWatcher {
146     public:
147         inline DeleteWatcher(QDeclarativeQtScriptExpression *data);
148         inline ~DeleteWatcher();
149         inline bool wasDeleted() const;
150     private:
151         bool *m_wasDeleted;
152         bool m_wasDeletedStorage;
153         QDeclarativeQtScriptExpression *m_d;
154     };
155
156 private:
157     void clearGuards();
158     v8::Local<v8::Value> eval(QObject *secondaryScope, bool *isUndefined);
159     void updateGuards(const QPODVector<QDeclarativeEnginePrivate::CapturedProperty> &properties);
160
161     bool trackChange;
162
163     QDeclarativeNotifierEndpoint *guardList;
164     int guardListLength;
165
166     QObject *guardObject;
167     int guardObjectNotifyIndex;
168     bool *deleted;
169
170     EvaluateFlags evalFlags;
171 };
172
173 Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativeQtScriptExpression::EvaluateFlags)
174
175
176 class QDeclarativeExpression;
177 class QString;
178 class QDeclarativeExpressionPrivate : public QObjectPrivate, public QDeclarativeQtScriptExpression
179 {
180     Q_DECLARE_PUBLIC(QDeclarativeExpression)
181 public:
182     QDeclarativeExpressionPrivate();
183     ~QDeclarativeExpressionPrivate();
184
185     void init(QDeclarativeContextData *, const QString &, QObject *);
186     void init(QDeclarativeContextData *, v8::Handle<v8::Function>, QObject *);
187     void init(QDeclarativeContextData *, void *, QDeclarativeRefCount *, QObject *, const QString &, int);
188
189     QVariant value(QObject *secondaryScope = 0, bool *isUndefined = 0);
190
191     v8::Local<v8::Value> v8value(QObject *secondaryScope = 0, bool *isUndefined = 0);
192
193     static QDeclarativeExpressionPrivate *get(QDeclarativeExpression *expr) {
194         return static_cast<QDeclarativeExpressionPrivate *>(QObjectPrivate::get(expr));
195     }
196     static QDeclarativeExpression *get(QDeclarativeExpressionPrivate *expr) {
197         return expr->q_func();
198     }
199
200     void _q_notify();
201     virtual void emitValueChanged();
202
203     static void exceptionToError(QScriptEngine *, QDeclarativeError &);
204     static void exceptionToError(v8::Handle<v8::Message>, QDeclarativeError &);
205     static QScriptValue evalInObjectScope(QDeclarativeContextData *, QObject *, const QString &, const QString &,
206                                           int, QScriptValue *);
207     static QScriptValue evalInObjectScope(QDeclarativeContextData *, QObject *, const QScriptProgram &, 
208                                           QScriptValue *);
209
210     static v8::Persistent<v8::Function> evalFunction(QDeclarativeContextData *ctxt, QObject *scope, 
211                                                      const QString &code, const QString &filename, int line,
212                                                      v8::Persistent<v8::Object> *qmlscope = 0);
213
214     bool expressionFunctionValid:1;
215
216     QString url; // This is a QString for a reason.  QUrls are slooooooow...
217     int line;
218     QByteArray name; //function name, hint for the debugger
219 };
220
221 QDeclarativeQtScriptExpression::DeleteWatcher::DeleteWatcher(QDeclarativeQtScriptExpression *data)
222 : m_wasDeletedStorage(false), m_d(data) 
223 {
224     if (!m_d->deleted) 
225         m_d->deleted = &m_wasDeletedStorage; 
226     m_wasDeleted = m_d->deleted;
227 }
228
229 QDeclarativeQtScriptExpression::DeleteWatcher::~DeleteWatcher() 
230 {
231     if (false == *m_wasDeleted && m_wasDeleted == m_d->deleted)
232         m_d->deleted = 0;
233 }
234
235 bool QDeclarativeQtScriptExpression::DeleteWatcher::wasDeleted() const 
236
237     return *m_wasDeleted; 
238 }
239
240 QT_END_NAMESPACE
241
242 #endif // QDECLARATIVEEXPRESSION_P_H