Bug 1227978 - Remove unecessary usages of promiseInvoke, rdpInvoke r=jlongster
☠☠ backed out by 8badb4d61bc8 ☠ ☠
authorAlexandre Poirot <poirot.alex@gmail.com>
Fri, 08 Jan 2016 06:59:34 -0800
changeset 320146 d8a429b575e3359ceaa13d2ae2b7bcfc4e3d730b
parent 320145 f99079d057cc45414b8e894c3703ee0221fe3f99
child 320147 bac08b0a467d8f4843a0bf147e3693a287832436
push id9143
push userahunt@mozilla.com
push dateFri, 08 Jan 2016 21:30:53 +0000
reviewersjlongster
bugs1227978
milestone46.0a1
Bug 1227978 - Remove unecessary usages of promiseInvoke, rdpInvoke r=jlongster
devtools/client/debugger/content/actions/breakpoints.js
devtools/client/debugger/content/actions/event-listeners.js
devtools/client/debugger/content/actions/sources.js
devtools/client/debugger/content/utils.js
devtools/client/debugger/test/mochitest/browser_dbg_pretty-print-06.js
devtools/client/debugger/test/mochitest/browser_dbg_pretty-print-on-paused.js
devtools/client/debugger/test/mochitest/head.js
devtools/client/inspector/markup/test/head.js
devtools/server/tests/mochitest/director-helpers.js
devtools/server/tests/unit/head_dbg.js
--- a/devtools/client/debugger/content/actions/breakpoints.js
+++ b/devtools/client/debugger/content/actions/breakpoints.js
@@ -1,16 +1,16 @@
 /* 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 constants = require('../constants');
 const promise = require('promise');
-const { asPaused, rdpInvoke } = require('../utils');
+const { asPaused } = require('../utils');
 const { PROMISE } = require('devtools/client/shared/redux/middleware/promise');
 const {
   getSource, getBreakpoint, getBreakpoints, makeLocationId
 } = require('../queries');
 
 // Because breakpoints are just simple data structures, we still need
 // a way to lookup the actual client instance to talk to the server.
 // We keep an internal database of clients based off of actor ID.
@@ -50,17 +50,17 @@ function addBreakpoint(location, conditi
     return dispatch({
       type: constants.ADD_BREAKPOINT,
       breakpoint: bp,
       condition: condition,
       [PROMISE]: Task.spawn(function*() {
         const sourceClient = gThreadClient.source(
           getSource(getState(), bp.location.actor)
         );
-        const [response, bpClient] = yield rdpInvoke(sourceClient, sourceClient.setBreakpoint, {
+        const [response, bpClient] = yield sourceClient.setBreakpoint({
           line: bp.location.line,
           column: bp.location.column,
           condition: bp.condition
         });
         const { isPending, actualLocation } = response;
 
         // Save the client instance
         setBreakpointClient(bpClient.actor, bpClient);
@@ -100,17 +100,17 @@ function _removeOrDisableBreakpoint(loca
     }
 
     const bpClient = getBreakpointClient(bp.actor);
 
     return dispatch({
       type: constants.REMOVE_BREAKPOINT,
       breakpoint: bp,
       disabled: isDisabled,
-      [PROMISE]: rdpInvoke(bpClient, bpClient.remove)
+      [PROMISE]: bpClient.remove()
     });
   }
 }
 
 function removeAllBreakpoints() {
   return (dispatch, getState) => {
     const breakpoints = getBreakpoints(getState());
     const activeBreakpoints = breakpoints.filter(bp => !bp.disabled);
--- a/devtools/client/debugger/content/actions/event-listeners.js
+++ b/devtools/client/debugger/content/actions/event-listeners.js
@@ -1,15 +1,15 @@
 /* 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 constants = require("../constants");
-const { rdpInvoke, asPaused } = require("../utils");
+const { asPaused } = require("../utils");
 const { reportException } = require("devtools/shared/DevToolsUtils");
 
 const FETCH_EVENT_LISTENERS_DELAY = 200; // ms
 
 function fetchEventListeners() {
   return (dispatch, getState) => {
     // Make sure we"re not sending a batch of closely repeated requests.
     // This can easily happen whenever new sources are fetched.
@@ -45,17 +45,17 @@ function fetchEventListeners() {
           listeners: listeners
         });
       });
     });
   };
 }
 
 const _getListeners = Task.async(function*() {
-  const response = yield rdpInvoke(gThreadClient, gThreadClient.eventListeners);
+  const response = yield gThreadClient.eventListeners();
 
   // Make sure all the listeners are sorted by the event type, since
   // they"re not guaranteed to be clustered together.
   response.listeners.sort((a, b) => a.type > b.type ? 1 : -1);
 
   // Add all the listeners in the debugger view event linsteners container.
   let fetchedDefinitions = new Map();
   let listeners = [];
@@ -81,17 +81,17 @@ const _getListeners = Task.async(functio
   return listeners;
 });
 
 const _getDefinitionSite = Task.async(function*(aFunction) {
   const grip = gThreadClient.pauseGrip(aFunction);
   let response;
 
   try {
-    response = yield rdpInvoke(grip, grip.getDefinitionSite);
+    response = yield grip.getDefinitionSite();
   }
   catch(e) {
     // Don't make this error fatal, because it would break the entire events pane.
     reportException("_getDefinitionSite", e);
     return null;
   }
 
   return response.source.url;
--- a/devtools/client/debugger/content/actions/sources.js
+++ b/devtools/client/debugger/content/actions/sources.js
@@ -1,16 +1,15 @@
 /* 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 constants = require('../constants');
 const promise = require('promise');
-const { rdpInvoke } = require('../utils');
 const { dumpn } = require("devtools/shared/DevToolsUtils");
 const { PROMISE, HISTOGRAM_ID } = require('devtools/client/shared/redux/middleware/promise');
 const { getSource, getSourceText } = require('../queries');
 
 const NEW_SOURCE_IGNORED_URLS = ["debugger eval code", "XStringBundle"];
 const FETCH_SOURCE_RESPONSE_DELAY = 200; // ms
 
 function getSourceClient(source) {
@@ -57,17 +56,17 @@ function selectSource(source, opts) {
     });
   };
 }
 
 function loadSources() {
   return {
     type: constants.LOAD_SOURCES,
     [PROMISE]: Task.spawn(function*() {
-      const response = yield rdpInvoke(gThreadClient, gThreadClient.getSources);
+      const response = yield gThreadClient.getSources();
 
       // Top-level breakpoints may pause the entire loading process
       // because scripts are executed as they are loaded, so the
       // engine may pause in the middle of loading all the sources.
       // This is relatively harmless, as individual `newSource`
       // notifications are fired for each script and they will be
       // added to the UI through that.
       if (!response.sources) {
@@ -99,18 +98,17 @@ function loadSources() {
  */
 function blackbox(source, shouldBlackBox) {
   const client = getSourceClient(source);
 
   return {
     type: constants.BLACKBOX,
     source: source,
     [PROMISE]: Task.spawn(function*() {
-      yield rdpInvoke(client,
-                      shouldBlackBox ? client.blackBox : client.unblackBox);
+      yield shouldBlackBox ? client.blackBox() : client.unblackBox();
       return {
         isBlackBoxed: shouldBlackBox
       }
     })
   };
 }
 
 /**
@@ -138,23 +136,20 @@ function togglePrettyPrint(source) {
         // Only attempt to pretty print JavaScript sources.
         const sourceText = getSourceText(getState(), source.actor);
         const contentType = sourceText ? sourceText.contentType : null;
         if (!SourceUtils.isJavaScript(source.url, contentType)) {
           throw new Error("Can't prettify non-javascript files.");
         }
 
         if (wantPretty) {
-          response = yield rdpInvoke(sourceClient,
-                                     sourceClient.prettyPrint,
-                                     Prefs.editorTabSize);
+          response = yield sourceClient.prettyPrint(Prefs.editorTabSize);
         }
         else {
-          response = yield rdpInvoke(sourceClient,
-                                     sourceClient.disablePrettyPrint);
+          response = yield sourceClient.disablePrettyPrint();
         }
 
         // Remove the cached source AST from the Parser, to avoid getting
         // wrong locations when searching for functions.
         DebuggerController.Parser.clearSource(source.url);
 
         return {
           isPrettyPrinted: wantPretty,
@@ -181,17 +176,17 @@ function loadSourceText(source) {
       type: constants.LOAD_SOURCE_TEXT,
       source: source,
       [PROMISE]: Task.spawn(function*() {
         let transportType = gClient.localTransport ? "_LOCAL" : "_REMOTE";
         let histogramId = "DEVTOOLS_DEBUGGER_DISPLAY_SOURCE" + transportType + "_MS";
         let histogram = Services.telemetry.getHistogramById(histogramId);
         let startTime = Date.now();
 
-        const response = yield rdpInvoke(sourceClient, sourceClient.source);
+        const response = yield sourceClient.source();
 
         histogram.add(Date.now() - startTime);
 
         // Automatically pretty print if enabled and the test is
         // detected to be "minified"
         if (Prefs.autoPrettyPrint &&
             !source.isPrettyPrinted &&
             SourceUtils.isMinified(source.actor, response.source)) {
--- a/devtools/client/debugger/content/utils.js
+++ b/devtools/client/debugger/content/utils.js
@@ -1,50 +1,32 @@
 /* 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 { promiseInvoke } = require("devtools/shared/async-utils");
 const { reportException } = require("devtools/shared/DevToolsUtils");
 
-// RDP utils
-
-function rdpInvoke(client, method, ...args) {
-  return (promiseInvoke(client, method, ...args)
-    .then((packet) => {
-      if (packet.error) {
-        let { error, message } = packet;
-        const err = new Error(error + ": " + message);
-        err.rdpError = error;
-        err.rdpMessage = message;
-        throw err;
-      }
-
-      return packet;
-    }));
-}
-
 function asPaused(client, func) {
   if (client.state != "paused") {
     return Task.spawn(function*() {
-      yield rdpInvoke(client, client.interrupt);
+      yield client.interrupt();
       let result;
 
       try {
         result = yield func();
       }
       catch(e) {
         // Try to put the debugger back in a working state by resuming
         // it
-        yield rdpInvoke(client, client.resume);
+        yield client.resume();
         throw e;
       }
 
-      yield rdpInvoke(client, client.resume);
+      yield client.resume();
       return result;
     });
   } else {
     return func();
   }
 }
 
 function handleError(err) {
@@ -88,17 +70,16 @@ function updateIn(destObj, path, fn) {
 function deleteIn(destObj, path) {
   const objPath = path.slice(0, -1);
   const propName = path[path.length - 1];
   const obj = _getIn(destObj, objPath);
   return setIn(destObj, objPath, obj.without(propName));
 }
 
 module.exports = {
-  rdpInvoke,
   asPaused,
   handleError,
   onReducerEvents,
   mergeIn,
   setIn,
   updateIn,
   deleteIn
 };
--- a/devtools/client/debugger/test/mochitest/browser_dbg_pretty-print-06.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_pretty-print-06.js
@@ -49,18 +49,18 @@ function test() {
       ok(gEditor.getText().includes("myFunction"),
         "The source shouldn't be pretty printed yet.");
 
       const source = queries.getSelectedSource(getState());
       try {
         yield actions.togglePrettyPrint(source);
         ok(false, "The promise for a prettified source should be rejected!");
       } catch(error) {
-        ok(error.rdpError, "Error came from a RDP request");
-        ok(error.rdpError.includes("prettyPrintError"),
+        ok(error.error, "Error came from a RDP request");
+        ok(error.error.includes("prettyPrintError"),
           "The promise was correctly rejected with a meaningful message.");
       }
 
       const { text } = yield queries.getSourceText(getState(), source.actor);
       is(getSelectedSourceURL(gSources), JS_URL,
         "The correct source is still selected.");
       ok(gEditor.getText().includes("myFunction"),
         "The displayed source hasn't changed.");
--- a/devtools/client/debugger/test/mochitest/browser_dbg_pretty-print-on-paused.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_pretty-print-on-paused.js
@@ -22,17 +22,17 @@ function test(){
 
     Task.spawn(function* () {
       try {
         yield ensureSourceIs(gPanel, "code_script-switching-02.js", true);
 
         yield doInterrupt(gPanel);
 
         let source = gThreadClient.source(getSourceForm(gSources, SECOND_SOURCE_VALUE));
-        yield rdpInvoke(source, source.setBreakpoint, {
+        yield source.setBreakpoint({
           line: 6
         });
         yield doResume(gPanel);
 
         const bpHit = waitForCaretAndScopes(gPanel, 6);
         callInTab(gTab, "secondCall");
         yield bpHit;
 
--- a/devtools/client/debugger/test/mochitest/head.js
+++ b/devtools/client/debugger/test/mochitest/head.js
@@ -11,17 +11,16 @@ Services.scriptloader.loadSubScript("chr
 var gEnableLogging = Services.prefs.getBoolPref("devtools.debugger.log");
 Services.prefs.setBoolPref("devtools.debugger.log", false);
 
 var { BrowserToolboxProcess } = Cu.import("resource://devtools/client/framework/ToolboxProcess.jsm", {});
 var { DebuggerServer } = require("devtools/server/main");
 var { DebuggerClient, ObjectClient } = require("devtools/shared/client/main");
 var { AddonManager } = Cu.import("resource://gre/modules/AddonManager.jsm", {});
 var EventEmitter = require("devtools/shared/event-emitter");
-const { promiseInvoke } = require("devtools/shared/async-utils");
 var { Toolbox } = require("devtools/client/framework/toolbox")
 
 // Override promise with deprecated-sync-thenables
 promise = Cu.import("resource://devtools/shared/deprecated-sync-thenables.js", {}).Promise;
 
 const EXAMPLE_URL = "http://example.com/browser/devtools/client/debugger/test/mochitest/";
 const FRAME_SCRIPT_URL = getRootDirectory(gTestPath) + "code_frame-script.js";
 
@@ -882,36 +881,24 @@ function attachAddonActorForUrl(aClient,
     aClient.attachAddon(aGrip.actor, aResponse => {
       deferred.resolve([aGrip, aResponse]);
     });
   });
 
   return deferred.promise;
 }
 
-function rdpInvoke(aClient, aMethod, ...args) {
-  return promiseInvoke(aClient, aMethod, ...args)
-    .then((packet) => {
-      let { error, message } = packet;
-      if (error) {
-        throw new Error(error + ": " + message);
-      }
-
-      return packet;
-    });
-}
-
 function doResume(aPanel) {
   const threadClient = aPanel.panelWin.gThreadClient;
-  return rdpInvoke(threadClient, threadClient.resume);
+  return threadClient.resume();
 }
 
 function doInterrupt(aPanel) {
   const threadClient = aPanel.panelWin.gThreadClient;
-  return rdpInvoke(threadClient, threadClient.interrupt);
+  return threadClient.interrupt();
 }
 
 function pushPrefs(...aPrefs) {
   let deferred = promise.defer();
   SpecialPowers.pushPrefEnv({"set": aPrefs}, deferred.resolve);
   return deferred.promise;
 }
 
@@ -1031,21 +1018,17 @@ function close(client) {
     client.close(() => {
       resolve();
     });
   });
 }
 
 function listTabs(client) {
   info("Listing tabs.");
-  return new Promise(function (resolve) {
-    client.listTabs(function (response) {
-      resolve(response);
-    });
-  });
+  return client.listTabs();
 }
 
 function findTab(tabs, url) {
   info("Finding tab with url '" + url + "'.");
   for (let tab of tabs) {
     if (tab.url === url) {
       return tab;
     }
@@ -1116,17 +1099,17 @@ function waitForWorkerClose(workerClient
       info("Worker did close.");
       resolve();
     });
   });
 }
 
 function resume(threadClient) {
   info("Resuming thread.");
-  return rdpInvoke(threadClient, threadClient.resume);
+  return threadClient.resume();
 }
 
 function findSource(sources, url) {
   info("Finding source with url '" + url + "'.\n");
   for (let source of sources) {
     if (source.url === url) {
       return source;
     }
@@ -1156,22 +1139,22 @@ function waitForEvent(client, type, pred
 
 function waitForPause(threadClient) {
   info("Waiting for pause.\n");
   return waitForEvent(threadClient, "paused");
 }
 
 function setBreakpoint(sourceClient, location) {
   info("Setting breakpoint.\n");
-  return rdpInvoke(sourceClient, sourceClient.setBreakpoint, location);
+  return sourceClient.setBreakpoint(location);
 }
 
 function source(sourceClient) {
   info("Getting source.\n");
-  return rdpInvoke(sourceClient, sourceClient.source);
+  return sourceClient.source();
 }
 
 // Return a promise with a reference to jsterm, opening the split
 // console if necessary.  This cleans up the split console pref so
 // it won't pollute other tests.
 function getSplitConsole(toolbox, win) {
   registerCleanupFunction(() => {
     Services.prefs.clearUserPref("devtools.toolbox.splitconsoleEnabled");
--- a/devtools/client/inspector/markup/test/head.js
+++ b/devtools/client/inspector/markup/test/head.js
@@ -5,17 +5,16 @@
 var Cu = Components.utils;
 var {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
 var {TargetFactory} = require("devtools/client/framework/target");
 var {console} = Cu.import("resource://gre/modules/Console.jsm", {});
 var promise = require("promise");
 var {getInplaceEditorForSpan: inplaceEditor} = require("devtools/client/shared/inplace-editor");
 var clipboard = require("sdk/clipboard");
 var {setTimeout, clearTimeout} = require("sdk/timers");
-var {promiseInvoke} = require("devtools/shared/async-utils");
 var DevToolsUtils = require("devtools/shared/DevToolsUtils");
 
 // All test are asynchronous
 waitForExplicitFinish();
 
 // If a test times out we want to see the complete log and not just the last few
 // lines.
 SimpleTest.requestCompleteLog();
@@ -758,20 +757,17 @@ function contextMenuClick(element) {
  *
  * - registrar {ActorActor}: A handle to the registered actor that allows
  * unregistration.
  * - form {Object}: The JSON actor form provided by the server.
  */
 function registerTabActor(client, options) {
   let moduleUrl = options.moduleUrl;
 
-  // Since client.listTabs doesn't use promises we need to
-  // 'promisify' it using 'promiseInvoke' helper method.
-  // This helps us to chain all promises and catch errors.
-  return promiseInvoke(client, client.listTabs).then(response => {
+  return client.listTabs().then(response => {
     let config = {
       prefix: options.prefix,
       constructor: options.actorClass,
       type: { tab: true },
     };
 
     // Register the custom actor on the backend.
     let registry = ActorRegistryFront(client, response);
--- a/devtools/server/tests/mochitest/director-helpers.js
+++ b/devtools/server/tests/mochitest/director-helpers.js
@@ -27,17 +27,17 @@ const {Task} = require("resource://gre/m
  **********************************/
 
 function* newConnectedDebuggerClient(opts) {
   var transport = DebuggerServer.connectPipe();
   var client = new DebuggerClient(transport);
 
   yield promiseInvoke(client, client.connect);
 
-  var root = yield promiseInvoke(client, client.listTabs);
+  var root = yield client.listTabs();
 
   return {
     client: client,
     root: root,
     transport: transport
   };
 }
 
--- a/devtools/server/tests/unit/head_dbg.js
+++ b/devtools/server/tests/unit/head_dbg.js
@@ -7,17 +7,16 @@ var Ci = Components.interfaces;
 var Cu = Components.utils;
 var Cr = Components.results;
 var CC = Components.Constructor;
 
 const { require, loader } = Cu.import("resource://devtools/shared/Loader.jsm", {});
 const { worker } = Cu.import("resource://devtools/shared/worker/loader.js", {})
 const promise = require("promise");
 const { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
-const { promiseInvoke } = require("devtools/shared/async-utils");
 
 const Services = require("Services");
 // Always log packets when running tests. runxpcshelltests.py will throw
 // the output away anyway, unless you give it the --verbose flag.
 Services.prefs.setBoolPref("devtools.debugger.log", true);
 // Enable remote debugging for the relevant tests.
 Services.prefs.setBoolPref("devtools.debugger.remote-enabled", true);
 
@@ -144,54 +143,54 @@ function close(client) {
     client.close(function () {
       resolve();
     });
   });
 }
 
 function listTabs(client) {
   dump("Listing tabs.\n");
-  return rdpRequest(client, client.listTabs);
+  return client.listTabs();
 }
 
 function findTab(tabs, title) {
   dump("Finding tab with title '" + title + "'.\n");
   for (let tab of tabs) {
     if (tab.title === title) {
       return tab;
     }
   }
   return null;
 }
 
 function attachTab(client, tab) {
   dump("Attaching to tab with title '" + tab.title + "'.\n");
-  return rdpRequest(client, client.attachTab, tab.actor);
+  return client.attachTab(tab.actor);
 }
 
 function waitForNewSource(threadClient, url) {
   dump("Waiting for new source with url '" + url + "'.\n");
   return waitForEvent(threadClient, "newSource", function (packet) {
     return packet.source.url === url;
   });
 }
 
 function attachThread(tabClient, options = {}) {
   dump("Attaching to thread.\n");
-  return rdpRequest(tabClient, tabClient.attachThread, options);
+  return tabClient.attachThread(options);
 }
 
 function resume(threadClient) {
   dump("Resuming thread.\n");
-  return rdpRequest(threadClient, threadClient.resume);
+  return threadClient.resume();
 }
 
 function getSources(threadClient) {
   dump("Getting sources.\n");
-  return rdpRequest(threadClient, threadClient.getSources);
+  return threadClient.getSources();
 }
 
 function findSource(sources, url) {
   dump("Finding source with url '" + url + "'.\n");
   for (let source of sources) {
     if (source.url === url) {
       return source;
     }
@@ -201,17 +200,17 @@ function findSource(sources, url) {
 
 function waitForPause(threadClient) {
   dump("Waiting for pause.\n");
   return waitForEvent(threadClient, "paused");
 }
 
 function setBreakpoint(sourceClient, location) {
   dump("Setting breakpoint.\n");
-  return rdpRequest(sourceClient, sourceClient.setBreakpoint, location);
+  return sourceClient.setBreakpoint(location);
 }
 
 function dumpn(msg) {
   dump("DBG-TEST: " + msg + "\n");
 }
 
 function tryImport(url) {
   try {
@@ -682,48 +681,24 @@ function waitForEvent(client, type, pred
  */
 function executeOnNextTickAndWaitForPause(action, client) {
   const paused = waitForPause(client);
   executeSoon(action);
   return paused;
 }
 
 /**
- * Create a promise that is resolved with the server's response to the client's
- * Remote Debugger Protocol request. If a response with the `error` property is
- * received, the promise is rejected. Any extra arguments passed in are
- * forwarded to the method invocation.
- *
- * See `setBreakpoint` below, for example usage.
- *
- * @param DebuggerClient/ThreadClient/SourceClient/etc client
- * @param Function method
- * @param any args
- * @returns Promise
- */
-function rdpRequest(client, method, ...args) {
-  return promiseInvoke(client, method, ...args)
-    .then(response => {
-      const { error, message } = response;
-      if (error) {
-        throw new Error(error + ": " + message);
-      }
-      return response;
-    });
-}
-
-/**
  * Interrupt JS execution for the specified thread.
  *
  * @param ThreadClient threadClient
  * @returns Promise
  */
 function interrupt(threadClient) {
   dumpn("Interrupting.");
-  return rdpRequest(threadClient, threadClient.interrupt);
+  return threadClient.interrupt();
 }
 
 /**
  * Resume JS execution for the specified thread and then wait for the next pause
  * event.
  *
  * @param DebuggerClient client
  * @param ThreadClient threadClient
@@ -740,66 +715,66 @@ function resumeAndWaitForPause(client, t
  *
  * @param DebuggerClient client
  * @param ThreadClient threadClient
  * @returns Promise
  */
 function stepIn(client, threadClient) {
   dumpn("Stepping in.");
   const paused = waitForPause(client);
-  return rdpRequest(threadClient, threadClient.stepIn)
+  return threadClient.stepIn()
     .then(() => paused);
 }
 
 /**
  * Get the list of `count` frames currently on stack, starting at the index
  * `first` for the specified thread.
  *
  * @param ThreadClient threadClient
  * @param Number first
  * @param Number count
  * @returns Promise
  */
 function getFrames(threadClient, first, count) {
   dumpn("Getting frames.");
-  return rdpRequest(threadClient, threadClient.getFrames, first, count);
+  return threadClient.getFrames(first, count);
 }
 
 /**
  * Black box the specified source.
  *
  * @param SourceClient sourceClient
  * @returns Promise
  */
 function blackBox(sourceClient) {
   dumpn("Black boxing source: " + sourceClient.actor);
-  return rdpRequest(sourceClient, sourceClient.blackBox);
+  return sourceClient.blackBox();
 }
 
 /**
  * Stop black boxing the specified source.
  *
  * @param SourceClient sourceClient
  * @returns Promise
  */
 function unBlackBox(sourceClient) {
   dumpn("Un-black boxing source: " + sourceClient.actor);
-  return rdpRequest(sourceClient, sourceClient.unblackBox);
+  return sourceClient.unblackBox();
 }
 
 /**
  * Perform a "source" RDP request with the given SourceClient to get the source
  * content and content type.
  *
  * @param SourceClient sourceClient
  * @returns Promise
  */
 function getSourceContent(sourceClient) {
   dumpn("Getting source content for " + sourceClient.actor);
-  return rdpRequest(sourceClient, sourceClient.source);
+  return sourceClient.source();
 }
 
 /**
  * Get a source at the specified url.
  *
  * @param ThreadClient threadClient
  * @param string url
  * @returns Promise<SourceClient>