From 293fb7011243f063d9948620f446a639117e39e3 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Mon, 25 Aug 2014 09:49:00 -0400 Subject: [PATCH] Bug 881480 - Part 1: Create RDP value forms for ES6 symbols. r=past --- toolkit/devtools/server/actors/script.js | 22 +++++++ .../server/tests/unit/test_symbols-01.js | 58 +++++++++++++++++++ .../server/tests/unit/test_symbols-02.js | 49 ++++++++++++++++ .../devtools/server/tests/unit/xpcshell.ini | 2 + 4 files changed, 131 insertions(+) create mode 100644 toolkit/devtools/server/tests/unit/test_symbols-01.js create mode 100644 toolkit/devtools/server/tests/unit/test_symbols-02.js diff --git a/toolkit/devtools/server/actors/script.js b/toolkit/devtools/server/actors/script.js index b80c3eefa17..acce9a78dfc 100644 --- a/toolkit/devtools/server/actors/script.js +++ b/toolkit/devtools/server/actors/script.js @@ -1965,11 +1965,13 @@ ThreadActor.prototype = { switch (typeof aValue) { case "boolean": return aValue; + case "string": if (this._stringIsLong(aValue)) { return this.longStringGrip(aValue, aPool); } return aValue; + case "number": if (aValue === Infinity) { return { type: "Infinity" }; @@ -1981,13 +1983,26 @@ ThreadActor.prototype = { return { type: "-0" }; } return aValue; + case "undefined": return { type: "undefined" }; + case "object": if (aValue === null) { return { type: "null" }; } return this.objectGrip(aValue, aPool); + + case "symbol": + let form = { + type: "symbol" + }; + let name = getSymbolName(aValue); + if (name !== undefined) { + form.name = this.createValueGrip(name); + } + return form; + default: dbg_assert(false, "Failed to provide a grip for: " + aValue); return null; @@ -5430,6 +5445,13 @@ function getInnerId(window) { getInterface(Ci.nsIDOMWindowUtils).currentInnerWindowID; }; +const symbolProtoToString = Symbol.prototype.toString; + +function getSymbolName(symbol) { + const name = symbolProtoToString.call(symbol).slice("Symbol(".length, -1); + return name || undefined; +} + exports.register = function(handle) { ThreadActor.breakpointStore = new BreakpointStore(); ThreadSources._blackBoxedSources = new Set(["self-hosted"]); diff --git a/toolkit/devtools/server/tests/unit/test_symbols-01.js b/toolkit/devtools/server/tests/unit/test_symbols-01.js new file mode 100644 index 00000000000..0976a998a73 --- /dev/null +++ b/toolkit/devtools/server/tests/unit/test_symbols-01.js @@ -0,0 +1,58 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Test that we can represent ES6 Symbols over the RDP. + */ + +const URL = "foo.js"; + +function run_test() { + initTestDebuggerServer(); + const debuggee = addTestGlobal("test-symbols"); + const client = new DebuggerClient(DebuggerServer.connectPipe()); + + client.connect(function() { + attachTestTabAndResume(client, "test-symbols", function(response, tabClient, threadClient) { + add_task(testSymbols.bind(null, client, debuggee)); + run_next_test(); + }); + }); + + do_test_pending(); +} + +function* testSymbols(client, debuggee) { + const evalCode = () => { + Components.utils.evalInSandbox( + "(" + function () { + var symbolWithName = Symbol("Chris"); + var symbolWithoutName = Symbol(); + var iteratorSymbol = Symbol.iterator; + debugger; + } + "())", + debuggee, + "1.8", + URL, + 1 + ); + }; + + const packet = yield executeOnNextTickAndWaitForPause(evalCode, client); + const { + symbolWithName, + symbolWithoutName, + iteratorSymbol + } = packet.frame.environment.bindings.variables; + + equal(symbolWithName.value.type, "symbol"); + equal(symbolWithName.value.name, "Chris"); + + equal(symbolWithoutName.value.type, "symbol"); + ok(!("name" in symbolWithoutName.value)); + + equal(iteratorSymbol.value.type, "symbol"); + equal(iteratorSymbol.value.name, "Symbol.iterator"); + + finishClient(client); +} diff --git a/toolkit/devtools/server/tests/unit/test_symbols-02.js b/toolkit/devtools/server/tests/unit/test_symbols-02.js new file mode 100644 index 00000000000..95753d6ddbb --- /dev/null +++ b/toolkit/devtools/server/tests/unit/test_symbols-02.js @@ -0,0 +1,49 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Test that we don't run debuggee code when getting symbol names. + */ + +const URL = "foo.js"; + +function run_test() { + initTestDebuggerServer(); + const debuggee = addTestGlobal("test-symbols"); + const client = new DebuggerClient(DebuggerServer.connectPipe()); + + client.connect(function() { + attachTestTabAndResume(client, "test-symbols", function(response, tabClient, threadClient) { + add_task(testSymbols.bind(null, client, debuggee)); + run_next_test(); + }); + }); + + do_test_pending(); +} + +function* testSymbols(client, debuggee) { + const evalCode = () => { + Components.utils.evalInSandbox( + "(" + function () { + Symbol.prototype.toString = () => { + throw new Error("lololol"); + }; + var sym = Symbol("le troll"); + debugger; + } + "())", + debuggee, + "1.8", + URL, + 1 + ); + }; + + const packet = yield executeOnNextTickAndWaitForPause(evalCode, client); + const { sym } = packet.frame.environment.bindings.variables; + + equal(sym.value.type, "symbol"); + equal(sym.value.name, "le troll"); + + finishClient(client); +} diff --git a/toolkit/devtools/server/tests/unit/xpcshell.ini b/toolkit/devtools/server/tests/unit/xpcshell.ini index 48e8e0bbe17..b5d98195a89 100644 --- a/toolkit/devtools/server/tests/unit/xpcshell.ini +++ b/toolkit/devtools/server/tests/unit/xpcshell.ini @@ -205,3 +205,5 @@ reason = bug 937197 [test_registerClient.js] [test_client_request.js] [test_monitor_actor.js] +[test_symbols-01.js] +[test_symbols-02.js]