source: trunk/src/script/qscriptcontextinfo.cpp@ 5

Last change on this file since 5 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 15.2 KB
Line 
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#include "qscriptcontextinfo.h"
43
44#ifndef QT_NO_SCRIPT
45
46#include "qscriptcontextinfo_p.h"
47#include "qscriptengine_p.h"
48#include "qscriptcontext_p.h"
49#include "qscriptvalueimpl_p.h"
50#include "qscriptmember_p.h"
51#include "qscriptobject_p.h"
52#include <QtCore/qdatastream.h>
53
54QT_BEGIN_NAMESPACE
55
56/*!
57 \since 4.4
58 \class QScriptContextInfo
59
60 \brief The QScriptContextInfo class provides additional information about a QScriptContext.
61
62 \ingroup script
63 \mainclass
64
65 QScriptContextInfo is typically used for debugging purposes. It can
66 provide information about the code being executed, such as the type
67 of the called function, and the original source code location of the
68 current statement.
69
70 If the called function is executing Qt Script code, you can obtain
71 the script location with the functions fileName(), lineNumber() and
72 columnNumber().
73
74 You can obtain the starting line number and ending line number of a
75 Qt Script function definition with functionStartLineNumber() and
76 functionEndLineNumber(), respectively.
77
78 For Qt Script functions and Qt methods (e.g. slots), you can call
79 functionParameterNames() to get the names of the formal parameters of the
80 function.
81
82 For Qt methods and Qt property accessors, you can obtain the index
83 of the underlying QMetaMethod or QMetaProperty by calling
84 functionMetaIndex().
85
86 \sa QScriptContext, QScriptEngineAgent
87*/
88
89/*!
90 \enum QScriptContextInfo::FunctionType
91
92 This enum specifies the type of function being called.
93
94 \value ScriptFunction The function is a Qt Script function, i.e. it was defined through a call to QScriptEngine::evaluate().
95 \value QtFunction The function is a Qt function (a signal, slot or method).
96 \value QtPropertyFunction The function is a Qt property getter or setter.
97 \value NativeFunction The function is a built-in Qt Script function, or it was defined through a call to QScriptEngine::newFunction().
98*/
99
100/*!
101 \internal
102*/
103QScriptContextInfoPrivate::QScriptContextInfoPrivate()
104 : q_ptr(0)
105{
106 ref = 0;
107 functionType = QScriptContextInfo::NativeFunction;
108 functionMetaIndex = -1;
109 functionStartLineNumber = -1;
110 functionEndLineNumber = -1;
111 scriptId = -1;
112 lineNumber = -1;
113 columnNumber = -1;
114}
115
116/*!
117 \internal
118*/
119QScriptContextInfoPrivate::QScriptContextInfoPrivate(const QScriptContext *context)
120 : q_ptr(0)
121{
122 Q_ASSERT(context);
123 ref = 0;
124 functionType = QScriptContextInfo::NativeFunction;
125 functionMetaIndex = -1;
126 functionStartLineNumber = -1;
127 functionEndLineNumber = -1;
128
129 const QScriptContextPrivate *ctx_p = QScriptContextPrivate::get(context);
130#ifndef Q_SCRIPT_NO_EVENT_NOTIFY
131 scriptId = ctx_p->scriptId();
132#endif
133 fileName = ctx_p->fileName();
134 lineNumber = ctx_p->currentLine;
135 columnNumber = ctx_p->currentColumn;
136
137 QScriptValueImpl callee = ctx_p->engine()->toImpl(context->callee());
138 QScriptFunction *fun = callee.toFunction();
139 if (fun) {
140 functionName = fun->functionName();
141 functionStartLineNumber = fun->startLineNumber();
142 functionEndLineNumber = fun->endLineNumber();
143
144 switch (fun->type()) {
145 case QScriptFunction::Unknown:
146 functionType = QScriptContextInfo::NativeFunction;
147 break;
148
149 case QScriptFunction::Script:
150 functionType = QScriptContextInfo::ScriptFunction;
151 for (int i = 0; i < fun->formals.count(); ++i)
152 parameterNames.append(fun->formals.at(i)->s);
153 break;
154
155 case QScriptFunction::C:
156 functionType = QScriptContextInfo::NativeFunction;
157 break;
158
159 case QScriptFunction::C2:
160 functionType = QScriptContextInfo::NativeFunction;
161 break;
162
163 case QScriptFunction::C3:
164 functionType = QScriptContextInfo::NativeFunction;
165 break;
166
167 case QScriptFunction::Qt: {
168 functionType = QScriptContextInfo::QtFunction;
169 functionMetaIndex = ctx_p->calleeMetaIndex;
170
171#ifndef QT_NO_QOBJECT
172 const QMetaObject *meta;
173 meta = static_cast<QScript::QtFunction*>(fun)->metaObject();
174 if (meta) {
175 QMetaMethod method = meta->method(functionMetaIndex);
176 QList<QByteArray> formals = method.parameterNames();
177 for (int i = 0; i < formals.count(); ++i)
178 parameterNames.append(QLatin1String(formals.at(i)));
179 }
180#endif
181 } break;
182
183 case QScriptFunction::QtProperty:
184 functionType = QScriptContextInfo::QtPropertyFunction;
185 functionMetaIndex = ctx_p->calleeMetaIndex;
186 break;
187 }
188 }
189}
190
191/*!
192 \internal
193*/
194QScriptContextInfoPrivate::~QScriptContextInfoPrivate()
195{
196}
197
198/*!
199 Constructs a new QScriptContextInfo from the given \a context.
200
201 The relevant information is extracted from the \a context at
202 construction time; i.e. if you continue script execution in the \a
203 context, the new state of the context will not be reflected in a
204 previously created QScriptContextInfo.
205*/
206QScriptContextInfo::QScriptContextInfo(const QScriptContext *context)
207{
208 if (context) {
209 d_ptr = new QScriptContextInfoPrivate(context);
210 d_ptr->q_ptr = this;
211 d_ptr->ref.ref();
212 } else {
213 d_ptr = 0;
214 }
215}
216
217/*!
218 Constructs a new QScriptContextInfo from the \a other info.
219*/
220QScriptContextInfo::QScriptContextInfo(const QScriptContextInfo &other)
221 : d_ptr(other.d_ptr)
222{
223 if (d_ptr)
224 d_ptr->ref.ref();
225}
226
227/*!
228 Constructs a null QScriptContextInfo.
229
230 \sa isNull()
231*/
232QScriptContextInfo::QScriptContextInfo()
233 : d_ptr(0)
234{
235}
236
237/*!
238 Destroys the QScriptContextInfo.
239*/
240QScriptContextInfo::~QScriptContextInfo()
241{
242 if (d_ptr && !d_ptr->ref.deref()) {
243 delete d_ptr;
244 d_ptr = 0;
245 }
246}
247
248/*!
249 Assigns the \a other info to this QScriptContextInfo,
250 and returns a reference to this QScriptContextInfo.
251*/
252QScriptContextInfo &QScriptContextInfo::operator=(const QScriptContextInfo &other)
253{
254 if (d_ptr == other.d_ptr)
255 return *this;
256 if (d_ptr && !d_ptr->ref.deref()) {
257 delete d_ptr;
258 d_ptr = 0;
259 }
260 d_ptr = other.d_ptr;
261 if (d_ptr)
262 d_ptr->ref.ref();
263 return *this;
264}
265
266/*!
267 Returns the ID of the script where the code being executed was
268 defined, or -1 if the ID is not available (i.e. a native function is
269 being executed).
270
271 \sa QScriptEngineAgent::scriptLoad()
272*/
273qint64 QScriptContextInfo::scriptId() const
274{
275 Q_D(const QScriptContextInfo);
276 if (!d)
277 return -1;
278 return d->scriptId;
279}
280
281/*!
282 Returns the name of the file where the code being executed was
283 defined, if available; otherwise returns an empty string.
284
285 For Qt Script code, this function returns the fileName argument
286 that was passed to QScriptEngine::evaluate().
287
288 \sa lineNumber(), functionName()
289*/
290QString QScriptContextInfo::fileName() const
291{
292 Q_D(const QScriptContextInfo);
293 if (!d)
294 return QString();
295 return d->fileName;
296}
297
298/*!
299 Returns the line number corresponding to the statement being
300 executed, or -1 if the line number is not available.
301
302 The line number is only available if Qt Script code is being
303 executed.
304
305 \sa columnNumber(), fileName()
306*/
307int QScriptContextInfo::lineNumber() const
308{
309 Q_D(const QScriptContextInfo);
310 if (!d)
311 return -1;
312 return d->lineNumber;
313}
314
315/*!
316 Returns the column number corresponding to the statement being
317 executed, or -1 if the column number is not available.
318
319 The column number is only available if Qt Script code is being
320 executed.
321
322 \sa lineNumber(), fileName()
323*/
324int QScriptContextInfo::columnNumber() const
325{
326 Q_D(const QScriptContextInfo);
327 if (!d)
328 return -1;
329 return d->columnNumber;
330}
331
332/*!
333 Returns the name of the called function, or an empty string if
334 the name is not available.
335
336 For script functions of type QtPropertyFunction, this function
337 always returns the name of the property; you can use
338 QScriptContext::argumentCount() to differentiate between reads and
339 writes.
340
341 \sa fileName(), functionType()
342*/
343QString QScriptContextInfo::functionName() const
344{
345 Q_D(const QScriptContextInfo);
346 if (!d)
347 return QString();
348 return d->functionName;
349}
350
351/*!
352 Returns the type of the called function.
353
354 \sa functionName(), QScriptContext::callee()
355*/
356QScriptContextInfo::FunctionType QScriptContextInfo::functionType() const
357{
358 Q_D(const QScriptContextInfo);
359 if (!d)
360 return NativeFunction;
361 return d->functionType;
362}
363
364/*!
365 Returns the line number where the definition of the called function
366 starts, or -1 if the line number is not available.
367
368 The starting line number is only available if the functionType() is
369 ScriptFunction.
370
371 \sa functionEndLineNumber(), fileName()
372*/
373int QScriptContextInfo::functionStartLineNumber() const
374{
375 Q_D(const QScriptContextInfo);
376 if (!d)
377 return -1;
378 return d->functionStartLineNumber;
379}
380
381/*!
382 Returns the line number where the definition of the called function
383 ends, or -1 if the line number is not available.
384
385 The ending line number is only available if the functionType() is
386 ScriptFunction.
387
388 \sa functionStartLineNumber()
389*/
390int QScriptContextInfo::functionEndLineNumber() const
391{
392 Q_D(const QScriptContextInfo);
393 if (!d)
394 return -1;
395 return d->functionEndLineNumber;
396}
397
398/*!
399 Returns the names of the formal parameters of the called function,
400 or an empty QStringList if the parameter names are not available.
401
402 \sa QScriptContext::argument()
403*/
404QStringList QScriptContextInfo::functionParameterNames() const
405{
406 Q_D(const QScriptContextInfo);
407 if (!d)
408 return QStringList();
409 return d->parameterNames;
410}
411
412/*!
413 Returns the meta index of the called function, or -1 if the meta
414 index is not available.
415
416 The meta index is only available if the functionType() is QtFunction
417 or QtPropertyFunction. For QtFunction, the meta index can be passed
418 to QMetaObject::method() to obtain the corresponding method
419 definition; for QtPropertyFunction, the meta index can be passed to
420 QMetaObject::property() to obtain the corresponding property
421 definition.
422
423 \sa QScriptContext::thisObject()
424*/
425int QScriptContextInfo::functionMetaIndex() const
426{
427 Q_D(const QScriptContextInfo);
428 if (!d)
429 return -1;
430 return d->functionMetaIndex;
431}
432
433/*!
434 Returns true if this QScriptContextInfo is null, i.e. does not
435 contain any information.
436*/
437bool QScriptContextInfo::isNull() const
438{
439 Q_D(const QScriptContextInfo);
440 return (d == 0);
441}
442
443/*!
444 Returns true if this QScriptContextInfo is equal to the \a other
445 info, otherwise returns false.
446*/
447bool QScriptContextInfo::operator==(const QScriptContextInfo &other) const
448{
449 Q_D(const QScriptContextInfo);
450 const QScriptContextInfoPrivate *od = other.d_func();
451 if (d == od)
452 return true;
453 if (!d || !od)
454 return false;
455 return ((d->scriptId == od->scriptId)
456 && (d->lineNumber == od->lineNumber)
457 && (d->columnNumber == od->columnNumber)
458 && (d->fileName == od->fileName)
459 && (d->functionName == od->functionName)
460 && (d->functionType == od->functionType)
461 && (d->functionStartLineNumber == od->functionStartLineNumber)
462 && (d->functionEndLineNumber == od->functionEndLineNumber)
463 && (d->functionMetaIndex == od->functionMetaIndex)
464 && (d->parameterNames == od->parameterNames));
465}
466
467/*!
468 Returns true if this QScriptContextInfo is not equal to the \a other
469 info, otherwise returns false.
470*/
471bool QScriptContextInfo::operator!=(const QScriptContextInfo &other) const
472{
473 return !(*this == other);
474}
475
476#ifndef QT_NO_DATASTREAM
477/*!
478 \fn QDataStream &operator<<(QDataStream &stream, const QScriptContextInfo &info)
479 \since 4.4
480 \relates QScriptContextInfo
481
482 Writes the given \a info to the specified \a stream.
483*/
484QDataStream &operator<<(QDataStream &out, const QScriptContextInfo &info)
485{
486 out << info.scriptId();
487 out << (qint32)info.lineNumber();
488 out << (qint32)info.columnNumber();
489
490 out << (quint32)info.functionType();
491 out << (qint32)info.functionStartLineNumber();
492 out << (qint32)info.functionEndLineNumber();
493 out << (qint32)info.functionMetaIndex();
494
495 out << info.fileName();
496 out << info.functionName();
497 out << info.functionParameterNames();
498
499 return out;
500}
501
502/*!
503 \fn QDataStream &operator>>(QDataStream &stream, QScriptContextInfo &info)
504 \since 4.4
505 \relates QScriptContextInfo
506
507 Reads a QScriptContextInfo from the specified \a stream into the
508 given \a info.
509*/
510Q_SCRIPT_EXPORT QDataStream &operator>>(QDataStream &in, QScriptContextInfo &info)
511{
512 if (!info.d_ptr) {
513 info.d_ptr = new QScriptContextInfoPrivate();
514 info.d_ptr->ref.ref();
515 }
516
517 in >> info.d_ptr->scriptId;
518
519 qint32 line;
520 in >> line;
521 info.d_ptr->lineNumber = line;
522
523 qint32 column;
524 in >> column;
525 info.d_ptr->columnNumber = column;
526
527 quint32 ftype;
528 in >> ftype;
529 info.d_ptr->functionType = QScriptContextInfo::FunctionType(ftype);
530
531 qint32 startLine;
532 in >> startLine;
533 info.d_ptr->functionStartLineNumber = startLine;
534
535 qint32 endLine;
536 in >> endLine;
537 info.d_ptr->functionEndLineNumber = endLine;
538
539 qint32 metaIndex;
540 in >> metaIndex;
541 info.d_ptr->functionMetaIndex = metaIndex;
542
543 in >> info.d_ptr->fileName;
544 in >> info.d_ptr->functionName;
545 in >> info.d_ptr->parameterNames;
546
547 return in;
548}
549#endif
550
551QT_END_NAMESPACE
552
553#endif // QT_NO_SCRIPT
Note: See TracBrowser for help on using the repository browser.