summaryrefslogtreecommitdiffstats
path: root/src/scripttools/debugging/qscriptdebuggerscriptedconsolecommand.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/scripttools/debugging/qscriptdebuggerscriptedconsolecommand.cpp')
-rw-r--r--src/scripttools/debugging/qscriptdebuggerscriptedconsolecommand.cpp430
1 files changed, 430 insertions, 0 deletions
diff --git a/src/scripttools/debugging/qscriptdebuggerscriptedconsolecommand.cpp b/src/scripttools/debugging/qscriptdebuggerscriptedconsolecommand.cpp
new file mode 100644
index 0000000..37634c8
--- /dev/null
+++ b/src/scripttools/debugging/qscriptdebuggerscriptedconsolecommand.cpp
@@ -0,0 +1,430 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** 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 "qscriptdebuggerscriptedconsolecommand_p.h"
+#include "qscriptdebuggerconsolecommand_p_p.h"
+#include "qscriptdebuggerconsolecommandjob_p.h"
+#include "qscriptdebuggerconsolecommandjob_p_p.h"
+#include "qscriptmessagehandlerinterface_p.h"
+#include "qscriptdebuggerconsoleglobalobject_p.h"
+#include "qscriptdebuggerresponse_p.h"
+#include "qscriptdebuggercommandschedulerinterface_p.h"
+
+#include <QtCore/qstring.h>
+#include <QtCore/qstringlist.h>
+#include <QtScript/qscriptengine.h>
+#include <QtScript/qscriptvalue.h>
+#include <QtScript/qscriptvalueiterator.h>
+#include <QtScript/qscriptcontextinfo.h>
+#include <QtCore/qdebug.h>
+
+Q_DECLARE_METATYPE(QScriptDebuggerResponse)
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \since 4.5
+ \class QScriptDebuggerScriptedConsoleCommand
+ \internal
+
+ \brief The QScriptDebuggerScriptedConsoleCommand class encapsulates a command defined in a script.
+*/
+
+class QScriptDebuggerScriptedConsoleCommandPrivate
+ : public QScriptDebuggerConsoleCommandPrivate
+{
+ Q_DECLARE_PUBLIC(QScriptDebuggerScriptedConsoleCommand)
+public:
+ QScriptDebuggerScriptedConsoleCommandPrivate();
+ ~QScriptDebuggerScriptedConsoleCommandPrivate();
+
+ QString name;
+ QString group;
+ QString shortDescription;
+ QString longDescription;
+ QStringList aliases;
+ QStringList seeAlso;
+ QStringList argumentTypes;
+ QStringList subCommands;
+ QScriptValue globalObject;
+ QScriptValue execFunction;
+ QScriptValue responseFunction;
+};
+
+QScriptDebuggerScriptedConsoleCommandPrivate::QScriptDebuggerScriptedConsoleCommandPrivate()
+{
+}
+
+QScriptDebuggerScriptedConsoleCommandPrivate::~QScriptDebuggerScriptedConsoleCommandPrivate()
+{
+}
+
+QScriptDebuggerScriptedConsoleCommand::QScriptDebuggerScriptedConsoleCommand(
+ const QString &name, const QString &group,
+ const QString &shortDescription, const QString &longDescription,
+ const QStringList &aliases, const QStringList &seeAlso,
+ const QStringList &argumentTypes, const QStringList &subCommands,
+ const QScriptValue &globalObject,
+ const QScriptValue &execFunction, const QScriptValue &responseFunction)
+ : QScriptDebuggerConsoleCommand(*new QScriptDebuggerScriptedConsoleCommandPrivate)
+{
+ Q_D(QScriptDebuggerScriptedConsoleCommand);
+ d->name = name;
+ d->group = group;
+ d->shortDescription = shortDescription;
+ d->longDescription = longDescription;
+ d->aliases = aliases;
+ d->seeAlso = seeAlso;
+ d->argumentTypes = argumentTypes;
+ d->subCommands = subCommands;
+ d->globalObject = globalObject;
+ d->execFunction = execFunction;
+ d->responseFunction = responseFunction;
+}
+
+QScriptDebuggerScriptedConsoleCommand::~QScriptDebuggerScriptedConsoleCommand()
+{
+}
+
+class QScriptDebuggerScriptedConsoleCommandJobPrivate;
+class QScriptDebuggerScriptedConsoleCommandJob
+ : public QScriptDebuggerConsoleCommandJob,
+ public QScriptDebuggerCommandSchedulerInterface
+{
+public:
+ QScriptDebuggerScriptedConsoleCommandJob(
+ QScriptDebuggerScriptedConsoleCommandPrivate *command,
+ const QStringList &arguments,
+ QScriptDebuggerConsole *console,
+ QScriptMessageHandlerInterface *messageHandler,
+ QScriptDebuggerCommandSchedulerInterface *commandScheduler);
+ ~QScriptDebuggerScriptedConsoleCommandJob();
+
+ int scheduleCommand(
+ const QScriptDebuggerCommand &command,
+ QScriptDebuggerResponseHandlerInterface *responseHandler);
+
+ void start();
+ void handleResponse(const QScriptDebuggerResponse &response,
+ int commandId);
+
+private:
+ Q_DECLARE_PRIVATE(QScriptDebuggerScriptedConsoleCommandJob)
+ Q_DISABLE_COPY(QScriptDebuggerScriptedConsoleCommandJob)
+};
+
+class QScriptDebuggerScriptedConsoleCommandJobPrivate
+ : public QScriptDebuggerConsoleCommandJobPrivate
+{
+public:
+ QScriptDebuggerScriptedConsoleCommandJobPrivate() : command(0), commandCount(0) {}
+ ~QScriptDebuggerScriptedConsoleCommandJobPrivate() {}
+
+ QScriptDebuggerScriptedConsoleCommandPrivate *command;
+ QStringList arguments;
+ int commandCount;
+};
+
+QScriptDebuggerScriptedConsoleCommandJob::QScriptDebuggerScriptedConsoleCommandJob(
+ QScriptDebuggerScriptedConsoleCommandPrivate *command,
+ const QStringList &arguments,
+ QScriptDebuggerConsole *console,
+ QScriptMessageHandlerInterface *messageHandler,
+ QScriptDebuggerCommandSchedulerInterface *commandScheduler)
+ : QScriptDebuggerConsoleCommandJob(*new QScriptDebuggerScriptedConsoleCommandJobPrivate,
+ console, messageHandler, commandScheduler)
+{
+ Q_D(QScriptDebuggerScriptedConsoleCommandJob);
+ d->command = command;
+ d->arguments = arguments;
+}
+
+QScriptDebuggerScriptedConsoleCommandJob::~QScriptDebuggerScriptedConsoleCommandJob()
+{
+}
+
+int QScriptDebuggerScriptedConsoleCommandJob::scheduleCommand(
+ const QScriptDebuggerCommand &command,
+ QScriptDebuggerResponseHandlerInterface *responseHandler)
+{
+ Q_D(QScriptDebuggerScriptedConsoleCommandJob);
+ ++d->commandCount;
+ return commandScheduler()->scheduleCommand(command, responseHandler);
+}
+
+void QScriptDebuggerScriptedConsoleCommandJob::start()
+{
+ Q_D(QScriptDebuggerScriptedConsoleCommandJob);
+ QScriptEngine *engine = d->command->globalObject.engine();
+ engine->setGlobalObject(d->command->globalObject);
+ QScriptValueList args;
+ for (int i = 0; i < d->arguments.size(); ++i)
+ args.append(QScriptValue(engine, d->arguments.at(i)));
+ QScriptDebuggerConsoleGlobalObject *global;
+ global = qobject_cast<QScriptDebuggerConsoleGlobalObject*>(engine->globalObject().toQObject());
+ Q_ASSERT(global != 0);
+ global->setScheduler(this);
+ global->setResponseHandler(this);
+ global->setMessageHandler(d->messageHandler);
+ global->setConsole(d->console);
+ d->commandCount = 0;
+ QScriptValue ret = d->command->execFunction.call(QScriptValue(), args);
+ global->setScheduler(0);
+ global->setResponseHandler(0);
+ global->setMessageHandler(0);
+ global->setConsole(0);
+ if (ret.isError()) {
+ qWarning("*** internal error: %s", qPrintable(ret.toString()));
+ }
+ if (d->commandCount == 0)
+ finish();
+}
+
+void QScriptDebuggerScriptedConsoleCommandJob::handleResponse(
+ const QScriptDebuggerResponse &response,
+ int commandId)
+{
+ Q_D(QScriptDebuggerScriptedConsoleCommandJob);
+ // ### generalize
+ QScriptEngine *engine = d->command->globalObject.engine();
+ engine->setGlobalObject(d->command->globalObject);
+ QScriptValueList args;
+ args.append(engine->toScriptValue(response));
+ args.append(QScriptValue(engine, commandId));
+ QScriptDebuggerConsoleGlobalObject *global;
+ global = qobject_cast<QScriptDebuggerConsoleGlobalObject*>(d->command->globalObject.toQObject());
+ Q_ASSERT(global != 0);
+ global->setScheduler(this);
+ global->setResponseHandler(this);
+ global->setMessageHandler(d->messageHandler);
+ global->setConsole(d->console);
+ d->commandCount = 0;
+ QScriptValue ret = d->command->responseFunction.call(QScriptValue(), args);
+ global->setScheduler(0);
+ global->setResponseHandler(0);
+ global->setMessageHandler(0);
+ global->setConsole(0);
+ if (ret.isError()) {
+ qWarning("*** internal error: %s", qPrintable(ret.toString()));
+ }
+ if (d->commandCount == 0)
+ finish();
+}
+
+/*!
+ \internal
+*/
+QString QScriptDebuggerScriptedConsoleCommand::name() const
+{
+ Q_D(const QScriptDebuggerScriptedConsoleCommand);
+ return d->name;
+}
+
+/*!
+ \internal
+*/
+QString QScriptDebuggerScriptedConsoleCommand::group() const
+{
+ Q_D(const QScriptDebuggerScriptedConsoleCommand);
+ return d->group;
+}
+
+/*!
+ \internal
+*/
+QString QScriptDebuggerScriptedConsoleCommand::shortDescription() const
+{
+ Q_D(const QScriptDebuggerScriptedConsoleCommand);
+ return d->shortDescription;
+}
+
+/*!
+ \internal
+*/
+QString QScriptDebuggerScriptedConsoleCommand::longDescription() const
+{
+ Q_D(const QScriptDebuggerScriptedConsoleCommand);
+ return d->longDescription;
+}
+
+/*!
+ \internal
+*/
+QStringList QScriptDebuggerScriptedConsoleCommand::aliases() const
+{
+ Q_D(const QScriptDebuggerScriptedConsoleCommand);
+ return d->aliases;
+}
+
+/*!
+ \internal
+*/
+QStringList QScriptDebuggerScriptedConsoleCommand::seeAlso() const
+{
+ Q_D(const QScriptDebuggerScriptedConsoleCommand);
+ return d->seeAlso;
+}
+
+/*!
+ \internal
+*/
+QStringList QScriptDebuggerScriptedConsoleCommand::argumentTypes() const
+{
+ Q_D(const QScriptDebuggerScriptedConsoleCommand);
+ return d->argumentTypes;
+}
+
+/*!
+ \internal
+*/
+QStringList QScriptDebuggerScriptedConsoleCommand::subCommands() const
+{
+ Q_D(const QScriptDebuggerScriptedConsoleCommand);
+ return d->subCommands;
+}
+
+/*!
+ \internal
+*/
+QScriptDebuggerConsoleCommandJob *QScriptDebuggerScriptedConsoleCommand::createJob(
+ const QStringList &arguments,
+ QScriptDebuggerConsole *console,
+ QScriptMessageHandlerInterface *messageHandler,
+ QScriptDebuggerCommandSchedulerInterface *commandScheduler)
+{
+ Q_D(QScriptDebuggerScriptedConsoleCommand);
+ return new QScriptDebuggerScriptedConsoleCommandJob(
+ d, arguments, console, messageHandler, commandScheduler);
+}
+
+/*!
+ Parses a command defined by the given \a program.
+ Returns an object that encapsulates the command, or 0 if parsing failed.
+*/
+QScriptDebuggerScriptedConsoleCommand *QScriptDebuggerScriptedConsoleCommand::parse(
+ const QString &program, const QString &fileName,
+ QScriptEngine *engine, QScriptMessageHandlerInterface *messageHandler)
+{
+ // create a custom global object
+ QScriptDebuggerConsoleGlobalObject *cppGlobal = new QScriptDebuggerConsoleGlobalObject();
+ QScriptValue global = engine->newQObject(cppGlobal,
+ QScriptEngine::ScriptOwnership,
+ QScriptEngine::ExcludeSuperClassContents);
+ {
+ QScriptValueIterator it(engine->globalObject());
+ while (it.hasNext()) {
+ it.next();
+ global.setProperty(it.scriptName(), it.value(), it.flags());
+ }
+ }
+ engine->setGlobalObject(global);
+
+ cppGlobal->setMessageHandler(messageHandler);
+ QScriptValue ret = engine->evaluate(program, fileName);
+ cppGlobal->setMessageHandler(0);
+ if (engine->hasUncaughtException()) {
+ messageHandler->message(QtCriticalMsg, ret.toString(), fileName,
+ engine->uncaughtExceptionLineNumber());
+ return 0;
+ }
+
+ QScriptValue name = global.property(QLatin1String("name"));
+ if (!name.isString()) {
+ messageHandler->message(QtCriticalMsg, QLatin1String("command definition lacks a name"), fileName);
+ return 0;
+ }
+ QString nameStr = name.toString();
+
+ QScriptValue group = global.property(QLatin1String("group"));
+ if (!group.isString()) {
+ messageHandler->message(QtCriticalMsg, QString::fromLatin1("definition of command \"%0\" lacks a group name")
+ .arg(nameStr), fileName);
+ return 0;
+ }
+ QString groupStr = group.toString();
+
+ QScriptValue shortDesc = global.property(QLatin1String("shortDescription"));
+ if (!shortDesc.isString()) {
+ messageHandler->message(QtCriticalMsg, QString::fromLatin1("definition of command \"%0\" lacks shortDescription")
+ .arg(nameStr), fileName);
+ return 0;
+ }
+ QString shortDescStr = shortDesc.toString();
+
+ QScriptValue longDesc = global.property(QLatin1String("longDescription"));
+ if (!longDesc.isString()) {
+ messageHandler->message(QtCriticalMsg, QString::fromLatin1("definition of command \"%0\" lacks longDescription")
+ .arg(nameStr), fileName);
+ return 0;
+ }
+ QString longDescStr = longDesc.toString();
+
+ QStringList aliases;
+ qScriptValueToSequence(global.property(QLatin1String("aliases")), aliases);
+
+ QStringList seeAlso;
+ qScriptValueToSequence(global.property(QLatin1String("seeAlso")), seeAlso);
+
+ QStringList argTypes;
+ qScriptValueToSequence(global.property(QLatin1String("argumentTypes")), argTypes);
+
+ QStringList subCommands;
+ qScriptValueToSequence(global.property(QLatin1String("subCommands")), subCommands);
+
+ QScriptValue execFunction = global.property(QLatin1String("execute"));
+ if (!execFunction.isFunction()) {
+ messageHandler->message(QtCriticalMsg, QString::fromLatin1("definition of command \"%0\" lacks execute() function")
+ .arg(nameStr), fileName);
+ return 0;
+ }
+
+ QScriptValue responseFunction = global.property(QLatin1String("handleResponse"));
+
+ QScriptDebuggerScriptedConsoleCommand *result = new QScriptDebuggerScriptedConsoleCommand(
+ nameStr, groupStr,
+ shortDescStr, longDescStr,
+ aliases, seeAlso,
+ argTypes, subCommands,
+ global, execFunction, responseFunction);
+ return result;
+}
+
+QT_END_NAMESPACE