src/scripttools/debugging/qscriptdebuggerscriptedconsolecommand.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtSCriptTools module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    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 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    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 "qscriptdebuggervalue_p.h"
       
    50 #include "qscriptdebuggervalueproperty_p.h"
       
    51 #include "qscriptdebuggercommandschedulerinterface_p.h"
       
    52 
       
    53 #include <QtCore/qstring.h>
       
    54 #include <QtCore/qstringlist.h>
       
    55 #include <QtScript/qscriptengine.h>
       
    56 #include <QtScript/qscriptvalue.h>
       
    57 #include <QtScript/qscriptvalueiterator.h>
       
    58 #include <QtScript/qscriptcontextinfo.h>
       
    59 #include <QtCore/qdebug.h>
       
    60 
       
    61 Q_DECLARE_METATYPE(QScriptDebuggerResponse)
       
    62 Q_DECLARE_METATYPE(QScriptBreakpointData)
       
    63 Q_DECLARE_METATYPE(QScriptBreakpointMap)
       
    64 Q_DECLARE_METATYPE(QScriptScriptData)
       
    65 Q_DECLARE_METATYPE(QScriptScriptMap)
       
    66 Q_DECLARE_METATYPE(QScriptContextInfo)
       
    67 Q_DECLARE_METATYPE(QScriptDebuggerValue)
       
    68 Q_DECLARE_METATYPE(QScriptDebuggerValueProperty)
       
    69 Q_DECLARE_METATYPE(QScriptDebuggerValuePropertyList)
       
    70 Q_DECLARE_METATYPE(QScriptDebuggerConsoleCommand*)
       
    71 Q_DECLARE_METATYPE(QScriptDebuggerConsoleCommandList)
       
    72 Q_DECLARE_METATYPE(QScriptDebuggerConsoleCommandGroupData)
       
    73 Q_DECLARE_METATYPE(QScriptDebuggerConsoleCommandGroupMap)
       
    74 
       
    75 QT_BEGIN_NAMESPACE
       
    76 
       
    77 static QScriptValue debuggerResponseToScriptValue(QScriptEngine *eng, const QScriptDebuggerResponse &in)
       
    78 {
       
    79     QScriptValue out = eng->newObject();
       
    80     out.setProperty(QString::fromLatin1("result"), qScriptValueFromValue(eng, in.result()));
       
    81     out.setProperty(QString::fromLatin1("error"), QScriptValue(eng, in.error()));
       
    82     out.setProperty(QString::fromLatin1("async"), QScriptValue(eng, in.async()));
       
    83     return out;
       
    84 }
       
    85 
       
    86 static void debuggerResponseFromScriptValue(const QScriptValue &, QScriptDebuggerResponse &)
       
    87 {
       
    88     Q_ASSERT(0);
       
    89 }
       
    90 
       
    91 static QScriptValue breakpointDataToScriptValue(QScriptEngine *eng, const QScriptBreakpointData &in)
       
    92 {
       
    93     QScriptValue out = eng->newObject();
       
    94     out.setProperty(QString::fromLatin1("scriptId"), QScriptValue(eng, qsreal(in.scriptId())));
       
    95     out.setProperty(QString::fromLatin1("fileName"), QScriptValue(eng, in.fileName()));
       
    96     out.setProperty(QString::fromLatin1("lineNumber"), QScriptValue(eng, in.lineNumber()));
       
    97     out.setProperty(QString::fromLatin1("enabled"), QScriptValue(eng, in.isEnabled()));
       
    98     out.setProperty(QString::fromLatin1("singleShot"), QScriptValue(eng, in.isSingleShot()));
       
    99     out.setProperty(QString::fromLatin1("ignoreCount"), QScriptValue(eng, in.ignoreCount()));
       
   100     out.setProperty(QString::fromLatin1("condition"), QScriptValue(eng, in.condition()));
       
   101     return out;
       
   102 }
       
   103 
       
   104 static void breakpointDataFromScriptValue(const QScriptValue &in, QScriptBreakpointData &out)
       
   105 {
       
   106     QScriptValue scriptId = in.property(QString::fromLatin1("scriptId"));
       
   107     if (scriptId.isValid())
       
   108         out.setScriptId((qint64)scriptId.toNumber());
       
   109     out.setFileName(in.property(QString::fromLatin1("fileName")).toString());
       
   110     out.setLineNumber(in.property(QString::fromLatin1("lineNumber")).toInt32());
       
   111     QScriptValue enabled = in.property(QString::fromLatin1("enabled"));
       
   112     if (enabled.isValid())
       
   113         out.setEnabled(enabled.toBoolean());
       
   114     QScriptValue singleShot = in.property(QString::fromLatin1("singleShot"));
       
   115     if (singleShot.isValid())
       
   116         out.setSingleShot(singleShot.toBoolean());
       
   117     out.setIgnoreCount(in.property(QString::fromLatin1("ignoreCount")).toInt32());
       
   118     out.setCondition(in.property(QString::fromLatin1("condition")).toString());
       
   119 }
       
   120 
       
   121 static QScriptValue breakpointMapToScriptValue(QScriptEngine *eng, const QScriptBreakpointMap &in)
       
   122 {
       
   123     QScriptValue out = eng->newObject();
       
   124     QScriptBreakpointMap::const_iterator it;
       
   125     for (it = in.constBegin(); it != in.constEnd(); ++it) {
       
   126         out.setProperty(QString::number(it.key()), qScriptValueFromValue(eng, it.value()));
       
   127     }
       
   128     return out;
       
   129 }
       
   130 
       
   131 static void breakpointMapFromScriptValue(const QScriptValue &, QScriptBreakpointMap &)
       
   132 {
       
   133     Q_ASSERT(0);
       
   134 }
       
   135 
       
   136 static QScriptValue scriptDataToScriptValue(QScriptEngine *eng, const QScriptScriptData &in)
       
   137 {
       
   138     QScriptValue out = eng->newObject();
       
   139     out.setProperty(QString::fromLatin1("contents"), QScriptValue(eng, in.contents()));
       
   140     out.setProperty(QString::fromLatin1("fileName"), QScriptValue(eng, in.fileName()));
       
   141     out.setProperty(QString::fromLatin1("baseLineNumber"), QScriptValue(eng, in.baseLineNumber()));
       
   142     return out;
       
   143 }
       
   144 
       
   145 static void scriptDataFromScriptValue(const QScriptValue &in, QScriptScriptData &out)
       
   146 {
       
   147     QString contents = in.property(QString::fromLatin1("contents")).toString();
       
   148     QString fileName = in.property(QString::fromLatin1("fileName")).toString();
       
   149     int baseLineNumber = in.property(QString::fromLatin1("baseLineNumber")).toInt32();
       
   150     QScriptScriptData tmp(contents, fileName, baseLineNumber);
       
   151     out = tmp;
       
   152 }
       
   153 
       
   154 static QScriptValue scriptMapToScriptValue(QScriptEngine *eng, const QScriptScriptMap &in)
       
   155 {
       
   156     QScriptValue out = eng->newObject();
       
   157     QScriptScriptMap::const_iterator it;
       
   158     for (it = in.constBegin(); it != in.constEnd(); ++it) {
       
   159         out.setProperty(QString::number(it.key()), qScriptValueFromValue(eng, it.value()));
       
   160     }
       
   161     return out;
       
   162 }
       
   163 
       
   164 static void scriptMapFromScriptValue(const QScriptValue &, QScriptScriptMap &)
       
   165 {
       
   166     Q_ASSERT(0);
       
   167 }
       
   168 
       
   169 static QScriptValue consoleCommandToScriptValue(
       
   170     QScriptEngine *eng, QScriptDebuggerConsoleCommand* const &in)
       
   171 {
       
   172     if (!in)
       
   173         return eng->undefinedValue();
       
   174     QScriptValue out = eng->newObject();
       
   175     out.setProperty(QString::fromLatin1("name"), QScriptValue(eng, in->name()));
       
   176     out.setProperty(QString::fromLatin1("group"), QScriptValue(eng, in->group()));
       
   177     out.setProperty(QString::fromLatin1("shortDescription"), QScriptValue(eng, in->shortDescription()));
       
   178     out.setProperty(QString::fromLatin1("longDescription"), QScriptValue(eng, in->longDescription()));
       
   179     out.setProperty(QString::fromLatin1("aliases"), qScriptValueFromValue(eng, in->aliases()));
       
   180     out.setProperty(QString::fromLatin1("seeAlso"), qScriptValueFromValue(eng, in->seeAlso()));
       
   181     return out;
       
   182 }
       
   183 
       
   184 static void consoleCommandFromScriptValue(
       
   185     const QScriptValue &, QScriptDebuggerConsoleCommand* &)
       
   186 {
       
   187     Q_ASSERT(0);
       
   188 }
       
   189 
       
   190 static QScriptValue consoleCommandGroupDataToScriptValue(
       
   191     QScriptEngine *eng, const QScriptDebuggerConsoleCommandGroupData &in)
       
   192 {
       
   193     QScriptValue out = eng->newObject();
       
   194     out.setProperty(QString::fromLatin1("longDescription"), QScriptValue(eng, in.longDescription()));
       
   195     out.setProperty(QString::fromLatin1("shortDescription"), QScriptValue(eng, in.shortDescription()));
       
   196     return out;
       
   197 }
       
   198 
       
   199 static void consoleCommandGroupDataFromScriptValue(
       
   200     const QScriptValue &, QScriptDebuggerConsoleCommandGroupData &)
       
   201 {
       
   202     Q_ASSERT(0);
       
   203 }
       
   204 
       
   205 static QScriptValue consoleCommandGroupMapToScriptValue(
       
   206     QScriptEngine *eng, const QScriptDebuggerConsoleCommandGroupMap &in)
       
   207 {
       
   208     QScriptValue out = eng->newObject();
       
   209     QScriptDebuggerConsoleCommandGroupMap::const_iterator it;
       
   210     for (it = in.constBegin(); it != in.constEnd(); ++it) {
       
   211         out.setProperty(it.key(), qScriptValueFromValue(eng, it.value()));
       
   212     }
       
   213     return out;
       
   214 }
       
   215 
       
   216 static void consoleCommandGroupMapFromScriptValue(
       
   217     const QScriptValue &, QScriptDebuggerConsoleCommandGroupMap &)
       
   218 {
       
   219     Q_ASSERT(0);
       
   220 }
       
   221 
       
   222 static QScriptValue contextInfoToScriptValue(QScriptEngine *eng, const QScriptContextInfo &in)
       
   223 {
       
   224     QScriptValue out = eng->newObject();
       
   225     out.setProperty(QString::fromLatin1("scriptId"), QScriptValue(eng, qsreal(in.scriptId())));
       
   226     out.setProperty(QString::fromLatin1("fileName"), QScriptValue(eng, in.fileName()));
       
   227     out.setProperty(QString::fromLatin1("lineNumber"), QScriptValue(eng, in.lineNumber()));
       
   228     out.setProperty(QString::fromLatin1("columnNumber"), QScriptValue(eng, in.columnNumber()));
       
   229     out.setProperty(QString::fromLatin1("functionName"), QScriptValue(eng, in.functionName()));
       
   230     return out;
       
   231 }
       
   232 
       
   233 static void contextInfoFromScriptValue(const QScriptValue &, QScriptContextInfo &)
       
   234 {
       
   235     Q_ASSERT(0);
       
   236 }
       
   237 
       
   238 static QScriptValue debuggerScriptValuePropertyToScriptValue(QScriptEngine *eng, const QScriptDebuggerValueProperty &in)
       
   239 {
       
   240     QScriptValue out = eng->newObject();
       
   241     out.setProperty(QString::fromLatin1("name"), QScriptValue(eng, in.name()));
       
   242     out.setProperty(QString::fromLatin1("value"), qScriptValueFromValue(eng, in.value()));
       
   243     out.setProperty(QString::fromLatin1("valueAsString"), QScriptValue(eng, in.valueAsString()));
       
   244     out.setProperty(QString::fromLatin1("flags"), QScriptValue(eng, static_cast<int>(in.flags())));
       
   245     return out;
       
   246 }
       
   247 
       
   248 static void debuggerScriptValuePropertyFromScriptValue(const QScriptValue &in, QScriptDebuggerValueProperty &out)
       
   249 {
       
   250     QString name = in.property(QString::fromLatin1("name")).toString();
       
   251     QScriptDebuggerValue value = qscriptvalue_cast<QScriptDebuggerValue>(in.property(QString::fromLatin1("value")));
       
   252     QString valueAsString = in.property(QString::fromLatin1("valueAsString")).toString();
       
   253     int flags = in.property(QString::fromLatin1("flags")).toInt32();
       
   254     QScriptDebuggerValueProperty tmp(name, value, valueAsString, QScriptValue::PropertyFlags(flags));
       
   255     out = tmp;
       
   256 }
       
   257 
       
   258 /*!
       
   259   \since 4.5
       
   260   \class QScriptDebuggerScriptedConsoleCommand
       
   261   \internal
       
   262 
       
   263   \brief The QScriptDebuggerScriptedConsoleCommand class encapsulates a command defined in a script.
       
   264 */
       
   265 
       
   266 class QScriptDebuggerScriptedConsoleCommandPrivate
       
   267     : public QScriptDebuggerConsoleCommandPrivate
       
   268 {
       
   269     Q_DECLARE_PUBLIC(QScriptDebuggerScriptedConsoleCommand)
       
   270 public:
       
   271     QScriptDebuggerScriptedConsoleCommandPrivate();
       
   272     ~QScriptDebuggerScriptedConsoleCommandPrivate();
       
   273 
       
   274     QString name;
       
   275     QString group;
       
   276     QString shortDescription;
       
   277     QString longDescription;
       
   278     QStringList aliases;
       
   279     QStringList seeAlso;
       
   280     QStringList argumentTypes;
       
   281     QStringList subCommands;
       
   282     QScriptEngine *engine;
       
   283     QScriptValue execFunction;
       
   284     QScriptValue responseFunction;
       
   285 };
       
   286 
       
   287 QScriptDebuggerScriptedConsoleCommandPrivate::QScriptDebuggerScriptedConsoleCommandPrivate()
       
   288 {
       
   289     engine = 0;
       
   290 }
       
   291 
       
   292 QScriptDebuggerScriptedConsoleCommandPrivate::~QScriptDebuggerScriptedConsoleCommandPrivate()
       
   293 {
       
   294     delete engine;
       
   295 }
       
   296 
       
   297 QScriptDebuggerScriptedConsoleCommand::QScriptDebuggerScriptedConsoleCommand(
       
   298     const QString &name, const QString &group,
       
   299     const QString &shortDescription, const QString &longDescription,
       
   300     const QStringList &aliases, const QStringList &seeAlso,
       
   301     const QStringList &argumentTypes, const QStringList &subCommands,
       
   302     const QScriptValue &execFunction, const QScriptValue &responseFunction)
       
   303     : QScriptDebuggerConsoleCommand(*new QScriptDebuggerScriptedConsoleCommandPrivate)
       
   304 {
       
   305     Q_D(QScriptDebuggerScriptedConsoleCommand);
       
   306     d->name = name;
       
   307     d->group = group;
       
   308     d->shortDescription = shortDescription;
       
   309     d->longDescription = longDescription;
       
   310     d->aliases = aliases;
       
   311     d->seeAlso = seeAlso;
       
   312     d->argumentTypes = argumentTypes;
       
   313     d->subCommands = subCommands;
       
   314     d->execFunction = execFunction;
       
   315     d->responseFunction = responseFunction;
       
   316     d->engine = execFunction.engine();
       
   317 
       
   318     qScriptRegisterMetaType<QScriptBreakpointData>(d->engine, breakpointDataToScriptValue, breakpointDataFromScriptValue);
       
   319     qScriptRegisterMetaType<QScriptBreakpointMap>(d->engine, breakpointMapToScriptValue, breakpointMapFromScriptValue);
       
   320     qScriptRegisterMetaType<QScriptScriptData>(d->engine, scriptDataToScriptValue, scriptDataFromScriptValue);
       
   321     qScriptRegisterMetaType<QScriptScriptMap>(d->engine, scriptMapToScriptValue, scriptMapFromScriptValue);
       
   322     qScriptRegisterMetaType<QScriptContextInfo>(d->engine, contextInfoToScriptValue, contextInfoFromScriptValue);
       
   323     qScriptRegisterMetaType<QScriptDebuggerValueProperty>(d->engine, debuggerScriptValuePropertyToScriptValue, debuggerScriptValuePropertyFromScriptValue);
       
   324     qScriptRegisterSequenceMetaType<QScriptDebuggerValuePropertyList>(d->engine);
       
   325     qScriptRegisterMetaType<QScriptDebuggerResponse>(d->engine, debuggerResponseToScriptValue, debuggerResponseFromScriptValue);
       
   326     qScriptRegisterMetaType<QScriptDebuggerConsoleCommand*>(d->engine, consoleCommandToScriptValue, consoleCommandFromScriptValue);
       
   327     qScriptRegisterSequenceMetaType<QScriptDebuggerConsoleCommandList>(d->engine);
       
   328     qScriptRegisterMetaType<QScriptDebuggerConsoleCommandGroupData>(d->engine, consoleCommandGroupDataToScriptValue, consoleCommandGroupDataFromScriptValue);
       
   329     qScriptRegisterMetaType<QScriptDebuggerConsoleCommandGroupMap>(d->engine, consoleCommandGroupMapToScriptValue, consoleCommandGroupMapFromScriptValue);
       
   330 // ### can't do this, if it's an object ID the conversion will be incorrect since
       
   331 // ### the object ID refers to an object in a different engine!
       
   332 //    qScriptRegisterMetaType(d->engine, debuggerScriptValueToScriptValue, debuggerScriptValueFromScriptValue);
       
   333 }
       
   334 
       
   335 QScriptDebuggerScriptedConsoleCommand::~QScriptDebuggerScriptedConsoleCommand()
       
   336 {
       
   337 }
       
   338 
       
   339 class QScriptDebuggerScriptedConsoleCommandJobPrivate;
       
   340 class QScriptDebuggerScriptedConsoleCommandJob
       
   341     : public QScriptDebuggerConsoleCommandJob,
       
   342       public QScriptDebuggerCommandSchedulerInterface
       
   343 {
       
   344 public:
       
   345     QScriptDebuggerScriptedConsoleCommandJob(
       
   346         QScriptDebuggerScriptedConsoleCommandPrivate *command,
       
   347         const QStringList &arguments,
       
   348         QScriptDebuggerConsole *console,
       
   349         QScriptMessageHandlerInterface *messageHandler,
       
   350         QScriptDebuggerCommandSchedulerInterface *commandScheduler);
       
   351     ~QScriptDebuggerScriptedConsoleCommandJob();
       
   352 
       
   353     int scheduleCommand(
       
   354         const QScriptDebuggerCommand &command,
       
   355         QScriptDebuggerResponseHandlerInterface *responseHandler);
       
   356 
       
   357     void start();
       
   358     void handleResponse(const QScriptDebuggerResponse &response,
       
   359                         int commandId);
       
   360 
       
   361 private:
       
   362     Q_DECLARE_PRIVATE(QScriptDebuggerScriptedConsoleCommandJob)
       
   363     Q_DISABLE_COPY(QScriptDebuggerScriptedConsoleCommandJob)
       
   364 };
       
   365 
       
   366 class QScriptDebuggerScriptedConsoleCommandJobPrivate
       
   367     : public QScriptDebuggerConsoleCommandJobPrivate
       
   368 {
       
   369 public:
       
   370     QScriptDebuggerScriptedConsoleCommandJobPrivate() : command(0), commandCount(0) {}
       
   371     ~QScriptDebuggerScriptedConsoleCommandJobPrivate() {}
       
   372 
       
   373     QScriptDebuggerScriptedConsoleCommandPrivate *command;
       
   374     QStringList arguments;
       
   375     int commandCount;
       
   376 };
       
   377 
       
   378 QScriptDebuggerScriptedConsoleCommandJob::QScriptDebuggerScriptedConsoleCommandJob(
       
   379     QScriptDebuggerScriptedConsoleCommandPrivate *command,
       
   380     const QStringList &arguments,
       
   381     QScriptDebuggerConsole *console,
       
   382     QScriptMessageHandlerInterface *messageHandler,
       
   383     QScriptDebuggerCommandSchedulerInterface *commandScheduler)
       
   384     : QScriptDebuggerConsoleCommandJob(*new QScriptDebuggerScriptedConsoleCommandJobPrivate,
       
   385                                        console, messageHandler, commandScheduler)
       
   386 {
       
   387     Q_D(QScriptDebuggerScriptedConsoleCommandJob);
       
   388     d->command = command;
       
   389     d->arguments = arguments;
       
   390 }
       
   391 
       
   392 QScriptDebuggerScriptedConsoleCommandJob::~QScriptDebuggerScriptedConsoleCommandJob()
       
   393 {
       
   394 }
       
   395 
       
   396 int QScriptDebuggerScriptedConsoleCommandJob::scheduleCommand(
       
   397     const QScriptDebuggerCommand &command,
       
   398     QScriptDebuggerResponseHandlerInterface *responseHandler)
       
   399 {
       
   400     Q_D(QScriptDebuggerScriptedConsoleCommandJob);
       
   401     ++d->commandCount;
       
   402     return commandScheduler()->scheduleCommand(command, responseHandler);
       
   403 }
       
   404 
       
   405 void QScriptDebuggerScriptedConsoleCommandJob::start()
       
   406 {
       
   407     Q_D(QScriptDebuggerScriptedConsoleCommandJob);
       
   408     QScriptEngine *engine = d->command->engine;
       
   409     QScriptValueList args;
       
   410     for (int i = 0; i < d->arguments.size(); ++i)
       
   411         args.append(QScriptValue(engine, d->arguments.at(i)));
       
   412     QScriptDebuggerConsoleGlobalObject *global;
       
   413     global = qobject_cast<QScriptDebuggerConsoleGlobalObject*>(engine->globalObject().toQObject());
       
   414     Q_ASSERT(global != 0);
       
   415     global->setScheduler(this);
       
   416     global->setResponseHandler(this);
       
   417     global->setMessageHandler(d->messageHandler);
       
   418     global->setConsole(d->console);
       
   419     d->commandCount = 0;
       
   420     QScriptValue ret = d->command->execFunction.call(QScriptValue(), args);
       
   421     global->setScheduler(0);
       
   422     global->setResponseHandler(0);
       
   423     global->setMessageHandler(0);
       
   424     global->setConsole(0);
       
   425     if (ret.isError()) {
       
   426         qWarning("*** internal error: %s", qPrintable(ret.toString()));
       
   427     }
       
   428     if (d->commandCount == 0)
       
   429         finish();
       
   430 }
       
   431 
       
   432 void QScriptDebuggerScriptedConsoleCommandJob::handleResponse(
       
   433     const QScriptDebuggerResponse &response,
       
   434     int commandId)
       
   435 {
       
   436     Q_D(QScriptDebuggerScriptedConsoleCommandJob);
       
   437     // ### generalize
       
   438     QScriptEngine *engine = d->command->engine;
       
   439     QScriptValueList args;
       
   440     args.append(qScriptValueFromValue(engine, response));
       
   441     args.append(QScriptValue(engine, commandId));
       
   442     QScriptDebuggerConsoleGlobalObject *global;
       
   443     global = qobject_cast<QScriptDebuggerConsoleGlobalObject*>(engine->globalObject().toQObject());
       
   444     Q_ASSERT(global != 0);
       
   445     global->setScheduler(this);
       
   446     global->setResponseHandler(this);
       
   447     global->setMessageHandler(d->messageHandler);
       
   448     global->setConsole(d->console);
       
   449     d->commandCount = 0;
       
   450     QScriptValue ret = d->command->responseFunction.call(QScriptValue(), args);
       
   451     global->setScheduler(0);
       
   452     global->setResponseHandler(0);
       
   453     global->setMessageHandler(0);
       
   454     global->setConsole(0);
       
   455     if (ret.isError()) {
       
   456         qWarning("*** internal error: %s", qPrintable(ret.toString()));
       
   457     }
       
   458     if (d->commandCount == 0)
       
   459         finish();
       
   460 }
       
   461 
       
   462 /*!
       
   463   \internal
       
   464 */
       
   465 QString QScriptDebuggerScriptedConsoleCommand::name() const
       
   466 {
       
   467     Q_D(const QScriptDebuggerScriptedConsoleCommand);
       
   468     return d->name;
       
   469 }
       
   470 
       
   471 /*!
       
   472   \internal
       
   473 */
       
   474 QString QScriptDebuggerScriptedConsoleCommand::group() const
       
   475 {
       
   476     Q_D(const QScriptDebuggerScriptedConsoleCommand);
       
   477     return d->group;
       
   478 }
       
   479 
       
   480 /*!
       
   481   \internal
       
   482 */
       
   483 QString QScriptDebuggerScriptedConsoleCommand::shortDescription() const
       
   484 {
       
   485     Q_D(const QScriptDebuggerScriptedConsoleCommand);
       
   486     return d->shortDescription;
       
   487 }
       
   488 
       
   489 /*!
       
   490   \internal
       
   491 */
       
   492 QString QScriptDebuggerScriptedConsoleCommand::longDescription() const
       
   493 {
       
   494     Q_D(const QScriptDebuggerScriptedConsoleCommand);
       
   495     return d->longDescription;
       
   496 }
       
   497 
       
   498 /*!
       
   499   \internal
       
   500 */
       
   501 QStringList QScriptDebuggerScriptedConsoleCommand::aliases() const
       
   502 {
       
   503     Q_D(const QScriptDebuggerScriptedConsoleCommand);
       
   504     return d->aliases;
       
   505 }
       
   506 
       
   507 /*!
       
   508   \internal
       
   509 */
       
   510 QStringList QScriptDebuggerScriptedConsoleCommand::seeAlso() const
       
   511 {
       
   512     Q_D(const QScriptDebuggerScriptedConsoleCommand);
       
   513     return d->seeAlso;
       
   514 }
       
   515 
       
   516 /*!
       
   517   \internal
       
   518 */
       
   519 QStringList QScriptDebuggerScriptedConsoleCommand::argumentTypes() const
       
   520 {
       
   521     Q_D(const QScriptDebuggerScriptedConsoleCommand);
       
   522     return d->argumentTypes;
       
   523 }
       
   524 
       
   525 /*!
       
   526   \internal
       
   527 */
       
   528 QStringList QScriptDebuggerScriptedConsoleCommand::subCommands() const
       
   529 {
       
   530     Q_D(const QScriptDebuggerScriptedConsoleCommand);
       
   531     return d->subCommands;
       
   532 }
       
   533 
       
   534 /*!
       
   535   \internal
       
   536 */
       
   537 QScriptDebuggerConsoleCommandJob *QScriptDebuggerScriptedConsoleCommand::createJob(
       
   538     const QStringList &arguments,
       
   539     QScriptDebuggerConsole *console,
       
   540     QScriptMessageHandlerInterface *messageHandler,
       
   541     QScriptDebuggerCommandSchedulerInterface *commandScheduler)
       
   542 {
       
   543     Q_D(QScriptDebuggerScriptedConsoleCommand);
       
   544     return new QScriptDebuggerScriptedConsoleCommandJob(
       
   545         d, arguments, console, messageHandler, commandScheduler);
       
   546 }
       
   547 
       
   548 /*!
       
   549   Parses a command defined by the given \a program.
       
   550   Returns an object that encapsulates the command, or 0 if parsing failed.
       
   551 */
       
   552 QScriptDebuggerScriptedConsoleCommand *QScriptDebuggerScriptedConsoleCommand::parse(
       
   553     const QString &program, const QString &fileName,
       
   554     QScriptMessageHandlerInterface *messageHandler)
       
   555 {
       
   556     QScriptEngine *engine = new QScriptEngine();
       
   557     // create a custom global object
       
   558     QScriptDebuggerConsoleGlobalObject *cppGlobal = new QScriptDebuggerConsoleGlobalObject();
       
   559     QScriptValue global = engine->newQObject(cppGlobal,
       
   560                                              QScriptEngine::ScriptOwnership,
       
   561                                              QScriptEngine::ExcludeSuperClassContents);
       
   562     {
       
   563         QScriptValueIterator it(engine->globalObject());
       
   564         while (it.hasNext()) {
       
   565             it.next();
       
   566             global.setProperty(it.scriptName(), it.value(), it.flags());
       
   567         }
       
   568     }
       
   569     engine->setGlobalObject(global);
       
   570 
       
   571     cppGlobal->setMessageHandler(messageHandler);
       
   572     QScriptValue ret = engine->evaluate(program, fileName);
       
   573     cppGlobal->setMessageHandler(0);
       
   574     if (engine->hasUncaughtException()) {
       
   575         messageHandler->message(QtCriticalMsg, ret.toString(), fileName,
       
   576                                 engine->uncaughtExceptionLineNumber());
       
   577         delete engine;
       
   578         return 0;
       
   579     }
       
   580 
       
   581     QScriptValue name = global.property(QLatin1String("name"));
       
   582     if (!name.isString()) {
       
   583         messageHandler->message(QtCriticalMsg, QLatin1String("command definition lacks a name"), fileName);
       
   584         delete engine;
       
   585         return 0;
       
   586     }
       
   587     QString nameStr = name.toString();
       
   588 
       
   589     QScriptValue group = global.property(QLatin1String("group"));
       
   590     if (!group.isString()) {
       
   591         messageHandler->message(QtCriticalMsg, QString::fromLatin1("definition of command \"%0\" lacks a group name")
       
   592                                 .arg(nameStr), fileName);
       
   593         delete engine;
       
   594         return 0;
       
   595     }
       
   596     QString groupStr = group.toString();
       
   597 
       
   598     QScriptValue shortDesc = global.property(QLatin1String("shortDescription"));
       
   599     if (!shortDesc.isString()) {
       
   600         messageHandler->message(QtCriticalMsg, QString::fromLatin1("definition of command \"%0\" lacks shortDescription")
       
   601                                 .arg(nameStr), fileName);
       
   602         delete engine;
       
   603         return 0;
       
   604     }
       
   605     QString shortDescStr = shortDesc.toString();
       
   606 
       
   607     QScriptValue longDesc = global.property(QLatin1String("longDescription"));
       
   608     if (!longDesc.isString()) {
       
   609         messageHandler->message(QtCriticalMsg, QString::fromLatin1("definition of command \"%0\" lacks longDescription")
       
   610                                 .arg(nameStr), fileName);
       
   611         delete engine;
       
   612         return 0;
       
   613     }
       
   614     QString longDescStr = longDesc.toString();
       
   615 
       
   616     QStringList aliases;
       
   617     qScriptValueToSequence(global.property(QLatin1String("aliases")), aliases);
       
   618 
       
   619     QStringList seeAlso;
       
   620     qScriptValueToSequence(global.property(QLatin1String("seeAlso")), seeAlso);
       
   621 
       
   622     QStringList argTypes;
       
   623     qScriptValueToSequence(global.property(QLatin1String("argumentTypes")), argTypes);
       
   624 
       
   625     QStringList subCommands;
       
   626     qScriptValueToSequence(global.property(QLatin1String("subCommands")), subCommands);
       
   627 
       
   628     QScriptValue execFunction = global.property(QLatin1String("execute"));
       
   629     if (!execFunction.isFunction()) {
       
   630         messageHandler->message(QtCriticalMsg, QString::fromLatin1("definition of command \"%0\" lacks execute() function")
       
   631                                 .arg(nameStr), fileName);
       
   632         delete engine;
       
   633         return 0;
       
   634     }
       
   635 
       
   636     QScriptValue responseFunction = global.property(QLatin1String("handleResponse"));
       
   637 
       
   638     QScriptDebuggerScriptedConsoleCommand *result = new QScriptDebuggerScriptedConsoleCommand(
       
   639         nameStr, groupStr,
       
   640         shortDescStr, longDescStr,
       
   641         aliases, seeAlso,
       
   642         argTypes, subCommands,
       
   643         execFunction, responseFunction);
       
   644     return result;
       
   645 }
       
   646 
       
   647 QT_END_NAMESPACE