qscriptengine.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446
  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-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.io/contact-us/.
  19. **
  20. ** $QT_END_LICENSE$
  21. **
  22. ****************************************************************************/
  23. #ifndef QSCRIPTENGINE_H
  24. #define QSCRIPTENGINE_H
  25. #include <QtCore/qmetatype.h>
  26. #include <QtCore/qvariant.h>
  27. #include <QtCore/qsharedpointer.h>
  28. #ifndef QT_NO_QOBJECT
  29. #include <QtCore/qobject.h>
  30. #else
  31. #include <QtCore/qobjectdefs.h>
  32. #endif
  33. #include <QtScript/qscriptvalue.h>
  34. #include <QtScript/qscriptcontext.h>
  35. #include <QtScript/qscriptstring.h>
  36. #include <QtScript/qscriptprogram.h>
  37. QT_BEGIN_NAMESPACE
  38. class QDateTime;
  39. class QScriptClass;
  40. class QScriptEngineAgent;
  41. class QScriptEnginePrivate;
  42. #ifndef QT_NO_QOBJECT
  43. template <class T>
  44. inline QScriptValue qscriptQMetaObjectConstructor(QScriptContext *, QScriptEngine *, T *)
  45. {
  46. return QScriptValue();
  47. }
  48. #endif // QT_NO_QOBJECT
  49. #ifndef QT_NO_REGEXP
  50. class QRegExp;
  51. #endif
  52. template <typename T>
  53. inline QScriptValue qScriptValueFromValue(QScriptEngine *, const T &);
  54. template <typename T>
  55. inline T qscriptvalue_cast(const QScriptValue &);
  56. class QScriptSyntaxCheckResultPrivate;
  57. class Q_SCRIPT_EXPORT QScriptSyntaxCheckResult
  58. {
  59. public:
  60. enum State {
  61. Error,
  62. Intermediate,
  63. Valid
  64. };
  65. QScriptSyntaxCheckResult(const QScriptSyntaxCheckResult &other);
  66. ~QScriptSyntaxCheckResult();
  67. State state() const;
  68. int errorLineNumber() const;
  69. int errorColumnNumber() const;
  70. QString errorMessage() const;
  71. QScriptSyntaxCheckResult &operator=(const QScriptSyntaxCheckResult &other);
  72. private:
  73. QScriptSyntaxCheckResult();
  74. QScriptSyntaxCheckResult(QScriptSyntaxCheckResultPrivate *d);
  75. QExplicitlySharedDataPointer<QScriptSyntaxCheckResultPrivate> d_ptr;
  76. Q_DECLARE_PRIVATE(QScriptSyntaxCheckResult)
  77. friend class QScriptEngine;
  78. friend class QScriptEnginePrivate;
  79. };
  80. class Q_SCRIPT_EXPORT QScriptEngine
  81. #ifndef QT_NO_QOBJECT
  82. : public QObject
  83. #endif
  84. {
  85. #ifndef QT_NO_QOBJECT
  86. Q_OBJECT
  87. #endif
  88. public:
  89. enum ValueOwnership {
  90. QtOwnership,
  91. ScriptOwnership,
  92. AutoOwnership
  93. };
  94. enum QObjectWrapOption {
  95. ExcludeChildObjects = 0x0001,
  96. ExcludeSuperClassMethods = 0x0002,
  97. ExcludeSuperClassProperties = 0x0004,
  98. ExcludeSuperClassContents = 0x0006,
  99. SkipMethodsInEnumeration = 0x0008,
  100. ExcludeDeleteLater = 0x0010,
  101. ExcludeSlots = 0x0020,
  102. AutoCreateDynamicProperties = 0x0100,
  103. PreferExistingWrapperObject = 0x0200
  104. };
  105. Q_DECLARE_FLAGS(QObjectWrapOptions, QObjectWrapOption)
  106. QScriptEngine();
  107. #ifndef QT_NO_QOBJECT
  108. explicit QScriptEngine(QObject *parent);
  109. #endif
  110. virtual ~QScriptEngine();
  111. QScriptValue globalObject() const;
  112. void setGlobalObject(const QScriptValue &object);
  113. QScriptContext *currentContext() const;
  114. QScriptContext *pushContext();
  115. void popContext();
  116. bool canEvaluate(const QString &program) const;
  117. static QScriptSyntaxCheckResult checkSyntax(const QString &program);
  118. QScriptValue evaluate(const QString &program, const QString &fileName = QString(), int lineNumber = 1);
  119. QScriptValue evaluate(const QScriptProgram &program);
  120. bool isEvaluating() const;
  121. void abortEvaluation(const QScriptValue &result = QScriptValue());
  122. bool hasUncaughtException() const;
  123. QScriptValue uncaughtException() const;
  124. int uncaughtExceptionLineNumber() const;
  125. QStringList uncaughtExceptionBacktrace() const;
  126. void clearExceptions();
  127. QScriptValue nullValue();
  128. QScriptValue undefinedValue();
  129. typedef QScriptValue (*FunctionSignature)(QScriptContext *, QScriptEngine *);
  130. typedef QScriptValue (*FunctionWithArgSignature)(QScriptContext *, QScriptEngine *, void *);
  131. QScriptValue newFunction(FunctionSignature signature, int length = 0);
  132. QScriptValue newFunction(FunctionSignature signature, const QScriptValue &prototype, int length = 0);
  133. QScriptValue newFunction(FunctionWithArgSignature signature, void *arg);
  134. QScriptValue newVariant(const QVariant &value);
  135. QScriptValue newVariant(const QScriptValue &object, const QVariant &value);
  136. #ifndef QT_NO_REGEXP
  137. QScriptValue newRegExp(const QRegExp &regexp);
  138. #endif
  139. QScriptValue newObject();
  140. QScriptValue newObject(QScriptClass *scriptClass, const QScriptValue &data = QScriptValue());
  141. QScriptValue newArray(uint length = 0);
  142. QScriptValue newRegExp(const QString &pattern, const QString &flags);
  143. QScriptValue newDate(qsreal value);
  144. QScriptValue newDate(const QDateTime &value);
  145. QScriptValue newActivationObject();
  146. #ifndef QT_NO_QOBJECT
  147. QScriptValue newQObject(QObject *object, ValueOwnership ownership = QtOwnership,
  148. const QObjectWrapOptions &options = QObjectWrapOptions());
  149. QScriptValue newQObject(const QScriptValue &scriptObject, QObject *qtObject,
  150. ValueOwnership ownership = QtOwnership,
  151. const QObjectWrapOptions &options = QObjectWrapOptions());
  152. QScriptValue newQMetaObject(const QMetaObject *metaObject, const QScriptValue &ctor = QScriptValue());
  153. template <class T> QScriptValue scriptValueFromQMetaObject();
  154. #endif // QT_NO_QOBJECT
  155. QScriptValue defaultPrototype(int metaTypeId) const;
  156. void setDefaultPrototype(int metaTypeId, const QScriptValue &prototype);
  157. typedef QScriptValue (*MarshalFunction)(QScriptEngine *, const void *);
  158. typedef void (*DemarshalFunction)(const QScriptValue &, void *);
  159. template <typename T>
  160. inline QScriptValue toScriptValue(const T &value)
  161. {
  162. return qScriptValueFromValue(this, value);
  163. }
  164. template <typename T>
  165. inline T fromScriptValue(const QScriptValue &value)
  166. {
  167. return qscriptvalue_cast<T>(value);
  168. }
  169. void installTranslatorFunctions(const QScriptValue &object = QScriptValue());
  170. QScriptValue importExtension(const QString &extension);
  171. QStringList availableExtensions() const;
  172. QStringList importedExtensions() const;
  173. void collectGarbage();
  174. void reportAdditionalMemoryCost(int size);
  175. void setProcessEventsInterval(int interval);
  176. int processEventsInterval() const;
  177. void setAgent(QScriptEngineAgent *agent);
  178. QScriptEngineAgent *agent() const;
  179. QScriptString toStringHandle(const QString &str);
  180. QScriptValue toObject(const QScriptValue &value);
  181. QScriptValue objectById(qint64 id) const;
  182. #ifndef QT_NO_QOBJECT
  183. Q_SIGNALS:
  184. void signalHandlerException(const QScriptValue &exception);
  185. #endif
  186. private:
  187. QScriptValue create(int type, const void *ptr);
  188. bool convert(const QScriptValue &value, int type, void *ptr);
  189. static bool convertV2(const QScriptValue &value, int type, void *ptr);
  190. void registerCustomType(int type, MarshalFunction mf, DemarshalFunction df,
  191. const QScriptValue &prototype);
  192. friend inline void qScriptRegisterMetaType_helper(QScriptEngine *,
  193. int, MarshalFunction, DemarshalFunction, const QScriptValue &);
  194. friend inline QScriptValue qScriptValueFromValue_helper(QScriptEngine *, int, const void *);
  195. friend inline bool qscriptvalue_cast_helper(const QScriptValue &, int, void *);
  196. protected:
  197. #ifdef QT_NO_QOBJECT
  198. QScopedPointer<QScriptEnginePrivate> d_ptr;
  199. QScriptEngine(QScriptEnginePrivate &dd);
  200. #else
  201. explicit QScriptEngine(QScriptEnginePrivate &dd, QObject *parent = Q_NULLPTR);
  202. #endif
  203. private:
  204. Q_DECLARE_PRIVATE(QScriptEngine)
  205. Q_DISABLE_COPY(QScriptEngine)
  206. #ifndef QT_NO_QOBJECT
  207. Q_PRIVATE_SLOT(d_func(), void _q_objectDestroyed(QObject *))
  208. #endif
  209. };
  210. #ifndef QT_NO_QOBJECT
  211. #define Q_SCRIPT_DECLARE_QMETAOBJECT(T, _Arg1) \
  212. template<> inline QScriptValue qscriptQMetaObjectConstructor<T>(QScriptContext *ctx, QScriptEngine *eng, T *) \
  213. { \
  214. _Arg1 arg1 = qscriptvalue_cast<_Arg1> (ctx->argument(0)); \
  215. T* t = new T(arg1); \
  216. if (ctx->isCalledAsConstructor()) \
  217. return eng->newQObject(ctx->thisObject(), t, QScriptEngine::AutoOwnership); \
  218. QScriptValue o = eng->newQObject(t, QScriptEngine::AutoOwnership); \
  219. o.setPrototype(ctx->callee().property(QString::fromLatin1("prototype"))); \
  220. return o; \
  221. }
  222. template <class T> QScriptValue QScriptEngine::scriptValueFromQMetaObject()
  223. {
  224. typedef QScriptValue(*ConstructPtr)(QScriptContext *, QScriptEngine *, T *);
  225. ConstructPtr cptr = qscriptQMetaObjectConstructor<T>;
  226. return newQMetaObject(&T::staticMetaObject,
  227. newFunction(reinterpret_cast<FunctionWithArgSignature>(cptr), 0));
  228. }
  229. #ifdef QT_DEPRECATED
  230. template <class T>
  231. inline QT_DEPRECATED QScriptValue qScriptValueFromQMetaObject(
  232. QScriptEngine *engine
  233. #ifndef qdoc
  234. , T * /* dummy */ = 0
  235. #endif
  236. )
  237. {
  238. return engine->scriptValueFromQMetaObject<T>();
  239. }
  240. #endif
  241. #endif // QT_NO_QOBJECT
  242. inline QScriptValue qScriptValueFromValue_helper(QScriptEngine *engine, int type, const void *ptr)
  243. {
  244. if (!engine)
  245. return QScriptValue();
  246. return engine->create(type, ptr);
  247. }
  248. template <typename T>
  249. inline QScriptValue qScriptValueFromValue(QScriptEngine *engine, const T &t)
  250. {
  251. return qScriptValueFromValue_helper(engine, qMetaTypeId<T>(), &t);
  252. }
  253. template <>
  254. inline QScriptValue qScriptValueFromValue<QVariant>(QScriptEngine *engine, const QVariant &v)
  255. {
  256. return qScriptValueFromValue_helper(engine, v.userType(), v.data());
  257. }
  258. inline bool qscriptvalue_cast_helper(const QScriptValue &value, int type, void *ptr)
  259. {
  260. return QScriptEngine::convertV2(value, type, ptr);
  261. }
  262. template<typename T>
  263. T qscriptvalue_cast(const QScriptValue &value)
  264. {
  265. T t;
  266. const int id = qMetaTypeId<T>();
  267. if (qscriptvalue_cast_helper(value, id, &t))
  268. return t;
  269. else if (value.isVariant())
  270. return qvariant_cast<T>(value.toVariant());
  271. return T();
  272. }
  273. template <>
  274. inline QVariant qscriptvalue_cast<QVariant>(const QScriptValue &value)
  275. {
  276. return value.toVariant();
  277. }
  278. #ifdef QT_DEPRECATED
  279. template <typename T>
  280. inline QT_DEPRECATED T qScriptValueToValue(const QScriptValue &value)
  281. {
  282. return qscriptvalue_cast<T>(value);
  283. }
  284. #endif
  285. inline void qScriptRegisterMetaType_helper(QScriptEngine *eng, int type,
  286. QScriptEngine::MarshalFunction mf,
  287. QScriptEngine::DemarshalFunction df,
  288. const QScriptValue &prototype)
  289. {
  290. eng->registerCustomType(type, mf, df, prototype);
  291. }
  292. template<typename T>
  293. int qScriptRegisterMetaType(
  294. QScriptEngine *eng,
  295. QScriptValue (*toScriptValue)(QScriptEngine *, const T &t),
  296. void (*fromScriptValue)(const QScriptValue &, T &t),
  297. const QScriptValue &prototype = QScriptValue()
  298. #ifndef qdoc
  299. , T * /* dummy */ = 0
  300. #endif
  301. )
  302. {
  303. const int id = qRegisterMetaType<T>(); // make sure it's registered
  304. qScriptRegisterMetaType_helper(
  305. eng, id, reinterpret_cast<QScriptEngine::MarshalFunction>(toScriptValue),
  306. reinterpret_cast<QScriptEngine::DemarshalFunction>(fromScriptValue),
  307. prototype);
  308. return id;
  309. }
  310. template <class Container>
  311. QScriptValue qScriptValueFromSequence(QScriptEngine *eng, const Container &cont)
  312. {
  313. QScriptValue a = eng->newArray();
  314. typename Container::const_iterator begin = cont.begin();
  315. typename Container::const_iterator end = cont.end();
  316. typename Container::const_iterator it;
  317. quint32 i;
  318. for (it = begin, i = 0; it != end; ++it, ++i)
  319. a.setProperty(i, eng->toScriptValue(*it));
  320. return a;
  321. }
  322. template <class Container>
  323. void qScriptValueToSequence(const QScriptValue &value, Container &cont)
  324. {
  325. quint32 len = value.property(QLatin1String("length")).toUInt32();
  326. for (quint32 i = 0; i < len; ++i) {
  327. QScriptValue item = value.property(i);
  328. cont.push_back(qscriptvalue_cast<typename Container::value_type>(item));
  329. }
  330. }
  331. template<typename T>
  332. int qScriptRegisterSequenceMetaType(
  333. QScriptEngine *engine,
  334. const QScriptValue &prototype = QScriptValue()
  335. #ifndef qdoc
  336. , T * /* dummy */ = 0
  337. #endif
  338. )
  339. {
  340. return qScriptRegisterMetaType<T>(engine, qScriptValueFromSequence,
  341. qScriptValueToSequence, prototype);
  342. }
  343. #ifndef QT_NO_QOBJECT
  344. Q_SCRIPT_EXPORT bool qScriptConnect(QObject *sender, const char *signal,
  345. const QScriptValue &receiver,
  346. const QScriptValue &function);
  347. Q_SCRIPT_EXPORT bool qScriptDisconnect(QObject *sender, const char *signal,
  348. const QScriptValue &receiver,
  349. const QScriptValue &function);
  350. #endif // QT_NO_QOBJECT
  351. Q_DECLARE_OPERATORS_FOR_FLAGS(QScriptEngine::QObjectWrapOptions)
  352. QT_END_NAMESPACE
  353. #endif // QSCRIPTENGINE_H