| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  | /****************************************************************************
 | 
					
						
							|  |  |  | ** | 
					
						
							| 
									
										
										
										
											2011-01-11 16:28:15 +01:00
										 |  |  | ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  | ** All rights reserved. | 
					
						
							|  |  |  | ** Contact: Nokia Corporation (qt-info@nokia.com) | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** This file is part of the QtSCriptTools module of the Qt Toolkit. | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** $QT_BEGIN_LICENSE:LGPL$ | 
					
						
							|  |  |  | ** No Commercial Usage | 
					
						
							|  |  |  | ** This file contains pre-release code and may not be distributed. | 
					
						
							|  |  |  | ** You may use this file in accordance with the terms and conditions | 
					
						
							|  |  |  | ** contained in the Technology Preview License Agreement accompanying | 
					
						
							|  |  |  | ** this package. | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** GNU Lesser General Public License Usage | 
					
						
							|  |  |  | ** Alternatively, this file may be used under the terms of the GNU Lesser | 
					
						
							|  |  |  | ** General Public License version 2.1 as published by the Free Software | 
					
						
							|  |  |  | ** Foundation and appearing in the file LICENSE.LGPL included in the | 
					
						
							|  |  |  | ** packaging of this file.  Please review the following information to | 
					
						
							|  |  |  | ** ensure the GNU Lesser General Public License version 2.1 requirements | 
					
						
							|  |  |  | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** In addition, as a special exception, Nokia gives you certain additional | 
					
						
							|  |  |  | ** rights.  These rights are described in the Nokia Qt LGPL Exception | 
					
						
							|  |  |  | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** If you have questions regarding the use of this file, please contact | 
					
						
							|  |  |  | ** Nokia at qt-info@nokia.com. | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** $QT_END_LICENSE$ | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ****************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "jsdebuggeragent.h"
 | 
					
						
							| 
									
										
										
										
											2010-09-27 10:46:08 +02:00
										 |  |  | #include "qt_private/qdeclarativedebughelper_p.h"
 | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-27 18:03:11 +02:00
										 |  |  | #include <QtCore/qdatetime.h>
 | 
					
						
							|  |  |  | #include <QtCore/qdebug.h>
 | 
					
						
							|  |  |  | #include <QtCore/qurl.h>
 | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  | #include <QtCore/qcoreapplication.h>
 | 
					
						
							|  |  |  | #include <QtCore/qset.h>
 | 
					
						
							| 
									
										
										
										
											2010-10-27 18:03:11 +02:00
										 |  |  | #include <QtScript/qscriptcontextinfo.h>
 | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  | #include <QtScript/qscriptengine.h>
 | 
					
						
							| 
									
										
										
										
											2010-07-22 13:00:26 +02:00
										 |  |  | #include <QtScript/qscriptvalueiterator.h>
 | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-22 09:59:18 +02:00
										 |  |  | namespace QmlJSDebugger { | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-27 18:44:25 +02:00
										 |  |  | enum JSDebuggerState | 
					
						
							| 
									
										
										
										
											2010-10-27 17:36:39 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-10-27 18:44:25 +02:00
										 |  |  |     NoState, | 
					
						
							|  |  |  |     SteppingIntoState, | 
					
						
							|  |  |  |     SteppingOverState, | 
					
						
							|  |  |  |     SteppingOutState, | 
					
						
							|  |  |  |     StoppedState | 
					
						
							| 
									
										
										
										
											2010-07-23 12:14:24 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-27 18:44:25 +02:00
										 |  |  | struct JSAgentWatchData | 
					
						
							| 
									
										
										
										
											2010-10-27 16:56:04 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-07-22 13:00:26 +02:00
										 |  |  |     QByteArray exp; | 
					
						
							| 
									
										
										
										
											2010-10-27 16:56:04 +02:00
										 |  |  |     QByteArray name; | 
					
						
							|  |  |  |     QByteArray value; | 
					
						
							|  |  |  |     QByteArray type; | 
					
						
							| 
									
										
										
										
											2010-07-22 13:00:26 +02:00
										 |  |  |     bool hasChildren; | 
					
						
							| 
									
										
										
										
											2010-07-22 14:58:37 +02:00
										 |  |  |     quint64 objectId; | 
					
						
							| 
									
										
										
										
											2010-07-22 13:00:26 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-27 17:36:39 +02:00
										 |  |  | QDataStream &operator<<(QDataStream &s, const JSAgentWatchData &data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return s << data.exp << data.name << data.value | 
					
						
							| 
									
										
										
										
											2010-12-01 11:46:49 +01:00
										 |  |  |              << data.type << data.hasChildren << data.objectId; | 
					
						
							| 
									
										
										
										
											2010-10-27 17:36:39 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-27 18:44:25 +02:00
										 |  |  | struct JSAgentStackData | 
					
						
							| 
									
										
										
										
											2010-10-27 17:36:39 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     QByteArray functionName; | 
					
						
							|  |  |  |     QByteArray fileName; | 
					
						
							|  |  |  |     qint32 lineNumber; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QDataStream &operator<<(QDataStream &s, const JSAgentStackData &data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return s << data.functionName << data.fileName << data.lineNumber; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-28 12:18:38 +02:00
										 |  |  | struct JSAgentBreakpointData | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QByteArray functionName; | 
					
						
							|  |  |  |     QByteArray fileName; | 
					
						
							|  |  |  |     qint32 lineNumber; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef QSet<JSAgentBreakpointData> JSAgentBreakpoints; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QDataStream &operator<<(QDataStream &s, const JSAgentBreakpointData &data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return s << data.functionName << data.fileName << data.lineNumber; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QDataStream &operator>>(QDataStream &s, JSAgentBreakpointData &data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return s >> data.functionName >> data.fileName >> data.lineNumber; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool operator==(const JSAgentBreakpointData &b1, const JSAgentBreakpointData &b2) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return b1.lineNumber == b2.lineNumber && b1.fileName == b2.fileName; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | uint qHash(const JSAgentBreakpointData &b) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return b.lineNumber ^ qHash(b.fileName); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-10-27 18:44:25 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | class JSDebuggerAgentPrivate | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     JSDebuggerAgentPrivate(JSDebuggerAgent *q) | 
					
						
							|  |  |  |         : q(q), state(NoState) | 
					
						
							|  |  |  |     {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void continueExec(); | 
					
						
							|  |  |  |     void recordKnownObjects(const QList<JSAgentWatchData> &); | 
					
						
							|  |  |  |     QList<JSAgentWatchData> getLocals(QScriptContext *); | 
					
						
							|  |  |  |     void positionChange(qint64 scriptId, int lineNumber, int columnNumber); | 
					
						
							|  |  |  |     QScriptEngine *engine() { return q->engine(); } | 
					
						
							|  |  |  |     void stopped(); | 
					
						
							|  |  |  |     void messageReceived(const QByteArray &message); | 
					
						
							|  |  |  |     void sendMessage(const QByteArray &message) { q->sendMessage(message); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     JSDebuggerAgent *q; | 
					
						
							|  |  |  |     JSDebuggerState state; | 
					
						
							|  |  |  |     int stepDepth; | 
					
						
							|  |  |  |     int stepCount; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QEventLoop loop; | 
					
						
							| 
									
										
										
										
											2010-10-28 12:18:38 +02:00
										 |  |  |     QHash<qint64, QString> filenames; | 
					
						
							|  |  |  |     JSAgentBreakpoints breakpoints; | 
					
						
							| 
									
										
										
										
											2010-10-27 18:44:25 +02:00
										 |  |  |     QStringList watchExpressions; | 
					
						
							|  |  |  |     QSet<qint64> knownObjectIds; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class SetupExecEnv | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     SetupExecEnv(JSDebuggerAgentPrivate *a) | 
					
						
							|  |  |  |         : agent(a), | 
					
						
							|  |  |  |           previousState(a->state), | 
					
						
							|  |  |  |           hadException(a->engine()->hasUncaughtException()) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         agent->state = StoppedState; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ~SetupExecEnv() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (!hadException && agent->engine()->hasUncaughtException()) | 
					
						
							|  |  |  |             agent->engine()->clearExceptions(); | 
					
						
							|  |  |  |         agent->state = previousState; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |     JSDebuggerAgentPrivate *agent; | 
					
						
							|  |  |  |     JSDebuggerState previousState; | 
					
						
							|  |  |  |     bool hadException; | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2010-10-27 17:36:39 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-27 16:56:04 +02:00
										 |  |  | static JSAgentWatchData fromScriptValue(const QString &expression, | 
					
						
							| 
									
										
										
										
											2010-12-01 11:46:49 +01:00
										 |  |  |                                         const QScriptValue &value) | 
					
						
							| 
									
										
										
										
											2010-10-27 16:56:04 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     static const QString arrayStr = QCoreApplication::translate | 
					
						
							| 
									
										
										
										
											2010-12-01 11:46:49 +01:00
										 |  |  |             ("Debugger::JSAgentWatchData", "[Array of length %1]"); | 
					
						
							| 
									
										
										
										
											2010-10-27 16:56:04 +02:00
										 |  |  |     static const QString undefinedStr = QCoreApplication::translate | 
					
						
							| 
									
										
										
										
											2010-12-01 11:46:49 +01:00
										 |  |  |             ("Debugger::JSAgentWatchData", "<undefined>"); | 
					
						
							| 
									
										
										
										
											2010-10-27 16:56:04 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     JSAgentWatchData data; | 
					
						
							|  |  |  |     data.exp = expression.toUtf8(); | 
					
						
							|  |  |  |     data.name = data.exp; | 
					
						
							|  |  |  |     data.hasChildren = false; | 
					
						
							|  |  |  |     data.value = value.toString().toUtf8(); | 
					
						
							|  |  |  |     data.objectId = value.objectId(); | 
					
						
							|  |  |  |     if (value.isArray()) { | 
					
						
							|  |  |  |         data.type = "Array"; | 
					
						
							|  |  |  |         data.value = arrayStr.arg(value.property("length").toString()).toUtf8(); | 
					
						
							|  |  |  |         data.hasChildren = true; | 
					
						
							|  |  |  |     } else if (value.isBool()) { | 
					
						
							|  |  |  |         data.type = "Bool"; | 
					
						
							|  |  |  |         // data.value = value.toBool() ? "true" : "false";
 | 
					
						
							|  |  |  |     } else if (value.isDate()) { | 
					
						
							|  |  |  |         data.type = "Date"; | 
					
						
							|  |  |  |         data.value = value.toDateTime().toString().toUtf8(); | 
					
						
							|  |  |  |     } else if (value.isError()) { | 
					
						
							|  |  |  |         data.type = "Error"; | 
					
						
							|  |  |  |     } else if (value.isFunction()) { | 
					
						
							|  |  |  |         data.type = "Function"; | 
					
						
							|  |  |  |     } else if (value.isUndefined()) { | 
					
						
							|  |  |  |         data.type = undefinedStr.toUtf8(); | 
					
						
							|  |  |  |     } else if (value.isNumber()) { | 
					
						
							|  |  |  |         data.type = "Number"; | 
					
						
							|  |  |  |     } else if (value.isRegExp()) { | 
					
						
							|  |  |  |         data.type = "RegExp"; | 
					
						
							|  |  |  |     } else if (value.isString()) { | 
					
						
							|  |  |  |         data.type = "String"; | 
					
						
							|  |  |  |     } else if (value.isVariant()) { | 
					
						
							|  |  |  |         data.type = "Variant"; | 
					
						
							|  |  |  |     } else if (value.isQObject()) { | 
					
						
							|  |  |  |         const QObject *obj = value.toQObject(); | 
					
						
							|  |  |  |         data.type = "Object"; | 
					
						
							|  |  |  |         data.value += '['; | 
					
						
							|  |  |  |         data.value += obj->metaObject()->className(); | 
					
						
							|  |  |  |         data.value += ']'; | 
					
						
							|  |  |  |         data.hasChildren = true; | 
					
						
							|  |  |  |     } else if (value.isObject()) { | 
					
						
							|  |  |  |         data.type = "Object"; | 
					
						
							|  |  |  |         data.hasChildren = true; | 
					
						
							|  |  |  |         data.value = "[Object]"; | 
					
						
							|  |  |  |     } else if (value.isNull()) { | 
					
						
							|  |  |  |         data.type = "<null>"; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         data.type = "<unknown>"; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return data; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-07-22 13:00:26 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-22 14:58:37 +02:00
										 |  |  | static QList<JSAgentWatchData> expandObject(const QScriptValue &object) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QList<JSAgentWatchData> result; | 
					
						
							|  |  |  |     QScriptValueIterator it(object); | 
					
						
							| 
									
										
										
										
											2010-07-22 19:06:26 +02:00
										 |  |  |     QByteArray expPrefix = '@' + QByteArray::number(object.objectId(), 16) + "->"; | 
					
						
							| 
									
										
										
										
											2010-07-22 14:58:37 +02:00
										 |  |  |     while (it.hasNext()) { | 
					
						
							|  |  |  |         it.next(); | 
					
						
							| 
									
										
										
										
											2010-07-22 16:26:38 +02:00
										 |  |  |         if (it.flags() & QScriptValue::SkipInEnumeration) | 
					
						
							|  |  |  |             continue; | 
					
						
							| 
									
										
										
										
											2010-10-27 17:04:07 +02:00
										 |  |  |         if (/*object.isQObject() &&*/ it.value().isFunction()) { | 
					
						
							|  |  |  |             // Cosmetics: skip all functions and slot, there are too many of them,
 | 
					
						
							|  |  |  |             // and it is not useful information in the debugger.
 | 
					
						
							| 
									
										
										
										
											2010-07-22 18:21:01 +02:00
										 |  |  |             continue; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-10-27 16:56:04 +02:00
										 |  |  |         JSAgentWatchData data = fromScriptValue(it.name(), it.value()); | 
					
						
							| 
									
										
										
										
											2010-07-22 19:06:26 +02:00
										 |  |  |         data.exp.prepend(expPrefix); | 
					
						
							| 
									
										
										
										
											2010-10-27 18:03:11 +02:00
										 |  |  |         result.append(data); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (result.isEmpty()) { | 
					
						
							|  |  |  |         JSAgentWatchData data; | 
					
						
							|  |  |  |         data.name = "<no initialized data>"; | 
					
						
							|  |  |  |         data.hasChildren = false; | 
					
						
							|  |  |  |         data.value = " "; | 
					
						
							|  |  |  |         data.exp.prepend(expPrefix); | 
					
						
							|  |  |  |         data.objectId = 0; | 
					
						
							|  |  |  |         result.append(data); | 
					
						
							| 
									
										
										
										
											2010-07-22 14:58:37 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-27 18:44:25 +02:00
										 |  |  | void JSDebuggerAgentPrivate::recordKnownObjects(const QList<JSAgentWatchData>& list) | 
					
						
							| 
									
										
										
										
											2010-07-22 14:58:37 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     foreach (const JSAgentWatchData &data, list) | 
					
						
							|  |  |  |         knownObjectIds << data.objectId; | 
					
						
							| 
									
										
										
										
											2010-07-22 13:00:26 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-27 18:44:25 +02:00
										 |  |  | QList<JSAgentWatchData> JSDebuggerAgentPrivate::getLocals(QScriptContext *ctx) | 
					
						
							| 
									
										
										
										
											2010-07-23 11:07:45 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     QList<JSAgentWatchData> locals; | 
					
						
							|  |  |  |     if (ctx) { | 
					
						
							|  |  |  |         QScriptValue activationObject = ctx->activationObject(); | 
					
						
							|  |  |  |         QScriptValue thisObject = ctx->thisObject(); | 
					
						
							|  |  |  |         locals = expandObject(activationObject); | 
					
						
							| 
									
										
										
										
											2010-10-27 18:44:25 +02:00
										 |  |  |         if (thisObject.isObject() | 
					
						
							|  |  |  |                 && thisObject.objectId() != engine()->globalObject().objectId()) | 
					
						
							| 
									
										
										
										
											2010-10-27 16:56:04 +02:00
										 |  |  |             locals.prepend(fromScriptValue("this", thisObject)); | 
					
						
							| 
									
										
										
										
											2010-07-23 11:07:45 +02:00
										 |  |  |         recordKnownObjects(locals); | 
					
						
							|  |  |  |         knownObjectIds << activationObject.objectId(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return locals; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-07-22 13:00:26 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  | /*!
 | 
					
						
							|  |  |  |   Constructs a new agent for the given \a engine. The agent will | 
					
						
							|  |  |  |   report debugging-related events (e.g. step completion) to the given | 
					
						
							|  |  |  |   \a backend. | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | JSDebuggerAgent::JSDebuggerAgent(QScriptEngine *engine) | 
					
						
							| 
									
										
										
										
											2010-10-27 18:44:25 +02:00
										 |  |  |     : QDeclarativeDebugService("JSDebugger") | 
					
						
							|  |  |  |     , QScriptEngineAgent(engine) | 
					
						
							|  |  |  |     , d(new JSDebuggerAgentPrivate(this)) | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  | {} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-22 13:03:37 +02:00
										 |  |  | JSDebuggerAgent::JSDebuggerAgent(QDeclarativeEngine *engine) | 
					
						
							|  |  |  |     : QDeclarativeDebugService("JSDebugger") | 
					
						
							| 
									
										
										
										
											2010-09-27 10:46:08 +02:00
										 |  |  |     , QScriptEngineAgent(QDeclarativeDebugHelper::getScriptEngine(engine)) | 
					
						
							| 
									
										
										
										
											2010-10-27 18:44:25 +02:00
										 |  |  |     , d(new JSDebuggerAgentPrivate(this)) | 
					
						
							| 
									
										
										
										
											2010-09-22 13:03:37 +02:00
										 |  |  | {} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  | /*!
 | 
					
						
							|  |  |  |   Destroys this QScriptDebuggerAgent. | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | JSDebuggerAgent::~JSDebuggerAgent() | 
					
						
							| 
									
										
										
										
											2010-10-27 18:44:25 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     delete d; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*!
 | 
					
						
							|  |  |  |   \reimp | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2010-10-27 18:44:25 +02:00
										 |  |  | void JSDebuggerAgent::scriptLoad(qint64 id, const QString &program, | 
					
						
							|  |  |  |                                  const QString &fileName, int) | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-07-08 14:27:45 +02:00
										 |  |  |     Q_UNUSED(program); | 
					
						
							| 
									
										
										
										
											2010-10-27 18:44:25 +02:00
										 |  |  |     d->filenames.insert(id, QUrl(fileName).toLocalFile()); | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*!
 | 
					
						
							|  |  |  |   \reimp | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | void JSDebuggerAgent::scriptUnload(qint64 id) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-10-27 18:44:25 +02:00
										 |  |  |     d->filenames.remove(id); | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*!
 | 
					
						
							|  |  |  |   \reimp | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | void JSDebuggerAgent::contextPush() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*!
 | 
					
						
							|  |  |  |   \reimp | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | void JSDebuggerAgent::contextPop() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*!
 | 
					
						
							|  |  |  |   \reimp | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | void JSDebuggerAgent::functionEntry(qint64 scriptId) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Q_UNUSED(scriptId); | 
					
						
							| 
									
										
										
										
											2010-10-27 18:44:25 +02:00
										 |  |  |     d->stepDepth++; | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*!
 | 
					
						
							|  |  |  |   \reimp | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | void JSDebuggerAgent::functionExit(qint64 scriptId, const QScriptValue &returnValue) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Q_UNUSED(scriptId); | 
					
						
							|  |  |  |     Q_UNUSED(returnValue); | 
					
						
							| 
									
										
										
										
											2010-10-27 18:44:25 +02:00
										 |  |  |     d->stepDepth--; | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*!
 | 
					
						
							|  |  |  |   \reimp | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2010-12-01 11:46:49 +01:00
										 |  |  | void JSDebuggerAgent::positionChange(qint64 scriptId, int lineNumber, int columnNumber) | 
					
						
							| 
									
										
										
										
											2010-10-27 18:44:25 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     d->positionChange(scriptId, lineNumber, columnNumber); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-01 11:46:49 +01:00
										 |  |  | void JSDebuggerAgentPrivate::positionChange(qint64 scriptId, int lineNumber, int columnNumber) | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     Q_UNUSED(columnNumber); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-27 18:44:25 +02:00
										 |  |  |     if (state == StoppedState) | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  |         return; //no re-entrency
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // check breakpoints
 | 
					
						
							| 
									
										
										
										
											2010-10-28 12:18:38 +02:00
										 |  |  |     if (!breakpoints.isEmpty()) { | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  |         QHash<qint64, QString>::const_iterator it = filenames.constFind(scriptId); | 
					
						
							| 
									
										
										
										
											2010-10-27 18:44:25 +02:00
										 |  |  |         QScriptContext *ctx = engine()->currentContext(); | 
					
						
							|  |  |  |         QScriptContextInfo info(ctx); | 
					
						
							| 
									
										
										
										
											2010-07-08 15:59:30 +02:00
										 |  |  |         if (it == filenames.constEnd()) { | 
					
						
							|  |  |  |             // It is possible that the scripts are loaded before the agent is attached
 | 
					
						
							| 
									
										
										
										
											2010-10-27 18:44:25 +02:00
										 |  |  |             QString filename = QUrl(info.fileName()).toLocalFile(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             JSAgentStackData frame; | 
					
						
							|  |  |  |             frame.functionName = info.functionName().toUtf8(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-08 15:59:30 +02:00
										 |  |  |             QPair<QString, qint32> key = qMakePair(filename, lineNumber); | 
					
						
							|  |  |  |             it = filenames.insert(scriptId, filename); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-10-28 12:18:38 +02:00
										 |  |  |         JSAgentBreakpointData bp; | 
					
						
							|  |  |  |         bp.fileName = it->toUtf8(); | 
					
						
							|  |  |  |         bp.lineNumber = lineNumber; | 
					
						
							|  |  |  |         if (breakpoints.contains(bp)) { | 
					
						
							| 
									
										
										
										
											2010-07-08 15:59:30 +02:00
										 |  |  |             stopped(); | 
					
						
							|  |  |  |             return; | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     switch (state) { | 
					
						
							|  |  |  |     case NoState: | 
					
						
							| 
									
										
										
										
											2010-10-27 18:44:25 +02:00
										 |  |  |     case StoppedState: | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  |         // Do nothing
 | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case SteppingOutState: | 
					
						
							|  |  |  |         if (stepDepth >= 0) | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         //fallthough
 | 
					
						
							|  |  |  |     case SteppingOverState: | 
					
						
							|  |  |  |         if (stepDepth > 0) | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         //fallthough
 | 
					
						
							|  |  |  |     case SteppingIntoState: | 
					
						
							|  |  |  |         stopped(); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*!
 | 
					
						
							|  |  |  |   \reimp | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | void JSDebuggerAgent::exceptionThrow(qint64 scriptId, | 
					
						
							| 
									
										
										
										
											2010-12-01 11:46:49 +01:00
										 |  |  |                                      const QScriptValue &exception, | 
					
						
							|  |  |  |                                      bool hasHandler) | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     Q_UNUSED(scriptId); | 
					
						
							| 
									
										
										
										
											2010-09-07 14:34:38 +02:00
										 |  |  |     Q_UNUSED(exception); | 
					
						
							|  |  |  |     Q_UNUSED(hasHandler); | 
					
						
							| 
									
										
										
										
											2010-07-23 18:40:12 +02:00
										 |  |  | //    qDebug() << Q_FUNC_INFO << exception.toString() << hasHandler;
 | 
					
						
							| 
									
										
										
										
											2010-08-31 16:39:41 +02:00
										 |  |  | #if 0 //sometimes, we get exceptions that we should just ignore.
 | 
					
						
							| 
									
										
										
										
											2010-10-27 18:44:25 +02:00
										 |  |  |     if (!hasHandler && state != StoppedState) | 
					
						
							| 
									
										
										
										
											2010-07-23 18:40:12 +02:00
										 |  |  |         stopped(true, exception); | 
					
						
							| 
									
										
										
										
											2010-08-31 16:39:41 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*!
 | 
					
						
							|  |  |  |   \reimp | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2010-10-27 18:44:25 +02:00
										 |  |  | void JSDebuggerAgent::exceptionCatch(qint64 scriptId, const QScriptValue &exception) | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     Q_UNUSED(scriptId); | 
					
						
							|  |  |  |     Q_UNUSED(exception); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-27 18:44:25 +02:00
										 |  |  | bool JSDebuggerAgent::supportsExtension(Extension extension) const | 
					
						
							| 
									
										
										
										
											2010-07-28 16:25:09 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     return extension == QScriptEngineAgent::DebuggerInvocationRequest; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-27 18:44:25 +02:00
										 |  |  | QVariant JSDebuggerAgent::extension(Extension extension, const QVariant &argument) | 
					
						
							| 
									
										
										
										
											2010-07-28 16:25:09 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     if (extension == QScriptEngineAgent::DebuggerInvocationRequest) { | 
					
						
							| 
									
										
										
										
											2010-10-27 18:44:25 +02:00
										 |  |  |         d->stopped(); | 
					
						
							| 
									
										
										
										
											2010-07-28 16:25:09 +02:00
										 |  |  |         return QVariant(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return QScriptEngineAgent::extension(extension, argument); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-27 18:44:25 +02:00
										 |  |  | void JSDebuggerAgent::messageReceived(const QByteArray &message) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     d->messageReceived(message); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-07-28 16:25:09 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-27 18:44:25 +02:00
										 |  |  | void JSDebuggerAgentPrivate::messageReceived(const QByteArray &message) | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     QDataStream ds(message); | 
					
						
							|  |  |  |     QByteArray command; | 
					
						
							|  |  |  |     ds >> command; | 
					
						
							|  |  |  |     if (command == "BREAKPOINTS") { | 
					
						
							| 
									
										
										
										
											2010-10-28 12:18:38 +02:00
										 |  |  |         ds >> breakpoints; | 
					
						
							|  |  |  |         //qDebug() << "BREAKPOINTS";
 | 
					
						
							|  |  |  |         //foreach (const JSAgentBreakpointData &bp, breakpoints)
 | 
					
						
							|  |  |  |         //    qDebug() << "BREAKPOINT: " << bp.fileName << bp.lineNumber;
 | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  |     } else if (command == "WATCH_EXPRESSIONS") { | 
					
						
							|  |  |  |         ds >> watchExpressions; | 
					
						
							|  |  |  |     } else if (command == "STEPOVER") { | 
					
						
							|  |  |  |         stepDepth = 0; | 
					
						
							|  |  |  |         state = SteppingOverState; | 
					
						
							|  |  |  |         continueExec(); | 
					
						
							|  |  |  |     } else if (command == "STEPINTO" || command == "INTERRUPT") { | 
					
						
							|  |  |  |         stepDepth = 0; | 
					
						
							|  |  |  |         state = SteppingIntoState; | 
					
						
							|  |  |  |         continueExec(); | 
					
						
							|  |  |  |     } else if (command == "STEPOUT") { | 
					
						
							|  |  |  |         stepDepth = 0; | 
					
						
							|  |  |  |         state = SteppingOutState; | 
					
						
							|  |  |  |         continueExec(); | 
					
						
							|  |  |  |     } else if (command == "CONTINUE") { | 
					
						
							|  |  |  |         state = NoState; | 
					
						
							|  |  |  |         continueExec(); | 
					
						
							|  |  |  |     } else if (command == "EXEC") { | 
					
						
							| 
									
										
										
										
											2010-07-23 12:14:24 +02:00
										 |  |  |         SetupExecEnv execEnv(this); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  |         QByteArray id; | 
					
						
							|  |  |  |         QString expr; | 
					
						
							|  |  |  |         ds >> id >> expr; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-27 16:56:04 +02:00
										 |  |  |         JSAgentWatchData data = fromScriptValue(expr, engine()->evaluate(expr)); | 
					
						
							| 
									
										
										
										
											2010-07-22 14:58:37 +02:00
										 |  |  |         knownObjectIds << data.objectId; | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         QByteArray reply; | 
					
						
							|  |  |  |         QDataStream rs(&reply, QIODevice::WriteOnly); | 
					
						
							| 
									
										
										
										
											2010-07-22 13:00:26 +02:00
										 |  |  |         rs << QByteArray("RESULT") << id << data; | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  |         sendMessage(reply); | 
					
						
							| 
									
										
										
										
											2010-07-22 14:58:37 +02:00
										 |  |  |     } else if (command == "EXPAND") { | 
					
						
							| 
									
										
										
										
											2010-07-23 12:14:24 +02:00
										 |  |  |         SetupExecEnv execEnv(this); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-22 14:58:37 +02:00
										 |  |  |         QByteArray requestId; | 
					
						
							|  |  |  |         quint64 objectId; | 
					
						
							|  |  |  |         ds >> requestId >> objectId; | 
					
						
							|  |  |  |         QScriptValue v; | 
					
						
							|  |  |  |         if (knownObjectIds.contains(objectId)) | 
					
						
							|  |  |  |             v = engine()->objectById(objectId); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         QList<JSAgentWatchData> result = expandObject(v); | 
					
						
							|  |  |  |         recordKnownObjects(result); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         QByteArray reply; | 
					
						
							|  |  |  |         QDataStream rs(&reply, QIODevice::WriteOnly); | 
					
						
							|  |  |  |         rs << QByteArray("EXPANDED") << requestId << result; | 
					
						
							|  |  |  |         sendMessage(reply); | 
					
						
							| 
									
										
										
										
											2010-07-23 12:14:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-22 15:22:46 +02:00
										 |  |  |     } else if (command == "ACTIVATE_FRAME") { | 
					
						
							| 
									
										
										
										
											2010-07-23 12:14:24 +02:00
										 |  |  |         SetupExecEnv execEnv(this); | 
					
						
							| 
									
										
										
										
											2010-07-22 15:22:46 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         int frameId; | 
					
						
							|  |  |  |         ds >> frameId; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         int deep = 0; | 
					
						
							|  |  |  |         QScriptContext *ctx = engine()->currentContext(); | 
					
						
							|  |  |  |         while (ctx && deep < frameId) { | 
					
						
							|  |  |  |             ctx = ctx->parentContext(); | 
					
						
							|  |  |  |             deep++; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-23 11:07:45 +02:00
										 |  |  |         QList<JSAgentWatchData> locals = getLocals(ctx); | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-22 15:22:46 +02:00
										 |  |  |         QByteArray reply; | 
					
						
							|  |  |  |         QDataStream rs(&reply, QIODevice::WriteOnly); | 
					
						
							|  |  |  |         rs << QByteArray("LOCALS") << frameId << locals; | 
					
						
							|  |  |  |         sendMessage(reply); | 
					
						
							| 
									
										
										
										
											2010-07-22 19:06:26 +02:00
										 |  |  |     } else if (command == "SET_PROPERTY") { | 
					
						
							| 
									
										
										
										
											2010-07-23 12:14:24 +02:00
										 |  |  |         SetupExecEnv execEnv(this); | 
					
						
							| 
									
										
										
										
											2010-07-22 19:06:26 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         QByteArray id; | 
					
						
							|  |  |  |         qint64 objectId; | 
					
						
							|  |  |  |         QString property; | 
					
						
							|  |  |  |         QString value; | 
					
						
							|  |  |  |         ds >> id >> objectId >> property >> value; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (knownObjectIds.contains(objectId)) { | 
					
						
							|  |  |  |             QScriptValue object; | 
					
						
							|  |  |  |             object = engine()->objectById(objectId); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-27 17:04:07 +02:00
										 |  |  |             if (object.isObject()) { | 
					
						
							| 
									
										
										
										
											2010-07-22 19:06:26 +02:00
										 |  |  |                 QScriptValue result = engine()->evaluate(value); | 
					
						
							|  |  |  |                 object.setProperty(property, result); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-07-23 12:14:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-22 19:06:26 +02:00
										 |  |  |         //TODO: feedback
 | 
					
						
							| 
									
										
										
										
											2010-07-23 11:30:07 +02:00
										 |  |  |     } else if (command == "PING") { | 
					
						
							|  |  |  |         int ping; | 
					
						
							|  |  |  |         ds >> ping; | 
					
						
							|  |  |  |         QByteArray reply; | 
					
						
							|  |  |  |         QDataStream rs(&reply, QIODevice::WriteOnly); | 
					
						
							|  |  |  |         rs << QByteArray("PONG") << ping; | 
					
						
							|  |  |  |         sendMessage(reply); | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  |     } else { | 
					
						
							|  |  |  |         qDebug() << Q_FUNC_INFO << "Unknown command" << command; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-27 18:44:25 +02:00
										 |  |  |     q->baseMessageReceived(message); | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-27 18:44:25 +02:00
										 |  |  | void JSDebuggerAgentPrivate::stopped() | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-10-27 18:44:25 +02:00
										 |  |  |     bool becauseOfException = false; | 
					
						
							|  |  |  |     const QScriptValue &exception = QScriptValue(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-22 14:58:37 +02:00
										 |  |  |     knownObjectIds.clear(); | 
					
						
							| 
									
										
										
										
											2010-10-27 18:44:25 +02:00
										 |  |  |     state = StoppedState; | 
					
						
							| 
									
										
										
										
											2010-10-27 17:36:39 +02:00
										 |  |  |     QList<JSAgentStackData> backtrace; | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     for (QScriptContext* ctx = engine()->currentContext(); ctx; ctx = ctx->parentContext()) { | 
					
						
							|  |  |  |         QScriptContextInfo info(ctx); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-27 17:36:39 +02:00
										 |  |  |         JSAgentStackData frame; | 
					
						
							|  |  |  |         frame.functionName = info.functionName().toUtf8(); | 
					
						
							|  |  |  |         if (frame.functionName.isEmpty()) { | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  |             if (ctx->parentContext()) { | 
					
						
							|  |  |  |                 switch (info.functionType()) { | 
					
						
							|  |  |  |                 case QScriptContextInfo::ScriptFunction: | 
					
						
							| 
									
										
										
										
											2010-10-27 17:36:39 +02:00
										 |  |  |                     frame.functionName = "<anonymous>"; | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  |                     break; | 
					
						
							|  |  |  |                 case QScriptContextInfo::NativeFunction: | 
					
						
							| 
									
										
										
										
											2010-10-27 17:36:39 +02:00
										 |  |  |                     frame.functionName = "<native>"; | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  |                     break; | 
					
						
							|  |  |  |                 case QScriptContextInfo::QtFunction: | 
					
						
							|  |  |  |                 case QScriptContextInfo::QtPropertyFunction: | 
					
						
							| 
									
										
										
										
											2010-10-27 17:36:39 +02:00
										 |  |  |                     frame.functionName = "<native slot>"; | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  |                     break; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } else { | 
					
						
							| 
									
										
										
										
											2010-10-27 17:36:39 +02:00
										 |  |  |                 frame.functionName = "<global>"; | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-10-27 17:36:39 +02:00
										 |  |  |         frame.lineNumber = info.lineNumber(); | 
					
						
							|  |  |  |         // if the line number is unknown, fallback to the function line number
 | 
					
						
							|  |  |  |         if (frame.lineNumber == -1) | 
					
						
							|  |  |  |             frame.lineNumber = info.functionStartLineNumber(); | 
					
						
							|  |  |  |         frame.fileName = QUrl(info.fileName()).toLocalFile().toUtf8(); | 
					
						
							|  |  |  |         backtrace.append(frame); | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-07-22 13:00:26 +02:00
										 |  |  |     QList<JSAgentWatchData> watches; | 
					
						
							| 
									
										
										
										
											2010-07-22 14:58:37 +02:00
										 |  |  |     foreach (const QString &expr, watchExpressions) | 
					
						
							| 
									
										
										
										
											2010-10-27 17:36:39 +02:00
										 |  |  |         watches << fromScriptValue(expr, engine()->evaluate(expr)); | 
					
						
							| 
									
										
										
										
											2010-07-22 14:58:37 +02:00
										 |  |  |     recordKnownObjects(watches); | 
					
						
							| 
									
										
										
										
											2010-07-23 11:07:45 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     QList<JSAgentWatchData> locals = getLocals(engine()->currentContext()); | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-23 18:40:12 +02:00
										 |  |  |     if (!becauseOfException) { | 
					
						
							|  |  |  |         // Clear any exceptions occurred during locals evaluation.
 | 
					
						
							|  |  |  |         engine()->clearExceptions(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     QByteArray reply; | 
					
						
							|  |  |  |     QDataStream rs(&reply, QIODevice::WriteOnly); | 
					
						
							| 
									
										
										
										
											2010-10-27 17:36:39 +02:00
										 |  |  |     rs << QByteArray("STOPPED") << backtrace << watches << locals | 
					
						
							| 
									
										
										
										
											2010-12-01 11:46:49 +01:00
										 |  |  |        << becauseOfException << exception.toString(); | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  |     sendMessage(reply); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     loop.exec(QEventLoop::ExcludeUserInputEvents); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-27 18:44:25 +02:00
										 |  |  | void JSDebuggerAgentPrivate::continueExec() | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     loop.quit(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-27 10:25:01 +02:00
										 |  |  | void JSDebuggerAgent::statusChanged(Status status) | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-09-27 10:25:01 +02:00
										 |  |  |     engine()->setAgent((status == QDeclarativeDebugService::Enabled) ? this : 0); | 
					
						
							| 
									
										
										
										
											2010-07-08 14:23:33 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-01 11:46:49 +01:00
										 |  |  | void JSDebuggerAgent::baseMessageReceived(const QByteArray &message) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QDeclarativeDebugService::messageReceived(message); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-22 09:59:18 +02:00
										 |  |  | } // namespace QmlJSDebugger
 |