summaryrefslogtreecommitdiffstats
path: root/src/scripttools/debugging/qscriptdebuggercommandexecutor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/scripttools/debugging/qscriptdebuggercommandexecutor.cpp')
-rw-r--r--src/scripttools/debugging/qscriptdebuggercommandexecutor.cpp109
1 files changed, 106 insertions, 3 deletions
diff --git a/src/scripttools/debugging/qscriptdebuggercommandexecutor.cpp b/src/scripttools/debugging/qscriptdebuggercommandexecutor.cpp
index 3dc4c05..b135efd 100644
--- a/src/scripttools/debugging/qscriptdebuggercommandexecutor.cpp
+++ b/src/scripttools/debugging/qscriptdebuggercommandexecutor.cpp
@@ -98,15 +98,20 @@ QScriptDebuggerCommandExecutor::QScriptDebuggerCommandExecutor()
QScriptDebuggerCommandExecutor::~QScriptDebuggerCommandExecutor()
{
- delete d_ptr;
+}
+
+static bool isPrefixOf(const QString &prefix, const QString &what)
+{
+ return ((what.length() > prefix.length())
+ && what.startsWith(prefix));
}
/*!
Applies the given \a command to the given \a backend.
*/
QScriptDebuggerResponse QScriptDebuggerCommandExecutor::execute(
- QScriptDebuggerBackend *backend,
- const QScriptDebuggerCommand &command)
+ QScriptDebuggerBackend *backend,
+ const QScriptDebuggerCommand &command)
{
QScriptDebuggerResponse response;
switch (command.type()) {
@@ -300,6 +305,104 @@ QScriptDebuggerResponse QScriptDebuggerCommandExecutor::execute(
response.setResult(qVariantFromValue(backend->contextsCheckpoint()));
} break;
+ case QScriptDebuggerCommand::GetPropertyExpressionValue: {
+ QScriptContext *ctx = backend->context(command.contextIndex());
+ int lineNumber = command.lineNumber();
+ QVariant attr = command.attribute(QScriptDebuggerCommand::UserAttribute);
+ QStringList path = attr.toStringList();
+ if (!ctx || path.isEmpty())
+ break;
+ QScriptContextInfo ctxInfo(ctx);
+ if (ctx->callee().isValid()
+ && ((lineNumber < ctxInfo.functionStartLineNumber())
+ || (lineNumber > ctxInfo.functionEndLineNumber()))) {
+ break;
+ }
+ QScriptValueList objects;
+ int pathIndex = 0;
+ if (path.at(0) == QLatin1String("this")) {
+ objects.append(ctx->thisObject());
+ ++pathIndex;
+ } else {
+ objects << ctx->scopeChain();
+ }
+ for (int i = 0; i < objects.size(); ++i) {
+ QScriptValue val = objects.at(i);
+ for (int j = pathIndex; val.isValid() && (j < path.size()); ++j) {
+ val = val.property(path.at(j));
+ }
+ if (val.isValid()) {
+ bool hadException = (ctx->state() == QScriptContext::ExceptionState);
+ QString str = val.toString();
+ if (!hadException && backend->engine()->hasUncaughtException())
+ backend->engine()->clearExceptions();
+ response.setResult(str);
+ break;
+ }
+ }
+ } break;
+
+ case QScriptDebuggerCommand::GetCompletions: {
+ QScriptContext *ctx = backend->context(command.contextIndex());
+ QVariant attr = command.attribute(QScriptDebuggerCommand::UserAttribute);
+ QStringList path = attr.toStringList();
+ if (!ctx || path.isEmpty())
+ break;
+ QScriptValueList objects;
+ QString prefix = path.last();
+ QSet<QString> matches;
+ if (path.size() > 1) {
+ const QString &topLevelIdent = path.at(0);
+ QScriptValue obj;
+ if (topLevelIdent == QLatin1String("this")) {
+ obj = ctx->thisObject();
+ } else {
+ QScriptValueList scopeChain;
+ scopeChain = ctx->scopeChain();
+ for (int i = 0; i < scopeChain.size(); ++i) {
+ QScriptValue oo = scopeChain.at(i).property(topLevelIdent);
+ if (oo.isObject()) {
+ obj = oo;
+ break;
+ }
+ }
+ }
+ for (int i = 1; obj.isObject() && (i < path.size()-1); ++i)
+ obj = obj.property(path.at(i));
+ if (obj.isValid())
+ objects.append(obj);
+ } else {
+ objects << ctx->scopeChain();
+ QStringList keywords;
+ keywords.append(QString::fromLatin1("this"));
+ keywords.append(QString::fromLatin1("true"));
+ keywords.append(QString::fromLatin1("false"));
+ keywords.append(QString::fromLatin1("null"));
+ for (int i = 0; i < keywords.size(); ++i) {
+ const QString &kwd = keywords.at(i);
+ if (isPrefixOf(prefix, kwd))
+ matches.insert(kwd);
+ }
+ }
+
+ for (int i = 0; i < objects.size(); ++i) {
+ QScriptValue obj = objects.at(i);
+ while (obj.isObject()) {
+ QScriptValueIterator it(obj);
+ while (it.hasNext()) {
+ it.next();
+ QString propertyName = it.name();
+ if (isPrefixOf(prefix, propertyName))
+ matches.insert(propertyName);
+ }
+ obj = obj.prototype();
+ }
+ }
+ QStringList matchesList = matches.toList();
+ qStableSort(matchesList);
+ response.setResult(matchesList);
+ } break;
+
case QScriptDebuggerCommand::NewScriptObjectSnapshot: {
int id = backend->newScriptObjectSnapshot();
response.setResult(id);