Bug 1515951 - [release 112] Blackbox original sources (#7370). r=bhackett
authorJason Laster <jlaster@mozilla.com>
Sun, 23 Dec 2018 14:46:23 -0500
changeset 452004 10dc48aa3b1e99cde812866d35e2c8f6ef39f942
parent 452003 5bfef086654140a79a6164ff660fcc097603e7c8
child 452005 ea2807921cc3c593661f611d6b7d4f31f145b147
push id35278
push useraiakab@mozilla.com
push dateThu, 27 Dec 2018 21:57:04 +0000
treeherdermozilla-central@a77e8f3efc4c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbhackett
bugs1515951
milestone66.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1515951 - [release 112] Blackbox original sources (#7370). r=bhackett
devtools/client/debugger/new/dist/parser-worker.js
devtools/client/debugger/new/src/actions/sources/blackbox.js
devtools/client/debugger/new/src/client/firefox/commands.js
devtools/client/debugger/new/src/utils/prefs.js
devtools/client/debugger/new/test/mochitest/browser.ini
devtools/client/debugger/new/test/mochitest/browser_dbg-blackbox-original.js
devtools/client/debugger/new/test/mochitest/helpers.js
devtools/client/preferences/debugger.js
devtools/client/shared/source-map/index.js
devtools/client/shared/source-map/worker.js
--- a/devtools/client/debugger/new/dist/parser-worker.js
+++ b/devtools/client/debugger/new/dist/parser-worker.js
@@ -23137,16 +23137,17 @@ const getGeneratedRanges = dispatcher.ta
 });
 const getGeneratedLocation = dispatcher.task("getGeneratedLocation", {
   queue: true
 });
 const getAllGeneratedLocations = dispatcher.task("getAllGeneratedLocations", {
   queue: true
 });
 const getOriginalLocation = dispatcher.task("getOriginalLocation");
