--- a/.eslintignore
+++ b/.eslintignore
@@ -79,17 +79,16 @@ devtools/client/canvasdebugger/**
devtools/client/commandline/**
devtools/client/debugger/**
devtools/client/eyedropper/**
devtools/client/framework/**
devtools/client/jsonview/lib/**
devtools/client/memory/**
devtools/client/netmonitor/test/**
devtools/client/netmonitor/har/test/**
-devtools/client/performance/components/**
devtools/client/performance/legacy/**
devtools/client/performance/modules/**
devtools/client/performance/test/**
devtools/client/projecteditor/**
devtools/client/promisedebugger/**
devtools/client/responsivedesign/**
devtools/client/scratchpad/**
devtools/client/shadereditor/**
--- a/devtools/client/performance/components/jit-optimizations-item.js
+++ b/devtools/client/performance/components/jit-optimizations-item.js
@@ -1,90 +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/. */
-
-const { Cu } = require("chrome");
+"use strict";
const { LocalizationHelper } = require("devtools/client/shared/l10n");
const STRINGS_URI = "chrome://devtools/locale/jit-optimizations.properties";
const L10N = new LocalizationHelper(STRINGS_URI);
const { PluralForm } = require("resource://gre/modules/PluralForm.jsm");
const { DOM: dom, PropTypes, createClass, createFactory } = require("devtools/client/shared/vendor/react");
-const {
- JITOptimizations, hasSuccessfulOutcome, isSuccessfulOutcome
-} = require("devtools/client/performance/modules/logic/jit");
const Frame = createFactory(require("devtools/client/shared/components/frame"));
-const OPTIMIZATION_FAILURE = L10N.getStr("jit.optimizationFailure");
-const JIT_SAMPLES = L10N.getStr("jit.samples");
-const JIT_TYPES = L10N.getStr("jit.types");
-const JIT_ATTEMPTS = L10N.getStr("jit.attempts");
const PROPNAME_MAX_LENGTH = 4;
// If TREE_ROW_HEIGHT changes, be sure to change `var(--jit-tree-row-height)`
// in `devtools/client/themes/jit-optimizations.css`
const TREE_ROW_HEIGHT = 14;
-const OPTIMIZATION_ITEM_TYPES = ["site", "attempts", "types", "attempt", "type", "observedtype"];
-const JITOptimizationsItem = module.exports = createClass({
+const OPTIMIZATION_ITEM_TYPES = ["site", "attempts", "types", "attempt", "type",
+ "observedtype"];
+
+/* eslint-disable no-unused-vars */
+/**
+ * TODO - Re-enable this eslint rule. The JIT tool is a work in progress, and isn't fully
+ * integrated as of yet.
+ */
+const {
+ JITOptimizations, hasSuccessfulOutcome, isSuccessfulOutcome
+} = require("devtools/client/performance/modules/logic/jit");
+const OPTIMIZATION_FAILURE = L10N.getStr("jit.optimizationFailure");
+const JIT_SAMPLES = L10N.getStr("jit.samples");
+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,
frameData: PropTypes.object.isRequired,
type: PropTypes.oneOf(OPTIMIZATION_ITEM_TYPES).isRequired,
},
- render() {
- let {
- item,
- depth,
- arrow,
- focused,
- type,
- frameData,
- onViewSourceInDebugger,
- } = this.props;
-
- let content;
- switch (type) {
- case "site": content = this._renderSite(this.props); break;
- case "attempts": content = this._renderAttempts(this.props); break;
- case "types": content = this._renderTypes(this.props); break;
- case "attempt": content = this._renderAttempt(this.props); break;
- case "type": content = this._renderType(this.props); break;
- case "observedtype": content = this._renderObservedType(this.props); break;
- }
-
- return dom.div(
- {
- className: `optimization-tree-item optimization-tree-item-${type}`,
- style: { marginLeft: depth * TREE_ROW_HEIGHT }
- },
- arrow,
- content
- );
- },
-
_renderSite({ item: site, onViewSourceInDebugger, 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) {
propString = ` (.${propertyName.substr(0, PROPNAME_MAX_LENGTH)}…)`;
} else {
propString = ` (.${propertyName})`;
}
}
- let sampleString = PluralForm.get(site.samples, JIT_SAMPLES).replace("#1", site.samples);
+ 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),
frame: {
source: frameData.url,
@@ -114,22 +92,24 @@ const JITOptimizationsItem = module.expo
},
_renderAttempt({ item: attempt }) {
let success = isSuccessfulOutcome(attempt.outcome);
let { strategy, outcome } = attempt;
return dom.span({ className: "optimization-attempt" },
dom.span({ className: "optimization-strategy" }, strategy),
" → ",
- dom.span({ className: `optimization-outcome ${success ? "success" : "failure"}` }, outcome)
+ dom.span({ className: `optimization-outcome ${success ? "success" : "failure"}` },
+ outcome)
);
},
_renderType({ item: type }) {
- return dom.span({ className: "optimization-ion-type" }, `${type.site}:${type.mirType}`);
+ return dom.span({ className: "optimization-ion-type" },
+ `${type.site}:${type.mirType}`);
},
_renderObservedType({ onViewSourceInDebugger, item: type }) {
let children = [
dom.span({ className: "optimization-observed-type-keyed" },
`${type.keyedBy}${type.name ? ` → ${type.name}` : ""}`)
];
@@ -140,17 +120,56 @@ const JITOptimizationsItem = module.expo
onClick: () => onViewSourceInDebugger(type.location, type.line),
frame: {
source: type.location,
line: type.line,
column: type.column,
}
})
);
- }
// Otherwise if we just have a location, it's probably just a memory location.
- else if (type.location) {
+ } else if (type.location) {
children.push(`@${type.location}`);
}
return dom.span({ className: "optimization-observed-type" }, ...children);
},
+
+ render() {
+ /* eslint-disable no-unused-vars */
+ /**
+ * TODO - Re-enable this eslint rule. The JIT tool is a work in progress, and these
+ * undefined variables may represent intended functionality.
+ */
+ let {
+ depth,
+ arrow,
+ type,
+ // TODO - The following are currently unused.
+ item,
+ focused,
+ frameData,
+ onViewSourceInDebugger,
+ } = this.props;
+ /* eslint-enable no-unused-vars */
+
+ let content;
+ switch (type) {
+ case "site": content = this._renderSite(this.props); break;
+ case "attempts": content = this._renderAttempts(this.props); break;
+ case "types": content = this._renderTypes(this.props); break;
+ case "attempt": content = this._renderAttempt(this.props); break;
+ case "type": content = this._renderType(this.props); break;
+ case "observedtype": content = this._renderObservedType(this.props); break;
+ }
+
+ return dom.div(
+ {
+ className: `optimization-tree-item optimization-tree-item-${type}`,
+ style: { marginLeft: depth * TREE_ROW_HEIGHT }
+ },
+ arrow,
+ content
+ );
+ },
});
+
+module.exports = JITOptimizationsItem;
--- a/devtools/client/performance/components/jit-optimizations.js
+++ b/devtools/client/performance/components/jit-optimizations.js
@@ -1,31 +1,37 @@
/* 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/. */
-
-const { Cu } = require("chrome");
+"use strict";
const { LocalizationHelper } = require("devtools/client/shared/l10n");
const STRINGS_URI = "chrome://devtools/locale/jit-optimizations.properties";
const L10N = new LocalizationHelper(STRINGS_URI);
const { assert } = require("devtools/shared/DevToolsUtils");
const { DOM: dom, createClass, createFactory, PropTypes } = require("devtools/client/shared/vendor/react");
const Tree = createFactory(require("../../shared/components/tree"));
const OptimizationsItem = createFactory(require("./jit-optimizations-item"));
const FrameView = createFactory(require("../../shared/components/frame"));
-
-const onClickTooltipString = frame =>
- L10N.getFormatStr("viewsourceindebugger", `${frame.source}:${frame.line}:${frame.column}`);
const JIT_TITLE = L10N.getStr("jit.title");
// If TREE_ROW_HEIGHT changes, be sure to change `var(--jit-tree-row-height)`
// in `devtools/client/themes/jit-optimizations.css`
const TREE_ROW_HEIGHT = 14;
+/* eslint-disable no-unused-vars */
+/**
+ * TODO - Re-enable this eslint rule. The JIT tool is a work in progress, and isn't fully
+ * integrated as of yet, and this may represent intended functionality.
+ */
+const onClickTooltipString = frame =>
+ L10N.getFormatStr("viewsourceindebugger",
+ `${frame.source}:${frame.line}:${frame.column}`);
+/* eslint-enable no-unused-vars */
+
const optimizationAttemptModel = {
id: PropTypes.number.isRequired,
strategy: PropTypes.string.isRequired,
outcome: PropTypes.string.isRequired,
};
const optimizationObservedTypeModel = {
keyedBy: PropTypes.string.isRequired,
@@ -47,43 +53,36 @@ const optimizationSiteModel = {
line: PropTypes.number.isRequired,
column: PropTypes.number.isRequired,
data: PropTypes.shape({
attempts: PropTypes.arrayOf(optimizationAttemptModel).isRequired,
types: PropTypes.arrayOf(optimizationIonTypeModel).isRequired,
}).isRequired,
};
-const JITOptimizations = module.exports = createClass({
+const JITOptimizations = createClass({
displayName: "JITOptimizations",
propTypes: {
onViewSourceInDebugger: PropTypes.func.isRequired,
frameData: PropTypes.object.isRequired,
optimizationSites: PropTypes.arrayOf(optimizationSiteModel).isRequired,
autoExpandDepth: PropTypes.number,
},
- getInitialState() {
- return {
- expanded: new Set()
- };
- },
-
getDefaultProps() {
return {
autoExpandDepth: 0
};
},
- render() {
- let header = this._createHeader(this.props);
- let tree = this._createTree(this.props);
-
- return dom.div({}, header, tree);
+ getInitialState() {
+ return {
+ expanded: new Set()
+ };
},
/**
* 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
@@ -113,35 +112,56 @@ const JITOptimizations = module.exports
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, optimizationSites: sites } = this.props;
+ let {
+ autoExpandDepth,
+ frameData,
+ onViewSourceInDebugger,
+ optimizationSites: sites
+ } = this.props;
let getSite = id => sites.find(site => site.id === id);
- let getIonTypeForObserved = type =>
- getSite(type.id).data.types.find(iontype => (iontype.typeset || []).indexOf(type) !== -1);
+ let getIonTypeForObserved = type => {
+ return getSite(type.id).data.types
+ .find(iontype => (iontype.typeset || [])
+ .indexOf(type) !== -1);
+ };
let isSite = site => getSite(site.id) === site;
let isAttempts = attempts => getSite(attempts.id).data.attempts === attempts;
let isAttempt = attempt => getSite(attempt.id).data.attempts.indexOf(attempt) !== -1;
let isTypes = types => getSite(types.id).data.types === types;
let isType = type => getSite(type.id).data.types.indexOf(type) !== -1;
let isObservedType = type => getIonTypeForObserved(type);
let getRowType = node => {
- return isSite(node) ? "site" :
- isAttempts(node) ? "attempts" :
- isTypes(node) ? "types" :
- isAttempt(node) ? "attempt" :
- isType(node) ? "type" :
- isObservedType(node) ? "observedtype" : null;
+ if (isSite(node)) {
+ return "site";
+ }
+ if (isAttempts(node)) {
+ return "attempts";
+ }
+ if (isTypes(node)) {
+ return "types";
+ }
+ if (isAttempt(node)) {
+ return "attempt";
+ }
+ if (isType(node)) {
+ return "type";
+ }
+ if (isObservedType(node)) {
+ return "observedtype";
+ }
+ return null;
};
// Creates a unique key for each node in the
// optimizations data
let getKey = node => {
let site = getSite(node.id);
if (isSite(node)) {
return node.id;
@@ -152,16 +172,17 @@ const JITOptimizations = module.exports
} else if (isType(node)) {
return `${node.id}-T-${site.data.types.indexOf(node)}`;
} else if (isAttempt(node)) {
return `${node.id}-A-${site.data.attempts.indexOf(node)}`;
} else if (isObservedType(node)) {
let iontype = getIonTypeForObserved(node);
return `${getKey(iontype)}-O-${iontype.typeset.indexOf(node)}`;
}
+ return "";
};
return Tree({
autoExpandDepth,
getParent: node => {
let site = getSite(node.id);
let parent;
if (isAttempts(node) || isTypes(node)) {
@@ -179,19 +200,18 @@ const JITOptimizations = module.exports
},
getChildren: node => {
if (isSite(node)) {
return [node.data.types, node.data.attempts];
} else if (isAttempts(node) || isTypes(node)) {
return node;
} else if (isType(node)) {
return node.typeset || [];
- } else {
- return [];
}
+ return [];
},
isExpanded: node => this.state.expanded.has(node),
onExpand: node => this.setState(state => {
let expanded = new Set(state.expanded);
expanded.add(node);
return { expanded };
}),
onCollapse: node => this.setState(state => {
@@ -210,10 +230,19 @@ const JITOptimizations = module.exports
depth,
focused,
arrow,
expanded,
type: getRowType(item),
frameData,
}),
});
+ },
+
+ render() {
+ let header = this._createHeader(this.props);
+ let tree = this._createTree(this.props);
+
+ return dom.div({}, header, tree);
}
});
+
+module.exports = JITOptimizations;
--- a/devtools/client/performance/components/test/head.js
+++ b/devtools/client/performance/components/test/head.js
@@ -1,55 +1,58 @@
/* Any copyright is dedicated to the Public Domain.
yield new Promise(function(){});
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
-var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+/* global document, SimpleTest, requestAnimationFrame, is, ok */
+/* exported Cc, Ci, Cu, Cr, Assert, Task, TargetFactory, Toolbox, browserRequire,
+ forceRender, setProps, dumpn, checkOptimizationHeader, checkOptimizationTree */
+let { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
-var { require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
-var { Assert } = require("resource://testing-common/Assert.jsm");
-var { BrowserLoader } = Cu.import("resource://devtools/client/shared/browser-loader.js", {});
-var defer = require("devtools/shared/defer");
-var DevToolsUtils = require("devtools/shared/DevToolsUtils");
-var { Task } = require("devtools/shared/task");
-var { TargetFactory } = require("devtools/client/framework/target");
-var { Toolbox } = require("devtools/client/framework/toolbox");
+let { require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
+let { Assert } = require("resource://testing-common/Assert.jsm");
+let { BrowserLoader } = Cu.import("resource://devtools/client/shared/browser-loader.js", {});
+let defer = require("devtools/shared/defer");
+let DevToolsUtils = require("devtools/shared/DevToolsUtils");
+let { Task } = require("devtools/shared/task");
+let { TargetFactory } = require("devtools/client/framework/target");
+let { Toolbox } = require("devtools/client/framework/toolbox");
DevToolsUtils.testing = true;
-var { require: browserRequire } = BrowserLoader({
+let { require: browserRequire } = BrowserLoader({
baseURI: "resource://devtools/client/performance/",
window: this
});
-var $ = (selector, scope = document) => scope.querySelector(selector);
-var $$ = (selector, scope = document) => scope.querySelectorAll(selector);
+let $ = (selector, scope = document) => scope.querySelector(selector);
+let $$ = (selector, scope = document) => scope.querySelectorAll(selector);
function forceRender(comp) {
return setState(comp, {})
.then(() => setState(comp, {}));
}
// All tests are asynchronous.
SimpleTest.waitForExplicitFinish();
function onNextAnimationFrame(fn) {
return () =>
requestAnimationFrame(() =>
requestAnimationFrame(fn));
}
function setState(component, newState) {
- var deferred = defer();
+ let deferred = defer();
component.setState(newState, onNextAnimationFrame(deferred.resolve));
return deferred.promise;
}
function setProps(component, newState) {
- var deferred = defer();
+ let deferred = defer();
component.setProps(newState, onNextAnimationFrame(deferred.resolve));
return deferred.promise;
}
function dumpn(msg) {
dump(`PERFORMANCE-COMPONENT-TEST: ${msg}\n`);
}
@@ -107,27 +110,27 @@ let OPTS_DATA_GENERAL = [{
{ id: 2, keyedBy: "primitive" },
{ id: 2, keyedBy: "constructor", name: "B", location: "http://mypage.com/file.js", line: "2" },
{ id: 2, keyedBy: "constructor", name: "C", location: "http://mypage.com/file.js", line: "3" },
{ id: 2, keyedBy: "constructor", name: "D", location: "http://mypage.com/file.js", line: "4" },
],
}]
}
}];
+
OPTS_DATA_GENERAL.forEach(site => {
site.data.types.forEach(type => {
if (type.typeset) {
type.typeset.id = site.id;
}
});
site.data.attempts.id = site.id;
site.data.types.id = site.id;
});
-
function checkOptimizationHeader(name, file, line) {
is($(".optimization-header .header-function-name").textContent, name,
"correct optimization header function name");
is($(".optimization-header .frame-link-filename").textContent, file,
"correct optimization header file name");
is($(".optimization-header .frame-link-line").textContent, `:${line}`,
"correct optimization header line");
}
@@ -170,14 +173,15 @@ function checkOptimizationTree(rowData)
expected.keyedBy,
`row ${i}th: correct observed type row`);
break;
case "attempt":
is($(".optimization-strategy", row).textContent, expected.strategy,
`row ${i}th: correct attempt row, attempt item`);
is($(".optimization-outcome", row).textContent, expected.outcome,
`row ${i}th: correct attempt row, outcome item`);
- ok($(".optimization-outcome", row).classList.contains(expected.success ? "success" : "failure"),
+ ok($(".optimization-outcome", row)
+ .classList.contains(expected.success ? "success" : "failure"),
`row ${i}th: correct attempt row, failure/success status`);
break;
}
}
}