Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(502)

Unified Diff: test/debugger/test-api.js

Issue 2497973002: [debug-wrapper] Further extend the debug wrapper (Closed)
Patch Set: One more test Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: test/debugger/test-api.js
diff --git a/test/debugger/test-api.js b/test/debugger/test-api.js
index 69c7c5d21937feace158cef15452dcaeb2c4ebbc..05acbbb8aa80f63aaa7ee7846efc24f983384ba8 100644
--- a/test/debugger/test-api.js
+++ b/test/debugger/test-api.js
@@ -155,18 +155,22 @@ class DebugWrapper {
this.takeReplyChecked(msgid);
}
- // Returns the serialized result of the given expression. For example:
- // {"type":"number", "value":33, "description":"33"}.
- evaluate(frameid, expression) {
+ debuggerFlags() {
+ return { breakPointsActive :
+ { setValue : (enabled) => this.setBreakPointsActive(enabled) }
+ };
+ }
+
+ scripts() {
+ // Collect all scripts in the heap.
+ return %DebugGetLoadedScripts();
+ }
+
+ setBreakPointsActive(enabled) {
const {msgid, msg} = this.createMessage(
- "Debugger.evaluateOnCallFrame",
- { callFrameId : frameid,
- expression : expression
- });
+ "Debugger.setBreakpointsActive", { active : enabled });
this.sendMessage(msg);
-
- const reply = this.takeReplyChecked(msgid);
- return reply.result.result;
+ this.takeReplyChecked(msgid);
}
// --- Internal methods. -----------------------------------------------------
@@ -236,13 +240,64 @@ class DebugWrapper {
}
}
+ execStateScopeObjectProperty(serialized_scope, prop) {
+ let found = null;
+ for (let i = 0; i < serialized_scope.length; i++) {
+ const elem = serialized_scope[i];
+ if (elem.name == prop) {
+ found = elem;
+ break;
+ }
+ }
+
+ if (found == null) return { isUndefined : true }
+
+ const val = { value : () => found.value.value };
+ return { value : () => val,
+ isUndefined : () => found.value.type == "undefined"
+ };
+ }
+
// Returns an array of property descriptors of the scope object.
// This is in contrast to the original API, which simply passed object
// mirrors.
execStateScopeObject(obj) {
const serialized_scope = this.getProperties(obj.objectId);
- const scope = {}
- const scope_tuples = serialized_scope.forEach((elem) => {
+ const scope = this.propertiesToObject(serialized_scope);
+ return { value : () => scope,
+ property : (prop) =>
+ this.execStateScopeObjectProperty(serialized_scope, prop)
+ };
+ }
+
+ setVariableValue(frame, scope_index, name, value) {
+ const frameid = frame.callFrameId;
+ const {msgid, msg} = this.createMessage(
+ "Debugger.setVariableValue",
+ { callFrameId : frameid,
+ scopeNumber : scope_index,
+ variableName : name,
+ newValue : { value : value }
+ });
+ this.sendMessage(msg);
+ this.takeReplyChecked(msgid);
+ }
+
+ execStateScope(frame, scope_index) {
+ const scope = frame.scopeChain[scope_index];
+ return { scopeType : () => this.execStateScopeType(scope.type),
+ scopeObject : () => this.execStateScopeObject(scope.object),
+ setVariableValue :
+ (name, value) => this.setVariableValue(frame, scope_index,
+ name, value)
+ };
+ }
+
+ // Takes a list of properties as produced by getProperties and turns them
+ // into an object.
+ propertiesToObject(props) {
+ const obj = {}
+ props.forEach((elem) => {
const key = elem.name;
let value;
@@ -254,16 +309,10 @@ class DebugWrapper {
}
}
- scope[key] = value;
+ obj[key] = value;
})
- return { value : () => scope };
- }
-
- execStateScope(scope) {
- return { scopeType : () => this.execStateScopeType(scope.type),
- scopeObject : () => this.execStateScopeObject(scope.object)
- };
+ return obj;
}
getProperties(objectId) {
@@ -312,7 +361,38 @@ class DebugWrapper {
return { value : () => localValue };
}
- execStateFrameEvaluate(frame, expr) {
+ reconstructRemoteObject(obj) {
+ let value = obj.value;
+ if (obj.type == "object") {
+ if (obj.subtype == "error") {
+ const desc = obj.description;
+ switch (obj.className) {
+ case "EvalError": throw new EvalError(desc);
+ case "RangeError": throw new RangeError(desc);
+ case "ReferenceError": throw new ReferenceError(desc);
+ case "SyntaxError": throw new SyntaxError(desc);
+ case "TypeError": throw new TypeError(desc);
+ case "URIError": throw new URIError(desc);
+ default: throw new Error(desc);
+ }
+ } else if (obj.subtype == "array") {
+ const array = [];
+ const props = this.propertiesToObject(
+ this.getProperties(obj.objectId));
+ for (let i = 0; i < props.length; i++) {
+ array[i] = props[i];
+ }
+ value = array;
+ }
+ }
+
+ return { value : () => value,
+ isUndefined : () => obj.type == "undefined"
+ };
+
+ }
+
+ evaluateOnCallFrame(frame, expr) {
const frameid = frame.callFrameId;
const {msgid, msg} = this.createMessage(
"Debugger.evaluateOnCallFrame",
@@ -323,11 +403,7 @@ class DebugWrapper {
const reply = this.takeReplyChecked(msgid);
const result = reply.result.result;
- if (result.subtype == "error") {
- throw new Error(result.description);
- }
-
- return { value : () => result.value };
+ return this.reconstructRemoteObject(result);
}
execStateFrame(frame) {
@@ -336,17 +412,68 @@ class DebugWrapper {
const column = frame.location.columnNumber;
const loc = %ScriptLocationFromLine2(scriptid, line, column, 0);
const func = { name : () => frame.functionName };
- return { sourceLineText : () => loc.sourceText,
- evaluate : (expr) => this.execStateFrameEvaluate(frame, expr),
+
+ function allScopes() {
+ const scopes = [];
+ for (let i = 0; i < frame.scopeChain.length; i++) {
+ scopes.push(this.execStateScope(frame, i));
+ }
+ return scopes;
+ };
+
+ return { sourceColumn : () => loc.column,
+ sourceLine : () => loc.line + 1,
+ sourceLineText : () => loc.sourceText,
+ evaluate : (expr) => this.evaluateOnCallFrame(frame, expr),
functionName : () => frame.functionName,
func : () => func,
localCount : () => this.execStateFrameLocalCount(frame),
localName : (ix) => this.execStateFrameLocalName(frame, ix),
localValue: (ix) => this.execStateFrameLocalValue(frame, ix),
scopeCount : () => frame.scopeChain.length,
- scope : (index) => this.execStateScope(frame.scopeChain[index]),
- allScopes : () => frame.scopeChain.map(
- this.execStateScope.bind(this))
+ scope : (index) => this.execStateScope(frame, index),
+ allScopes : allScopes.bind(this)
+ };
+ }
+
+ eventDataException(params) {
+ switch (params.data.type) {
+ case "string": {
+ return params.data.value;
+ }
+ case "object": {
+ const props = this.getProperties(params.data.objectId);
+ return this.propertiesToObject(props);
+ }
+ default: {
+ return undefined;
+ }
+ }
+ }
+
+ eventDataScriptSource(id) {
+ const {msgid, msg} = this.createMessage(
+ "Debugger.getScriptSource", { scriptId : id });
+ this.sendMessage(msg);
+ const reply = this.takeReplyChecked(msgid);
+ return reply.result.scriptSource;
+ }
+
+ eventDataScriptSetSource(id, src) {
+ const {msgid, msg} = this.createMessage(
+ "Debugger.setScriptSource", { scriptId : id, scriptSource : src });
+ this.sendMessage(msg);
+ this.takeReplyChecked(msgid);
+ }
+
+ eventDataScript(params) {
+ const id = params.scriptId;
+ const name = params.url ? params.url : undefined;
+
+ return { id : () => id,
+ name : () => name,
+ source : () => this.eventDataScriptSource(id),
+ setSource : (src) => this.eventDataScriptSetSource(id, src)
};
}
@@ -358,6 +485,8 @@ class DebugWrapper {
this.handleDebuggerPaused(message);
} else if (method == "Debugger.scriptParsed") {
this.handleDebuggerScriptParsed(message);
+ } else if (method == "Debugger.scriptFailedToParse") {
+ this.handleDebuggerScriptFailedToParse(message);
}
}
@@ -391,6 +520,7 @@ class DebugWrapper {
let eventData = this.execStateFrame(params.callFrames[0]);
if (debugEvent == this.DebugEvent.Exception) {
eventData.uncaught = () => params.data.uncaught;
+ eventData.exception = () => this.eventDataException(params);
}
this.invokeListener(debugEvent, execState, eventData);
@@ -399,6 +529,7 @@ class DebugWrapper {
handleDebuggerScriptParsed(message) {
const params = message.params;
let eventData = { scriptId : params.scriptId,
+ script : () => this.eventDataScript(params),
eventType : this.DebugEvent.AfterCompile
}
@@ -408,6 +539,19 @@ class DebugWrapper {
undefined);
}
+ handleDebuggerScriptFailedToParse(message) {
+ const params = message.params;
+ let eventData = { scriptId : params.scriptId,
+ script : () => this.eventDataScript(params),
+ eventType : this.DebugEvent.CompileError
+ }
+
+ // TODO(jgruber): Arguments as needed. Still completely missing exec_state,
+ // and eventData used to contain the script mirror instead of its id.
+ this.invokeListener(this.DebugEvent.CompileError, undefined, eventData,
+ undefined);
+ }
+
invokeListener(event, exec_state, event_data, data) {
if (this.listener) {
this.listener(event, exec_state, event_data, data);

Powered by Google App Engine
This is Rietveld 408576698