1/****************************************************************************
2**
3** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4** Contact: http://www.qt-project.org/legal
5**
6** This file is part of the QtScript module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL-ONLY$
9** GNU Lesser General Public License Usage
10** This file may be used under the terms of the GNU Lesser
11** General Public License version 2.1 as published by the Free Software
12** Foundation and appearing in the file LICENSE.LGPL included in the
13** packaging of this file. Please review the following information to
14** ensure the GNU Lesser General Public License version 2.1 requirements
15** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16**
17** If you have questions regarding the use of this file, please contact
18** us via http://www.qt-project.org/.
19**
20** $QT_END_LICENSE$
21**
22****************************************************************************/
23
24#ifndef QSCRIPTENGINE_H
25#define QSCRIPTENGINE_H
26
27#include <QtCore/qmetatype.h>
28
29#include <QtCore/qvariant.h>
30#include <QtCore/qsharedpointer.h>
31
32#ifndef QT_NO_QOBJECT
33#include <QtCore/qobject.h>
34#else
35#include <QtCore/qobjectdefs.h>
36#endif
37
38#include <QtScript/qscriptvalue.h>
39#include <QtScript/qscriptcontext.h>
40#include <QtScript/qscriptstring.h>
41#include <QtScript/qscriptprogram.h>
42
43QT_BEGIN_HEADER
44
45QT_BEGIN_NAMESPACE
46
47QT_MODULE(Script)
48
49class QDateTime;
50class QScriptClass;
51class QScriptEngineAgent;
52class QScriptEnginePrivate;
53
54#ifndef QT_NO_QOBJECT
55
56template <class T>
57inline QScriptValue qscriptQMetaObjectConstructor(QScriptContext *, QScriptEngine *, T *)
58{
59 return QScriptValue();
60}
61
62#endif // QT_NO_QOBJECT
63
64#ifndef QT_NO_REGEXP
65class QRegExp;
66#endif
67
68template <typename T>
69inline QScriptValue qScriptValueFromValue(QScriptEngine *, const T &);
70
71template <typename T>
72inline T qscriptvalue_cast(const QScriptValue &);
73
74class QScriptSyntaxCheckResultPrivate;
75class Q_SCRIPT_EXPORT QScriptSyntaxCheckResult
76{
77public:
78 enum State {
79 Error,
80 Intermediate,
81 Valid
82 };
83
84 QScriptSyntaxCheckResult(const QScriptSyntaxCheckResult &other);
85 ~QScriptSyntaxCheckResult();
86
87 State state() const;
88 int errorLineNumber() const;
89 int errorColumnNumber() const;
90 QString errorMessage() const;
91
92 QScriptSyntaxCheckResult &operator=(const QScriptSyntaxCheckResult &other);
93
94private:
95 QScriptSyntaxCheckResult();
96 QScriptSyntaxCheckResult(QScriptSyntaxCheckResultPrivate *d);
97 QExplicitlySharedDataPointer<QScriptSyntaxCheckResultPrivate> d_ptr;
98
99 Q_DECLARE_PRIVATE(QScriptSyntaxCheckResult)
100 friend class QScriptEngine;
101 friend class QScriptEnginePrivate;
102};
103
104class Q_SCRIPT_EXPORT QScriptEngine
105#ifndef QT_NO_QOBJECT
106 : public QObject
107#endif
108{
109#ifndef QT_NO_QOBJECT
110 Q_OBJECT
111#endif
112public:
113 enum ValueOwnership {
114 QtOwnership,
115 ScriptOwnership,
116 AutoOwnership
117 };
118
119 enum QObjectWrapOption {
120 ExcludeChildObjects = 0x0001,
121 ExcludeSuperClassMethods = 0x0002,
122 ExcludeSuperClassProperties = 0x0004,
123 ExcludeSuperClassContents = 0x0006,
124 SkipMethodsInEnumeration = 0x0008,
125 ExcludeDeleteLater = 0x0010,
126 ExcludeSlots = 0x0020,
127
128 AutoCreateDynamicProperties = 0x0100,
129 PreferExistingWrapperObject = 0x0200
130 };
131 Q_DECLARE_FLAGS(QObjectWrapOptions, QObjectWrapOption)
132
133 QScriptEngine();
134#ifndef QT_NO_QOBJECT
135 explicit QScriptEngine(QObject *parent);
136#endif
137 virtual ~QScriptEngine();
138
139 QScriptValue globalObject() const;
140 void setGlobalObject(const QScriptValue &object);
141
142 QScriptContext *currentContext() const;
143 QScriptContext *pushContext();
144 void popContext();
145
146 bool canEvaluate(const QString &program) const;
147 static QScriptSyntaxCheckResult checkSyntax(const QString &program);
148
149 QScriptValue evaluate(const QString &program, const QString &fileName = QString(), int lineNumber = 1);
150
151 QScriptValue evaluate(const QScriptProgram &program);
152
153 bool isEvaluating() const;
154 void abortEvaluation(const QScriptValue &result = QScriptValue());
155
156 bool hasUncaughtException() const;
157 QScriptValue uncaughtException() const;
158 int uncaughtExceptionLineNumber() const;
159 QStringList uncaughtExceptionBacktrace() const;
160 void clearExceptions();
161
162 QScriptValue nullValue();
163 QScriptValue undefinedValue();
164
165 typedef QScriptValue (*FunctionSignature)(QScriptContext *, QScriptEngine *);
166 typedef QScriptValue (*FunctionWithArgSignature)(QScriptContext *, QScriptEngine *, void *);
167
168 QScriptValue newFunction(FunctionSignature signature, int length = 0);
169 QScriptValue newFunction(FunctionSignature signature, const QScriptValue &prototype, int length = 0);
170
171 QScriptValue newFunction(FunctionWithArgSignature signature, void *arg);
172
173 QScriptValue newVariant(const QVariant &value);
174 QScriptValue newVariant(const QScriptValue &object, const QVariant &value);
175
176#ifndef QT_NO_REGEXP
177 QScriptValue newRegExp(const QRegExp &regexp);
178#endif
179
180 QScriptValue newObject();
181 QScriptValue newObject(QScriptClass *scriptClass, const QScriptValue &data = QScriptValue());
182 QScriptValue newArray(uint length = 0);
183 QScriptValue newRegExp(const QString &pattern, const QString &flags);
184 QScriptValue newDate(qsreal value);
185 QScriptValue newDate(const QDateTime &value);
186 QScriptValue newActivationObject();
187
188#ifndef QT_NO_QOBJECT
189 QScriptValue newQObject(QObject *object, ValueOwnership ownership = QtOwnership,
190 const QObjectWrapOptions &options = 0);
191 QScriptValue newQObject(const QScriptValue &scriptObject, QObject *qtObject,
192 ValueOwnership ownership = QtOwnership,
193 const QObjectWrapOptions &options = 0);
194
195 QScriptValue newQMetaObject(const QMetaObject *metaObject, const QScriptValue &ctor = QScriptValue());
196
197 template <class T> QScriptValue scriptValueFromQMetaObject();
198
199#endif // QT_NO_QOBJECT
200
201
202
203 QScriptValue defaultPrototype(int metaTypeId) const;
204 void setDefaultPrototype(int metaTypeId, const QScriptValue &prototype);
205
206
207 typedef QScriptValue (*MarshalFunction)(QScriptEngine *, const void *);
208 typedef void (*DemarshalFunction)(const QScriptValue &, void *);
209
210
211
212 template <typename T>
213 inline QScriptValue toScriptValue(const T &value)
214 {
215 return qScriptValueFromValue(this, value);
216 }
217 template <typename T>
218 inline T fromScriptValue(const QScriptValue &value)
219 {
220 return qscriptvalue_cast<T>(value);
221 }
222
223 void installTranslatorFunctions(const QScriptValue &object = QScriptValue());
224
225 QScriptValue importExtension(const QString &extension);
226 QStringList availableExtensions() const;
227 QStringList importedExtensions() const;
228
229 void collectGarbage();
230 void reportAdditionalMemoryCost(int size);
231
232 void setProcessEventsInterval(int interval);
233 int processEventsInterval() const;
234
235 void setAgent(QScriptEngineAgent *agent);
236 QScriptEngineAgent *agent() const;
237
238 QScriptString toStringHandle(const QString &str);
239 QScriptValue toObject(const QScriptValue &value);
240
241 QScriptValue objectById(qint64 id) const;
242
243#ifndef QT_NO_QOBJECT
244Q_SIGNALS:
245 void signalHandlerException(const QScriptValue &exception);
246#endif
247
248private:
249 QScriptValue create(int type, const void *ptr);
250
251 bool convert(const QScriptValue &value, int type, void *ptr);
252 static bool convertV2(const QScriptValue &value, int type, void *ptr);
253
254 void registerCustomType(int type, MarshalFunction mf, DemarshalFunction df,
255 const QScriptValue &prototype);
256
257 friend inline void qScriptRegisterMetaType_helper(QScriptEngine *,
258 int, MarshalFunction, DemarshalFunction, const QScriptValue &);
259
260 friend inline QScriptValue qScriptValueFromValue_helper(QScriptEngine *, int, const void *);
261
262 friend inline bool qscriptvalue_cast_helper(const QScriptValue &, int, void *);
263
264protected:
265#ifdef QT_NO_QOBJECT
266 QScopedPointer<QScriptEnginePrivate> d_ptr;
267
268 QScriptEngine(QScriptEnginePrivate &dd);
269#else
270 QScriptEngine(QScriptEnginePrivate &dd, QObject *parent = 0);
271#endif
272
273private:
274 Q_DECLARE_PRIVATE(QScriptEngine)
275 Q_DISABLE_COPY(QScriptEngine)
276#ifndef QT_NO_QOBJECT
277 Q_PRIVATE_SLOT(d_func(), void _q_objectDestroyed(QObject *))
278#endif
279};
280
281#ifndef QT_NO_QOBJECT
282
283#define Q_SCRIPT_DECLARE_QMETAOBJECT(T, _Arg1) \
284template<> inline QScriptValue qscriptQMetaObjectConstructor<T>(QScriptContext *ctx, QScriptEngine *eng, T *) \
285{ \
286 _Arg1 arg1 = qscriptvalue_cast<_Arg1> (ctx->argument(0)); \
287 T* t = new T(arg1); \
288 if (ctx->isCalledAsConstructor()) \
289 return eng->newQObject(ctx->thisObject(), t, QScriptEngine::AutoOwnership); \
290 QScriptValue o = eng->newQObject(t, QScriptEngine::AutoOwnership); \
291 o.setPrototype(ctx->callee().property(QString::fromLatin1("prototype"))); \
292 return o; \
293}
294
295template <class T> QScriptValue QScriptEngine::scriptValueFromQMetaObject()
296{
297 typedef QScriptValue(*ConstructPtr)(QScriptContext *, QScriptEngine *, T *);
298 ConstructPtr cptr = qscriptQMetaObjectConstructor<T>;
299 return newQMetaObject(&T::staticMetaObject,
300 newFunction(reinterpret_cast<FunctionWithArgSignature>(cptr), 0));
301}
302
303#ifdef QT_DEPRECATED
304template <class T>
305inline QT_DEPRECATED QScriptValue qScriptValueFromQMetaObject(
306 QScriptEngine *engine
307#ifndef qdoc
308 , T * /* dummy */ = 0
309#endif
310 )
311{
312 return engine->scriptValueFromQMetaObject<T>();
313}
314#endif
315
316#endif // QT_NO_QOBJECT
317
318inline QScriptValue qScriptValueFromValue_helper(QScriptEngine *engine, int type, const void *ptr)
319{
320 if (!engine)
321 return QScriptValue();
322
323 return engine->create(type, ptr);
324}
325
326template <typename T>
327inline QScriptValue qScriptValueFromValue(QScriptEngine *engine, const T &t)
328{
329 return qScriptValueFromValue_helper(engine, qMetaTypeId<T>(), &t);
330}
331
332template <>
333inline QScriptValue qScriptValueFromValue<QVariant>(QScriptEngine *engine, const QVariant &v)
334{
335 return qScriptValueFromValue_helper(engine, v.userType(), v.data());
336}
337
338inline bool qscriptvalue_cast_helper(const QScriptValue &value, int type, void *ptr)
339{
340 return QScriptEngine::convertV2(value, type, ptr);
341}
342
343template<typename T>
344T qscriptvalue_cast(const QScriptValue &value)
345{
346 T t;
347 const int id = qMetaTypeId<T>();
348
349 if (qscriptvalue_cast_helper(value, id, &t))
350 return t;
351 else if (value.isVariant())
352 return qvariant_cast<T>(value.toVariant());
353
354 return T();
355}
356
357template <>
358inline QVariant qscriptvalue_cast<QVariant>(const QScriptValue &value)
359{
360 return value.toVariant();
361}
362
363#ifdef QT_DEPRECATED
364template <typename T>
365inline QT_DEPRECATED T qScriptValueToValue(const QScriptValue &value)
366{
367 return qscriptvalue_cast<T>(value);
368}
369#endif
370
371inline void qScriptRegisterMetaType_helper(QScriptEngine *eng, int type,
372 QScriptEngine::MarshalFunction mf,
373 QScriptEngine::DemarshalFunction df,
374 const QScriptValue &prototype)
375{
376 eng->registerCustomType(type, mf, df, prototype);
377}
378
379template<typename T>
380int qScriptRegisterMetaType(
381 QScriptEngine *eng,
382 QScriptValue (*toScriptValue)(QScriptEngine *, const T &t),
383 void (*fromScriptValue)(const QScriptValue &, T &t),
384 const QScriptValue &prototype = QScriptValue()
385#ifndef qdoc
386 , T * /* dummy */ = 0
387#endif
388)
389{
390 const int id = qRegisterMetaType<T>(); // make sure it's registered
391
392 qScriptRegisterMetaType_helper(
393 eng, id, reinterpret_cast<QScriptEngine::MarshalFunction>(toScriptValue),
394 reinterpret_cast<QScriptEngine::DemarshalFunction>(fromScriptValue),
395 prototype);
396
397 return id;
398}
399
400template <class Container>
401QScriptValue qScriptValueFromSequence(QScriptEngine *eng, const Container &cont)
402{
403 QScriptValue a = eng->newArray();
404 typename Container::const_iterator begin = cont.begin();
405 typename Container::const_iterator end = cont.end();
406 typename Container::const_iterator it;
407 quint32 i;
408 for (it = begin, i = 0; it != end; ++it, ++i)
409 a.setProperty(i, eng->toScriptValue(*it));
410 return a;
411}
412
413template <class Container>
414void qScriptValueToSequence(const QScriptValue &value, Container &cont)
415{
416 quint32 len = value.property(QLatin1String("length")).toUInt32();
417 for (quint32 i = 0; i < len; ++i) {
418 QScriptValue item = value.property(i);
419 cont.push_back(qscriptvalue_cast<typename Container::value_type>(item));
420 }
421}
422
423template<typename T>
424int qScriptRegisterSequenceMetaType(
425 QScriptEngine *engine,
426 const QScriptValue &prototype = QScriptValue()
427#ifndef qdoc
428 , T * /* dummy */ = 0
429#endif
430)
431{
432 return qScriptRegisterMetaType<T>(engine, qScriptValueFromSequence,
433 qScriptValueToSequence, prototype);
434}
435
436#ifndef QT_NO_QOBJECT
437Q_SCRIPT_EXPORT bool qScriptConnect(QObject *sender, const char *signal,
438 const QScriptValue &receiver,
439 const QScriptValue &function);
440Q_SCRIPT_EXPORT bool qScriptDisconnect(QObject *sender, const char *signal,
441 const QScriptValue &receiver,
442 const QScriptValue &function);
443#endif // QT_NO_QOBJECT
444
445Q_DECLARE_OPERATORS_FOR_FLAGS(QScriptEngine::QObjectWrapOptions)
446
447QT_END_NAMESPACE
448
449QT_END_HEADER
450
451#endif // QSCRIPTENGINE_H
452