Bug 1588997 - Convert ObjectClient to protocol.js front. r=nchevobbe.

- Converted the ObjectClient into an protocoljs Front
- Converted the SymbolIteratorClient into a protocoljs Front and moved it to devtools/shared/fronts
- Converted the PropertyIteratorClient into a protocoljs Front and moved it to devtools/shared/fronts
- Converted the EnvironmentClient into a protocoljs Front and moved it to devtools/shared/fronts
- Modified calls to `DebuggerClient.release()` so that it tries to call the ObjectFront's release method first, and falls back on `DebuggerClient.release()` if there's no object front
- Changed reps so that it instantiates only one ObjectClient per grip
- Changed tests so that they expect what the Front's request method resolves to where applicable (i.e. ObjectFront.allocationStack resolves to allocationStack, not a packet object with an allocationStack property)
- Changed callbacks provided to ObjectClient methods to be chained to the ObjectFront methods (e.g. ObjectClient.getScope(callback) changed to ObjectFront.getScope().callback())
- Changed tests to use async/await (test_framebindings-x.js, test_functiongrips-x.js, test_objectgrips-x.js)
- Changed tests to expect protocoljs to throw an error string instead of an error object (test_objectgrips-fn-apply-03.js, test_threadlifetime-02.js, test_pauselifetime-03.js)

Differential Revision: https://phabricator.services.mozilla.com/D48182

--HG--
rename : devtools/shared/client/environment-client.js => devtools/shared/fronts/environment.js
rename : devtools/shared/client/property-iterator-client.js => devtools/shared/fronts/property-iterator.js
rename : devtools/shared/client/symbol-iterator-client.js => devtools/shared/fronts/symbol-iterator.js
extra : moz-landing-system : lando
This commit is contained in:
jaril 2019-10-17 16:06:25 +00:00
Родитель 8fdca46bc7
Коммит 696cf3b52a
61 изменённых файлов: 697 добавлений и 878 удалений

Просмотреть файл

@ -561,10 +561,18 @@ class ParentDevToolsInspectorSidebar extends BaseDevToolsPanel {
const oldActor = _lastObjectValueGrip && _lastObjectValueGrip.actor;
const newActor = newObjectValueGrip && newObjectValueGrip.actor;
const client = this.toolbox.target.client;
// Release the previously active actor on the remote debugging server.
if (oldActor && oldActor !== newActor) {
this.toolbox.target.client.release(oldActor);
const objFront = client.getFrontByID(oldActor);
if (objFront) {
objFront.release();
return;
}
// In case there's no object front, use the client's release method.
client.release(oldActor).catch(() => {});
}
}
}

Просмотреть файл

@ -34,7 +34,15 @@ function onConnect(connection) {
return connection.tabConnection.tabTarget.activeConsole.longString(grip);
},
releaseActor: function(actor) {
return connection.tabConnection.debuggerClient.release(actor);
const debuggerClient = connection.tabConnection.debuggerClient;
const objFront = debuggerClient.getFrontByID(actor);
if (objFront) {
return objFront.release();
}
// In case there's no object front, use the client's release method.
return debuggerClient.release(actor).catch(() => {});
},
};

Просмотреть файл

