source: trunk/src/scripttools/debugging/qscriptdebuggerscriptedconsolecommand.cpp@ 1054

Last change on this file since 1054 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 14.6 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtSCriptTools module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this 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 have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qscriptdebuggerscriptedconsolecommand_p.h"
43#include "qscriptdebuggerconsolecommand_p_p.h"
44#include "qscriptdebuggerconsolecommandjob_p.h"
45#include "qscriptdebuggerconsolecommandjob_p_p.h"
46#include "qscriptmessagehandlerinterface_p.h"
47#include "qscriptdebuggerconsoleglobalobject_p.h"
48#include "qscriptdebuggerresponse_p.h"
49#include "qscriptdebuggercommandschedulerinterface_p.h"
50
51#include <QtCore/qstring.h>
52#include <QtCore/qstringlist.h>
53#include <QtScript/qscriptengine.h>
54#include <QtScript/qscriptvalue.h>
55#include <QtScript/qscriptvalueiterator.h>
56#include <QtScript/qscriptcontextinfo.h>
57#include <QtCore/qdebug.h>
58
59Q_DECLARE_METATYPE(QScriptDebuggerResponse)
60
61QT_BEGIN_NAMESPACE
62
63/*!
64 \since 4.5
65 \class QScriptDebuggerScriptedConsoleCommand
66 \internal
67
68 \brief The QScriptDebuggerScriptedConsoleCommand class encapsulates a command defined in a script.
69*/
70
71class QScriptDebuggerScriptedConsoleCommandPrivate
72 : public QScriptDebuggerConsoleCommandPrivate
73{
74 Q_DECLARE_PUBLIC(QScriptDebuggerScriptedConsoleCommand)
75public:
76 QScriptDebuggerScriptedConsoleCommandPrivate();
77 ~QScriptDebuggerScriptedConsoleCommandPrivate();
78
79 QString name;
80 QString group;
81 QString shortDescription;
82 QString longDescription;
83 QStringList aliases;
84 QStringList seeAlso;
85 QStringList argumentTypes;
86 QStringList subCommands;
87 QScriptValue globalObject;
88 QScriptValue execFunction;
89 QScriptValue responseFunction;
90};
91
92QScriptDebuggerScriptedConsoleCommandPrivate::QScriptDebuggerScriptedConsoleCommandPrivate()
93{
94}
95
96QScriptDebuggerScriptedConsoleCommandPrivate::~QScriptDebuggerScriptedConsoleCommandPrivate()
97{
98}
99
100QScriptDebuggerScriptedConsoleCommand::QScriptDebuggerScriptedConsoleCommand(
101 const QString &name, const QString &group,
102 const QString &shortDescription, const QString &longDescription,
103 const QStringList &aliases, const QStringList &seeAlso,
104 const QStringList &argumentTypes, const QStringList &subCommands,
105 const QScriptValue &globalObject,
106 const QScriptValue &execFunction, const QScriptValue &responseFunction)
107 : QScriptDebuggerConsoleCommand(*new QScriptDebuggerScriptedConsoleCommandPrivate)
108{
109 Q_D(QScriptDebuggerScriptedConsoleCommand);
110 d->name = name;
111 d->group = group;
112 d->shortDescription = shortDescription;
113 d->longDescription = longDescription;
114 d->aliases = aliases;
115 d->seeAlso = seeAlso;
116 d->argumentTypes = argumentTypes;
117 d->subCommands = subCommands;
118 d->globalObject = globalObject;
119 d->execFunction = execFunction;
120 d->responseFunction = responseFunction;
121}
122
123QScriptDebuggerScriptedConsoleCommand::~QScriptDebuggerScriptedConsoleCommand()
124{
125}
126
127class QScriptDebuggerScriptedConsoleCommandJobPrivate;
128class QScriptDebuggerScriptedConsoleCommandJob
129 : public QScriptDebuggerConsoleCommandJob,
130 public QScriptDebuggerCommandSchedulerInterface
131{
132public:
133 QScriptDebuggerScriptedConsoleCommandJob(
134 QScriptDebuggerScriptedConsoleCommandPrivate *command,
135 const QStringList &arguments,
136 QScriptDebuggerConsole *console,
137 QScriptMessageHandlerInterface *messageHandler,
138 QScriptDebuggerCommandSchedulerInterface *commandScheduler);
139 ~QScriptDebuggerScriptedConsoleCommandJob();
140
141 int scheduleCommand(
142 const QScriptDebuggerCommand &command,
143 QScriptDebuggerResponseHandlerInterface *responseHandler);
144
145 void start();
146 void handleResponse(const QScriptDebuggerResponse &response,
147 int commandId);
148
149private:
150 Q_DECLARE_PRIVATE(QScriptDebuggerScriptedConsoleCommandJob)
151 Q_DISABLE_COPY(QScriptDebuggerScriptedConsoleCommandJob)
152};
153
154class QScriptDebuggerScriptedConsoleCommandJobPrivate
155 : public QScriptDebuggerConsoleCommandJobPrivate
156{
157public:
158 QScriptDebuggerScriptedConsoleCommandJobPrivate() : command(0), commandCount(0) {}
159 ~QScriptDebuggerScriptedConsoleCommandJobPrivate() {}
160
161 QScriptDebuggerScriptedConsoleCommandPrivate *command;
162 QStringList arguments;
163 int commandCount;
164};
165
166QScriptDebuggerScriptedConsoleCommandJob::QScriptDebuggerScriptedConsoleCommandJob(
167 QScriptDebuggerScriptedConsoleCommandPrivate *command,
168 const QStringList &arguments,
169 QScriptDebuggerConsole *console,
170 QScriptMessageHandlerInterface *messageHandler,
171 QScriptDebuggerCommandSchedulerInterface *commandScheduler)
172 : QScriptDebuggerConsoleCommandJob(*new QScriptDebuggerScriptedConsoleCommandJobPrivate,
173 console, messageHandler, commandScheduler)
174{
175 Q_D(QScriptDebuggerScriptedConsoleCommandJob);
176 d->command = command;
177 d->arguments = arguments;
178}
179
180QScriptDebuggerScriptedConsoleCommandJob::~QScriptDebuggerScriptedConsoleCommandJob()
181{
182}
183
184int QScriptDebuggerScriptedConsoleCommandJob::scheduleCommand(
185 const QScriptDebuggerCommand &command,
186 QScriptDebuggerResponseHandlerInterface *responseHandler)
187{
188 Q_D(QScriptDebuggerScriptedConsoleCommandJob);
189 ++d->commandCount;
190 return commandScheduler()->scheduleCommand(command, responseHandler);
191}
192
193void QScriptDebuggerScriptedConsoleCommandJob::start()
194{
195 Q_D(QScriptDebuggerScriptedConsoleCommandJob);
196 QScriptEngine *engine = d->command->globalObject.engine();
197 engine->setGlobalObject(d->command->globalObject);
198 QScriptValueList args;
199 for (int i = 0; i < d->arguments.size(); ++i)
200 args.append(QScriptValue(engine, d->arguments.at(i)));
201 QScriptDebuggerConsoleGlobalObject *global;
202 global = qobject_cast<QScriptDebuggerConsoleGlobalObject*>(engine->globalObject().toQObject());
203 Q_ASSERT(global != 0);
204 global->setScheduler(this);
205 global->setResponseHandler(this);
206 global->setMessageHandler(d->messageHandler);
207 global->setConsole(d->console);
208 d->commandCount = 0;
209 QScriptValue ret = d->command->execFunction.call(QScriptValue(), args);
210 global->setScheduler(0);
211 global->setResponseHandler(0);
212 global->setMessageHandler(0);
213 global->setConsole(0);
214 if (ret.isError()) {
215 qWarning("*** internal error: %s", qPrintable(ret.toString()));
216 }
217 if (d->commandCount == 0)
218 finish();
219}
220
221void QScriptDebuggerScriptedConsoleCommandJob::handleResponse(
222 const QScriptDebuggerResponse &response,
223 int commandId)
224{
225 Q_D(QScriptDebuggerScriptedConsoleCommandJob);
226 // ### generalize
227 QScriptEngine *engine = d->command->globalObject.engine();
228 engine->setGlobalObject(d->command->globalObject);
229 QScriptValueList args;
230 args.append(qScriptValueFromValue(engine, response));
231 args.append(QScriptValue(engine, commandId));
232 QScriptDebuggerConsoleGlobalObject *global;
233 global = qobject_cast<QScriptDebuggerConsoleGlobalObject*>(d->command->globalObject.toQObject());
234 Q_ASSERT(global != 0);
235 global->setScheduler(this);
236 global->setResponseHandler(this);
237 global->setMessageHandler(d->messageHandler);
238 global->setConsole(d->console);
239 d->commandCount = 0;
240 QScriptValue ret = d->command->responseFunction.call(QScriptValue(), args);
241 global->setScheduler(0);
242 global->setResponseHandler(0);
243 global->setMessageHandler(0);
244 global->setConsole(0);
245 if (ret.isError()) {
246 qWarning("*** internal error: %s", qPrintable(ret.toString()));
247 }
248 if (d->commandCount == 0)
249 finish();
250}
251
252/*!
253 \internal
254*/
255QString QScriptDebuggerScriptedConsoleCommand::name() const
256{
257 Q_D(const QScriptDebuggerScriptedConsoleCommand);
258 return d->name;
259}
260
261/*!
262 \internal
263*/
264QString QScriptDebuggerScriptedConsoleCommand::group() const
265{
266 Q_D(const QScriptDebuggerScriptedConsoleCommand);
267 return d->group;
268}
269
270/*!
271 \internal
272*/
273QString QScriptDebuggerScriptedConsoleCommand::shortDescription() const
274{
275 Q_D(const QScriptDebuggerScriptedConsoleCommand);
276 return d->shortDescription;
277}
278
279/*!
280 \internal
281*/
282QString QScriptDebuggerScriptedConsoleCommand::longDescription() const
283{
284 Q_D(const QScriptDebuggerScriptedConsoleCommand);
285 return d->longDescription;
286}
287
288/*!
289 \internal
290*/
291QStringList QScriptDebuggerScriptedConsoleCommand::aliases() const
292{
293 Q_D(const QScriptDebuggerScriptedConsoleCommand);
294 return d->aliases;
295}
296
297/*!
298 \internal
299*/
300QStringList QScriptDebuggerScriptedConsoleCommand::seeAlso() const
301{
302 Q_D(const QScriptDebuggerScriptedConsoleCommand);
303 return d->seeAlso;
304}
305
306/*!
307 \internal
308*/
309QStringList QScriptDebuggerScriptedConsoleCommand::argumentTypes() const
310{
311 Q_D(const QScriptDebuggerScriptedConsoleCommand);
312 return d->argumentTypes;
313}
314
315/*!
316 \internal
317*/
318QStringList QScriptDebuggerScriptedConsoleCommand::subCommands() const
319{
320 Q_D(const QScriptDebuggerScriptedConsoleCommand);
321 return d->subCommands;
322}
323
324/*!
325 \internal
326*/
327QScriptDebuggerConsoleCommandJob *QScriptDebuggerScriptedConsoleCommand::createJob(
328 const QStringList &arguments,
329 QScriptDebuggerConsole *console,
330 QScriptMessageHandlerInterface *messageHandler,
331 QScriptDebuggerCommandSchedulerInterface *commandScheduler)
332{
333 Q_D(QScriptDebuggerScriptedConsoleCommand);
334 return new QScriptDebuggerScriptedConsoleCommandJob(
335 d, arguments, console, messageHandler, commandScheduler);
336}
337
338/*!
339 Parses a command defined by the given \a program.
340 Returns an object that encapsulates the command, or 0 if parsing failed.
341*/
342QScriptDebuggerScriptedConsoleCommand *QScriptDebuggerScriptedConsoleCommand::parse(
343 const QString &program, const QString &fileName,
344 QScriptEngine *engine, QScriptMessageHandlerInterface *messageHandler)
345{
346 // create a custom global object
347 QScriptDebuggerConsoleGlobalObject *cppGlobal = new QScriptDebuggerConsoleGlobalObject();
348 QScriptValue global = engine->newQObject(cppGlobal,
349 QScriptEngine::ScriptOwnership,
350 QScriptEngine::ExcludeSuperClassContents);
351 {
352 QScriptValueIterator it(engine->globalObject());
353 while (it.hasNext()) {
354 it.next();
355 global.setProperty(it.scriptName(), it.value(), it.flags());
356 }
357 }
358 engine->setGlobalObject(global);
359
360 cppGlobal->setMessageHandler(messageHandler);
361 QScriptValue ret = engine->evaluate(program, fileName);
362 cppGlobal->setMessageHandler(0);
363 if (engine->hasUncaughtException()) {
364 messageHandler->message(QtCriticalMsg, ret.toString(), fileName,
365 engine->uncaughtExceptionLineNumber());
366 return 0;
367 }
368
369 QScriptValue name = global.property(QLatin1String("name"));
370 if (!name.isString()) {
371 messageHandler->message(QtCriticalMsg, QLatin1String("command definition lacks a name"), fileName);
372 return 0;
373 }
374 QString nameStr = name.toString();
375
376 QScriptValue group = global.property(QLatin1String("group"));
377 if (!group.isString()) {
378 messageHandler->message(QtCriticalMsg, QString::fromLatin1("definition of command \"%0\" lacks a group name")
379 .arg(nameStr), fileName);
380 return 0;
381 }
382 QString groupStr = group.toString();
383
384 QScriptValue shortDesc = global.property(QLatin1String("shortDescription"));
385 if (!shortDesc.isString()) {
386 messageHandler->message(QtCriticalMsg, QString::fromLatin1("definition of command \"%0\" lacks shortDescription")
387 .arg(nameStr), fileName);
388 return 0;
389 }
390 QString shortDescStr = shortDesc.toString();
391
392 QScriptValue longDesc = global.property(QLatin1String("longDescription"));
393 if (!longDesc.isString()) {
394 messageHandler->message(QtCriticalMsg, QString::fromLatin1("definition of command \"%0\" lacks longDescription")
395 .arg(nameStr), fileName);
396 return 0;
397 }
398 QString longDescStr = longDesc.toString();
399
400 QStringList aliases;
401 qScriptValueToSequence(global.property(QLatin1String("aliases")), aliases);
402
403 QStringList seeAlso;
404 qScriptValueToSequence(global.property(QLatin1String("seeAlso")), seeAlso);
405
406 QStringList argTypes;
407 qScriptValueToSequence(global.property(QLatin1String("argumentTypes")), argTypes);
408
409 QStringList subCommands;
410 qScriptValueToSequence(global.property(QLatin1String("subCommands")), subCommands);
411
412 QScriptValue execFunction = global.property(QLatin1String("execute"));
413 if (!execFunction.isFunction()) {
414 messageHandler->message(QtCriticalMsg, QString::fromLatin1("definition of command \"%0\" lacks execute() function")
415 .arg(nameStr), fileName);
416 return 0;
417 }
418
419 QScriptValue responseFunction = global.property(QLatin1String("handleResponse"));
420
421 QScriptDebuggerScriptedConsoleCommand *result = new QScriptDebuggerScriptedConsoleCommand(
422 nameStr, groupStr,
423 shortDescStr, longDescStr,
424 aliases, seeAlso,
425 argTypes, subCommands,
426 global, execFunction, responseFunction);
427 return result;
428}
429
430QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.