Bug 923396 - use source maps in performance tool draft
authorTom Tromey <tom@tromey.com>
Mon, 15 May 2017 03:48:20 -0600
changeset 668426 672255067ea498ac4111d6a35ae0a3e84c4e2123
parent 667953 a88ee0137c104a57c747cd129c45952ccf1431ad
child 668427 369ae05a5d2692f2cb8895013b068d89ddc9b3fe
push id81041
push userbmo:ttromey@mozilla.com
push dateThu, 21 Sep 2017 16:49:27 +0000
bugs923396
milestone57.0a1
Bug 923396 - use source maps in performance tool Change the performance tool to pass the sourceMapService down to the Frame component, and to use the correct onClick binding. MozReview-Commit-ID: JcYROUnmwRZ
devtools/client/performance/components/jit-optimizations-item.js
devtools/client/performance/components/jit-optimizations.js
devtools/client/performance/views/details-js-call-tree.js
--- a/devtools/client/performance/components/jit-optimizations-item.js
+++ b/devtools/client/performance/components/jit-optimizations-item.js
@@ -32,25 +32,26 @@ const JIT_TYPES = L10N.getStr("jit.types
 const JIT_ATTEMPTS = L10N.getStr("jit.attempts");
 /* eslint-enable no-unused-vars */
 
 const JITOptimizationsItem = createClass({
   displayName: "JITOptimizationsItem",
 
   propTypes: {
     onViewSourceInDebugger: PropTypes.func.isRequired,
+    sourceMapService: PropTypes.object,
     frameData: PropTypes.object.isRequired,
     type: PropTypes.oneOf(OPTIMIZATION_ITEM_TYPES).isRequired,
     depth: PropTypes.number.isRequired,
     arrow: PropTypes.element.isRequired,
     item: PropTypes.object,
     focused: PropTypes.bool
   },
 
-  _renderSite({ item: site, onViewSourceInDebugger, frameData }) {
+  _renderSite({ item: site, onViewSourceInDebugger, sourceMapService, frameData }) {
     let attempts = site.data.attempts;
     let lastStrategy = attempts[attempts.length - 1].strategy;
     let propString = "";
     let propertyName = site.data.propertyName;
 
     // Display property name if it exists
     if (propertyName) {
       if (propertyName.length > PROPNAME_MAX_LENGTH) {
@@ -62,17 +63,18 @@ const JITOptimizationsItem = createClass
 
     let sampleString = PluralForm.get(site.samples, JIT_SAMPLES)
       .replace("#1", site.samples);
     let text = dom.span(
       { className: "optimization-site-title" },
       `${lastStrategy}${propString} – (${sampleString})`
     );
     let frame = Frame({
-      onClick: () => onViewSourceInDebugger(frameData.url, site.data.line),
+      onClick: onViewSourceInDebugger,
+      sourceMapService,
       frame: {
         source: frameData.url,
         line: +site.data.line,
         column: site.data.column,
       }
     });
     let children = [text, frame];
 
@@ -106,27 +108,28 @@ const JITOptimizationsItem = createClass
     );
   },
 
   _renderType({ item: type }) {
     return dom.span({ className: "optimization-ion-type" },
                     `${type.site}:${type.mirType}`);
   },
 
-  _renderObservedType({ onViewSourceInDebugger, item: type }) {
+  _renderObservedType({ onViewSourceInDebugger, sourceMapService, item: type }) {
     let children = [
       dom.span({ className: "optimization-observed-type-keyed" },
         `${type.keyedBy}${type.name ? ` → ${type.name}` : ""}`)
     ];
 
     // If we have a line and location, make a link to the debugger
     if (type.location && type.line) {
       children.push(
         Frame({
-          onClick: () => onViewSourceInDebugger(type.location, type.line),
+          onClick: onViewSourceInDebugger,
+          sourceMapService,
           frame: {
             source: type.location,
             line: type.line,
             column: type.column,
           }
         })
       );
     // Otherwise if we just have a location, it's probably just a memory location.
--- a/devtools/client/performance/components/jit-optimizations.js
+++ b/devtools/client/performance/components/jit-optimizations.js
@@ -58,16 +58,17 @@ const optimizationSiteModel = {
   }).isRequired,
 };
 
 const JITOptimizations = createClass({
   displayName: "JITOptimizations",
 
   propTypes: {
     onViewSourceInDebugger: PropTypes.func.isRequired,
+    sourceMapService: PropTypes.object,
     frameData: PropTypes.object.isRequired,
     optimizationSites: PropTypes.arrayOf(optimizationSiteModel).isRequired,
     autoExpandDepth: PropTypes.number,
   },
 
   getDefaultProps() {
     return {
       autoExpandDepth: 0
@@ -81,51 +82,54 @@ const JITOptimizations = createClass({
   },
 
   /**
    * Frame data generated from `frameNode.getInfo()`, or an empty
    * object, as well as a handler for clicking on the frame component.
    *
    * @param {?Object} .frameData
    * @param {Function} .onViewSourceInDebugger
+   * @param {Object} .sourceMapService
    * @return {ReactElement}
    */
-  _createHeader: function ({ frameData, onViewSourceInDebugger }) {
+  _createHeader: function ({ frameData, onViewSourceInDebugger, sourceMapService }) {
     let { isMetaCategory, url, line } = frameData;
     let name = isMetaCategory ? frameData.categoryData.label :
                frameData.functionName || "";
 
     // Simulate `SavedFrame`s interface
     let frame = { source: url, line: +line, functionDisplayName: name };
 
     // Neither Meta Category nodes, or the lack of a selected frame node,
     // renders out a frame source, like "file.js:123"; so just use
     // an empty span.
     let frameComponent;
     if (isMetaCategory || !name) {
       frameComponent = dom.span();
     } else {
       frameComponent = FrameView({
         frame,
-        onClick: () => onViewSourceInDebugger(frame),
+        onClick: onViewSourceInDebugger,
+        sourceMapService,
       });
     }
 
     return dom.div({ className: "optimization-header" },
       dom.span({ className: "header-title" }, JIT_TITLE),
       dom.span({ className: "header-function-name" }, name),
       frameComponent
     );
   },
 
   _createTree(props) {
     let {
       autoExpandDepth,
       frameData,
       onViewSourceInDebugger,
+      sourceMapService,
       optimizationSites: sites
     } = this.props;
 
     let getSite = id => sites.find(site => site.id === id);
     let getIonTypeForObserved = type => {
       return getSite(type.id).data.types
         .find(iontype => (iontype.typeset || [])
         .indexOf(type) !== -1);
@@ -221,16 +225,17 @@ const JITOptimizations = createClass({
       }),
       onFocus: function () {},
       getKey,
       getRoots: () => sites || [],
       itemHeight: TREE_ROW_HEIGHT,
       renderItem: (item, depth, focused, arrow, expanded) =>
         new OptimizationsItem({
           onViewSourceInDebugger,
+          sourceMapService,
           item,
           depth,
           focused,
           arrow,
           expanded,
           type: getRowType(item),
           frameData,
         }),
--- a/devtools/client/performance/views/details-js-call-tree.js
+++ b/devtools/client/performance/views/details-js-call-tree.js
@@ -103,17 +103,18 @@ var JsCallTreeView = Heritage.extend(Det
       onViewSourceInDebugger: (url, line) => {
         gToolbox.viewSourceInDebugger(url, line).then(success => {
           if (success) {
             this.emit(EVENTS.SOURCE_SHOWN_IN_JS_DEBUGGER);
           } else {
             this.emit(EVENTS.SOURCE_NOT_FOUND_IN_JS_DEBUGGER);
           }
         });
-      }
+      },
+      sourceMapService: gToolbox.sourceMapURLService,
     });
 
     ReactDOM.render(optimizations, this.optimizationsElement);
 
     this.emit("focus", treeItem);
   },
 
   /**