@ -70,9 +70,10 @@ function createObjectClient(grip: Grip) {
async function loadObjectProperties(root: Node) {
const utils = Reps.objectInspector.utils;
const properties = await utils.loadProperties.loadItemProperties(root, {
createObjectClient,
});
const properties = await utils.loadProperties.loadItemProperties(
root,
debuggerClient
);
return utils.node.getChildren({
item: root,
loadedProperties: new Map([[root.path, properties]]),
@ -84,7 +85,11 @@ function releaseActor(actor: String) {
return;
}
return debuggerClient.release(actor);
const objFront = debuggerClient.getFrontByID(actor);
if (objFront) {
return objFront.release().catch(() => {});
}
}
function sendPacket(packet: Object) {
@ -536,6 +541,10 @@ async function getSourceActorBreakableLines({
return actorLines;
}
function getFrontByID(actorID: String) {
return debuggerClient.getFrontByID(actorID);
}
const clientCommands = {
autocomplete,
blackBox,
@ -582,6 +591,7 @@ const clientCommands = {
getEventListenerBreakpointTypes,
detachWorkers,
lookupTarget,
getFrontByID,
};
export { setupCommands, clientCommands };

Просмотреть файл

@ -263,6 +263,7 @@ export type DebuggerClient = {
attachConsole: (actor: String, listeners: Array<*>) => Promise<*>,
createObjectClient: (grip: Grip) => ObjectClient,
release: (actor: String) => {},
getFrontByID: (actor: String) => { release: () => Promise<*> },
};
type ProcessDescriptor = Object;

Просмотреть файл

@ -26,6 +26,7 @@ add_task(async function() {
invokeInTab("mutate");
await onPaused;
await waitForSelectedSource(dbg, "script-mutate");
await waitForDispatch(dbg, "ADD_INLINE_PREVIEW");
is(
getScopeNodeLabel(dbg, 2),
@ -74,6 +75,7 @@ add_task(async function() {
await resume(dbg);
await waitForPaused(dbg);
await waitForDispatch(dbg, "ADD_INLINE_PREVIEW");
is(
getScopeNodeLabel(dbg, 2),

Просмотреть файл

@ -38,6 +38,7 @@ add_task(async function() {
await waitForDispatch(dbg, "LOAD_SOURCE_TEXT");
await waitForPaused(dbg);
await waitForDispatch(dbg, "ADD_INLINE_PREVIEW");
assertPausedLocation(dbg);
await waitForBreakpointCount(dbg, 2);

Просмотреть файл

@ -158,7 +158,14 @@ function Inspector(toolbox) {
if (!actor) {
return;
}
toolbox.target.client.release(actor);
const objFront = toolbox.target.client.getFrontByID(actor);
if (objFront) {
objFront.release();
return;
}
// In case there's no object front, use the client's release method.
toolbox.target.client.release(actor).catch(() => {});
},
});

Просмотреть файл

@ -121,8 +121,8 @@ loader.lazyRequireGetter(
);
loader.lazyRequireGetter(
this,
"EnvironmentClient",
"devtools/shared/client/environment-client"
"EnvironmentFront",
"devtools/shared/fronts/environment"
);
loader.lazyRequireGetter(
this,
@ -2333,8 +2333,8 @@ ScratchpadSidebar.prototype = {
});
VariablesViewController.attach(this.variablesView, {
getEnvironmentClient: grip => {
return new EnvironmentClient(
getEnvironmentFront: grip => {
return new EnvironmentFront(
this._scratchpad.debuggerClient,
grip
);
@ -2346,8 +2346,13 @@ ScratchpadSidebar.prototype = {
return this._scratchpad.webConsoleFront.longString(actor);
},
releaseActor: actor => {
const objFront = this._scratchpad.debuggerClient.getFrontByID(
actor
);
// Ignore release failure, since the object actor may have been already GC.
this._scratchpad.debuggerClient.release(actor).catch(() => {});
if (objFront) {
objFront.release().catch(() => {});
}
},
});
}

Просмотреть файл

@ -3957,11 +3957,22 @@ const {
function loadItemProperties(item, client, loadedProperties) {
const gripItem = getClosestGripNode(item);
const value = getValue(gripItem);
const [start, end] = item.meta ? [item.meta.startIndex, item.meta.endIndex] : [];
const promises = [];
let objectClient;
const getObjectClient = () => objectClient || client.createObjectClient(value);
if (value && client && client.getFrontByID) {
objectClient = client.getFrontByID(value.actor);
}
const getObjectClient = function() {
if (!objectClient) {
objectClient = client.createObjectClient(value);
}
return objectClient;
}
if (shouldLoadItemIndexedProperties(item, loadedProperties)) {
promises.push(enumIndexedProperties(getObjectClient(), start, end));
@ -4090,9 +4101,7 @@ const {
async function enumIndexedProperties(objectClient, start, end) {
try {
const {
iterator
} = await objectClient.enumProperties({
const iterator = await objectClient.enumProperties({
ignoreNonIndexedProperties: true
});
const response = await iteratorSlice(iterator, start, end);
@ -4105,9 +4114,7 @@ async function enumIndexedProperties(objectClient, start, end) {
async function enumNonIndexedProperties(objectClient, start, end) {
try {
const {
iterator
} = await objectClient.enumProperties({
const iterator = await objectClient.enumProperties({
ignoreIndexedProperties: true
});
const response = await iteratorSlice(iterator, start, end);
@ -4120,9 +4127,7 @@ async function enumNonIndexedProperties(objectClient, start, end) {
async function enumEntries(objectClient, start, end) {
try {
const {
iterator
} = await objectClient.enumEntries();
const iterator = await objectClient.enumEntries();
const response = await iteratorSlice(iterator, start, end);
return response;
} catch (e) {
@ -4133,9 +4138,7 @@ async function enumEntries(objectClient, start, end) {
async function enumSymbols(objectClient, start, end) {
try {
const {
iterator
} = await objectClient.enumSymbols();
const iterator = await objectClient.enumSymbols();
const response = await iteratorSlice(iterator, start, end);
return response;
} catch (e) {

Просмотреть файл

@ -39,7 +39,7 @@ var L10N = new LocalizationHelper(DBG_STRINGS_URI);
* Options for configuring the controller. Supported options:
* - getObjectClient: @see this._setClientGetters
* - getLongStringClient: @see this._setClientGetters
* - getEnvironmentClient: @see this._setClientGetters
* - getEnvironmentFront: @see this._setClientGetters
* - releaseActor: @see this._setClientGetters
* - overrideValueEvalMacro: @see _setEvaluationMacros
* - getterOrSetterEvalMacro: @see _setEvaluationMacros
@ -80,7 +80,7 @@ VariablesViewController.prototype = {
* Options for getting the client grips. Supported options:
* - getObjectClient: callback for creating an object grip client
* - getLongStringClient: callback for creating a long string grip client
* - getEnvironmentClient: callback for creating an environment client
* - getEnvironmentFront: callback for creating an environment front
* - releaseActor: callback for releasing an actor when it's no longer needed
*/
_setClientGetters: function(aOptions) {
@ -90,8 +90,8 @@ VariablesViewController.prototype = {
if (aOptions.getLongStringClient) {
this._getLongStringClient = aOptions.getLongStringClient;
}
if (aOptions.getEnvironmentClient) {
this._getEnvironmentClient = aOptions.getEnvironmentClient;
if (aOptions.getEnvironmentFront) {
this._getEnvironmentFront = aOptions.getEnvironmentFront;
}
if (aOptions.releaseActor) {
this._releaseActor = aOptions.releaseActor;
@ -253,7 +253,7 @@ VariablesViewController.prototype = {
ignoreNonIndexedProperties: true,
query: aQuery,
};
objectClient.enumProperties(options, ({ iterator }) => {
objectClient.enumProperties(options).then(iterator => {
const sliceGrip = {
type: "property-iterator",
propertyIterator: iterator,
@ -267,7 +267,7 @@ VariablesViewController.prototype = {
sort: true,
query: aQuery,
};
objectClient.enumProperties(options, ({ iterator }) => {
objectClient.enumProperties(options).then(iterator => {
const sliceGrip = {
type: "property-iterator",
propertyIterator: iterator,
@ -279,10 +279,9 @@ VariablesViewController.prototype = {
});
});
} else {
const options = { sort: true, query: aQuery };
// For objects, we just enumerate all the properties sorted by name.
objectClient.enumProperties(
{ sort: true, query: aQuery },
({ iterator }) => {
objectClient.enumProperties(options).then(iterator => {
const sliceGrip = {
type: "property-iterator",
propertyIterator: iterator,
@ -290,8 +289,7 @@ VariablesViewController.prototype = {
count: iterator.count,
};
deferred.resolve(this._populatePropertySlices(aTarget, sliceGrip));
}
);
});
}
return deferred.promise;
},
@ -326,7 +324,7 @@ VariablesViewController.prototype = {
// Refuse to play the proxy's stupid game and just expose the target and handler.
const deferred = defer();
const objectClient = this._getObjectClient(aGrip);
objectClient.getProxySlots(aResponse => {
objectClient.getProxySlots().then(aResponse => {
const target = aTarget.addItem(
"<target>",
{ value: aResponse.proxyTarget },
@ -383,7 +381,7 @@ VariablesViewController.prototype = {
return this._populateFromObjectWithIterator(aTarget, aGrip).then(() => {
const deferred = defer();
const objectClient = this._getObjectClient(aGrip);
objectClient.getPrototype(({ prototype }) => {
objectClient.getPrototype().then(prototype => {
this._populateObjectPrototype(aTarget, prototype);
deferred.resolve();
});
@ -398,7 +396,7 @@ VariablesViewController.prototype = {
const deferred = defer();
const objectClient = this._getObjectClient(aGrip);
objectClient.getPrototypeAndProperties(aResponse => {
objectClient.getPrototypeAndProperties().then(aResponse => {
const ownProperties = aResponse.ownProperties || {};
const prototype = aResponse.prototype || null;
// 'safeGetterValues' is new and isn't necessary defined on old actors.
@ -431,7 +429,7 @@ VariablesViewController.prototype = {
// If the object is a function we need to fetch its scope chain
// to show them as closures for the respective function.
if (aGrip.class == "Function") {
objectClient.getScope(aResponse => {
objectClient.getScope().then(aResponse => {
if (aResponse.error) {
// This function is bound to a built-in object or it's not present
// in the current scope chain. Not necessarily an actual error,
@ -481,7 +479,9 @@ VariablesViewController.prototype = {
} else {
const deferred = defer();
objectScopes.push(deferred.promise);
this._getEnvironmentClient(environment).getBindings(response => {
this._getEnvironmentFront(environment)
.getBindings()
.then(response => {
this._populateWithEnvironmentBindings(closure, response.bindings);
deferred.resolve();
});
@ -534,7 +534,7 @@ VariablesViewController.prototype = {
// eslint-disable-next-line new-cap
return new promise((resolve, reject) => {
objectClient.enumEntries(response => {
objectClient.enumEntries().then(response => {
if (response.error) {
// Older server might not support the enumEntries method
console.warn(response.error + ": " + response.message);

Просмотреть файл

@ -32,12 +32,18 @@ class ConsoleCommands {
return null;
}
return this.debuggerClient.release(actor);
const objFront = this.debuggerClient.getFrontByID(actor);
if (objFront) {
return objFront.release();
}
// In case there's no object front, use the client's release method.
return this.debuggerClient.release(actor).catch(() => {});
}
async fetchObjectProperties(grip, ignoreNonIndexedProperties) {
const client = new ObjectClient(this.currentTarget.client, grip);
const { iterator } = await client.enumProperties({
const iterator = await client.enumProperties({
ignoreNonIndexedProperties,
});
const { ownProperties } = await iterator.slice(0, iterator.count);
@ -46,7 +52,7 @@ class ConsoleCommands {
async fetchObjectEntries(grip) {
const client = new ObjectClient(this.currentTarget.client, grip);
const { iterator } = await client.enumEntries();
const iterator = await client.enumEntries();
const { ownProperties } = await iterator.slice(0, iterator.count);
return ownProperties;
}

Просмотреть файл

@ -97,7 +97,7 @@ async function testBackEnd(hud, actor) {
is(response.prototype.type, "null", "The prototype is null.");
response = await objClient.enumProperties({ ignoreIndexedProperties: true });
let slice = await response.iterator.slice(0, response.iterator.count);
let slice = await response.slice(0, response.count);
is(
Reflect.ownKeys(slice.ownProperties).length,
0,
@ -105,7 +105,7 @@ async function testBackEnd(hud, actor) {
);
response = await objClient.enumProperties({});
slice = await response.iterator.slice(0, response.iterator.count);
slice = await response.slice(0, response.count);
is(
Reflect.ownKeys(slice.ownProperties).length,
0,
@ -119,7 +119,7 @@ async function testBackEnd(hud, actor) {
is(response.descriptor, undefined, "The property does not exist.");
response = await objClient.enumSymbols();
slice = await response.iterator.slice(0, response.iterator.count);
slice = await response.slice(0, response.count);
is(slice.ownSymbols.length, 0, "No symbol property was retrieved.");
response = await objClient.getPrototype();

Просмотреть файл

@ -148,5 +148,9 @@ async function checkContentConsoleApiMessages(nonPrimitiveVariablesDisplayed) {
info("Clear and close the Browser Console");
await clearOutput(hud);
// We use waitForTick here because of a race condition. Otherwise, the test
// would occassionally fail because the transport is closed before pending server
// responses have been sent.
await waitForTick();
await BrowserConsoleManager.toggleBrowserConsole();
}

Просмотреть файл

@ -362,6 +362,12 @@ class WebConsoleConnectionProxy {
*/
releaseActor(actor) {
if (this.client) {
const objFront = this.client.getFrontByID(actor);
if (objFront) {
objFront.release().catch(() => {});
return;
}
// In case there's no object front, use the client's release method.
this.client.release(actor).catch(() => {});
}
}

Просмотреть файл

@ -53,9 +53,9 @@ async function testGetAllocationStack(tab, target) {
ok(objectClient, "Got Object Client");
const response = await objectClient.getPromiseAllocationStack();
ok(response.allocationStack.length, "Got promise allocation stack.");
ok(response.length, "Got promise allocation stack.");
for (const stack of response.allocationStack) {
for (const stack of response) {
is(stack.source.url, TAB_URL, "Got correct source URL.");
is(
stack.functionDisplayName,

Просмотреть файл

@ -83,12 +83,12 @@ async function testGetAllocationStack(client, target, makePromises) {
const objectClient = new ObjectClient(client, form);
ok(objectClient, "Got Object Client");
const response = await objectClient.getPromiseAllocationStack();
ok(response.allocationStack.length, "Got promise allocation stack.");
const allocationStack = await objectClient.getPromiseAllocationStack();
ok(allocationStack.length, "Got promise allocation stack.");
for (let i = 0; i < STACK_DATA.length; i++) {
const data = STACK_DATA[i];
const stack = response.allocationStack[i];
const stack = allocationStack[i];
ok(stack.source.url.startsWith("chrome:"), "Got a chrome source URL");
ok(stack.source.url.endsWith(SOURCE_URL), "Got correct source URL.");

Просмотреть файл

@ -69,11 +69,11 @@ async function testGetFulfillmentStack(tab, target) {
const objectClient = new ObjectClient(target.client, form);
ok(objectClient, "Got Object Client");
const response = await objectClient.getPromiseFulfillmentStack();
ok(response.fulfillmentStack.length, "Got promise allocation stack.");
const fulfillmentStack = await objectClient.getPromiseFulfillmentStack();
ok(fulfillmentStack.length, "Got promise allocation stack.");
for (let i = 0; i < TEST_DATA.length; i++) {
const stack = response.fulfillmentStack[i];
const stack = fulfillmentStack[i];
const data = TEST_DATA[i];
is(stack.source.url, TAB_URL, "Got correct source URL.");
is(

Просмотреть файл

@ -78,11 +78,11 @@ async function testGetRejectionStack(tab, target) {
const objectClient = new ObjectClient(target.client, form);
ok(objectClient, "Got Object Client");
const response = await objectClient.getPromiseRejectionStack();
ok(response.rejectionStack.length, "Got promise allocation stack.");
const rejectionStack = await objectClient.getPromiseRejectionStack();
ok(rejectionStack.length, "Got promise allocation stack.");
for (let i = 0; i < TEST_DATA.length; i++) {
const stack = response.rejectionStack[i];
const stack = rejectionStack[i];
const data = TEST_DATA[i];
is(stack.source.url, TAB_URL, "Got correct source URL.");
is(

Просмотреть файл

@ -276,9 +276,7 @@ function setBreakpoint(threadFront, location) {
function getPrototypeAndProperties(objClient) {
dump("getting prototype and properties.\n");
return new Promise(resolve => {
objClient.getPrototypeAndProperties(response => resolve(response));
});
return objClient.getPrototypeAndProperties();
}
function dumpn(msg) {

Просмотреть файл

@ -35,7 +35,7 @@ function run_test() {
}
function test_pause_frame() {
gThreadFront.once("paused", function(packet) {
gThreadFront.once("paused", async function(packet) {
const bindings = packet.frame.environment.bindings;
const args = bindings.arguments;
const vars = bindings.variables;
@ -57,7 +57,7 @@ function test_pause_frame() {
Assert.ok(!!vars.c.value.actor);
const objClient = gThreadFront.pauseGrip(vars.c.value);
objClient.getPrototypeAndProperties(function(response) {
const response = await objClient.getPrototypeAndProperties();
Assert.equal(response.ownProperties.a.configurable, true);
Assert.equal(response.ownProperties.a.enumerable, true);
Assert.equal(response.ownProperties.a.writable, true);
@ -69,11 +69,9 @@ function test_pause_frame() {
Assert.equal(response.ownProperties.b.value.type, "undefined");
Assert.equal(false, "class" in response.ownProperties.b.value);
gThreadFront.resume().then(function() {
await gThreadFront.resume();
finishClient(gClient);
});
});
});
/* eslint-disable */
gDebuggee.eval("(" + function () {

Просмотреть файл

@ -35,7 +35,7 @@ function run_test() {
}
function test_pause_frame() {
gThreadFront.once("paused", function(packet) {
gThreadFront.once("paused", async function(packet) {
let parentEnv = packet.frame.environment.parent;
const bindings = parentEnv.bindings;
const args = bindings.arguments;
@ -50,16 +50,14 @@ function test_pause_frame() {
parentEnv = parentEnv.parent.parent;
Assert.notEqual(parentEnv, undefined);
const objClient = gThreadFront.pauseGrip(parentEnv.object);
objClient.getPrototypeAndProperties(function(response) {
const response = await objClient.getPrototypeAndProperties();
Assert.equal(response.ownProperties.Object.value.type, "object");
Assert.equal(response.ownProperties.Object.value.class, "Function");
Assert.ok(!!response.ownProperties.Object.value.actor);
gThreadFront.resume().then(function() {
await gThreadFront.resume();
finishClient(gClient);
});
});
});
/* eslint-disable */
gDebuggee.eval("(" + function () {

Просмотреть файл

@ -36,7 +36,7 @@ function run_test() {
}
function test_pause_frame() {
gThreadFront.once("paused", function(packet) {
gThreadFront.once("paused", async function(packet) {
const env = packet.frame.environment;
Assert.notEqual(env, undefined);
@ -54,17 +54,15 @@ function test_pause_frame() {
Assert.ok(!!vars.arguments.value.actor);
const objClient = gThreadFront.pauseGrip(env.object);
objClient.getPrototypeAndProperties(function(response) {
const response = await objClient.getPrototypeAndProperties();
Assert.equal(response.ownProperties.PI.value, Math.PI);
Assert.equal(response.ownProperties.cos.value.type, "object");
Assert.equal(response.ownProperties.cos.value.class, "Function");
Assert.ok(!!response.ownProperties.cos.value.actor);
gThreadFront.resume().then(function() {
await gThreadFront.resume();
finishClient(gClient);
});
});
});
/* eslint-disable */
gDebuggee.eval("(" + function () {

Просмотреть файл

@ -37,12 +37,12 @@ function run_test() {
}
function test_pause_frame() {
gThreadFront.once("paused", function(packet) {
gThreadFront.once("paused", async function(packet) {
const env = packet.frame.environment;
Assert.notEqual(env, undefined);
const objClient = gThreadFront.pauseGrip(env.object);
objClient.getPrototypeAndProperties(function(response) {
let response = await objClient.getPrototypeAndProperties();
Assert.equal(response.ownProperties.one.value, 1);
Assert.equal(response.ownProperties.two.value, 2);
Assert.equal(response.ownProperties.foo, undefined);
@ -51,7 +51,7 @@ function test_pause_frame() {
Assert.notEqual(parentEnv, undefined);
const parentClient = gThreadFront.pauseGrip(parentEnv.object);
parentClient.getPrototypeAndProperties(function(response) {
response = await parentClient.getPrototypeAndProperties();
Assert.equal(response.ownProperties.PI.value, Math.PI);
Assert.equal(response.ownProperties.cos.value.type, "object");
Assert.equal(response.ownProperties.cos.value.class, "Function");
@ -71,12 +71,9 @@ function test_pause_frame() {
Assert.ok(!!vars.arguments.value.actor);
Assert.equal(vars.foo.value, 2 * Math.PI);
gThreadFront.resume().then(function() {
await gThreadFront.resume();
finishClient(gClient);
});
});
});
});
/* eslint-disable */
gDebuggee.eval("(" + function () {

Просмотреть файл

@ -36,12 +36,12 @@ function run_test() {
}
function test_pause_frame() {
gThreadFront.once("paused", function(packet) {
gThreadFront.once("paused", async function(packet) {
const env = packet.frame.environment;
Assert.notEqual(env, undefined);
const objClient = gThreadFront.pauseGrip(env.object);
objClient.getPrototypeAndProperties(function(response) {
let response = await objClient.getPrototypeAndProperties();
Assert.equal(response.ownProperties.PI.value, Math.PI);
Assert.equal(response.ownProperties.cos.value.type, "object");
Assert.equal(response.ownProperties.cos.value.class, "Function");
@ -52,19 +52,16 @@ function test_pause_frame() {
Assert.notEqual(parentEnv, undefined);
const parentClient = gThreadFront.pauseGrip(parentEnv.object);
parentClient.getPrototypeAndProperties(function(response) {
response = await parentClient.getPrototypeAndProperties();
Assert.equal(response.ownProperties.a.value, Math.PI * 100);
Assert.equal(response.ownProperties.r.value, 10);
Assert.equal(response.ownProperties.Object.value.type, "object");
Assert.equal(response.ownProperties.Object.value.class, "Function");
Assert.ok(!!response.ownProperties.Object.value.actor);
gThreadFront.resume().then(function() {
await gThreadFront.resume();
finishClient(gClient);
});
});
});
});
gDebuggee.eval(
"var a, r = 10;\n" +

Просмотреть файл

@ -32,7 +32,7 @@ function run_test() {
}
function test_banana_environment() {
gThreadFront.once("paused", function(packet) {
gThreadFront.once("paused", async function(packet) {
const env = packet.frame.environment;
equal(env.type, "function");
equal(env.function.name, "banana3");
@ -49,10 +49,9 @@ function test_banana_environment() {
equal(parent.type, "function");
equal(parent.function.name, "banana");
gThreadFront.resume().then(function() {
await gThreadFront.resume();
finishClient(gClient);
});
});
gDebuggee.eval(
"function banana(x) {\n" +

Просмотреть файл

@ -7,7 +7,7 @@
var gDebuggee;
var gClient;
var gThreadFront;
const EnvironmentClient = require("devtools/shared/client/environment-client");
const { EnvironmentFront } = require("devtools/shared/fronts/environment");
Services.prefs.setBoolPref("security.allow_eval_with_system_principal", true);
@ -15,7 +15,7 @@ registerCleanupFunction(() => {
Services.prefs.clearUserPref("security.allow_eval_with_system_principal");
});
// Test that the EnvironmentClient's getBindings() method works as expected.
// Test that the EnvironmentFront's getBindings() method works as expected.
function run_test() {
initTestDebuggerServer();
gDebuggee = addTestGlobal("test-bindings");
@ -35,7 +35,7 @@ function run_test() {
}
function test_banana_environment() {
gThreadFront.once("paused", function(packet) {
gThreadFront.once("paused", async function(packet) {
const environment = packet.frame.environment;
Assert.equal(environment.type, "function");
@ -45,24 +45,19 @@ function test_banana_environment() {
const grandpa = parent.parent;
Assert.equal(grandpa.type, "function");
const envClient = new EnvironmentClient(gClient, environment);
envClient.getBindings(response => {
Assert.equal(response.bindings.arguments[0].z.value, "z");
const envClient = new EnvironmentFront(gClient, environment);
let response = await envClient.getBindings();
Assert.equal(response.arguments[0].z.value, "z");
const parentClient = new EnvironmentClient(gClient, parent);
parentClient.getBindings(response => {
Assert.equal(
response.bindings.variables.banana3.value.class,
"Function"
);
const parentClient = new EnvironmentFront(gClient, parent);
response = await parentClient.getBindings();
Assert.equal(response.variables.banana3.value.class, "Function");
const grandpaClient = new EnvironmentClient(gClient, grandpa);
grandpaClient.getBindings(response => {
Assert.equal(response.bindings.arguments[0].y.value, "y");
gThreadFront.resume().then(() => finishClient(gClient));
});
});
});
const grandpaClient = new EnvironmentFront(gClient, grandpa);
response = await grandpaClient.getBindings();
Assert.equal(response.arguments[0].y.value, "y");
await gThreadFront.resume();
finishClient(gClient);
});
gDebuggee.eval(

Просмотреть файл

@ -35,7 +35,7 @@ function run_test() {
}
function test_named_function() {
gThreadFront.once("paused", function(packet) {
gThreadFront.once("paused", async function(packet) {
const args = packet.frame.arguments;
Assert.equal(args[0].class, "Function");
@ -43,19 +43,19 @@ function test_named_function() {
Assert.equal(args[0].displayName, "stopMe");
const objClient = gThreadFront.pauseGrip(args[0]);
objClient.getParameterNames(function(response) {
const response = await objClient.getParameterNames();
Assert.equal(response.parameterNames.length, 1);
Assert.equal(response.parameterNames[0], "arg1");
gThreadFront.resume().then(test_inferred_name_function);
});
await gThreadFront.resume();
test_inferred_name_function();
});
gDebuggee.eval("stopMe(stopMe)");
}
function test_inferred_name_function() {
gThreadFront.once("paused", function(packet) {
gThreadFront.once("paused", async function(packet) {
const args = packet.frame.arguments;
Assert.equal(args[0].class, "Function");
@ -64,21 +64,21 @@ function test_inferred_name_function() {
Assert.equal(args[0].displayName, "m");
const objClient = gThreadFront.pauseGrip(args[0]);
objClient.getParameterNames(function(response) {
const response = await objClient.getParameterNames();
Assert.equal(response.parameterNames.length, 3);
Assert.equal(response.parameterNames[0], "foo");
Assert.equal(response.parameterNames[1], "bar");
Assert.equal(response.parameterNames[2], "baz");
gThreadFront.resume().then(test_anonymous_function);
});
await gThreadFront.resume();
test_anonymous_function();
});
gDebuggee.eval("var o = { m: function(foo, bar, baz) { } }; stopMe(o.m)");
}
function test_anonymous_function() {
gThreadFront.once("paused", function(packet) {
gThreadFront.once("paused", async function(packet) {
const args = packet.frame.arguments;
Assert.equal(args[0].class, "Function");
@ -87,17 +87,15 @@ function test_anonymous_function() {
Assert.equal(args[0].displayName, undefined);
const objClient = gThreadFront.pauseGrip(args[0]);
objClient.getParameterNames(function(response) {
const response = await objClient.getParameterNames();
Assert.equal(response.parameterNames.length, 3);
Assert.equal(response.parameterNames[0], "foo");
Assert.equal(response.parameterNames[1], "bar");
Assert.equal(response.parameterNames[2], "baz");
gThreadFront.resume().then(function() {
await gThreadFront.resume();
finishClient(gClient);
});
});
});
gDebuggee.eval("stopMe(function(foo, bar, baz) { })");
}

Просмотреть файл

@ -11,20 +11,20 @@ registerCleanupFunction(() => {
add_task(
threadFrontTest(async ({ threadFront, debuggee, client }) => {
return new Promise(resolve => {
threadFront.once("paused", function(packet) {
threadFront.once("paused", async function(packet) {
const args = packet.frame.arguments;
Assert.equal(args[0].class, "Object");
const objClient = threadFront.pauseGrip(args[0]);
objClient.getOwnPropertyNames(function(response) {
const response = await objClient.getOwnPropertyNames();
Assert.equal(response.ownPropertyNames.length, 3);
Assert.equal(response.ownPropertyNames[0], "a");
Assert.equal(response.ownPropertyNames[1], "b");
Assert.equal(response.ownPropertyNames[2], "c");
threadFront.resume().then(resolve);
});
await threadFront.resume();
resolve();
});
debuggee.eval(

Просмотреть файл

@ -12,24 +12,23 @@ registerCleanupFunction(() => {
add_task(
threadFrontTest(async ({ threadFront, debuggee, client }) => {
return new Promise(resolve => {
threadFront.once("paused", function(packet) {
threadFront.once("paused", async function(packet) {
const args = packet.frame.arguments;
Assert.equal(args[0].class, "Object");
const objClient = threadFront.pauseGrip(args[0]);
objClient.getPrototype(function(response) {
let response = await objClient.getPrototype();
Assert.ok(response.prototype != undefined);
const protoClient = threadFront.pauseGrip(response.prototype);
protoClient.getOwnPropertyNames(function(response) {
response = await protoClient.getOwnPropertyNames();
Assert.equal(response.ownPropertyNames.length, 2);
Assert.equal(response.ownPropertyNames[0], "b");
Assert.equal(response.ownPropertyNames[1], "c");
threadFront.resume().then(resolve);
});
});
await threadFront.resume();
resolve();
});
debuggee.eval(

Просмотреть файл

@ -12,35 +12,33 @@ registerCleanupFunction(() => {
add_task(
threadFrontTest(async ({ threadFront, debuggee, client }) => {
return new Promise(resolve => {
threadFront.once("paused", function(packet) {
threadFront.once("paused", async function(packet) {
const args = packet.frame.arguments;
Assert.equal(args[0].class, "Object");
const objClient = threadFront.pauseGrip(args[0]);
objClient.getProperty("x", function(response) {
let response = await objClient.getProperty("x");
Assert.equal(response.descriptor.configurable, true);
Assert.equal(response.descriptor.enumerable, true);
Assert.equal(response.descriptor.writable, true);
Assert.equal(response.descriptor.value, 10);
objClient.getProperty("y", function(response) {
response = await objClient.getProperty("y");
Assert.equal(response.descriptor.configurable, true);
Assert.equal(response.descriptor.enumerable, true);
Assert.equal(response.descriptor.writable, true);
Assert.equal(response.descriptor.value, "kaiju");
objClient.getProperty("a", function(response) {
response = await objClient.getProperty("a");
Assert.equal(response.descriptor.configurable, true);
Assert.equal(response.descriptor.enumerable, true);
Assert.equal(response.descriptor.get.type, "object");
Assert.equal(response.descriptor.get.class, "Function");
Assert.equal(response.descriptor.set.type, "undefined");
threadFront.resume().then(resolve);
});
});
});
await threadFront.resume();
resolve();
});
debuggee.eval(

Просмотреть файл

@ -12,13 +12,13 @@ registerCleanupFunction(() => {
add_task(
threadFrontTest(async ({ threadFront, debuggee, client }) => {
return new Promise(resolve => {
threadFront.once("paused", function(packet) {
threadFront.once("paused", async function(packet) {
const args = packet.frame.arguments;
Assert.equal(args[0].class, "Object");
const objClient = threadFront.pauseGrip(args[0]);
objClient.getPrototypeAndProperties(function(response) {
let response = await objClient.getPrototypeAndProperties();
Assert.equal(response.ownProperties.x.configurable, true);
Assert.equal(response.ownProperties.x.enumerable, true);
Assert.equal(response.ownProperties.x.writable, true);
@ -38,12 +38,11 @@ add_task(
Assert.ok(response.prototype != undefined);
const protoClient = threadFront.pauseGrip(response.prototype);
protoClient.getOwnPropertyNames(function(response) {
response = await protoClient.getOwnPropertyNames();
Assert.ok(response.ownPropertyNames.toString != undefined);
threadFront.resume().then(resolve);
});
});
await threadFront.resume();
resolve();
});
debuggee.eval(

Просмотреть файл

@ -16,7 +16,7 @@ registerCleanupFunction(() => {
add_task(
threadFrontTest(async ({ threadFront, debuggee, client }) => {
return new Promise(resolve => {
threadFront.once("paused", function(packet) {
threadFront.once("paused", async function(packet) {
const obj1 = packet.frame.arguments[0];
Assert.ok(obj1.frozen);
@ -29,7 +29,8 @@ add_task(
const obj2Client = threadFront.pauseGrip(obj2);
Assert.ok(!obj2Client.isFrozen);
threadFront.resume().then(resolve);
await threadFront.resume();
resolve();
});
debuggee.eval(

Просмотреть файл

@ -16,7 +16,7 @@ registerCleanupFunction(() => {
add_task(
threadFrontTest(async ({ threadFront, debuggee, client }) => {
return new Promise(resolve => {
threadFront.once("paused", function(packet) {
threadFront.once("paused", async function(packet) {
const obj1 = packet.frame.arguments[0];
Assert.ok(obj1.sealed);
@ -29,7 +29,8 @@ add_task(
const obj2Client = threadFront.pauseGrip(obj2);
Assert.ok(!obj2Client.isSealed);
threadFront.resume().then(resolve);
await threadFront.resume();
resolve();
});
debuggee.eval(

Просмотреть файл

@ -16,7 +16,7 @@ registerCleanupFunction(() => {
add_task(
threadFrontTest(async ({ threadFront, debuggee, client }) => {
return new Promise(resolve => {
threadFront.once("paused", function(packet) {
threadFront.once("paused", async function(packet) {
const [f, s, ne, e] = packet.frame.arguments;
const [
fClient,
@ -37,7 +37,8 @@ add_task(
Assert.ok(e.extensible);
Assert.ok(eClient.isExtensible);
threadFront.resume().then(resolve);
await threadFront.resume();
resolve();
});
debuggee.eval(

Просмотреть файл

@ -11,13 +11,13 @@ registerCleanupFunction(() => {
add_task(
threadFrontTest(async ({ threadFront, debuggee }) => {
return new Promise(resolve => {
threadFront.once("paused", function(packet) {
threadFront.once("paused", async function(packet) {
const args = packet.frame.arguments;
Assert.equal(args[0].class, "Object");
const objClient = threadFront.pauseGrip(args[0]);
objClient.getPrototypeAndProperties(function(response) {
const response = await objClient.getPrototypeAndProperties();
const { a, b, c, d, e, f, g } = response.ownProperties;
testPropertyType(a, "Infinity");
testPropertyType(b, "-Infinity");
@ -27,8 +27,8 @@ add_task(
testPropertyType(f, "BigInt");
testPropertyType(g, "BigInt");
threadFront.resume().then(resolve);
});
await threadFront.resume();
resolve();
});
debuggee.eval(

Просмотреть файл

@ -35,13 +35,13 @@ function run_test() {
}
function test_object_grip() {
gThreadFront.once("paused", function(packet) {
gThreadFront.once("paused", async function(packet) {
const person = packet.frame.environment.bindings.variables.person;
Assert.equal(person.value.class, "Object");
const personClient = gThreadFront.pauseGrip(person.value);
personClient.getPrototypeAndProperties(response => {
let response = await personClient.getPrototypeAndProperties();
Assert.equal(response.ownProperties.getName.value.class, "Function");
Assert.equal(response.ownProperties.getAge.value.class, "Function");
@ -57,20 +57,21 @@ function test_object_grip() {
const getFooClient = gThreadFront.pauseGrip(
response.ownProperties.getFoo.value
);
getNameClient.getScope(response => {
Assert.equal(response.scope.bindings.arguments[0].name.value, "Bob");
getAgeClient.getScope(response => {
Assert.equal(response.scope.bindings.arguments[1].age.value, 58);
response = await getNameClient.getScope();
let bindings = await response.scope.bindings();
Assert.equal(bindings.arguments[0].name.value, "Bob");
getFooClient.getScope(response => {
Assert.equal(response.scope.bindings.variables.foo.value, 10);
response = await getAgeClient.getScope();
bindings = await response.scope.bindings();
Assert.equal(bindings.arguments[1].age.value, 58);
gThreadFront.resume().then(() => finishClient(gClient));
});
});
});
});
response = await getFooClient.getScope();
bindings = await response.scope.bindings();
Assert.equal(bindings.variables.foo.value, 10);
await gThreadFront.resume();
finishClient(gClient);
});
/* eslint-disable */

Просмотреть файл

@ -39,11 +39,11 @@ function run_test() {
}
function test_object_grip() {
gThreadFront.once("paused", function(packet) {
gThreadFront.once("paused", async function(packet) {
const args = packet.frame.arguments;
const objClient = gThreadFront.pauseGrip(args[0]);
objClient.getOwnPropertyNames(function(response) {
const response = await objClient.getOwnPropertyNames();
const opn = response.ownPropertyNames;
Assert.equal(opn.length, 4);
opn.sort();
@ -52,11 +52,9 @@ function test_object_grip() {
Assert.equal(opn[2], "lineNumber");
Assert.equal(opn[3], "message");
gThreadFront.resume().then(function() {
await gThreadFront.resume();
finishClient(gClient);
});
});
});
gDebuggee.eval("stopMe(new TypeError('error message text'))");
}

Просмотреть файл

@ -163,18 +163,16 @@ function test_display_string() {
gThreadFront.once("paused", function(packet) {
const args = packet.frame.arguments;
(function loop() {
(async function loop() {
const objClient = gThreadFront.pauseGrip(args.pop());
objClient.getDisplayString(function({ displayString }) {
Assert.equal(displayString, testCases.pop().output);
const response = await objClient.getDisplayString();
Assert.equal(response.displayString, testCases.pop().output);
if (args.length) {
loop();
} else {
gThreadFront.resume().then(function() {
await gThreadFront.resume();
finishClient(gClient);
});
}
});
})();
});

Просмотреть файл

@ -56,15 +56,14 @@ function eval_code() {
);
}
function test_definition_site(func, obj) {
func.getDefinitionSite(({ error, source, line, column }) => {
Assert.ok(!error);
Assert.equal(source.url, getFilePath("test_objectgrips-13.js"));
Assert.equal(line, gDebuggee.line0 + 1);
Assert.equal(column, 0);
async function test_definition_site(func, obj) {
const response = await func.getDefinitionSite();
Assert.ok(!response.error);
Assert.equal(response.source.url, getFilePath("test_objectgrips-13.js"));
Assert.equal(response.line, gDebuggee.line0 + 1);
Assert.equal(response.column, 0);
test_bad_definition_site(obj);
});
}
function test_bad_definition_site(obj) {

Просмотреть файл

@ -201,7 +201,7 @@ function check_proxy_slots(debuggee, testOptions, grip, proxySlots) {
if (grip.class !== "Proxy") {
strictEqual(
proxySlots,
undefined,
null,
"Slots can only be retrived for Proxy grips."
);
} else if (global === debuggee) {

Просмотреть файл

@ -53,14 +53,7 @@ add_task(
`);
});
async function check_enum_properties(response) {
info("Check enumProperties response");
ok(
response && Object.getOwnPropertyNames(response).includes("iterator"),
"The response object has an iterator property"
);
const { iterator } = response;
async function check_enum_properties(iterator) {
equal(iterator.count, 10, "iterator.count has the expected value");
info("Check iterator.slice response for all properties");
@ -113,14 +106,7 @@ add_task(
equal(ownProperties[names[1]].value, `property_3_value`);
}
async function check_enum_symbols(response) {
info("Check enumProperties response");
ok(
response && Object.getOwnPropertyNames(response).includes("iterator"),
"The response object has an iterator property"
);
const { iterator } = response;
async function check_enum_symbols(iterator) {
equal(iterator.count, 13, "iterator.count has the expected value");
info("Check iterator.slice response for all symbols");

Просмотреть файл

@ -286,13 +286,7 @@ async function test_object_grip(
});
}
async function check_enum_properties(response, expected = []) {
ok(
response && Object.getOwnPropertyNames(response).includes("iterator"),
"The response object has an iterator property"
);
const { iterator } = response;
async function check_enum_properties(iterator, expected = []) {
equal(
iterator.count,
expected.length,

Просмотреть файл

@ -246,11 +246,11 @@ async function test_unsafe_grips(
response = await objClient.enumProperties({
ignoreIndexedProperties: true,
});
slice = await response.iterator.slice(0, response.iterator.count);
slice = await response.slice(0, response.count);
check_properties(slice.ownProperties, data, isUnsafe);
response = await objClient.enumProperties({});
slice = await response.iterator.slice(0, response.iterator.count);
slice = await response.slice(0, response.count);
check_properties(slice.ownProperties, data, isUnsafe);
response = await objClient.getOwnPropertyNames();
@ -260,7 +260,7 @@ async function test_unsafe_grips(
check_property(response.descriptor, data, isUnsafe);
response = await objClient.enumSymbols();
slice = await response.iterator.slice(0, response.iterator.count);
slice = await response.slice(0, response.count);
check_symbol_names(slice.ownSymbols, data, isUnsafe);
response = await objClient.getProperty(Symbol.for("x"));

Просмотреть файл

@ -15,7 +15,7 @@ add_task(
threadFront.once("paused", async function(packet) {
const [grip] = packet.frame.arguments;
const objClient = threadFront.pauseGrip(grip);
const { iterator } = await objClient.enumSymbols();
const iterator = await objClient.enumSymbols();
const { ownSymbols } = await iterator.slice(0, iterator.count);
strictEqual(ownSymbols.length, 1, "There is 1 symbol property.");

Просмотреть файл

@ -49,7 +49,7 @@ async function test_object_grip(debuggee, threadFront) {
await method.apply(obj, []);
Assert.ok(false, "expected exception");
} catch (err) {
Assert.equal(err.message, "debugee object is not callable");
Assert.ok(!!err.match(/debugee object is not callable/));
}
}

Просмотреть файл

@ -46,11 +46,12 @@ function test_pause_frame() {
// Make a bogus request to the grip actor. Should get
// unrecognized-packet-type (and not no-such-actor).
try {
await gClient.request({ to: objActor, type: "bogusRequest" });
const objFront = gClient.getFrontByID(objActor);
await objFront.request({ to: objActor, type: "bogusRequest" });
ok(false, "bogusRequest should throw");
} catch (e) {
ok(true, "bogusRequest thrown");
Assert.equal(e.error, "unrecognizedPacketType");
Assert.ok(!!e.match(/unrecognizedPacketType/));
}
Assert.ok(objClient.valid);
@ -58,11 +59,12 @@ function test_pause_frame() {
// Now that we've resumed, should get no-such-actor for the
// same request.
try {
await gClient.request({ to: objActor, type: "bogusRequest" });
const objFront = gClient.getFrontByID(objActor);
await objFront.request({ to: objActor, type: "bogusRequest" });
ok(false, "bogusRequest should throw");
} catch (e) {
ok(true, "bogusRequest thrown");
Assert.equal(e.error, "noSuchActor");
Assert.ok(!!e.match(/noSuchActor/));
}
Assert.ok(!objClient.valid);
finishClient(gClient);

Просмотреть файл

@ -68,7 +68,7 @@ async function testGetDependentPromises(client, front, makePromises) {
// Get the dependent promises for promise p and assert that the list of
// dependent promises is correct
await new Promise(resolve => {
objectClient.getDependentPromises(response => {
objectClient.getDependentPromises().then(response => {
const dependentNames = response.promises.map(
p => p.preview.ownProperties.name.value
);

Просмотреть файл

@ -44,27 +44,29 @@ function test_thread_lifetime() {
});
// Successful promotion won't return an error.
Assert.equal(response.error, undefined);
gThreadFront.once("paused", function(packet) {
gThreadFront.once("paused", async function(packet) {
// Verify that the promoted actor is returned again.
Assert.equal(pauseGrip.actor, packet.frame.arguments[0].actor);
// Now that we've resumed, release the thread-lifetime grip.
gClient.release(pauseGrip.actor, async function(response) {
const objFront = new ObjectClient(gClient, pauseGrip);
await objFront.release();
const objFront2 = new ObjectClient(gClient, pauseGrip);
try {
await gClient.request(
{ to: pauseGrip.actor, type: "bogusRequest" },
function(response) {
Assert.equal(response.error, "noSuchActor");
await objFront2
.request({ to: pauseGrip.actor, type: "bogusRequest" })
.catch(function(response) {
Assert.ok(!!response.match(/noSuchActor/));
gThreadFront.resume().then(function() {
finishClient(gClient);
});
}
);
throw new Error();
});
ok(false, "bogusRequest should throw");
} catch (e) {
ok(true, "bogusRequest thrown");
}
});
});
gThreadFront.resume();
});

Просмотреть файл

@ -1,53 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const {
arg,
DebuggerClient,
} = require("devtools/shared/client/debugger-client");
/**
* Environment clients are used to manipulate the lexical environment actors.
*
* @param client DebuggerClient
* The debugger client parent.
* @param form Object
* The form sent across the remote debugging protocol.
*/
function EnvironmentClient(client, form) {
this._client = client;
this._form = form;
this.request = this._client.request;
}
exports.EnvironmentClient = EnvironmentClient;
EnvironmentClient.prototype = {
get actor() {
return this._form.actor;
},
get _transport() {
return this._client._transport;
},
/**
* Fetches the bindings introduced by this lexical environment.
*/
getBindings: DebuggerClient.requester({
type: "bindings",
}),
/**
* Changes the value of the identifier whose name is name (a string) to that
* represented by value (a grip).
*/
assign: DebuggerClient.requester({
type: "assign",
name: arg(0),
value: arg(1),
}),
};
module.exports = EnvironmentClient;

Просмотреть файл

@ -9,10 +9,7 @@ DevToolsModules(
'constants.js',
'debugger-client.js',
'deprecated-thread-client.js',
'environment-client.js',
'event-source.js',
'long-string-client.js',
'object-client.js',
'property-iterator-client.js',
'symbol-iterator-client.js',
)

Просмотреть файл

@ -4,20 +4,11 @@
"use strict";
const { objectSpec } = require("devtools/shared/specs/object");
const {
arg,
DebuggerClient,
} = require("devtools/shared/client/debugger-client");
loader.lazyRequireGetter(
this,
"PropertyIteratorClient",
"devtools/shared/client/property-iterator-client"
);
loader.lazyRequireGetter(
this,
"SymbolIteratorClient",
"devtools/shared/client/symbol-iterator-client"
);
FrontClassWithSpec,
registerFront,
} = require("devtools/shared/protocol");
/**
* Grip clients are used to retrieve information about the relevant object.
@ -27,97 +18,73 @@ loader.lazyRequireGetter(
* @param grip object
* A pause-lifetime object grip returned by the protocol.
*/
function ObjectClient(client, grip) {
class ObjectClient extends FrontClassWithSpec(objectSpec) {
constructor(client, grip) {
super(client);
this._grip = grip;
this._client = client;
this.request = this._client.request;
}
this.valid = true;
this.actorID = this._grip.actor;
this.manage(this);
}
ObjectClient.prototype = {
get actor() {
return this._grip.actor;
},
return this.actorID;
}
get _transport() {
return this._client._transport;
},
valid: true,
}
get isFrozen() {
return this._grip.frozen;
},
}
get isSealed() {
return this._grip.sealed;
},
}
get isExtensible() {
return this._grip.extensible;
},
}
threadGrip: DebuggerClient.requester({
type: "threadGrip",
}),
getDefinitionSite: DebuggerClient.requester(
{
type: "definitionSite",
},
{
before: function(packet) {
getDefinitionSite() {
if (this._grip.class != "Function") {
throw new Error(
"getDefinitionSite is only valid for function grips."
);
console.error("getDefinitionSite is only valid for function grips.");
return null;
}
return packet;
},
return super.definitionSite();
}
),
/**
* Request the names of a function's formal parameters.
*
* @param onResponse function
* Called with an object of the form:
* { parameterNames:[<parameterName>, ...] }
* where each <parameterName> is the name of a parameter.
*/
getParameterNames: DebuggerClient.requester(
{
type: "parameterNames",
},
{
before: function(packet) {
getParameterNames() {
if (this._grip.class !== "Function") {
throw new Error(
"getParameterNames is only valid for function grips."
);
console.error("getParameterNames is only valid for function grips.");
return null;
}
return packet;
},
return super.parameterNames();
}
),
/**
* Request the names of the properties defined on the object and not its
* prototype.
*
* @param onResponse function Called with the request's response.
*/
getOwnPropertyNames: DebuggerClient.requester({
type: "ownPropertyNames",
}),
getOwnPropertyNames() {
return super.ownPropertyNames();
}
/**
* Request the prototype and own properties of the object.
*
* @param onResponse function Called with the request's response.
*/
getPrototypeAndProperties: DebuggerClient.requester({
type: "prototypeAndProperties",
}),
getPrototypeAndProperties() {
return super.prototypeAndProperties();
}
/**
* Request a PropertyIteratorClient instance to ease listing
* Request a PropertyIteratorFront instance to ease listing
* properties for this object.
*
* @param options Object
@ -132,277 +99,154 @@ ObjectClient.prototype = {
* - sort Boolean
* If true, the iterator will sort the properties by name
* before dispatching them.
* @param onResponse function Called with the client instance.
*/
enumProperties: DebuggerClient.requester(
{
type: "enumProperties",
options: arg(0),
},
{
after: function(response) {
if (response.iterator) {
return {
iterator: new PropertyIteratorClient(
this._client,
response.iterator
),
};
enumProperties(options) {
return super.enumProperties(options);
}
return response;
},
}
),
/**
* Request a PropertyIteratorClient instance to enumerate entries in a
* Request a PropertyIteratorFront instance to enumerate entries in a
* Map/Set-like object.
*
* @param onResponse function Called with the request's response.
*/
enumEntries: DebuggerClient.requester(
{
type: "enumEntries",
},
{
before: function(packet) {
enumEntries() {
if (
!["Map", "WeakMap", "Set", "WeakSet", "Storage"].includes(
this._grip.class
)
) {
throw new Error(
console.error(
"enumEntries is only valid for Map/Set/Storage-like grips."
);
return null;
}
return packet;
},
after: function(response) {
if (response.iterator) {
return {
iterator: new PropertyIteratorClient(
this._client,
response.iterator
),
};
return super.enumEntries();
}
return response;
},
}
),
/**
* Request a SymbolIteratorClient instance to enumerate symbols in an object.
*
* @param onResponse function Called with the request's response.
* Request a SymbolIteratorFront instance to enumerate symbols in an object.
*/
enumSymbols: DebuggerClient.requester(
{
type: "enumSymbols",
},
{
before: function(packet) {
enumSymbols() {
if (this._grip.type !== "object") {
throw new Error("enumSymbols is only valid for objects grips.");
console.error("enumSymbols is only valid for objects grips.");
return null;
}
return packet;
},
after: function(response) {
if (response.iterator) {
return {
iterator: new SymbolIteratorClient(this._client, response.iterator),
};
return super.enumSymbols();
}
return response;
},
}
),
/**
* Request the property descriptor of the object's specified property.
*
* @param name string The name of the requested property.
* @param onResponse function Called with the request's response.
*/
getProperty: DebuggerClient.requester({
type: "property",
name: arg(0),
}),
getProperty(name) {
return super.property(name);
}
/**
* Request the value of the object's specified property.
*
* @param name string The name of the requested property.
* @param receiverId string|null The actorId of the receiver to be used for getters.
* @param onResponse function Called with the request's response.
*/
getPropertyValue: DebuggerClient.requester({
type: "propertyValue",
name: arg(0),
receiverId: arg(1),
}),
getPropertyValue(name, receiverId) {
return super.propertyValue(name, receiverId);
}
/**
* Request the prototype of the object.
*
* @param onResponse function Called with the request's response.
*/
getPrototype: DebuggerClient.requester({
type: "prototype",
}),
/**
* Evaluate a callable object with context and arguments.
*
* @param context any The value to use as the function context.
* @param arguments Array<any> An array of values to use as the function's arguments.
* @param onResponse function Called with the request's response.
*/
apply: DebuggerClient.requester({
type: "apply",
context: arg(0),
arguments: arg(1),
}),
getPrototype() {
return super.prototype();
}
/**
* Request the display string of the object.
*
* @param onResponse function Called with the request's response.
*/
getDisplayString: DebuggerClient.requester({
type: "displayString",
}),
getDisplayString() {
return super.displayString();
}
/**
* Request the scope of the object.
*
* @param onResponse function Called with the request's response.
*/
getScope: DebuggerClient.requester(
{
type: "scope",
},
{
before: function(packet) {
getScope() {
if (this._grip.class !== "Function") {
throw new Error("scope is only valid for function grips.");
console.error("scope is only valid for function grips.");
return null;
}
return packet;
},
return super.scope();
}
),
/**
* Request the promises directly depending on the current promise.
*/
getDependentPromises: DebuggerClient.requester(
{
type: "dependentPromises",
},
{
before: function(packet) {
getDependentPromises() {
if (this._grip.class !== "Promise") {
throw new Error(
"getDependentPromises is only valid for promise " + "grips."
);
console.error("getDependentPromises is only valid for promise grips.");
return null;
}
return packet;
},
return super.dependentPromises();
}
),
/**
* Request the stack to the promise's allocation point.
*/
getPromiseAllocationStack: DebuggerClient.requester(
{
type: "allocationStack",
},
{
before: function(packet) {
getPromiseAllocationStack() {
if (this._grip.class !== "Promise") {
throw new Error(
"getAllocationStack is only valid for promise grips."
console.error(
"getPromiseAllocationStack is only valid for promise grips."
);
return null;
}
return packet;
},
return super.allocationStack();
}
),
/**
* Request the stack to the promise's fulfillment point.
*/
getPromiseFulfillmentStack: DebuggerClient.requester(
{
type: "fulfillmentStack",
},
{
before: function(packet) {
getPromiseFulfillmentStack() {
if (this._grip.class !== "Promise") {
throw new Error(
"getPromiseFulfillmentStack is only valid for " + "promise grips."
console.error(
"getPromiseFulfillmentStack is only valid for promise grips."
);
return null;
}
return packet;
},
return super.fulfillmentStack();
}
),
/**
* Request the stack to the promise's rejection point.
*/
getPromiseRejectionStack: DebuggerClient.requester(
{
type: "rejectionStack",
},
{
before: function(packet) {
getPromiseRejectionStack() {
if (this._grip.class !== "Promise") {
throw new Error(
"getPromiseRejectionStack is only valid for " + "promise grips."
console.error(
"getPromiseRejectionStack is only valid for promise grips."
);
return null;
}
return packet;
},
return super.rejectionStack();
}
),
/**
* Request the target and handler internal slots of a proxy.
*/
getProxySlots: DebuggerClient.requester(
{
type: "proxySlots",
},
{
before: function(packet) {
getProxySlots() {
if (this._grip.class !== "Proxy") {
throw new Error("getProxySlots is only valid for proxy grips.");
console.error("getProxySlots is only valid for proxy grips.");
return null;
}
return packet;
},
after: function(response) {
const response = super.proxySlots();
// Before Firefox 68 (bug 1392760), the proxySlots request didn't exist.
// The proxy target and handler were directly included in the grip.
if (response.error === "unrecognizedPacketType") {
const { proxyTarget, proxyHandler } = this._grip;
return { proxyTarget, proxyHandler };
}
return response;
},
}
),
addWatchpoint: DebuggerClient.requester({
type: "addWatchpoint",
property: arg(0),
label: arg(1),
watchpointType: arg(2),
}),
removeWatchpoint: DebuggerClient.requester({
type: "removeWatchpoint",
property: arg(0),
}),
};
}
module.exports = ObjectClient;
registerFront(ObjectClient);

Просмотреть файл

@ -1,93 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const {
arg,
DebuggerClient,
} = require("devtools/shared/client/debugger-client");
/**
* A PropertyIteratorClient provides a way to access to property names and
* values of an object efficiently, slice by slice.
* Note that the properties can be sorted in the backend,
* this is controled while creating the PropertyIteratorClient
* from ObjectClient.enumProperties.
*
* @param client DebuggerClient
* The debugger client parent.
* @param grip Object
* A PropertyIteratorActor grip returned by the protocol via
* BrowsingContextTargetActor.enumProperties request.
*/
function PropertyIteratorClient(client, grip) {
this._grip = grip;
this._client = client;
this.request = this._client.request;
}
PropertyIteratorClient.prototype = {
get actor() {
return this._grip.actor;
},
/**
* Get the total number of properties available in the iterator.
*/
get count() {
return this._grip.count;
},
/**
* Get one or more property names that correspond to the positions in the
* indexes parameter.
*
* @param indexes Array
* An array of property indexes.
* @param callback Function
* The function called when we receive the property names.
*/
names: DebuggerClient.requester(
{
type: "names",
indexes: arg(0),
},
{}
),
/**
* Get a set of following property value(s).
*
* @param start Number
* The index of the first property to fetch.
* @param count Number
* The number of properties to fetch.
* @param callback Function
* The function called when we receive the property values.
*/
slice: DebuggerClient.requester(
{
type: "slice",
start: arg(0),
count: arg(1),
},
{}
),
/**
* Get all the property values.
*
* @param callback Function
* The function called when we receive the property values.
*/
all: DebuggerClient.requester(
{
type: "all",
},
{}
),
};
module.exports = PropertyIteratorClient;

Просмотреть файл

@ -0,0 +1,48 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const {
FrontClassWithSpec,
registerFront,
} = require("devtools/shared/protocol");
const { environmentSpec } = require("devtools/shared/specs/environment");
/**
* Environment fronts are used to manipulate the lexical environment actors.
*
* @param client DebuggerClient
* The debugger client parent.
* @param form Object
* The form sent across the remote debugging protocol.
*/
class EnvironmentFront extends FrontClassWithSpec(environmentSpec) {
constructor(client, form) {
super(client, form);
this._client = client;
if (form) {
this._form = form;
this.actorID = form.actor;
this.manage(this);
}
}
get actor() {
return this._form.actor;
}
get _transport() {
return this._client._transport;
}
/**
* Fetches the bindings introduced by this lexical environment.
*/
getBindings() {
return super.bindings();
}
}
exports.EnvironmentFront = EnvironmentFront;
registerFront(EnvironmentFront);

Просмотреть файл

@ -21,6 +21,7 @@ DevToolsModules(
'css-properties.js',
'device.js',
'emulation.js',
'environment.js',
'framerate.js',
'highlighters.js',
'inspector.js',
@ -33,6 +34,7 @@ DevToolsModules(
'performance.js',
'preference.js',
'promises.js',
'property-iterator.js',
'reflow.js',
'root.js',
'screenshot.js',
@ -41,7 +43,8 @@ DevToolsModules(
'string.js',
'styles.js',
'stylesheets.js',
'symbol-iterator.js',
'thread.js',
'webconsole.js',
'websocket.js',
'websocket.js'
)

Просмотреть файл

@ -0,0 +1,68 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const {
FrontClassWithSpec,
registerFront,
} = require("devtools/shared/protocol");
const {
propertyIteratorSpec,
} = require("devtools/shared/specs/property-iterator");
/**
* A PropertyIteratorFront provides a way to access to property names and
* values of an object efficiently, slice by slice.
* Note that the properties can be sorted in the backend,
* this is controled while creating the PropertyIteratorFront
* from ObjectClient.enumProperties.
*/
class PropertyIteratorFront extends FrontClassWithSpec(propertyIteratorSpec) {
constructor(client, targetFront, parentFront) {
super(client, targetFront, parentFront);
this._client = client;
}
get actor() {
return this._grip.actor;
}
/**
* Get the total number of properties available in the iterator.
*/
get count() {
return this._grip.count;
}
/**
* Get one or more property names that correspond to the positions in the
* indexes parameter.
*
* @param indexes Array
* An array of property indexes.
*/
names(indexes) {
return super.names({ indexes });
}
/**
* Get a set of following property value(s).
*
* @param start Number
* The index of the first property to fetch.
* @param count Number
* The number of properties to fetch.
*/
slice(start, count) {
return super.slice({ start, count });
}
form(form) {
this._grip = form;
}
}
exports.PropertyIteratorFront = PropertyIteratorFront;
registerFront(PropertyIteratorFront);

Просмотреть файл

@ -5,12 +5,13 @@
"use strict";
const {
arg,
DebuggerClient,
} = require("devtools/shared/client/debugger-client");
FrontClassWithSpec,
registerFront,
} = require("devtools/shared/protocol");
const { symbolIteratorSpec } = require("devtools/shared/specs/symbol-iterator");
/**
* A SymbolIteratorClient provides a way to access to symbols
* A SymbolIteratorFront provides a way to access to symbols
* of an object efficiently, slice by slice.
*
* @param client DebuggerClient
@ -19,23 +20,22 @@ const {
* A SymbolIteratorActor grip returned by the protocol via
* BrowsingContextTargetActor.enumSymbols request.
*/
function SymbolIteratorClient(client, grip) {
this._grip = grip;
class SymbolIteratorFront extends FrontClassWithSpec(symbolIteratorSpec) {
constructor(client, targetFront, parentFront) {
super(client, targetFront, parentFront);
this._client = client;
this.request = this._client.request;
}
}
SymbolIteratorClient.prototype = {
get actor() {
return this._grip.actor;
},
}
/**
* Get the total number of symbols available in the iterator.
*/
get count() {
return this._grip.count;
},
}
/**
* Get a set of following symbols.
@ -47,27 +47,15 @@ SymbolIteratorClient.prototype = {
* @param callback Function
* The function called when we receive the symbols.
*/
slice: DebuggerClient.requester(
{
type: "slice",
start: arg(0),
count: arg(1),
},
{}
),
slice(start, count) {
const argumentObject = { start, count };
return super.slice(argumentObject);
}
/**
* Get all the symbols.
*
* @param callback Function
* The function called when we receive the symbols.
*/
all: DebuggerClient.requester(
{
type: "all",
},
{}
),
};
form(form) {
this._grip = form;
}
}
module.exports = SymbolIteratorClient;
exports.SymbolIteratorFront = SymbolIteratorFront;
registerFront(SymbolIteratorFront);

Просмотреть файл

@ -77,11 +77,10 @@ const Types = (exports.__TypesForTests = [
spec: "devtools/shared/specs/emulation",
front: "devtools/shared/fronts/emulation",
},
/* environment has old fashion client and no front */
{
types: ["environment"],
spec: "devtools/shared/specs/environment",
front: null,
front: "devtools/shared/fronts/environment",
},
/* frame has old fashion client and no front */
{
@ -174,7 +173,7 @@ const Types = (exports.__TypesForTests = [
{
types: ["propertyIterator"],
spec: "devtools/shared/specs/property-iterator",
front: null,
front: "devtools/shared/fronts/property-iterator",
},
{
types: ["reflow"],
@ -232,7 +231,7 @@ const Types = (exports.__TypesForTests = [
{
types: ["symbolIterator"],
spec: "devtools/shared/specs/symbol-iterator",
front: null,
front: "devtools/shared/fronts/symbol-iterator",
},
{
types: ["browsingContextTarget"],

Просмотреть файл

@ -42,7 +42,7 @@ function onEvaluate(aState, aResponse)
onInspect = onInspect.bind(null, aState);
let client = new ObjectClient(aState.dbgClient, aResponse.result);
client.getPrototypeAndProperties(onInspect);
client.getPrototypeAndProperties().then(onInspect);
}
function onInspect(aState, aResponse)

Просмотреть файл

@ -153,7 +153,7 @@ function onConsoleCall(state, aPacket) {
onProperties = onProperties.bind(null, state);
let client = new ObjectClient(state.dbgClient, args[1]);
client.getPrototypeAndProperties(onProperties);
client.getPrototypeAndProperties().then(onProperties);
}
function onProperties(state, response) {

Просмотреть файл

@ -74,7 +74,7 @@ function onConsoleCall(aState, aPacket)
onProperties = onProperties.bind(null, aState);
let client = new ObjectClient(aState.dbgClient, args[1]);
client.getPrototypeAndProperties(onProperties);
client.getPrototypeAndProperties().then(onProperties);
}
function onProperties(aState, aResponse)

Просмотреть файл

@ -53,7 +53,7 @@ function onConsoleCall(aState, aPacket)
onProperties = onProperties.bind(null, aState);
let client = new ObjectClient(aState.dbgClient, args[1]);
client.getPrototypeAndProperties(onProperties);
client.getPrototypeAndProperties().then(onProperties);
}
function onProperties(aState, aResponse)