+const getFileGeneratedRange = dispatcher.task("getFileGeneratedRange");
 const getLocationScopes = dispatcher.task("getLocationScopes");
 const getOriginalSourceText = dispatcher.task("getOriginalSourceText");
 const applySourceMap = dispatcher.task("applySourceMap");
 const clearSourceMaps = dispatcher.task("clearSourceMaps");
 const hasMappedSource = dispatcher.task("hasMappedSource");
 const getOriginalStackFrames = dispatcher.task("getOriginalStackFrames");
 
 module.exports = {
@@ -23156,16 +23157,17 @@ module.exports = {
   isOriginalId,
   hasMappedSource,
   getOriginalURLs,
   getOriginalRanges,
   getGeneratedRanges,
   getGeneratedLocation,
   getAllGeneratedLocations,
   getOriginalLocation,
+  getFileGeneratedRange,
   getLocationScopes,
   getOriginalSourceText,
   applySourceMap,
   clearSourceMaps,
   getOriginalStackFrames,
   startSourceMapWorker(url, assetRoot) {
     dispatcher.start(url);
     setAssetRootURL(assetRoot);
--- a/devtools/client/debugger/new/src/actions/sources/blackbox.js
+++ b/devtools/client/debugger/new/src/actions/sources/blackbox.js
@@ -4,37 +4,41 @@
 
 // @flow
 
 /**
  * Redux actions for the sources state
  * @module actions/sources
  */
 
-import { isOriginalId } from "devtools-source-map";
+import { isOriginalId, originalToGeneratedId } from "devtools-source-map";
 import { recordEvent } from "../../utils/telemetry";
 import { features } from "../../utils/prefs";
 
 import { PROMISE } from "../utils/middleware/promise";
+
 import type { Source } from "../../types";
 import type { ThunkArgs } from "../types";
 
 export function toggleBlackBox(source: Source) {
   return async ({ dispatch, getState, client, sourceMaps }: ThunkArgs) => {
-    const { isBlackBoxed, id } = source;
+    const { isBlackBoxed } = source;
 
     if (!isBlackBoxed) {
       recordEvent("blackbox");
     }
 
     let promise;
-    if (features.originalBlackbox && isOriginalId(id)) {
-      promise = Promise.resolve({ isBlackBoxed: !isBlackBoxed });
+
+    if (features.originalBlackbox && isOriginalId(source.id)) {
+      const range = await sourceMaps.getFileGeneratedRange(source);
+      const generatedId = originalToGeneratedId(source.id);
+      promise = client.blackBox(generatedId, isBlackBoxed, range);
     } else {
-      promise = client.blackBox(id, isBlackBoxed);
+      promise = client.blackBox(source.id, isBlackBoxed);
     }
 
     return dispatch({
       type: "BLACKBOX",
       source,
       [PROMISE]: promise
     });
   };
--- a/devtools/client/debugger/new/src/client/firefox/commands.js
+++ b/devtools/client/debugger/new/src/client/firefox/commands.js
@@ -340,22 +340,26 @@ function pauseOnExceptions(
   );
 }
 
 function prettyPrint(sourceId: SourceId, indentSize: number): Promise<*> {
   const sourceClient = threadClient.source({ actor: sourceId });
   return sourceClient.prettyPrint(indentSize);
 }
 
-async function blackBox(sourceId: SourceId, isBlackBoxed: boolean): Promise<*> {
+async function blackBox(
+  sourceId: SourceId,
+  isBlackBoxed: boolean,
+  range?: Range
+): Promise<*> {
   const sourceClient = threadClient.source({ actor: sourceId });
   if (isBlackBoxed) {
-    await sourceClient.unblackBox(null);
+    await sourceClient.unblackBox(range);
   } else {
-    await sourceClient.blackBox(null);
+    await sourceClient.blackBox(range);
   }
 
   return { isBlackBoxed: !isBlackBoxed };
 }
 
 function disablePrettyPrint(sourceId: SourceId): Promise<*> {
   const sourceClient = threadClient.source({ actor: sourceId });
   return sourceClient.disablePrettyPrint();
--- a/devtools/client/debugger/new/src/utils/prefs.js
+++ b/devtools/client/debugger/new/src/utils/prefs.js
@@ -56,17 +56,17 @@ if (isDevelopment()) {
   pref("devtools.debugger.features.column-breakpoints", false);
   pref("devtools.debugger.features.pause-points", true);
   pref("devtools.debugger.features.skip-pausing", true);
   pref("devtools.debugger.features.component-pane", false);
   pref("devtools.debugger.features.autocomplete-expressions", false);
   pref("devtools.debugger.features.map-expression-bindings", true);
   pref("devtools.debugger.features.map-await-expression", true);
   pref("devtools.debugger.features.xhr-breakpoints", true);
-  pref("devtools.debugger.features.origial-blackbox", false);
+  pref("devtools.debugger.features.origial-blackbox", true);
   pref("devtools.debugger.features.windowless-workers", false);
 }
 
 export const prefs = new PrefsHelper("devtools", {
   logging: ["Bool", "debugger.alphabetize-outline"],
   alphabetizeOutline: ["Bool", "debugger.alphabetize-outline"],
   autoPrettyPrint: ["Bool", "debugger.auto-pretty-print"],
   clientSourceMapsEnabled: ["Bool", "source-map.client-service.enabled"],
--- a/devtools/client/debugger/new/test/mochitest/browser.ini
+++ b/devtools/client/debugger/new/test/mochitest/browser.ini
@@ -735,16 +735,17 @@ skip-if = os == "win"
 skip-if = true
 [browser_dbg-pause-points.js]
 [browser_dbg-scopes-mutations.js]
 [browser_dbg-search-file.js]
 skip-if = os == "win" # Bug 1393121
 [browser_dbg-quick-open.js]
 skip-if = os == "win"
 [browser_dbg-search-project.js]
+[browser_dbg-blackbox-original.js]
 [browser_dbg-sourcemaps.js]
 [browser_dbg-sourcemaps-disabled.js]
 [browser_dbg-sourcemaps-reload.js]
 skip-if = os == "win" || (verify) # Bug 1434792
 [browser_dbg-sourcemaps-reloading.js]
 [browser_dbg-sourcemaps2.js]
 [browser_dbg-sourcemaps3.js]
 [browser_dbg-sourcemaps-bogus.js]
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-blackbox-original.js
@@ -0,0 +1,42 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// This source map does not have source contents, so it's fetched separately
+add_task(async function() {
+  // NOTE: the CORS call makes the test run times inconsistent
+  await pushPref("devtools.debugger.features.map-scopes", true);
+
+  const dbg = await initDebugger("doc-sourcemaps3.html");
+  const {
+    selectors: { getBreakpoint, getBreakpointCount },
+    getState
+  } = dbg;
+
+  await waitForSources(dbg, "bundle.js", "sorted.js", "test.js");
+
+  const sortedSrc = findSource(dbg, "sorted.js");
+
+  await selectSource(dbg, sortedSrc);
+
+  await clickElement(dbg, "blackbox");
+  await waitForDispatch(dbg, "BLACKBOX");
+
+  // breakpoint at line 38 in sorted
+  await addBreakpoint(dbg, sortedSrc, 38);
+  // invoke test
+  invokeInTab("test");
+  // should not pause
+  is(isPaused(dbg), false);
+
+
+  // unblackbox
+  await clickElement(dbg, "blackbox");
+  await waitForDispatch(dbg, "BLACKBOX");
+
+  // click on test
+  invokeInTab("test");
+  // should pause
+  await waitForPaused(dbg);
+
+  ok(true, "blackbox works")
+});
--- a/devtools/client/debugger/new/test/mochitest/helpers.js
+++ b/devtools/client/debugger/new/test/mochitest/helpers.js
@@ -1131,17 +1131,18 @@ const selectors = {
   fileMatch: ".project-text-search .line-value",
   popup: ".popover",
   tooltip: ".tooltip",
   previewPopup: ".preview-popup",
   outlineItem: i =>
     `.outline-list__element:nth-child(${i}) .function-signature`,
   outlineItems: ".outline-list__element",
   conditionalPanelInput: ".conditional-breakpoint-panel input",
-  searchField: ".search-field"
+  searchField: ".search-field",
+  blackbox: ".action.black-box"
 };
 
 function getSelector(elementName, ...args) {
   let selector = selectors[elementName];
   if (!selector) {
     throw new Error(`The selector ${elementName} is not defined`);
   }
 
--- a/devtools/client/preferences/debugger.js
+++ b/devtools/client/preferences/debugger.js
@@ -62,10 +62,10 @@ pref("devtools.debugger.features.code-fo
 pref("devtools.debugger.features.outline", true);
 pref("devtools.debugger.features.pause-points", true);
 pref("devtools.debugger.features.component-pane", false);
 pref("devtools.debugger.features.async-stepping", true);
 pref("devtools.debugger.features.skip-pausing", true);
 pref("devtools.debugger.features.autocomplete-expressions", false);
 pref("devtools.debugger.features.map-expression-bindings", true);
 pref("devtools.debugger.features.xhr-breakpoints", true);
-pref("devtools.debugger.features.origial-blackbox", false);
+pref("devtools.debugger.features.origial-blackbox", true);
 pref("devtools.debugger.features.windowless-workers", false);
--- a/devtools/client/shared/source-map/index.js
+++ b/devtools/client/shared/source-map/index.js
@@ -444,16 +444,17 @@ const getGeneratedRanges = dispatcher.ta
 });
 const getGeneratedLocation = dispatcher.task("getGeneratedLocation", {
   queue: true
 });
 const getAllGeneratedLocations = dispatcher.task("getAllGeneratedLocations", {
   queue: true
 });
 const getOriginalLocation = dispatcher.task("getOriginalLocation");
+const getFileGeneratedRange = dispatcher.task("getFileGeneratedRange");
 const getLocationScopes = dispatcher.task("getLocationScopes");
 const getOriginalSourceText = dispatcher.task("getOriginalSourceText");
 const applySourceMap = dispatcher.task("applySourceMap");
 const clearSourceMaps = dispatcher.task("clearSourceMaps");
 const hasMappedSource = dispatcher.task("hasMappedSource");
 const getOriginalStackFrames = dispatcher.task("getOriginalStackFrames");
 
 module.exports = {
@@ -463,16 +464,17 @@ module.exports = {
   isOriginalId,
   hasMappedSource,
   getOriginalURLs,
   getOriginalRanges,
   getGeneratedRanges,
   getGeneratedLocation,
   getAllGeneratedLocations,
   getOriginalLocation,
+  getFileGeneratedRange,
   getLocationScopes,
   getOriginalSourceText,
   applySourceMap,
   clearSourceMaps,
   getOriginalStackFrames,
   startSourceMapWorker(url, assetRoot) {
     dispatcher.start(url);
     setAssetRootURL(assetRoot);
--- a/devtools/client/shared/source-map/worker.js
+++ b/devtools/client/shared/source-map/worker.js
@@ -1871,16 +1871,17 @@ exports.ArraySet = ArraySet;
 const {
   getOriginalURLs,
   getOriginalRanges,
   getGeneratedRanges,
   getGeneratedLocation,
   getAllGeneratedLocations,
   getOriginalLocation,
   getOriginalSourceText,
+  getFileGeneratedRange,
   hasMappedSource,
   clearSourceMaps,
   applySourceMap
 } = __webpack_require__(3710);
 
 const { getOriginalStackFrames } = __webpack_require__(3783);
 const { setAssetRootURL } = __webpack_require__(3794);
 
@@ -1895,16 +1896,17 @@ self.onmessage = workerHandler({
   getOriginalURLs,
   getOriginalRanges,
   getGeneratedRanges,
   getGeneratedLocation,
   getAllGeneratedLocations,
   getOriginalLocation,
   getOriginalSourceText,
   getOriginalStackFrames,
+  getFileGeneratedRange,
   hasMappedSource,
   applySourceMap,
   clearSourceMaps
 });
 
 /***/ }),
 
 /***/ 3710:
@@ -2182,16 +2184,44 @@ async function getOriginalSourceText(ori
   }
 
   return {
     text,
     contentType: getContentType(originalSource.url || "")
   };
 }
 
+async function getFileGeneratedRange(originalSource) {
+  assert(isOriginalId(originalSource.id), "Source is not an original source");
+
+  const map = await getSourceMap(originalToGeneratedId(originalSource.id));
+  if (!map) {
+    return;
+  }
+
+  const start = map.generatedPositionFor({
+    source: originalSource.url,
+    line: 1,
+    column: 0,
+    bias: SourceMapConsumer.LEAST_UPPER_BOUND
+  });
+
+  const end = map.generatedPositionFor({
+    source: originalSource.url,
+    line: Number.MAX_SAFE_INTEGER,
+    column: Number.MAX_SAFE_INTEGER,
+    bias: SourceMapConsumer.GREATEST_LOWER_BOUND
+  });
+
+  return {
+    start,
+    end
+  };
+}
+
 async function hasMappedSource(location) {
   if (isOriginalId(location.sourceId)) {
     return true;
   }
 
   const loc = await getOriginalLocation(location);
   return loc.sourceId !== location.sourceId;
 }
@@ -2213,16 +2243,17 @@ function clearSourceMaps() {
 module.exports = {
   getOriginalURLs,
   getOriginalRanges,
   getGeneratedRanges,
   getGeneratedLocation,
   getAllGeneratedLocations,
   getOriginalLocation,
   getOriginalSourceText,
+  getFileGeneratedRange,
   applySourceMap,
   clearSourceMaps,
   hasMappedSource
 };
 
 /***/ }),
 
 /***/ 3711: