source: branches/4.5.1/src/scripttools/debugging/qscriptdebuggercommandexecutor.cpp@ 559

Last change on this file since 559 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.3 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 QtSCriptTools 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 "qscriptdebuggercommandexecutor_p.h"
43
44#include "qscriptdebuggerbackend_p.h"
45#include "qscriptdebuggercommand_p.h"
46#include "qscriptdebuggerresponse_p.h"
47#include "qscriptdebuggervalue_p.h"
48#include "qscriptdebuggervalueproperty_p.h"
49#include "qscriptbreakpointdata_p.h"
50#include "qscriptobjectsnapshot_p.h"
51#include "qscriptdebuggerobjectsnapshotdelta_p.h"
52
53#include <QtCore/qstringlist.h>
54#include <QtScript/qscriptengine.h>
55#include <QtScript/qscriptcontextinfo.h>
56#include <QtScript/qscriptvalueiterator.h>
57#include <QtCore/qdebug.h>
58
59Q_DECLARE_METATYPE(QScriptScriptsDelta)
60Q_DECLARE_METATYPE(QScriptDebuggerValueProperty)
61Q_DECLARE_METATYPE(QScriptDebuggerValuePropertyList)
62Q_DECLARE_METATYPE(QScriptDebuggerObjectSnapshotDelta)
63
64QT_BEGIN_NAMESPACE
65
66/*!
67 \since 4.5
68 \class QScriptDebuggerCommandExecutor
69 \internal
70
71 \brief The QScriptDebuggerCommandExecutor applies debugger commands to a back-end.
72
73 The execute() function takes a command (typically produced by a
74 QScriptDebuggerFrontend) and applies it to a QScriptDebuggerBackend.
75
76 \sa QScriptDebuggerCommmand
77*/
78
79class QScriptDebuggerCommandExecutorPrivate
80{
81public:
82 QScriptDebuggerCommandExecutorPrivate();
83 ~QScriptDebuggerCommandExecutorPrivate();
84};
85
86QScriptDebuggerCommandExecutorPrivate::QScriptDebuggerCommandExecutorPrivate()
87{
88}
89
90QScriptDebuggerCommandExecutorPrivate::~QScriptDebuggerCommandExecutorPrivate()
91{
92}
93
94QScriptDebuggerCommandExecutor::QScriptDebuggerCommandExecutor()
95 : d_ptr(new QScriptDebuggerCommandExecutorPrivate())
96{
97}
98
99QScriptDebuggerCommandExecutor::~QScriptDebuggerCommandExecutor()
100{
101 delete d_ptr;
102}
103
104/*!
105 Applies the given \a command to the given \a backend.
106*/
107QScriptDebuggerResponse QScriptDebuggerCommandExecutor::execute(
108 QScriptDebuggerBackend *backend,
109 const QScriptDebuggerCommand &command)
110{
111 QScriptDebuggerResponse response;
112 switch (command.type()) {
113 case QScriptDebuggerCommand::None:
114 break;
115
116 case QScriptDebuggerCommand::Interrupt:
117 backend->interruptEvaluation();
118 break;
119
120 case QScriptDebuggerCommand::Continue:
121 if (backend->engine()->isEvaluating()) {
122 backend->continueEvalution();
123 response.setAsync(true);
124 }
125 break;
126
127 case QScriptDebuggerCommand::StepInto: {
128 QVariant attr = command.attribute(QScriptDebuggerCommand::StepCount);
129 int count = attr.isValid() ? attr.toInt() : 1;
130 backend->stepInto(count);
131 response.setAsync(true);
132 } break;
133
134 case QScriptDebuggerCommand::StepOver: {
135 QVariant attr = command.attribute(QScriptDebuggerCommand::StepCount);
136 int count = attr.isValid() ? attr.toInt() : 1;
137 backend->stepOver(count);
138 response.setAsync(true);
139 } break;
140
141 case QScriptDebuggerCommand::StepOut:
142 backend->stepOut();
143 response.setAsync(true);
144 break;
145
146 case QScriptDebuggerCommand::RunToLocation:
147 backend->runToLocation(command.fileName(), command.lineNumber());
148 response.setAsync(true);
149 break;
150
151 case QScriptDebuggerCommand::RunToLocationByID:
152 backend->runToLocation(command.scriptId(), command.lineNumber());
153 response.setAsync(true);
154 break;
155
156 case QScriptDebuggerCommand::ForceReturn: {
157 int contextIndex = command.contextIndex();
158 QScriptDebuggerValue value = command.scriptValue();
159 QScriptEngine *engine = backend->engine();
160 QScriptValue realValue = value.toScriptValue(engine);
161 backend->returnToCaller(contextIndex, realValue);
162 response.setAsync(true);
163 } break;
164
165 case QScriptDebuggerCommand::Resume:
166 backend->resume();
167 response.setAsync(true);
168 break;
169
170 case QScriptDebuggerCommand::SetBreakpoint: {
171 QScriptBreakpointData data = command.breakpointData();
172 if (!data.isValid())
173 data = QScriptBreakpointData(command.fileName(), command.lineNumber());
174 int id = backend->setBreakpoint(data);
175 response.setResult(id);
176 } break;
177
178 case QScriptDebuggerCommand::DeleteBreakpoint: {
179 int id = command.breakpointId();
180 if (!backend->deleteBreakpoint(id))
181 response.setError(QScriptDebuggerResponse::InvalidBreakpointID);
182 } break;
183
184 case QScriptDebuggerCommand::DeleteAllBreakpoints:
185 backend->deleteAllBreakpoints();
186 break;
187
188 case QScriptDebuggerCommand::GetBreakpoints: {
189 QScriptBreakpointMap bps = backend->breakpoints();
190 if (!bps.isEmpty())
191 response.setResult(bps);
192 } break;
193
194 case QScriptDebuggerCommand::GetBreakpointData: {
195 int id = command.breakpointId();
196 QScriptBreakpointData data = backend->breakpointData(id);
197 if (data.isValid())
198 response.setResult(data);
199 else
200 response.setError(QScriptDebuggerResponse::InvalidBreakpointID);
201 } break;
202
203 case QScriptDebuggerCommand::SetBreakpointData: {
204 int id = command.breakpointId();
205 QScriptBreakpointData data = command.breakpointData();
206 if (!backend->setBreakpointData(id, data))
207 response.setError(QScriptDebuggerResponse::InvalidBreakpointID);
208 } break;
209
210 case QScriptDebuggerCommand::GetScripts: {
211 QScriptScriptMap scripts = backend->scripts();
212 if (!scripts.isEmpty())
213 response.setResult(scripts);
214 } break;
215
216 case QScriptDebuggerCommand::GetScriptData: {
217 qint64 id = command.scriptId();
218 QScriptScriptData data = backend->scriptData(id);
219 if (data.isValid())
220 response.setResult(data);
221 else
222 response.setError(QScriptDebuggerResponse::InvalidScriptID);
223 } break;
224
225 case QScriptDebuggerCommand::ScriptsCheckpoint:
226 backend->scriptsCheckpoint();
227 response.setResult(qVariantFromValue(backend->scriptsDelta()));
228 break;
229
230 case QScriptDebuggerCommand::GetScriptsDelta:
231 response.setResult(qVariantFromValue(backend->scriptsDelta()));
232 break;
233
234 case QScriptDebuggerCommand::ResolveScript:
235 response.setResult(backend->resolveScript(command.fileName()));
236 break;
237
238 case QScriptDebuggerCommand::GetBacktrace:
239 response.setResult(backend->backtrace());
240 break;
241
242 case QScriptDebuggerCommand::GetContextCount:
243 response.setResult(backend->contextCount());
244 break;
245
246 case QScriptDebuggerCommand::GetContextState: {
247 QScriptContext *ctx = backend->context(command.contextIndex());
248 if (ctx)
249 response.setResult(static_cast<int>(ctx->state()));
250 else
251 response.setError(QScriptDebuggerResponse::InvalidContextIndex);
252 } break;
253
254 case QScriptDebuggerCommand::GetContextID: {
255 int idx = command.contextIndex();
256 if ((idx >= 0) && (idx < backend->contextCount()))
257 response.setResult(backend->contextIds()[idx]);
258 else
259 response.setError(QScriptDebuggerResponse::InvalidContextIndex);
260 } break;
261
262 case QScriptDebuggerCommand::GetContextInfo: {
263 QScriptContext *ctx = backend->context(command.contextIndex());
264 if (ctx)
265 response.setResult(QScriptContextInfo(ctx));
266 else
267 response.setError(QScriptDebuggerResponse::InvalidContextIndex);
268 } break;
269
270 case QScriptDebuggerCommand::GetThisObject: {
271 QScriptContext *ctx = backend->context(command.contextIndex());
272 if (ctx)
273 response.setResult(ctx->thisObject());
274 else
275 response.setError(QScriptDebuggerResponse::InvalidContextIndex);
276 } break;
277
278 case QScriptDebuggerCommand::GetActivationObject: {
279 QScriptContext *ctx = backend->context(command.contextIndex());
280 if (ctx)
281 response.setResult(ctx->activationObject());
282 else
283 response.setError(QScriptDebuggerResponse::InvalidContextIndex);
284 } break;
285
286 case QScriptDebuggerCommand::GetScopeChain: {
287 QScriptContext *ctx = backend->context(command.contextIndex());
288 if (ctx) {
289 QScriptDebuggerValueList dest;
290#if QT_VERSION >= 0x040500
291 QScriptValueList src = ctx->scopeChain();
292 for (int i = 0; i < src.size(); ++i)
293 dest.append(src.at(i));
294#else
295 dest.append(ctx->activationObject());
296#endif
297 response.setResult(dest);
298 } else {
299 response.setError(QScriptDebuggerResponse::InvalidContextIndex);
300 }
301 } break;
302
303 case QScriptDebuggerCommand::ContextsCheckpoint: {
304 response.setResult(qVariantFromValue(backend->contextsCheckpoint()));
305 } break;
306
307 case QScriptDebuggerCommand::NewScriptObjectSnapshot: {
308 int id = backend->newScriptObjectSnapshot();
309 response.setResult(id);
310 } break;
311
312 case QScriptDebuggerCommand::ScriptObjectSnapshotCapture: {
313 int id = command.snapshotId();
314 QScriptObjectSnapshot *snap = backend->scriptObjectSnapshot(id);
315 Q_ASSERT(snap != 0);
316 QScriptDebuggerValue object = command.scriptValue();
317 Q_ASSERT(object.type() == QScriptDebuggerValue::ObjectValue);
318 QScriptEngine *engine = backend->engine();
319 QScriptValue realObject = object.toScriptValue(engine);
320 Q_ASSERT(realObject.isObject());
321 QScriptObjectSnapshot::Delta delta = snap->capture(realObject);
322 QScriptDebuggerObjectSnapshotDelta result;
323 result.removedProperties = delta.removedProperties;
324 bool didIgnoreExceptions = backend->ignoreExceptions();
325 backend->setIgnoreExceptions(true);
326 for (int i = 0; i < delta.changedProperties.size(); ++i) {
327 const QScriptValueProperty &src = delta.changedProperties.at(i);
328 bool hadException = engine->hasUncaughtException();
329 QString str = src.value().toString();
330 if (!hadException && engine->hasUncaughtException())
331 engine->clearExceptions();
332 QScriptDebuggerValueProperty dest(src.name(), src.value(), str, src.flags());
333 result.changedProperties.append(dest);
334 }
335 for (int j = 0; j < delta.addedProperties.size(); ++j) {
336 const QScriptValueProperty &src = delta.addedProperties.at(j);
337 bool hadException = engine->hasUncaughtException();
338 QString str = src.value().toString();
339 if (!hadException && engine->hasUncaughtException())
340 engine->clearExceptions();
341 QScriptDebuggerValueProperty dest(src.name(), src.value(), str, src.flags());
342 result.addedProperties.append(dest);
343 }
344 backend->setIgnoreExceptions(didIgnoreExceptions);
345 response.setResult(qVariantFromValue(result));
346 } break;
347
348 case QScriptDebuggerCommand::DeleteScriptObjectSnapshot: {
349 int id = command.snapshotId();
350 backend->deleteScriptObjectSnapshot(id);
351 } break;
352
353 case QScriptDebuggerCommand::NewScriptValueIterator: {
354 QScriptDebuggerValue object = command.scriptValue();
355 Q_ASSERT(object.type() == QScriptDebuggerValue::ObjectValue);
356 QScriptEngine *engine = backend->engine();
357 QScriptValue realObject = object.toScriptValue(engine);
358 Q_ASSERT(realObject.isObject());
359 int id = backend->newScriptValueIterator(realObject);
360 response.setResult(id);
361 } break;
362
363 case QScriptDebuggerCommand::GetPropertiesByIterator: {
364 int id = command.iteratorId();
365 int count = 1000;
366 QScriptValueIterator *it = backend->scriptValueIterator(id);
367 Q_ASSERT(it != 0);
368 QScriptDebuggerValuePropertyList props;
369 for (int i = 0; (i < count) && it->hasNext(); ++i) {
370 it->next();
371 QString name = it->name();
372 QScriptValue value = it->value();
373 QString valueAsString = value.toString();
374 QScriptValue::PropertyFlags flags = it->flags();
375 QScriptDebuggerValueProperty prp(name, value, valueAsString, flags);
376 props.append(prp);
377 }
378 response.setResult(props);
379 } break;
380
381 case QScriptDebuggerCommand::DeleteScriptValueIterator: {
382 int id = command.iteratorId();
383 backend->deleteScriptValueIterator(id);
384 } break;
385
386 case QScriptDebuggerCommand::Evaluate: {
387 int contextIndex = command.contextIndex();
388 QString program = command.program();
389 QString fileName = command.fileName();
390 int lineNumber = command.lineNumber();
391 backend->evaluate(contextIndex, program, fileName, lineNumber);
392 response.setAsync(true);
393 } break;
394
395 case QScriptDebuggerCommand::ScriptValueToString: {
396 QScriptDebuggerValue value = command.scriptValue();
397 QScriptEngine *engine = backend->engine();
398 QScriptValue realValue = value.toScriptValue(engine);
399 response.setResult(realValue.toString());
400 } break;
401
402 case QScriptDebuggerCommand::SetScriptValueProperty: {
403 QScriptDebuggerValue object = command.scriptValue();
404 QScriptEngine *engine = backend->engine();
405 QScriptValue realObject = object.toScriptValue(engine);
406 QScriptDebuggerValue value = command.subordinateScriptValue();
407 QScriptValue realValue = value.toScriptValue(engine);
408 QString name = command.name();
409 realObject.setProperty(name, realValue);
410 } break;
411
412 case QScriptDebuggerCommand::ClearExceptions:
413 backend->engine()->clearExceptions();
414 break;
415
416 case QScriptDebuggerCommand::UserCommand:
417 case QScriptDebuggerCommand::MaxUserCommand:
418 break;
419 }
420 return response;
421}
422
423QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.