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 | |
43 | QT_BEGIN_HEADER |
44 | |
45 | QT_BEGIN_NAMESPACE |
46 | |
47 | QT_MODULE(Script) |
48 | |
49 | class QDateTime; |
50 | class QScriptClass; |
51 | class QScriptEngineAgent; |
52 | class QScriptEnginePrivate; |
53 | |
54 | #ifndef QT_NO_QOBJECT |
55 | |
56 | template <class T> |
57 | inline QScriptValue qscriptQMetaObjectConstructor(QScriptContext *, QScriptEngine *, T *) |
58 | { |
59 | return QScriptValue(); |
60 | } |
61 | |
62 | #endif // QT_NO_QOBJECT |
63 | |
64 | #ifndef QT_NO_REGEXP |
65 | class QRegExp; |
66 | #endif |
67 | |
68 | template <typename T> |
69 | inline QScriptValue qScriptValueFromValue(QScriptEngine *, const T &); |
70 | |
71 | template <typename T> |
72 | inline T qscriptvalue_cast(const QScriptValue &); |
73 | |
74 | class QScriptSyntaxCheckResultPrivate; |
75 | class Q_SCRIPT_EXPORT QScriptSyntaxCheckResult |
76 | { |
77 | public: |
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 | |
94 | private: |
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 | |
104 | class 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 |
112 | public: |
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 ®exp); |
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 |
244 | Q_SIGNALS: |
245 | void signalHandlerException(const QScriptValue &exception); |
246 | #endif |
247 | |
248 | private: |
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 | |
264 | protected: |
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 | |
273 | private: |
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) \ |
284 | template<> 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 | |
295 | template <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 |
304 | template <class T> |
305 | inline 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 | |
318 | inline 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 | |
326 | template <typename T> |
327 | inline QScriptValue qScriptValueFromValue(QScriptEngine *engine, const T &t) |
328 | { |
329 | return qScriptValueFromValue_helper(engine, qMetaTypeId<T>(), &t); |
330 | } |
331 | |
332 | template <> |
333 | inline QScriptValue qScriptValueFromValue<QVariant>(QScriptEngine *engine, const QVariant &v) |
334 | { |
335 | return qScriptValueFromValue_helper(engine, v.userType(), v.data()); |
336 | } |
337 | |
338 | inline bool qscriptvalue_cast_helper(const QScriptValue &value, int type, void *ptr) |
339 | { |
340 | return QScriptEngine::convertV2(value, type, ptr); |
341 | } |
342 | |
343 | template<typename T> |
344 | T 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 | |
357 | template <> |
358 | inline QVariant qscriptvalue_cast<QVariant>(const QScriptValue &value) |
359 | { |
360 | return value.toVariant(); |
361 | } |
362 | |
363 | #ifdef QT_DEPRECATED |
364 | template <typename T> |
365 | inline QT_DEPRECATED T qScriptValueToValue(const QScriptValue &value) |
366 | { |
367 | return qscriptvalue_cast<T>(value); |
368 | } |
369 | #endif |
370 | |
371 | inline 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 | |
379 | template<typename T> |
380 | int 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 | |
400 | template <class Container> |
401 | QScriptValue 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 | |
413 | template <class Container> |
414 | void 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 | |
423 | template<typename T> |
424 | int 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 |
437 | Q_SCRIPT_EXPORT bool qScriptConnect(QObject *sender, const char *signal, |
438 | const QScriptValue &receiver, |
439 | const QScriptValue &function); |
440 | Q_SCRIPT_EXPORT bool qScriptDisconnect(QObject *sender, const char *signal, |
441 | const QScriptValue &receiver, |
442 | const QScriptValue &function); |
443 | #endif // QT_NO_QOBJECT |
444 | |
445 | Q_DECLARE_OPERATORS_FOR_FLAGS(QScriptEngine::QObjectWrapOptions) |
446 | |
447 | QT_END_NAMESPACE |
448 | |
449 | QT_END_HEADER |
450 | |
451 | #endif // QSCRIPTENGINE_H |
452 | |