Commit 91ace57f authored by Sathya Gunasekaran's avatar Sathya Gunasekaran Committed by Commit Bot

Reland "[presubmit] Add JS formatting for tools/system-analyzer"

This is a reland of 1ec8f1da

Original change's description:
> [presubmit] Add JS formatting for tools/system-analyzer
>
> Bug: v8:10670
> Change-Id: Ifb653ada003719faff261b6e5b2169db37cffdaf
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2282522
> Reviewed-by: Tamer Tas <tmrts@chromium.org>
> Commit-Queue: Sathya Gunasekaran  <gsathya@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#68909}

Bug: v8:10670
Change-Id: I4903b3eb8ff39a76594324076f0840b06290044e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2307229
Commit-Queue: Sathya Gunasekaran  <gsathya@chromium.org>
Reviewed-by: 's avatarTamer Tas <tmrts@chromium.org>
Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70938}
parent efff3d18
......@@ -29,6 +29,7 @@
.cproject
.gclient_entries
.gdb_history
.jslint-cache
.landmines
.project
.pydevproject
......
......@@ -80,6 +80,7 @@ def _V8PresubmitChecks(input_api, output_api):
sys.path.append(input_api.os_path.join(
input_api.PresubmitLocalPath(), 'tools'))
from v8_presubmit import CppLintProcessor
from v8_presubmit import JSLintProcessor
from v8_presubmit import TorqueLintProcessor
from v8_presubmit import SourceProcessor
from v8_presubmit import StatusFilesProcessor
......@@ -95,6 +96,11 @@ def _V8PresubmitChecks(input_api, output_api):
affected_file,
files_to_check=(r'.+\.tq'))
def FilterJSFile(affected_file):
return input_api.FilterSourceFile(
affected_file,
white_list=(r'.+\.m?js'))
results = []
if not CppLintProcessor().RunOnFiles(
input_api.AffectedFiles(file_filter=FilterFile, include_deletes=False)):
......@@ -103,6 +109,10 @@ def _V8PresubmitChecks(input_api, output_api):
input_api.AffectedFiles(file_filter=FilterTorqueFile,
include_deletes=False)):
results.append(output_api.PresubmitError("Torque format check failed"))
if not JSLintProcessor().RunOnFiles(
input_api.AffectedFiles(file_filter=FilterJSFile,
include_deletes=False)):
results.append(output_api.PresubmitError("JS format check failed"))
if not SourceProcessor().RunOnFiles(
input_api.AffectedFiles(include_deletes=False)):
results.append(output_api.PresubmitError(
......
......@@ -3,7 +3,7 @@
// found in the LICENSE file.
class State {
_timeSelection = { start: 0, end: Infinity };
_timeSelection = {start: 0, end: Infinity};
_map;
_ic;
_selectedMapLogEntries;
......@@ -60,11 +60,11 @@ class State {
this._deoptTimeline = timeline;
}
set chunks(value) {
//TODO(zcankara) split up between maps and ics, and every timeline track
// TODO(zcankara) split up between maps and ics, and every timeline track
this._chunks = value;
}
get chunks() {
//TODO(zcankara) split up between maps and ics, and every timeline track
// TODO(zcankara) split up between maps and ics, and every timeline track
return this._chunks;
}
get nofChunks() {
......@@ -74,20 +74,20 @@ class State {
this._nofChunks = count;
}
get map() {
//TODO(zcankara) rename as selectedMapEvents, array of selected events
// TODO(zcankara) rename as selectedMapEvents, array of selected events
return this._map;
}
set map(value) {
//TODO(zcankara) rename as selectedMapEvents, array of selected events
// TODO(zcankara) rename as selectedMapEvents, array of selected events
if (!value) return;
this._map = value;
}
get ic() {
//TODO(zcankara) rename selectedICEvents, array of selected events
// TODO(zcankara) rename selectedICEvents, array of selected events
return this._ic;
}
set ic(value) {
//TODO(zcankara) rename selectedIcEvents, array of selected events
// TODO(zcankara) rename selectedIcEvents, array of selected events
if (!value) return;
this._ic = value;
}
......@@ -122,4 +122,4 @@ class State {
}
}
export { State };
export {State};
......@@ -4,44 +4,48 @@
class SelectionEvent extends CustomEvent {
// TODO: turn into static class fields once Safari supports it.
static get name() { return "showentries"; }
static get name() {
return 'showentries';
}
constructor(entries) {
super(SelectionEvent.name, { bubbles: true, composed: true });
super(SelectionEvent.name, {bubbles: true, composed: true});
if (!Array.isArray(entries) || entries.length == 0) {
throw new Error("No valid entries selected!");
throw new Error('No valid entries selected!');
}
this.entries = entries;
}
}
class FocusEvent extends CustomEvent {
static get name() { return "showentrydetail"; }
static get name() {
return 'showentrydetail';
}
constructor(entry) {
super(FocusEvent.name, { bubbles: true, composed: true });
super(FocusEvent.name, {bubbles: true, composed: true});
this.entry = entry;
}
}
class SelectTimeEvent extends CustomEvent {
static get name() { return 'timerangeselect'; }
static get name() {
return 'timerangeselect';
}
constructor(start, end) {
super(SelectTimeEvent.name, { bubbles: true, composed: true });
super(SelectTimeEvent.name, {bubbles: true, composed: true});
this.start = start;
this.end = end;
}
}
class SynchronizeSelectionEvent extends CustomEvent {
static get name() { return 'syncselection'; }
static get name() {
return 'syncselection';
}
constructor(start, end) {
super(SynchronizeSelectionEvent.name, { bubbles: true, composed: true });
super(SynchronizeSelectionEvent.name, {bubbles: true, composed: true});
this.start = start;
this.end = end;
}
}
export {
SelectionEvent, FocusEvent, SelectTimeEvent,
SynchronizeSelectionEvent
};
export {SelectionEvent, FocusEvent, SelectTimeEvent, SynchronizeSelectionEvent};
......@@ -162,12 +162,13 @@ class DOM {
}
static defineCustomElement(path, generator) {
let name = path.substring(path.lastIndexOf("/") + 1, path.length);
let name = path.substring(path.lastIndexOf('/') + 1, path.length);
path = path + '-template.html';
fetch(path)
.then(stream => stream.text())
.then(
templateText => customElements.define(name, generator(templateText)));
templateText =>
customElements.define(name, generator(templateText)));
}
}
......@@ -178,7 +179,7 @@ function $(id) {
class V8CustomElement extends HTMLElement {
constructor(templateText) {
super();
const shadowRoot = this.attachShadow({ mode: 'open' });
const shadowRoot = this.attachShadow({mode: 'open'});
shadowRoot.innerHTML = templateText;
}
$(id) {
......@@ -190,7 +191,6 @@ class V8CustomElement extends HTMLElement {
}
}
class LazyTable {
constructor(table, rowData, rowElementCreator) {
this._table = table;
......@@ -198,7 +198,7 @@ class LazyTable {
this._rowElementCreator = rowElementCreator;
const tbody = table.querySelector('tbody');
table.replaceChild(document.createElement('tbody'), tbody);
table.querySelector("tfoot td").onclick = (e) => this._addMoreRows();
table.querySelector('tfoot td').onclick = (e) => this._addMoreRows();
this._addMoreRows();
}
......@@ -216,7 +216,6 @@ class LazyTable {
}
}
class LazyTable {
constructor(table, rowData, rowElementCreator) {
this._table = table;
......@@ -224,7 +223,7 @@ class LazyTable {
this._rowElementCreator = rowElementCreator;
const tbody = table.querySelector('tbody');
table.replaceChild(document.createElement('tbody'), tbody);
table.querySelector("tfoot td").onclick = (e) => this._addMoreRows();
table.querySelector('tfoot td').onclick = (e) => this._addMoreRows();
this._addMoreRows();
}
......@@ -247,6 +246,12 @@ function delay(time) {
}
export {
DOM, $, V8CustomElement, formatBytes,
typeToColor, CSSColor, delay, LazyTable,
DOM,
$,
V8CustomElement,
formatBytes,
typeToColor,
CSSColor,
delay,
LazyTable,
};
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import { IcLogEntry } from "./log/ic.mjs";
import {IcLogEntry} from './log/ic.mjs';
// For compatibility with console scripts:
print = console.log;
......@@ -51,8 +51,7 @@ export class Group {
group.percentage = Math.round(group.count / length * 100 * 100) / 100;
result.push(group);
}
result.sort((a, b) => { return b.count - a.count });
result.sort((a, b) => {return b.count - a.count});
return result;
}
}
......@@ -2,24 +2,23 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import { Group } from './ic-model.mjs';
import { MapLogEntry } from "./log/map.mjs";
import { FocusEvent, SelectTimeEvent, SelectionEvent } from './events.mjs';
import { DOM, V8CustomElement, delay } from './helper.mjs';
import { IcLogEntry } from './log/ic.mjs';
DOM.defineCustomElement('ic-panel', (templateText) =>
class ICPanel extends V8CustomElement {
import {FocusEvent, SelectionEvent, SelectTimeEvent} from './events.mjs';
import {delay, DOM, V8CustomElement} from './helper.mjs';
import {Group} from './ic-model.mjs';
import {IcLogEntry} from './log/ic.mjs';
import {MapLogEntry} from './log/map.mjs';
DOM.defineCustomElement(
'ic-panel', (templateText) => class ICPanel extends V8CustomElement {
_selectedLogEntries;
_timeline;
constructor() {
super(templateText);
this.initGroupKeySelect();
this.groupKey.addEventListener(
'change', e => this.updateTable(e));
this.groupKey.addEventListener('change', e => this.updateTable(e));
}
set timeline(value) {
console.assert(value !== undefined, "timeline undefined!");
console.assert(value !== undefined, 'timeline undefined!');
this._timeline = value;
this.selectedLogEntries = this._timeline.all;
this.updateCount();
......@@ -41,7 +40,7 @@ DOM.defineCustomElement('ic-panel', (templateText) =>
}
get spanSelectAll() {
return this.querySelectorAll("span");
return this.querySelectorAll('span');
}
set selectedLogEntries(value) {
......@@ -56,7 +55,7 @@ DOM.defineCustomElement('ic-panel', (templateText) =>
}
updateCount() {
this.count.innerHTML = "length=" + this._selectedLogEntries.length;
this.count.innerHTML = 'length=' + this._selectedLogEntries.length;
}
updateTable(event) {
......@@ -69,13 +68,13 @@ DOM.defineCustomElement('ic-panel', (templateText) =>
}
escapeHtml(unsafe) {
if (!unsafe) return "";
if (!unsafe) return '';
return unsafe.toString()
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#039;");
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#039;');
}
handleMapClick(e) {
......@@ -97,7 +96,8 @@ DOM.defineCustomElement('ic-panel', (templateText) =>
return Array.from(selectedMapLogEntriesSet);
}
//TODO(zcankara) Handle in the processor for events with source positions.
// TODO(zcankara) Handle in the processor for events with source
// positions.
handleFilePositionClick(e) {
const tr = e.target.parentNode;
const sourcePosition = tr.group.entries[0].sourcePosition;
......@@ -116,13 +116,13 @@ DOM.defineCustomElement('ic-panel', (templateText) =>
tr.group = group;
const details = tr.appendChild(DOM.td('', 'toggle'));
details.onclick = detailsClickHandler;
tr.appendChild(DOM.td(group.percentage + "%", 'percentage'));
tr.appendChild(DOM.td(group.percentage + '%', 'percentage'));
tr.appendChild(DOM.td(group.count, 'count'));
const valueTd = tr.appendChild(DOM.td(group.key, 'key'));
if (group.property === "map") {
if (group.property === 'map') {
valueTd.onclick = mapClickHandler;
valueTd.classList.add('clickable');
} else if (group.property == "filePosition") {
} else if (group.property == 'filePosition') {
valueTd.classList.add('clickable');
valueTd.onclick = fileClickHandler;
}
......@@ -132,7 +132,7 @@ DOM.defineCustomElement('ic-panel', (templateText) =>
if (omitted > 0) {
const tr = DOM.tr();
const tdNode =
tr.appendChild(DOM.td('Omitted ' + omitted + " entries."));
tr.appendChild(DOM.td('Omitted ' + omitted + ' entries.'));
tdNode.colSpan = 4;
fragment.appendChild(tr);
}
......@@ -148,18 +148,18 @@ DOM.defineCustomElement('ic-panel', (templateText) =>
this.renderDrilldown(group, tr);
}
let detailsTr = tr.nextSibling;
if (tr.classList.contains("open")) {
tr.classList.remove("open");
detailsTr.style.display = "none";
if (tr.classList.contains('open')) {
tr.classList.remove('open');
detailsTr.style.display = 'none';
} else {
tr.classList.add("open");
detailsTr.style.display = "table-row";
tr.classList.add('open');
detailsTr.style.display = 'table-row';
}
}
renderDrilldown(group, previousSibling) {
let tr = DOM.tr("entry-details");
tr.style.display = "none";
let tr = DOM.tr('entry-details');
tr.style.display = 'none';
// indent by one td.
tr.appendChild(DOM.td());
let td = DOM.td();
......@@ -187,7 +187,7 @@ DOM.defineCustomElement('ic-panel', (templateText) =>
const select = this.groupKey;
select.options.length = 0;
for (const propertyName of IcLogEntry.propertyNames) {
const option = document.createElement("option");
const option = document.createElement('option');
option.text = propertyName;
select.add(option);
}
......
......@@ -2,22 +2,23 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import { SelectionEvent, FocusEvent, SelectTimeEvent } from "./events.mjs";
import { State } from "./app-model.mjs";
import { MapLogEntry } from "./log/map.mjs";
import { IcLogEntry } from "./log/ic.mjs";
import { Processor } from "./processor.mjs";
import { SourcePosition } from "../profile.mjs";
import { $ } from "./helper.mjs";
import {SourcePosition} from '../profile.mjs';
import {State} from './app-model.mjs';
import {FocusEvent, SelectionEvent, SelectTimeEvent} from './events.mjs';
import {$} from './helper.mjs';
import {IcLogEntry} from './log/ic.mjs';
import {MapLogEntry} from './log/map.mjs';
import {Processor} from './processor.mjs';
class App {
_state;
_view;
_navigation;
_startupPromise;
constructor(fileReaderId, mapPanelId, mapStatsPanelId, timelinePanelId,
icPanelId, mapTrackId, icTrackId, deoptTrackId, sourcePanelId) {
constructor(
fileReaderId, mapPanelId, mapStatsPanelId, timelinePanelId, icPanelId,
mapTrackId, icTrackId, deoptTrackId, sourcePanelId) {
this._view = {
__proto__: null,
logFileReader: $(fileReaderId),
......@@ -31,32 +32,30 @@ class App {
sourcePanel: $(sourcePanelId)
};
this.toggleSwitch = $('.theme-switch input[type="checkbox"]');
this.toggleSwitch.addEventListener("change", (e) => this.switchTheme(e));
this._view.logFileReader.addEventListener("fileuploadstart", (e) =>
this.handleFileUploadStart(e)
);
this._view.logFileReader.addEventListener("fileuploadend", (e) =>
this.handleFileUploadEnd(e)
);
this.toggleSwitch.addEventListener('change', (e) => this.switchTheme(e));
this._view.logFileReader.addEventListener(
'fileuploadstart', (e) => this.handleFileUploadStart(e));
this._view.logFileReader.addEventListener(
'fileuploadend', (e) => this.handleFileUploadEnd(e));
this._startupPromise = this.runAsyncInitialize();
}
async runAsyncInitialize() {
await Promise.all([
import("./ic-panel.mjs"),
import("./timeline-panel.mjs"),
import("./stats-panel.mjs"),
import("./map-panel.mjs"),
import("./source-panel.mjs"),
import('./ic-panel.mjs'),
import('./timeline-panel.mjs'),
import('./stats-panel.mjs'),
import('./map-panel.mjs'),
import('./source-panel.mjs'),
]);
document.addEventListener('keydown',
e => this._navigation?.handleKeyDown(e));
document.addEventListener(SelectionEvent.name,
e => this.handleShowEntries(e));
document.addEventListener(FocusEvent.name,
e => this.handleShowEntryDetail(e));
document.addEventListener(SelectTimeEvent.name,
e => this.handleTimeRangeSelect(e));
document.addEventListener(
'keydown', e => this._navigation?.handleKeyDown(e));
document.addEventListener(
SelectionEvent.name, e => this.handleShowEntries(e));
document.addEventListener(
FocusEvent.name, e => this.handleShowEntryDetail(e));
document.addEventListener(
SelectTimeEvent.name, e => this.handleTimeRangeSelect(e));
}
handleShowEntries(e) {
......@@ -67,7 +66,7 @@ class App {
} else if (e.entries[0] instanceof SourcePosition) {
this.showSourcePositionEntries(e.entries);
} else {
throw new Error("Unknown selection type!");
throw new Error('Unknown selection type!');
}
e.stopPropagation();
}
......@@ -84,7 +83,7 @@ class App {
this._state.selectedDeoptLogEntries = entries;
}
showSourcePositionEntries(entries) {
//TODO: Handle multiple source position selection events
// TODO: Handle multiple source position selection events
this._view.sourcePanel.selectedSourcePositions = entries
}
......@@ -98,7 +97,7 @@ class App {
this.showMapEntries(this._state.mapTimeline.selection);
this.showIcEntries(this._state.icTimeline.selection);
this.showDeoptEntries(this._state.deoptTimeline.selection);
this._view.timelinePanel.timeSelection = {start,end};
this._view.timelinePanel.timeSelection = {start, end};
}
handleShowEntryDetail(e) {
......@@ -109,7 +108,7 @@ class App {
} else if (e.entry instanceof SourcePosition) {
this.selectSourcePosition(e.entry);
} else {
throw new Error("Unknown selection type!");
throw new Error('Unknown selection type!');
}
e.stopPropagation();
}
......@@ -129,7 +128,7 @@ class App {
handleFileUploadStart(e) {
this.restartApp();
$("#container").className = "initial";
$('#container').className = 'initial';
}
restartApp() {
......@@ -150,17 +149,18 @@ class App {
// Transitions must be set before timeline for stats panel.
this._view.mapPanel.timeline = mapTimeline;
this._view.mapTrack.data = mapTimeline;
this._view.mapStatsPanel.transitions = this._state.mapTimeline.transitions;
this._view.mapStatsPanel.transitions =
this._state.mapTimeline.transitions;
this._view.mapStatsPanel.timeline = mapTimeline;
this._view.icPanel.timeline = icTimeline;
this._view.icTrack.data = icTimeline;
this._view.deoptTrack.data = deoptTimeline;
this._view.sourcePanel.data = processor.scripts
} catch(e) {
this._view.logFileReader.error = "Log file contains errors!"
throw(e);
} catch (e) {
this._view.logFileReader.error = 'Log file contains errors!'
throw (e);
} finally {
$("#container").className = "loaded";
$('#container').className = 'loaded';
this.fileLoaded = true;
}
}
......@@ -172,9 +172,8 @@ class App {
}
switchTheme(event) {
document.documentElement.dataset.theme = event.target.checked
? "light"
: "dark";
document.documentElement.dataset.theme =
event.target.checked ? 'light' : 'dark';
if (this.fileLoaded) {
this.refreshTimelineTrackView();
}
......@@ -268,7 +267,7 @@ class Navigation {
}
handleKeyDown(event) {
switch (event.key) {
case "ArrowUp":
case 'ArrowUp':
event.preventDefault();
if (event.shiftKey) {
this.selectPrevEdge();
......@@ -276,7 +275,7 @@ class Navigation {
this.moveInChunk(-1);
}
return false;
case "ArrowDown":
case 'ArrowDown':
event.preventDefault();
if (event.shiftKey) {
this.selectNextEdge();
......@@ -284,20 +283,20 @@ class Navigation {
this.moveInChunk(1);
}
return false;
case "ArrowLeft":
case 'ArrowLeft':
this.moveInChunks(false);
break;
case "ArrowRight":
case 'ArrowRight':
this.moveInChunks(true);
break;
case "+":
case '+':
this.increaseTimelineResolution();
break;
case "-":
case '-':
this.decreaseTimelineResolution();
break;
}
}
}
export { App };
export {App};
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import { DOM, V8CustomElement } from './helper.mjs';
import {DOM, V8CustomElement} from './helper.mjs';
DOM.defineCustomElement('log-file-reader', (templateText) =>
DOM.defineCustomElement('log-file-reader',
(templateText) =>
class LogFileReader extends V8CustomElement {
constructor() {
super(templateText);
......@@ -11,8 +12,8 @@ DOM.defineCustomElement('log-file-reader', (templateText) =>
this.addEventListener('dragover', e => this.handleDragOver(e));
this.addEventListener('drop', e => this.handleChange(e));
this.$('#file').addEventListener('change', e => this.handleChange(e));
this.$('#fileReader').addEventListener('keydown',
e => this.handleKeyEvent(e));
this.$('#fileReader')
.addEventListener('keydown', e => this.handleKeyEvent(e));
}
set error(message) {
......@@ -25,7 +26,7 @@ DOM.defineCustomElement('log-file-reader', (templateText) =>
}
handleKeyEvent(event) {
if (event.key == "Enter") this.handleClick(event);
if (event.key == 'Enter') this.handleClick(event);
}
handleClick(event) {
......@@ -35,8 +36,8 @@ DOM.defineCustomElement('log-file-reader', (templateText) =>
handleChange(event) {
// Used for drop and file change.
event.preventDefault();
this.dispatchEvent(new CustomEvent(
'fileuploadstart', { bubbles: true, composed: true }));
this.dispatchEvent(
new CustomEvent('fileuploadstart', {bubbles: true, composed: true}));
var host = event.dataTransfer ? event.dataTransfer : event.target;
this.readFile(host.files[0]);
}
......@@ -53,7 +54,9 @@ DOM.defineCustomElement('log-file-reader', (templateText) =>
return this.$('#fileReader');
}
get root() { return this.$("#root"); }
get root() {
return this.$('#root');
}
readFile(file) {
if (!file) {
......@@ -71,12 +74,11 @@ DOM.defineCustomElement('log-file-reader', (templateText) =>
handleFileLoad(e, file) {
const chunk = e.target.result;
this.updateLabel('Finished loading \'' + file.name + '\'.');
this.dispatchEvent(new CustomEvent(
'fileuploadend', {
this.dispatchEvent(new CustomEvent('fileuploadend', {
bubbles: true,
composed: true,
detail: chunk,
}));
this.root.className = 'done';
}
});
});
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import { LogEntry } from './log.mjs';
import {LogEntry} from './log.mjs';
export class DeoptLogEntry extends LogEntry {
constructor(type, time) {
......
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import { LogEntry } from './log.mjs';
import {LogEntry} from './log.mjs';
export class IcLogEntry extends LogEntry {
constructor(
......@@ -58,15 +58,8 @@ export class IcLogEntry extends LogEntry {
static get propertyNames() {
return [
'type',
'category',
'functionName',
'filePosition',
'state',
'key',
'map',
'reason',
'file'
'type', 'category', 'functionName', 'filePosition', 'state', 'key', 'map',
'reason', 'file'
];
}
}
......@@ -6,7 +6,7 @@ export class LogEntry {
_time;
_type;
constructor(type, time) {
//TODO(zcankara) remove type and add empty getters to override
// TODO(zcankara) remove type and add empty getters to override
this._time = time;
this._type = type;
}
......@@ -18,6 +18,6 @@ export class LogEntry {
}
// Returns an Array of all possible #type values.
static get allTypes() {
throw new Error("Not implemented.");
throw new Error('Not implemented.');
}
}
\ No newline at end of file
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import { LogEntry } from './log.mjs';
import {LogEntry} from './log.mjs';
// ===========================================================================
// Map Log Events
......@@ -11,10 +11,10 @@ const kChunkHeight = 200;
const kChunkWidth = 10;
function define(prototype, name, fn) {
Object.defineProperty(prototype, name, { value: fn, enumerable: false });
Object.defineProperty(prototype, name, {value: fn, enumerable: false});
}
define(Array.prototype, 'max', function (fn) {
define(Array.prototype, 'max', function(fn) {
if (this.length === 0) return undefined;
if (fn === undefined) fn = (each) => each;
let max = fn(this[0]);
......@@ -23,10 +23,10 @@ define(Array.prototype, 'max', function (fn) {
}
return max;
})
define(Array.prototype, 'first', function () {
define(Array.prototype, 'first', function() {
return this[0]
});
define(Array.prototype, 'last', function () {
define(Array.prototype, 'last', function() {
return this[this.length - 1]
});
......@@ -286,5 +286,4 @@ class Edge {
}
}
export { MapLogEntry, Edge, kChunkWidth, kChunkHeight };
export {MapLogEntry, Edge, kChunkWidth, kChunkHeight};
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import "./stats-panel.mjs";
import "./map-panel/map-details.mjs";
import "./map-panel/map-transitions.mjs";
import { FocusEvent } from './events.mjs';
import { MapLogEntry } from "./log/map.mjs";
import { DOM, V8CustomElement } from './helper.mjs';
import './stats-panel.mjs';
import './map-panel/map-details.mjs';
import './map-panel/map-transitions.mjs';
DOM.defineCustomElement('map-panel', (templateText) =>
import {FocusEvent} from './events.mjs';
import {DOM, V8CustomElement} from './helper.mjs';
import {MapLogEntry} from './log/map.mjs';
DOM.defineCustomElement('map-panel',
(templateText) =>
class MapPanel extends V8CustomElement {
_map;
constructor() {
super(templateText);
this.searchBarBtn.addEventListener(
'click', e => this.handleSearchBar(e));
this.addEventListener(
FocusEvent.name, e => this.handleUpdateMapDetails(e));
this.searchBarBtn.addEventListener('click', e => this.handleSearchBar(e));
this.addEventListener(FocusEvent.name, e => this.handleUpdateMapDetails(e));
}
handleUpdateMapDetails(e) {
......@@ -57,12 +57,12 @@ DOM.defineCustomElement('map-panel', (templateText) =>
handleSearchBar(e) {
let searchBar = this.$('#searchBarInput');
let searchBarInput = searchBar.value;
//access the map from model cache
// access the map from model cache
let selectedMap = MapLogEntry.get(parseInt(searchBarInput));
if (selectedMap) {
searchBar.className = "success";
searchBar.className = 'success';
} else {
searchBar.className = "failure";
searchBar.className = 'failure';
}
this.dispatchEvent(new FocusEvent(selectedMap));
}
......@@ -73,5 +73,4 @@ DOM.defineCustomElement('map-panel', (templateText) =>
get selectedMapLogEntries() {
return this.mapTransitionsPanel.selectedMapLogEntries;
}
});
});
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import { V8CustomElement, DOM} from "../helper.mjs";
import { FocusEvent } from "../events.mjs";
import {FocusEvent} from '../events.mjs';
import {DOM, V8CustomElement} from '../helper.mjs';
DOM.defineCustomElement(
"./map-panel/map-details",
(templateText) =>
class MapDetails extends V8CustomElement {
'./map-panel/map-details',
(templateText) => class MapDetails extends V8CustomElement {
constructor() {
super(templateText);
this._filePositionNode.addEventListener("click", e =>
this.handleFilePositionClick(e)
);
this._filePositionNode.addEventListener(
'click', e => this.handleFilePositionClick(e));
this.selectedMap = undefined;
}
get mapDetails() {
return this.$("#mapDetails");
return this.$('#mapDetails');
}
get _filePositionNode() {
return this.$("#filePositionNode");
return this.$('#filePositionNode');
}
setSelectedMap(value) {
......@@ -28,21 +26,20 @@ DOM.defineCustomElement(
}
set mapDetails(map) {
let details = "";
let clickableDetails = "";
let details = '';
let clickableDetails = '';
if (map) {
clickableDetails += "ID: " + map.id;
clickableDetails += "\nSource location: " + map.filePosition;
details += "\n" + map.description;
clickableDetails += 'ID: ' + map.id;
clickableDetails += '\nSource location: ' + map.filePosition;
details += '\n' + map.description;
this.setSelectedMap(map);
}
this._filePositionNode.innerText = clickableDetails;
this._filePositionNode.classList.add("clickable");
this._filePositionNode.classList.add('clickable');
this.mapDetails.innerText = details;
}
handleFilePositionClick() {
this.dispatchEvent(new FocusEvent(this.selectedMap.sourcePosition));
}
}
);
});
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import { V8CustomElement, DOM, typeToColor } from "../helper.mjs";
import { FocusEvent, SelectionEvent } from "../events.mjs";
import {FocusEvent, SelectionEvent} from '../events.mjs';
import {DOM, typeToColor, V8CustomElement} from '../helper.mjs';
DOM.defineCustomElement(
"./map-panel/map-transitions",
DOM.defineCustomElement('./map-panel/map-transitions',
(templateText) =>
class MapTransitions extends V8CustomElement {
_map;
......@@ -14,23 +13,22 @@ DOM.defineCustomElement(
_showMapsUpdateId;
constructor() {
super(templateText);
this.transitionView.addEventListener("mousemove", (e) =>
this.handleTransitionViewChange(e)
);
this.transitionView.addEventListener(
'mousemove', (e) => this.handleTransitionViewChange(e));
this.currentNode = this.transitionView;
this.currentMap = undefined;
}
get transitionView() {
return this.$("#transitionView");
return this.$('#transitionView');
}
get tooltip() {
return this.$("#tooltip");
return this.$('#tooltip');
}
get tooltipContents() {
return this.$("#tooltipContents");
return this.$('#tooltipContents');
}
set map(value) {
......@@ -39,8 +37,8 @@ DOM.defineCustomElement(
}
handleTransitionViewChange(e) {
this.tooltip.style.left = e.pageX + "px";
this.tooltip.style.top = e.pageY + "px";
this.tooltip.style.left = e.pageX + 'px';
this.tooltip.style.top = e.pageY + 'px';
let map = e.target.map;
if (map) {
this.tooltipContents.innerText = map.description;
......@@ -63,14 +61,14 @@ DOM.defineCustomElement(
this._showMapsUpdateId = setTimeout(() => this._showMaps(), 250);
}
_showMaps() {
this.transitionView.style.display = "none";
this.transitionView.style.display = 'none';
DOM.removeAllChildren(this.transitionView);
this._displayedMapsInTree = new Set();
// Limit view to 200 maps for performance reasons.
this.selectedMapLogEntries.slice(0, 200).forEach((map) =>
this.addMapAndParentTransitions(map));
this.selectedMapLogEntries.slice(0, 200).forEach(
(map) => this.addMapAndParentTransitions(map));
this._displayedMapsInTree = undefined;
this.transitionView.style.display = "";
this.transitionView.style.display = '';
}
set selectedMapLogEntries(list) {
......@@ -94,17 +92,15 @@ DOM.defineCustomElement(
}
let mapNode = this.addSubtransitions(map);
// Mark and show the selected map.
mapNode.classList.add("selected");
mapNode.classList.add('selected');
if (this.selectedMap == map) {
setTimeout(
() =>
mapNode.scrollIntoView({
behavior: "smooth",
block: "nearest",
inline: "nearest",
() => mapNode.scrollIntoView({
behavior: 'smooth',
block: 'nearest',
inline: 'nearest',
}),
1
);
1);
}
}
......@@ -120,10 +116,10 @@ DOM.defineCustomElement(
}
addTransitionEdge(map) {
let classes = ["transitionEdge"];
let classes = ['transitionEdge'];
let edge = DOM.div(classes);
edge.style.backgroundColor = typeToColor(map.edge);
let labelNode = DOM.div("transitionLabel");
let labelNode = DOM.div('transitionLabel');
labelNode.innerText = map.edge.toString();
edge.appendChild(labelNode);
return edge;
......@@ -132,15 +128,15 @@ DOM.defineCustomElement(
addTransitionTo(map) {
// transition[ transitions[ transition[...], transition[...], ...]];
this._displayedMapsInTree?.add(map);
let transition = DOM.div("transition");
if (map.isDeprecated()) transition.classList.add("deprecated");
let transition = DOM.div('transition');
if (map.isDeprecated()) transition.classList.add('deprecated');
if (map.edge) {
transition.appendChild(this.addTransitionEdge(map));
}
let mapNode = this.addMapNode(map);
transition.appendChild(mapNode);
let subtree = DOM.div("transitions");
let subtree = DOM.div('transitions');
transition.appendChild(subtree);
this.currentNode.appendChild(transition);
......@@ -150,36 +146,32 @@ DOM.defineCustomElement(
}
addMapNode(map) {
let node = DOM.div("map");
let node = DOM.div('map');
if (map.edge) node.style.backgroundColor = typeToColor(map.edge);
node.map = map;
node.addEventListener("click", () => this.selectMap(map));
node.addEventListener('click', () => this.selectMap(map));
if (map.children.length > 1) {
node.innerText = map.children.length;
let showSubtree = DOM.div("showSubtransitions");
showSubtree.addEventListener("click", (e) =>
this.toggleSubtree(e, node)
);
let showSubtree = DOM.div('showSubtransitions');
showSubtree.addEventListener('click', (e) => this.toggleSubtree(e, node));
node.appendChild(showSubtree);
} else if (map.children.length == 0) {
node.innerHTML = "&#x25CF;";
node.innerHTML = '&#x25CF;';
}
this.currentNode.appendChild(node);
return node;
}
toggleSubtree(event, node) {
let map = node.map;
event.target.classList.toggle("opened");
let transitionsNode = node.parentElement.querySelector(".transitions");
event.target.classList.toggle('opened');
let transitionsNode = node.parentElement.querySelector('.transitions');
let subtransitionNodes = transitionsNode.children;
if (subtransitionNodes.length <= 1) {
// Add subtransitions excepth the one that's already shown.
let visibleTransitionMap =
subtransitionNodes.length == 1
? transitionsNode.querySelector(".map").map
: void 0;
let visibleTransitionMap = subtransitionNodes.length == 1 ?
transitionsNode.querySelector('.map').map :
void 0;
map.children.forEach((edge) => {
if (edge.to != visibleTransitionMap) {
this.currentNode = transitionsNode;
......@@ -193,5 +185,4 @@ DOM.defineCustomElement(
}
}
}
}
);
});
......@@ -2,12 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import { MapLogEntry, Edge } from "./log/map.mjs";
import { IcLogEntry } from "./log/ic.mjs";
import { DeoptLogEntry } from "./log/deopt.mjs";
import { Timeline } from "./timeline.mjs";
import { LogReader, parseString, parseVarArgs } from "../logreader.mjs";
import { Profile } from "../profile.mjs";
import {LogReader, parseString, parseVarArgs} from '../logreader.mjs';
import {Profile} from '../profile.mjs';
import {DeoptLogEntry} from './log/deopt.mjs';
import {IcLogEntry} from './log/ic.mjs';
import {Edge, MapLogEntry} from './log/map.mjs';
import {Timeline} from './timeline.mjs';
// ===========================================================================
......@@ -43,7 +44,8 @@ export class Processor extends LogReader {
},
'v8-version': {
parsers: [
parseInt, parseInt,
parseInt,
parseInt,
],
processor: this.processV8Version
},
......@@ -52,12 +54,12 @@ export class Processor extends LogReader {
processor: this.processScriptSource
},
'code-move':
{ parsers: [parseInt, parseInt], processor: this.processCodeMove },
'code-delete': { parsers: [parseInt], processor: this.processCodeDelete },
{parsers: [parseInt, parseInt], processor: this.processCodeMove},
'code-delete': {parsers: [parseInt], processor: this.processCodeDelete},
'sfi-move':
{ parsers: [parseInt, parseInt], processor: this.processFunctionMove },
{parsers: [parseInt, parseInt], processor: this.processFunctionMove},
'map-create':
{ parsers: [parseInt, parseString], processor: this.processMapCreate },
{parsers: [parseInt, parseString], processor: this.processMapCreate},
'map': {
parsers: [
parseString, parseInt, parseString, parseString, parseInt, parseInt,
......@@ -190,15 +192,16 @@ export class Processor extends LogReader {
}
}
processCodeDeopt(timestamp, codeSize, instructionStart, inliningId,
scriptOffset, deoptKind, deoptLocation, deoptReason) {
processCodeDeopt(
timestamp, codeSize, instructionStart, inliningId, scriptOffset,
deoptKind, deoptLocation, deoptReason) {
this._deoptTimeline.push(new DeoptLogEntry(deoptKind, timestamp));
}
processV8Version(majorVersion, minorVersion) {
if (
(majorVersion == this.MAJOR_VERSION && minorVersion <= this.MINOR_VERSION)
|| (majorVersion < this.MAJOR_VERSION)) {
if ((majorVersion == this.MAJOR_VERSION &&
minorVersion <= this.MINOR_VERSION) ||
(majorVersion < this.MAJOR_VERSION)) {
window.alert(
`Unsupported version ${majorVersion}.${minorVersion}. \n` +
`Please use the matching tool for given the V8 version.`);
......@@ -235,7 +238,7 @@ export class Processor extends LogReader {
slow_reason) {
let fnName = this.functionName(pc);
let parts = fnName.split(' ');
let fileName = parts[parts.length-1];
let fileName = parts[parts.length - 1];
let script = this.getScript(fileName);
// TODO: Use SourcePosition here directly
let entry = new IcLogEntry(
......@@ -272,7 +275,7 @@ export class Processor extends LogReader {
// Try to handle urls with file positions: https://foo.bar.com/:17:330"
filePositionLine = filePositionLine.split(' ');
let parts = filePositionLine[1].split(':');
if (parts[0].length <= 5) return parts[0] + ':' + parts[1]
if (parts[0].length <= 5) return parts[0] + ':' + parts[1];
return parts[1];
}
......
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import { V8CustomElement, DOM, delay, formatBytes} from "./helper.mjs";
import { SelectionEvent, FocusEvent } from "./events.mjs";
import { MapLogEntry } from "./log/map.mjs";
import { IcLogEntry } from "./log/ic.mjs";
import {FocusEvent, SelectionEvent} from './events.mjs';
import {delay, DOM, formatBytes, V8CustomElement} from './helper.mjs';
import {IcLogEntry} from './log/ic.mjs';
import {MapLogEntry} from './log/map.mjs';
DOM.defineCustomElement(
"source-panel",
DOM.defineCustomElement('source-panel',
(templateText) =>
class SourcePanel extends V8CustomElement {
_selectedSourcePositions = [];
......@@ -48,7 +47,7 @@ DOM.defineCustomElement(
}
get scriptDropdown() {
return this.$("#script-dropdown");
return this.$('#script-dropdown');
}
_initializeScriptDropdown() {
......@@ -56,7 +55,7 @@ DOM.defineCustomElement(
let select = this.scriptDropdown;
select.options.length = 0;
for (const script of this._scripts) {
const option = document.createElement("option");
const option = document.createElement('option');
const size = formatBytes(script.source.length);
option.text = `${script.name} (id=${script.id} size=${size})`;
option.script = script;
......@@ -72,12 +71,12 @@ DOM.defineCustomElement(
let scriptNode;
if (this._script) {
await delay(1);
const builder = new LineBuilder(
this, this._script, this._selectedSourcePositions);
const builder =
new LineBuilder(this, this._script, this._selectedSourcePositions);
scriptNode = builder.createScriptNode();
this._sourcePositionsToMarkNodes = builder.sourcePositionToMarkers;
} else {
scriptNode = document.createElement("pre");
scriptNode = document.createElement('pre');
this._selectedMarkNodes = undefined;
}
const oldScriptNode = this.script.childNodes[1];
......@@ -88,18 +87,16 @@ DOM.defineCustomElement(
await delay(100);
// Remove all marked nodes.
for (let markNode of this._sourcePositionsToMarkNodes.values()) {
markNode.className = "";
markNode.className = '';
}
for (let sourcePosition of this._selectedSourcePositions) {
this._sourcePositionsToMarkNodes
.get(sourcePosition).className = "marked";
this._sourcePositionsToMarkNodes.get(sourcePosition).className = 'marked';
}
const sourcePosition = this._selectedSourcePositions[0];
if (!sourcePosition) return;
const markNode = this._sourcePositionsToMarkNodes.get(sourcePosition);
markNode.scrollIntoView({
behavior: "smooth", block: "nearest", inline: "center"
});
markNode.scrollIntoView(
{behavior: 'smooth', block: 'nearest', inline: 'center'});
}
_handleSelectScript(e) {
......@@ -123,16 +120,14 @@ DOM.defineCustomElement(
icLogEntries.push(entry);
}
}
if (icLogEntries.length > 0 ) {
if (icLogEntries.length > 0) {
this.dispatchEvent(new SelectionEvent(icLogEntries));
}
if (mapLogEntries.length > 0) {
this.dispatchEvent(new SelectionEvent(mapLogEntries));
}
}
}
);
});
class SourcePositionIterator {
_entries;
......@@ -141,16 +136,16 @@ class SourcePositionIterator {
this._entries = sourcePositions;
}
*forLine(lineIndex) {
* forLine(lineIndex) {
this._findStart(lineIndex);
while(!this._done() && this._current().line === lineIndex) {
while (!this._done() && this._current().line === lineIndex) {
yield this._current();
this._next();
}
}
_findStart(lineIndex) {
while(!this._done() && this._current().line < lineIndex) {
while (!this._done() && this._current().line < lineIndex) {
this._next();
}
}
......@@ -168,11 +163,11 @@ class SourcePositionIterator {
}
}
function * lineIterator(source) {
function* lineIterator(source) {
let current = 0;
let line = 1;
while(current < source.length) {
const next = source.indexOf("\n", current);
while (current < source.length) {
const next = source.indexOf('\n', current);
if (next === -1) break;
yield [line, source.substring(current, next)];
line++;
......@@ -181,7 +176,6 @@ function * lineIterator(source) {
if (current < source.length) yield [line, source.substring(current)];
}
class LineBuilder {
_script;
_clickHandler;
......@@ -194,12 +188,12 @@ class LineBuilder {
this._selection = new Set(highlightPositions);
this._clickHandler = panel.handleSourcePositionClick.bind(panel);
// TODO: sort on script finalization.
script.sourcePositions.sort((a, b) => {
script.sourcePositions
.sort((a, b) => {
if (a.line === b.line) return a.column - b.column;
return a.line - b.line;
})
this._sourcePositions
= new SourcePositionIterator(script.sourcePositions);
}) this._sourcePositions =
new SourcePositionIterator(script.sourcePositions);
}
get sourcePositionToMarkers() {
......@@ -207,7 +201,7 @@ class LineBuilder {
}
createScriptNode() {
const scriptNode = document.createElement("pre");
const scriptNode = document.createElement('pre');
scriptNode.classList.add('scriptNode');
for (let [lineIndex, line] of lineIterator(this._script.source)) {
scriptNode.appendChild(this._createLineNode(lineIndex, line));
......@@ -216,12 +210,11 @@ class LineBuilder {
}
_createLineNode(lineIndex, line) {
const lineNode = document.createElement("span");
const lineNode = document.createElement('span');
let columnIndex = 0;
for (const sourcePosition of this._sourcePositions.forLine(lineIndex)) {
const nextColumnIndex = sourcePosition.column - 1;
lineNode.appendChild(
document.createTextNode(
lineNode.appendChild(document.createTextNode(
line.substring(columnIndex, nextColumnIndex)));
columnIndex = nextColumnIndex;
......@@ -230,12 +223,12 @@ class LineBuilder {
columnIndex++;
}
lineNode.appendChild(
document.createTextNode(line.substring(columnIndex) + "\n"));
document.createTextNode(line.substring(columnIndex) + '\n'));
return lineNode;
}
_createMarkerNode(text, sourcePosition) {
const marker = document.createElement("mark");
const marker = document.createElement('mark');
this._sourcePositionToMarkers.set(sourcePosition, marker);
marker.textContent = text;
marker.sourcePosition = sourcePosition;
......
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import { V8CustomElement, DOM} from "./helper.mjs";
import { SelectionEvent } from "./events.mjs";
import { delay, LazyTable } from "./helper.mjs";
import {SelectionEvent} from './events.mjs';
import {DOM, V8CustomElement} from './helper.mjs';
import {delay, LazyTable} from './helper.mjs';
DOM.defineCustomElement(
"stats-panel",
(templateText) =>
class StatsPanel extends V8CustomElement {
'stats-panel', (templateText) => class StatsPanel extends V8CustomElement {
_timeline;
_transitions;
_selectedLogEntries;
......@@ -17,7 +15,7 @@ DOM.defineCustomElement(
}
get stats() {
return this.$("#stats");
return this.$('#stats');
}
set timeline(timeline) {
......@@ -51,40 +49,40 @@ DOM.defineCustomElement(
}
updateGeneralStats() {
console.assert(this._timeline !== undefined, "Timeline not set yet!");
console.assert(this._timeline !== undefined, 'Timeline not set yet!');
let pairs = [
["Transitions", "primary", (e) => e.edge && e.edge.isTransition()],
["Fast to Slow", "violet", (e) => e.edge && e.edge.isFastToSlow()],
["Slow to Fast", "orange", (e) => e.edge && e.edge.isSlowToFast()],
["Initial Map", "yellow", (e) => e.edge && e.edge.isInitial()],
['Transitions', 'primary', (e) => e.edge && e.edge.isTransition()],
['Fast to Slow', 'violet', (e) => e.edge && e.edge.isFastToSlow()],
['Slow to Fast', 'orange', (e) => e.edge && e.edge.isSlowToFast()],
['Initial Map', 'yellow', (e) => e.edge && e.edge.isInitial()],
[
"Replace Descriptors",
"red",
'Replace Descriptors',
'red',
(e) => e.edge && e.edge.isReplaceDescriptors(),
],
[
"Copy as Prototype",
"red",
'Copy as Prototype',
'red',
(e) => e.edge && e.edge.isCopyAsPrototype(),
],
[
"Optimize as Prototype",
'Optimize as Prototype',
null,
(e) => e.edge && e.edge.isOptimizeAsPrototype(),
],
["Deprecated", null, (e) => e.isDeprecated()],
["Bootstrapped", "green", (e) => e.isBootstrapped()],
["Total", null, (e) => true],
['Deprecated', null, (e) => e.isDeprecated()],
['Bootstrapped', 'green', (e) => e.isBootstrapped()],
['Total', null, (e) => true],
];
let tbody = document.createElement("tbody");
let tbody = document.createElement('tbody');
let total = this._selectedLogEntries.length;
pairs.forEach(([name, color, filter]) => {
let row = DOM.tr();
if (color !== null) {
row.appendChild(DOM.td(DOM.div(["colorbox", color])));
row.appendChild(DOM.td(DOM.div(['colorbox', color])));
} else {
row.appendChild(DOM.td(""));
row.appendChild(DOM.td(''));
}
row.classList.add('clickable');
row.onclick = (e) => {
......@@ -99,10 +97,10 @@ DOM.defineCustomElement(
let count = this.count(filter);
row.appendChild(DOM.td(count));
let percent = Math.round((count / total) * 1000) / 10;
row.appendChild(DOM.td(percent.toFixed(1) + "%"));
row.appendChild(DOM.td(percent.toFixed(1) + '%'));
tbody.appendChild(row);
});
this.$("#typeTable").replaceChild(tbody, this.$("#typeTable tbody"));
this.$('#typeTable').replaceChild(tbody, this.$('#typeTable tbody'));
}
count(filter) {
......@@ -116,21 +114,17 @@ DOM.defineCustomElement(
updateNamedTransitionsStats() {
let rowData = Array.from(this._transitions.entries());
rowData.sort((a, b) => b[1].length - a[1].length);
new LazyTable(this.$("#nameTable"), rowData, ([name, maps]) => {
new LazyTable(this.$('#nameTable'), rowData, ([name, maps]) => {
let row = DOM.tr();
row.maps = maps;
row.classList.add('clickable');
row.addEventListener("click", (e) =>
this.dispatchEvent(
new SelectionEvent(
e.target.parentNode.maps.map((map) => map.to)
)
)
);
row.addEventListener(
'click',
(e) => this.dispatchEvent(new SelectionEvent(
e.target.parentNode.maps.map((map) => map.to))));
row.appendChild(DOM.td(maps.length));
row.appendChild(DOM.td(name));
return row;
});
}
}
);
});
......@@ -2,16 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import { DOM, V8CustomElement } from './helper.mjs';
import { SynchronizeSelectionEvent } from './events.mjs';
import './timeline/timeline-track.mjs';
DOM.defineCustomElement('timeline-panel', (templateText) =>
class TimelinePanel extends V8CustomElement {
import {SynchronizeSelectionEvent} from './events.mjs';
import {DOM, V8CustomElement} from './helper.mjs';
DOM.defineCustomElement(
'timeline-panel',
(templateText) => class TimelinePanel extends V8CustomElement {
constructor() {
super(templateText);
this.addEventListener(
'scrolltrack', e => this.handleTrackScroll(e));
this.addEventListener('scrolltrack', e => this.handleTrackScroll(e));
this.addEventListener(
SynchronizeSelectionEvent.name,
e => this.handleSelectionSyncronization(e));
......@@ -28,27 +29,28 @@ DOM.defineCustomElement('timeline-panel', (templateText) =>
}
get timelineTracks() {
return this.$("slot").assignedNodes().filter(
return this.$('slot').assignedNodes().filter(
node => node.nodeType === Node.ELEMENT_NODE);
}
handleTrackScroll(event) {
//TODO(zcankara) add forEachTrack helper method
// TODO(zcankara) add forEachTrack helper method
for (const track of this.timelineTracks) {
track.scrollLeft = event.detail;
}
}
handleSelectionSyncronization(event) {
this.timeSelection = {start:event.start, end:event.end};
this.timeSelection = {start: event.start, end: event.end};
}
set timeSelection(timeSelection) {
if (timeSelection.start > timeSelection.end) {
throw new Error("Invalid time range");
throw new Error('Invalid time range');
}
for (const track of this.timelineTracks) {
track.timeSelection = timeSelection;;
track.timeSelection = timeSelection;
;
}
}
});
......@@ -35,17 +35,16 @@ class Timeline {
}
selectTimeRange(start, end) {
this._selection = this.filter(
e => e.time >= start && e.time <= end);
this._selection = this.filter(e => e.time >= start && e.time <= end);
}
getChunks(windowSizeMs) {
//TODO(zcankara) Fill this one
// TODO(zcankara) Fill this one
return this.chunkSizes(windowSizeMs);
}
get values() {
//TODO(zcankara) Not to break something delete later
// TODO(zcankara) Not to break something delete later
return this._values;
}
......@@ -253,7 +252,7 @@ class Chunk {
if (event_fn === void 0) {
event_fn = each => each;
}
let breakdown = { __proto__: null };
let breakdown = {__proto__: null};
this.items.forEach(each => {
const type = event_fn(each);
const v = breakdown[type];
......@@ -265,7 +264,6 @@ class Chunk {
filter() {
return this.items.filter(map => !map.parent() || !this.has(map.parent()));
}
}
export { Timeline, Chunk };
export {Timeline, Chunk};
......@@ -2,12 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import { DOM, V8CustomElement, CSSColor, delay } from '../helper.mjs';
import { kChunkWidth, kChunkHeight } from "../log/map.mjs";
import {
SelectionEvent, FocusEvent, SelectTimeEvent,
SynchronizeSelectionEvent
} from '../events.mjs';
import {FocusEvent, SelectionEvent, SelectTimeEvent, SynchronizeSelectionEvent} from '../events.mjs';
import {CSSColor, delay, DOM, V8CustomElement} from '../helper.mjs';
import {kChunkHeight, kChunkWidth} from '../log/map.mjs';
const kColors = [
CSSColor.green,
......@@ -21,29 +18,31 @@ const kColors = [
CSSColor.secondaryColor,
];
DOM.defineCustomElement('./timeline/timeline-track', (templateText) =>
DOM.defineCustomElement('./timeline/timeline-track',
(templateText) =>
class TimelineTrack extends V8CustomElement {
// TODO turn into static field once Safari supports it.
static get SELECTION_OFFSET() { return 10 };
static get SELECTION_OFFSET() {
return 10
};
_timeline;
_nofChunks = 400;
_chunks;
_selectedEntry;
_timeToPixel;
_timeSelection = { start: -1, end: Infinity };
_timeSelection = {start: -1, end: Infinity};
_timeStartOffset;
_selectionOriginTime;
_typeToColor;
constructor() {
super(templateText);
this.timeline.addEventListener("scroll",
e => this.handleTimelineScroll(e));
this.timeline.addEventListener("mousedown",
e => this.handleTimeSelectionMouseDown(e));
this.timeline.addEventListener("mouseup",
e => this.handleTimeSelectionMouseUp(e));
this.timeline.addEventListener("mousemove",
e => this.handleTimeSelectionMouseMove(e));
this.timeline.addEventListener('scroll', e => this.handleTimelineScroll(e));
this.timeline.addEventListener(
'mousedown', e => this.handleTimeSelectionMouseDown(e));
this.timeline.addEventListener(
'mouseup', e => this.handleTimeSelectionMouseUp(e));
this.timeline.addEventListener(
'mousemove', e => this.handleTimeSelectionMouseMove(e));
this.backgroundCanvas = document.createElement('canvas');
this.isLocked = false;
}
......@@ -53,20 +52,22 @@ DOM.defineCustomElement('./timeline/timeline-track', (templateText) =>
// Update origin time in case we click on a handle.
if (this.isOnLeftHandle(xPosition)) {
xPosition = this.rightHandlePosX;
} else if (this.isOnRightHandle(xPosition)) {
}
else if (this.isOnRightHandle(xPosition)) {
xPosition = this.leftHandlePosX;
}
this._selectionOriginTime = this.positionToTime(xPosition);
}
isOnLeftHandle(posX) {
return (Math.abs(this.leftHandlePosX - posX)
<= TimelineTrack.SELECTION_OFFSET);
return (
Math.abs(this.leftHandlePosX - posX) <= TimelineTrack.SELECTION_OFFSET);
}
isOnRightHandle(posX) {
return (Math.abs(this.rightHandlePosX - posX)
<= TimelineTrack.SELECTION_OFFSET);
return (
Math.abs(this.rightHandlePosX - posX) <=
TimelineTrack.SELECTION_OFFSET);
}
handleTimeSelectionMouseMove(e) {
......@@ -81,13 +82,13 @@ DOM.defineCustomElement('./timeline/timeline-track', (templateText) =>
this._selectionOriginTime = -1;
const delta = this._timeSelection.end - this._timeSelection.start;
if (delta <= 1 || isNaN(delta)) return;
this.dispatchEvent(new SelectTimeEvent(this._timeSelection.start,
this._timeSelection.end));
this.dispatchEvent(new SelectTimeEvent(
this._timeSelection.start, this._timeSelection.end));
}
set timeSelection(selection) {
this._timeSelection.start = selection.start;
this._timeSelection.end= selection.end;
this._timeSelection.end = selection.end;
this.updateSelection();
}
......@@ -99,10 +100,10 @@ DOM.defineCustomElement('./timeline/timeline-track', (templateText) =>
const startPosition = this.timeToPosition(this._timeSelection.start);
const endPosition = this.timeToPosition(this._timeSelection.end);
const delta = endPosition - startPosition;
this.leftHandle.style.left = startPosition + "px";
this.selection.style.left = startPosition + "px";
this.rightHandle.style.left = endPosition + "px";
this.selection.style.width = delta + "px";
this.leftHandle.style.left = startPosition + 'px';
this.selection.style.left = startPosition + 'px';
this.rightHandle.style.left = endPosition + 'px';
this.selection.style.width = delta + 'px';
}
get leftHandlePosX() {
......@@ -223,12 +224,12 @@ DOM.defineCustomElement('./timeline/timeline-track', (templateText) =>
let timelineLegendContent = this.timelineLegendContent;
DOM.removeAllChildren(timelineLegendContent);
this._timeline.uniqueTypes.forEach((entries, type) => {
let row = DOM.tr("clickable");
let row = DOM.tr('clickable');
row.entries = entries;
row.addEventListener('dblclick', e => this.handleEntryTypeDblClick(e));
let color = this.typeToColor(type);
if (color !== null) {
let div = DOM.div("colorbox");
let div = DOM.div('colorbox');
div.style.backgroundColor = color;
row.appendChild(DOM.td(div));
} else {
......@@ -238,15 +239,15 @@ DOM.defineCustomElement('./timeline/timeline-track', (templateText) =>
row.appendChild(td);
row.appendChild(DOM.td(entries.length));
let percent = (entries.length / this.data.all.length) * 100;
row.appendChild(DOM.td(percent.toFixed(1) + "%"));
row.appendChild(DOM.td(percent.toFixed(1) + '%'));
timelineLegendContent.appendChild(row);
});
// Add Total row.
let row = DOM.tr();
row.appendChild(DOM.td(""));
row.appendChild(DOM.td("All"));
row.appendChild(DOM.td(''));
row.appendChild(DOM.td('All'));
row.appendChild(DOM.td(this.data.all.length));
row.appendChild(DOM.td("100%"));
row.appendChild(DOM.td('100%'));
timelineLegendContent.appendChild(row);
timelineLegend.appendChild(timelineLegendContent);
}
......@@ -262,10 +263,7 @@ DOM.defineCustomElement('./timeline/timeline-track', (templateText) =>
handleTimelineScroll(e) {
let horizontal = e.currentTarget.scrollLeft;
this.dispatchEvent(new CustomEvent(
'scrolltrack', {
bubbles: true, composed: true,
detail: horizontal
}));
'scrolltrack', {bubbles: true, composed: true, detail: horizontal}));
}
async setChunkBackgrounds(backgroundTodo) {
......@@ -335,8 +333,7 @@ DOM.defineCustomElement('./timeline/timeline-track', (templateText) =>
if (chunk.isEmpty()) continue;
let node = DOM.div();
node.className = 'chunk';
node.style.left =
((chunks[i].start - start) * this._timeToPixel) + 'px';
node.style.left = ((chunks[i].start - start) * this._timeToPixel) + 'px';
node.style.height = height + 'px';
node.chunk = chunk;
node.addEventListener('mousemove', e => this.handleChunkMouseMove(e));
......@@ -394,8 +391,8 @@ DOM.defineCustomElement('./timeline/timeline-track', (templateText) =>
this.drawEdges(ctx);
}
setMapStyle(map, ctx) {
ctx.fillStyle = map.edge && map.edge.from ?
CSSColor.onBackgroundColor : CSSColor.onPrimaryColor;
ctx.fillStyle = map.edge && map.edge.from ? CSSColor.onBackgroundColor :
CSSColor.onPrimaryColor;
}
setEdgeStyle(edge, ctx) {
......@@ -516,5 +513,4 @@ DOM.defineCustomElement('./timeline/timeline-track', (templateText) =>
this.drawOutgoingEdges(ctx, edge.to, max, depth + 1);
}
}
}
);
});
......@@ -131,6 +131,31 @@ def TorqueLintWorker(command):
print('Error running format-torque.py')
process.kill()
def JSLintWorker(command):
try:
file_name = command[-1]
with open(file_name, "r") as file_handle:
contents = file_handle.read()
process = subprocess.Popen(command, stdout=PIPE, stderr=subprocess.PIPE)
output, err = process.communicate()
rc = process.returncode
if rc != 0:
sys.stdout.write("error code " + str(rc) + " running clang-format.\n")
return rc
if output != contents:
sys.stdout.write(file_name + " requires formatting.\n")
return 1
return 0
except KeyboardInterrupt:
process.kill()
except Exception:
print('Error running clang-format. Please make sure you have depot_tools' +
' in your $PATH. Lint check skipped.')
process.kill()
class FileContentsCache(object):
def __init__(self, sums_file_name):
......@@ -392,6 +417,33 @@ class TorqueLintProcessor(CacheableSourceFileProcessor):
return None, arguments
class JSLintProcessor(CacheableSourceFileProcessor):
"""
Check .{m}js file to verify they follow the JS Style guide.
"""
def __init__(self, use_cache=True):
super(JSLintProcessor, self).__init__(
use_cache=use_cache, cache_file_path='.jslint-cache',
file_type='JavaScript')
def IsRelevant(self, name):
return name.endswith('.js') or name.endswith('.mjs')
def GetPathsToSearch(self):
return ['tools/system-analyzer']
def GetProcessorWorker(self):
return JSLintWorker
def GetProcessorScript(self):
for path in [TOOLS_PATH] + os.environ["PATH"].split(os.pathsep):
path = path.strip('"')
clang_format = os.path.join(path, 'clang_format.py')
if os.path.isfile(clang_format):
return clang_format, []
return None, []
COPYRIGHT_HEADER_PATTERN = re.compile(
r'Copyright [\d-]*20[0-2][0-9] the V8 project authors. All rights reserved.')
......@@ -708,6 +760,9 @@ def Main():
print("Running Torque formatting check...")
success &= TorqueLintProcessor(use_cache=use_linter_cache).RunOnPath(
workspace)
print("Running JavaScript formatting check...")
success &= JSLintProcessor(use_cache=use_linter_cache).RunOnPath(
workspace)
print("Running copyright header, trailing whitespaces and " \
"two empty lines between declarations check...")
success &= SourceProcessor().RunOnPath(workspace)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment