1 | /****************************************************************************
|
---|
2 | **
|
---|
3 | ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
---|
4 | ** Contact: Qt Software Information ([email protected])
|
---|
5 | **
|
---|
6 | ** This file is part of the QtScript module of the Qt Toolkit.
|
---|
7 | **
|
---|
8 | ** $QT_BEGIN_LICENSE:LGPL$
|
---|
9 | ** Commercial Usage
|
---|
10 | ** Licensees holding valid Qt Commercial licenses may use this file in
|
---|
11 | ** accordance with the Qt Commercial License Agreement provided with the
|
---|
12 | ** Software or, alternatively, in accordance with the terms contained in
|
---|
13 | ** a written agreement between you and Nokia.
|
---|
14 | **
|
---|
15 | ** GNU Lesser General Public License Usage
|
---|
16 | ** Alternatively, this file may be used under the terms of the GNU Lesser
|
---|
17 | ** General Public License version 2.1 as published by the Free Software
|
---|
18 | ** Foundation and appearing in the file LICENSE.LGPL included in the
|
---|
19 | ** packaging of this file. Please review the following information to
|
---|
20 | ** ensure the GNU Lesser General Public License version 2.1 requirements
|
---|
21 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
---|
22 | **
|
---|
23 | ** In addition, as a special exception, Nokia gives you certain
|
---|
24 | ** additional rights. These rights are described in the Nokia Qt LGPL
|
---|
25 | ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
|
---|
26 | ** package.
|
---|
27 | **
|
---|
28 | ** GNU General Public License Usage
|
---|
29 | ** Alternatively, this file may be used under the terms of the GNU
|
---|
30 | ** General Public License version 3.0 as published by the Free Software
|
---|
31 | ** Foundation and appearing in the file LICENSE.GPL included in the
|
---|
32 | ** packaging of this file. Please review the following information to
|
---|
33 | ** ensure the GNU General Public License version 3.0 requirements will be
|
---|
34 | ** met: http://www.gnu.org/copyleft/gpl.html.
|
---|
35 | **
|
---|
36 | ** If you are unsure which license is appropriate for your use, please
|
---|
37 | ** contact the sales department at [email protected].
|
---|
38 | ** $QT_END_LICENSE$
|
---|
39 | **
|
---|
40 | ****************************************************************************/
|
---|
41 |
|
---|
42 | #ifndef QSCRIPTEXTQOBJECT_P_H
|
---|
43 | #define QSCRIPTEXTQOBJECT_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 | #ifndef QT_NO_QOBJECT
|
---|
57 |
|
---|
58 | #include "qscriptecmacore_p.h"
|
---|
59 |
|
---|
60 | #ifndef QT_NO_SCRIPT
|
---|
61 |
|
---|
62 | #include "qscriptclassdata_p.h"
|
---|
63 | #include "qscriptfunction_p.h"
|
---|
64 | #include "qscriptengine.h"
|
---|
65 | #include "qscriptmemberfwd_p.h"
|
---|
66 |
|
---|
67 | #include <QtCore/QHash>
|
---|
68 | #include <QtCore/QPointer>
|
---|
69 | #include <QtCore/QObject>
|
---|
70 | #include <QtCore/QVariant>
|
---|
71 | #include <QtCore/QVarLengthArray>
|
---|
72 | #include <QtCore/QVector>
|
---|
73 |
|
---|
74 | QT_BEGIN_NAMESPACE
|
---|
75 |
|
---|
76 | namespace QScript {
|
---|
77 |
|
---|
78 | class QObjectConnectionManager;
|
---|
79 |
|
---|
80 | class ExtQObject: public Ecma::Core
|
---|
81 | {
|
---|
82 | public:
|
---|
83 | ExtQObject(QScriptEnginePrivate *engine);
|
---|
84 | virtual ~ExtQObject();
|
---|
85 |
|
---|
86 | virtual void execute(QScriptContextPrivate *context);
|
---|
87 |
|
---|
88 | class Instance: public QScriptObjectData {
|
---|
89 | public:
|
---|
90 | Instance() : ownership(QScriptEngine::QtOwnership) { }
|
---|
91 | virtual void finalize(QScriptEnginePrivate *engine);
|
---|
92 | virtual ~Instance() {}
|
---|
93 |
|
---|
94 | static Instance *get(const QScriptValueImpl &object, QScriptClassInfo *klass = 0);
|
---|
95 |
|
---|
96 | public:
|
---|
97 | QPointer<QObject> value;
|
---|
98 | QScriptEngine::ValueOwnership ownership;
|
---|
99 | QScriptEngine::QObjectWrapOptions options;
|
---|
100 | };
|
---|
101 |
|
---|
102 | inline Instance *get(const QScriptValueImpl &object) const
|
---|
103 | { return Instance::get(object, classInfo()); }
|
---|
104 |
|
---|
105 | void newQObject(QScriptValueImpl *result, QObject *value,
|
---|
106 | QScriptEngine::ValueOwnership ownership = QScriptEngine::QtOwnership,
|
---|
107 | const QScriptEngine::QObjectWrapOptions &options = 0);
|
---|
108 |
|
---|
109 | protected:
|
---|
110 | static QScriptValueImpl method_findChild(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo);
|
---|
111 | static QScriptValueImpl method_findChildren(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo);
|
---|
112 | static QScriptValueImpl method_toString(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo);
|
---|
113 | };
|
---|
114 |
|
---|
115 | class QtFunction: public QScriptFunction
|
---|
116 | {
|
---|
117 | public:
|
---|
118 | QtFunction(const QScriptValueImpl &object, int initialIndex, bool maybeOverloaded)
|
---|
119 | : m_object(object), m_initialIndex(initialIndex),
|
---|
120 | m_maybeOverloaded(maybeOverloaded)
|
---|
121 | { }
|
---|
122 |
|
---|
123 | virtual ~QtFunction() { }
|
---|
124 |
|
---|
125 | virtual void execute(QScriptContextPrivate *context);
|
---|
126 |
|
---|
127 | virtual Type type() const { return QScriptFunction::Qt; }
|
---|
128 |
|
---|
129 | virtual QString functionName() const;
|
---|
130 |
|
---|
131 | virtual void mark(QScriptEnginePrivate *engine, int generation);
|
---|
132 |
|
---|
133 | inline QScriptValueImpl object() const { return m_object; }
|
---|
134 |
|
---|
135 | inline QObject *qobject() const {
|
---|
136 | if (!m_object.isQObject())
|
---|
137 | return 0;
|
---|
138 | return m_object.toQObject();
|
---|
139 | }
|
---|
140 |
|
---|
141 | inline const QMetaObject *metaObject() const {
|
---|
142 | if (!m_object.isQObject())
|
---|
143 | return 0;
|
---|
144 | QObject *qobj = m_object.toQObject();
|
---|
145 | if (!qobj)
|
---|
146 | return 0;
|
---|
147 | return qobj->metaObject();
|
---|
148 | }
|
---|
149 |
|
---|
150 | int mostGeneralMethod(QMetaMethod *out = 0) const;
|
---|
151 | QList<int> overloadedIndexes() const;
|
---|
152 |
|
---|
153 | inline int initialIndex() const { return m_initialIndex; }
|
---|
154 | inline bool maybeOverloaded() const { return m_maybeOverloaded; }
|
---|
155 |
|
---|
156 | private:
|
---|
157 | QScriptValueImpl m_object;
|
---|
158 | int m_initialIndex;
|
---|
159 | bool m_maybeOverloaded;
|
---|
160 | };
|
---|
161 |
|
---|
162 | class ExtQMetaObject: public Ecma::Core
|
---|
163 | {
|
---|
164 | public:
|
---|
165 | ExtQMetaObject(QScriptEnginePrivate *engine);
|
---|
166 | virtual ~ExtQMetaObject();
|
---|
167 |
|
---|
168 | virtual void execute(QScriptContextPrivate *context);
|
---|
169 |
|
---|
170 | class Instance: public QScriptFunction {
|
---|
171 | public:
|
---|
172 | Instance() : value(0) { }
|
---|
173 | virtual ~Instance() { }
|
---|
174 |
|
---|
175 | static Instance *get(const QScriptValueImpl &object, QScriptClassInfo *klass);
|
---|
176 |
|
---|
177 | virtual void execute(QScriptContextPrivate *context);
|
---|
178 |
|
---|
179 | public:
|
---|
180 | const QMetaObject *value;
|
---|
181 | QScriptValueImpl ctor;
|
---|
182 | QScriptValueImpl prototype;
|
---|
183 | };
|
---|
184 |
|
---|
185 | inline Instance *get(const QScriptValueImpl &object) const
|
---|
186 | { return Instance::get(object, classInfo()); }
|
---|
187 |
|
---|
188 | void newQMetaObject(QScriptValueImpl *result, const QMetaObject *value,
|
---|
189 | const QScriptValueImpl &ctor = QScriptValueImpl());
|
---|
190 |
|
---|
191 | protected:
|
---|
192 | static QScriptValueImpl method_className(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo);
|
---|
193 | };
|
---|
194 |
|
---|
195 | } // namespace QScript
|
---|
196 |
|
---|
197 | struct QScriptQObjectWrapperInfo
|
---|
198 | {
|
---|
199 | QScriptQObjectWrapperInfo(const QScriptValueImpl &obj,
|
---|
200 | QScriptEngine::ValueOwnership own,
|
---|
201 | const QScriptEngine::QObjectWrapOptions &opt)
|
---|
202 | : object(obj), ownership(own), options(opt) {}
|
---|
203 |
|
---|
204 | QScriptValueImpl object;
|
---|
205 | QScriptEngine::ValueOwnership ownership;
|
---|
206 | QScriptEngine::QObjectWrapOptions options;
|
---|
207 | };
|
---|
208 |
|
---|
209 | class QScriptQObjectData // : public QObjectUserData
|
---|
210 | {
|
---|
211 | public:
|
---|
212 | QScriptQObjectData();
|
---|
213 | ~QScriptQObjectData();
|
---|
214 |
|
---|
215 | bool addSignalHandler(QObject *sender,
|
---|
216 | int signalIndex,
|
---|
217 | const QScriptValueImpl &receiver,
|
---|
218 | const QScriptValueImpl &slot,
|
---|
219 | const QScriptValueImpl &senderWrapper = QScriptValueImpl());
|
---|
220 | bool removeSignalHandler(QObject *sender,
|
---|
221 | int signalIndex,
|
---|
222 | const QScriptValueImpl &receiver,
|
---|
223 | const QScriptValueImpl &slot);
|
---|
224 |
|
---|
225 | bool findWrapper(QScriptEngine::ValueOwnership ownership,
|
---|
226 | const QScriptEngine::QObjectWrapOptions &options,
|
---|
227 | QScriptValueImpl *out);
|
---|
228 | void registerWrapper(const QScriptValueImpl &wrapper,
|
---|
229 | QScriptEngine::ValueOwnership ownership,
|
---|
230 | const QScriptEngine::QObjectWrapOptions &options);
|
---|
231 |
|
---|
232 | void mark(int generation);
|
---|
233 |
|
---|
234 | private:
|
---|
235 | QScript::QObjectConnectionManager *m_connectionManager;
|
---|
236 | QList<QScriptQObjectWrapperInfo> wrappers;
|
---|
237 | };
|
---|
238 |
|
---|
239 | class QScriptMetaType
|
---|
240 | {
|
---|
241 | public:
|
---|
242 | enum Kind {
|
---|
243 | Invalid,
|
---|
244 | Variant,
|
---|
245 | MetaType,
|
---|
246 | Unresolved,
|
---|
247 | MetaEnum
|
---|
248 | };
|
---|
249 |
|
---|
250 | inline QScriptMetaType()
|
---|
251 | : m_kind(Invalid), m_typeId(0) { }
|
---|
252 |
|
---|
253 | inline Kind kind() const
|
---|
254 | { return m_kind; }
|
---|
255 |
|
---|
256 | int typeId() const;
|
---|
257 |
|
---|
258 | inline bool isValid() const
|
---|
259 | { return (m_kind != Invalid); }
|
---|
260 |
|
---|
261 | inline bool isVariant() const
|
---|
262 | { return (m_kind == Variant); }
|
---|
263 |
|
---|
264 | inline bool isMetaType() const
|
---|
265 | { return (m_kind == MetaType); }
|
---|
266 |
|
---|
267 | inline bool isUnresolved() const
|
---|
268 | { return (m_kind == Unresolved); }
|
---|
269 |
|
---|
270 | inline bool isMetaEnum() const
|
---|
271 | { return (m_kind == MetaEnum); }
|
---|
272 |
|
---|
273 | QByteArray name() const;
|
---|
274 |
|
---|
275 | inline int enumeratorIndex() const
|
---|
276 | { Q_ASSERT(isMetaEnum()); return m_typeId; }
|
---|
277 |
|
---|
278 | inline bool operator==(const QScriptMetaType &other) const
|
---|
279 | {
|
---|
280 | return (m_kind == other.m_kind) && (m_typeId == other.m_typeId);
|
---|
281 | }
|
---|
282 |
|
---|
283 | static inline QScriptMetaType variant()
|
---|
284 | { return QScriptMetaType(Variant); }
|
---|
285 |
|
---|
286 | static inline QScriptMetaType metaType(int typeId, const QByteArray &name)
|
---|
287 | { return QScriptMetaType(MetaType, typeId, name); }
|
---|
288 |
|
---|
289 | static inline QScriptMetaType metaEnum(int enumIndex, const QByteArray &name)
|
---|
290 | { return QScriptMetaType(MetaEnum, enumIndex, name); }
|
---|
291 |
|
---|
292 | static inline QScriptMetaType unresolved(const QByteArray &name)
|
---|
293 | { return QScriptMetaType(Unresolved, /*typeId=*/0, name); }
|
---|
294 |
|
---|
295 | private:
|
---|
296 | inline QScriptMetaType(Kind kind, int typeId = 0, const QByteArray &name = QByteArray())
|
---|
297 | : m_kind(kind), m_typeId(typeId), m_name(name) { }
|
---|
298 |
|
---|
299 | Kind m_kind;
|
---|
300 | int m_typeId;
|
---|
301 | QByteArray m_name;
|
---|
302 | };
|
---|
303 |
|
---|
304 | class QScriptMetaMethod
|
---|
305 | {
|
---|
306 | public:
|
---|
307 | inline QScriptMetaMethod()
|
---|
308 | : m_firstUnresolvedIndex(-1)
|
---|
309 | { }
|
---|
310 | inline QScriptMetaMethod(const QByteArray &name, const QVector<QScriptMetaType> &types)
|
---|
311 | : m_name(name), m_types(types), m_firstUnresolvedIndex(-1)
|
---|
312 | {
|
---|
313 | QVector<QScriptMetaType>::const_iterator it;
|
---|
314 | for (it = m_types.constBegin(); it != m_types.constEnd(); ++it) {
|
---|
315 | if ((*it).kind() == QScriptMetaType::Unresolved) {
|
---|
316 | m_firstUnresolvedIndex = it - m_types.constBegin();
|
---|
317 | break;
|
---|
318 | }
|
---|
319 | }
|
---|
320 | }
|
---|
321 | inline bool isValid() const
|
---|
322 | { return !m_types.isEmpty(); }
|
---|
323 |
|
---|
324 | QByteArray name() const
|
---|
325 | { return m_name; }
|
---|
326 |
|
---|
327 | inline QScriptMetaType returnType() const
|
---|
328 | { return m_types.at(0); }
|
---|
329 |
|
---|
330 | inline int argumentCount() const
|
---|
331 | { return m_types.count() - 1; }
|
---|
332 |
|
---|
333 | inline QScriptMetaType argumentType(int arg) const
|
---|
334 | { return m_types.at(arg + 1); }
|
---|
335 |
|
---|
336 | inline bool fullyResolved() const
|
---|
337 | { return m_firstUnresolvedIndex == -1; }
|
---|
338 |
|
---|
339 | inline bool hasUnresolvedReturnType() const
|
---|
340 | { return (m_firstUnresolvedIndex == 0); }
|
---|
341 |
|
---|
342 | inline int firstUnresolvedIndex() const
|
---|
343 | { return m_firstUnresolvedIndex; }
|
---|
344 |
|
---|
345 | inline int count() const
|
---|
346 | { return m_types.count(); }
|
---|
347 |
|
---|
348 | inline QScriptMetaType type(int index) const
|
---|
349 | { return m_types.at(index); }
|
---|
350 |
|
---|
351 | inline QVector<QScriptMetaType> types() const
|
---|
352 | { return m_types; }
|
---|
353 |
|
---|
354 | private:
|
---|
355 | QByteArray m_name;
|
---|
356 | QVector<QScriptMetaType> m_types;
|
---|
357 | int m_firstUnresolvedIndex;
|
---|
358 | };
|
---|
359 |
|
---|
360 | struct QScriptMetaArguments
|
---|
361 | {
|
---|
362 | int matchDistance;
|
---|
363 | int index;
|
---|
364 | QScriptMetaMethod method;
|
---|
365 | QVarLengthArray<QVariant, 9> args;
|
---|
366 |
|
---|
367 | inline QScriptMetaArguments(int dist, int idx, const QScriptMetaMethod &mtd,
|
---|
368 | const QVarLengthArray<QVariant, 9> &as)
|
---|
369 | : matchDistance(dist), index(idx), method(mtd), args(as) { }
|
---|
370 | inline QScriptMetaArguments()
|
---|
371 | : matchDistance(0), index(-1) { }
|
---|
372 |
|
---|
373 | inline bool isValid() const
|
---|
374 | { return (index != -1); }
|
---|
375 | };
|
---|
376 |
|
---|
377 | class QScriptMetaObject
|
---|
378 | {
|
---|
379 | public:
|
---|
380 | inline QScriptMetaMethod findMethod(int index) const
|
---|
381 | {
|
---|
382 | return m_methods.value(index);
|
---|
383 | }
|
---|
384 |
|
---|
385 | inline void registerMethod(int index, const QScriptMetaMethod &method)
|
---|
386 | {
|
---|
387 | m_methods.insert(index, method);
|
---|
388 | }
|
---|
389 |
|
---|
390 | inline bool findMember(QScriptNameIdImpl *nameId, QScript::Member *member) const
|
---|
391 | {
|
---|
392 | QHash<QScriptNameIdImpl*, QScript::Member>::const_iterator it;
|
---|
393 | it = m_members.constFind(nameId);
|
---|
394 | if (it == m_members.constEnd())
|
---|
395 | return false;
|
---|
396 | *member = it.value();
|
---|
397 | return true;
|
---|
398 | }
|
---|
399 |
|
---|
400 | inline void registerMember(QScriptNameIdImpl *nameId, const QScript::Member &member)
|
---|
401 | {
|
---|
402 | m_members.insert(nameId, member);
|
---|
403 | }
|
---|
404 |
|
---|
405 | inline QList<QScriptNameIdImpl*> registeredMemberNames() const
|
---|
406 | {
|
---|
407 | return m_members.keys();
|
---|
408 | }
|
---|
409 |
|
---|
410 | inline QScriptValueImpl findPropertyAccessor(int index) const
|
---|
411 | {
|
---|
412 | return m_propertyAccessors.value(index);
|
---|
413 | }
|
---|
414 |
|
---|
415 | inline void registerPropertyAccessor(int index, const QScriptValueImpl &accessor)
|
---|
416 | {
|
---|
417 | m_propertyAccessors.insert(index, accessor);
|
---|
418 | }
|
---|
419 |
|
---|
420 | inline QList<QScriptValueImpl> registeredPropertyAccessors() const
|
---|
421 | {
|
---|
422 | return m_propertyAccessors.values();
|
---|
423 | }
|
---|
424 |
|
---|
425 | inline int methodLowerBound(int index) const
|
---|
426 | {
|
---|
427 | return m_methodBounds.value(index, 0);
|
---|
428 | }
|
---|
429 |
|
---|
430 | inline void setMethodLowerBound(int index, int bound)
|
---|
431 | {
|
---|
432 | m_methodBounds.insert(index, bound);
|
---|
433 | }
|
---|
434 |
|
---|
435 | private:
|
---|
436 | QHash<int, QScriptValueImpl> m_propertyAccessors;
|
---|
437 | QHash<int, QScriptMetaMethod> m_methods;
|
---|
438 | QHash<int, int> m_methodBounds;
|
---|
439 | QHash<QScriptNameIdImpl*, QScript::Member> m_members;
|
---|
440 | };
|
---|
441 |
|
---|
442 | #endif // QT_NO_QOBJECT
|
---|
443 |
|
---|
444 | QT_END_NAMESPACE
|
---|
445 |
|
---|
446 | #endif // QT_NO_SCRIPT
|
---|
447 | #endif // QSCRIPTEXTQOBJECT_P_H
|
---|