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

source code of qtscript/src/script/api/qscriptengine.h