7f162dbcb6
This change analyzes and links the output of --code-comments in the disassembly view within turbolizer with the other views, such that selecting these comments will also select the respective blocks/lines/nodes within the other views. The block start comments (e.g. -- B4 start --) are linked with the blocks in the schedule phase view and vice versa. The source position comments (e.g. -- primes.js:3:10 --) select the respective spans, lines, and nodes in the JavaScript code view, the schedule phase view, and the other compilation phase views respectively, and vice versa. It also modifies the display of the line and column numbers in the source position comments to be offset from 1 instead of 0 and ignore the initial source position of the first line of code (from removal of the function name in the compiler). Also fixed the bug where previous selections weren't being cleared properly across multiple views, adding appropriate clear calls when using the selection broker. Review-Url: https://codereview.chromium.org/2133663002 Cr-Commit-Position: refs/heads/master@{#37627}
179 lines
5.4 KiB
JavaScript
179 lines
5.4 KiB
JavaScript
// Copyright 2015 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.
|
|
|
|
var CodeView = function(divID, PR, sourceText, sourcePosition, broker) {
|
|
"use strict";
|
|
var view = this;
|
|
|
|
view.divElement = document.getElementById(divID);
|
|
view.broker = broker;
|
|
view.codeSelection = null;
|
|
view.allSpans = [];
|
|
|
|
var selectionHandler = {
|
|
clear: function() {
|
|
broker.clear(selectionHandler);
|
|
},
|
|
select: function(items, selected) {
|
|
var handler = this;
|
|
var divElement = view.divElement;
|
|
var broker = view.broker;
|
|
for (let span of items) {
|
|
if (selected) {
|
|
span.classList.add("selected");
|
|
} else {
|
|
span.classList.remove("selected");
|
|
}
|
|
}
|
|
var ranges = [];
|
|
for (var span of items) {
|
|
ranges.push([span.start, span.end, null]);
|
|
}
|
|
broker.clear(selectionHandler);
|
|
broker.select(selectionHandler, ranges, selected);
|
|
},
|
|
selectionDifference: function(span1, inclusive1, span2, inclusive2) {
|
|
var pos1 = span1.start;
|
|
var pos2 = span2.start;
|
|
var result = [];
|
|
var lineListDiv = view.divElement.firstChild.firstChild.childNodes;
|
|
for (var i=0; i < lineListDiv.length; i++) {
|
|
var currentLineElement = lineListDiv[i];
|
|
var spans = currentLineElement.childNodes;
|
|
for (var j=0; j < spans.length; ++j) {
|
|
var currentSpan = spans[j];
|
|
if (currentSpan.start > pos1 || (inclusive1 && currentSpan.start == pos1)) {
|
|
if (currentSpan.start < pos2 || (inclusive2 && currentSpan.start == pos2)) {
|
|
result.push(currentSpan);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
},
|
|
brokeredSelect: function(ranges, selected) {
|
|
var firstSelect = view.codeSelection.isEmpty();
|
|
for (var range of ranges) {
|
|
var start = range[0];
|
|
var end = range[1];
|
|
var lower = 0;
|
|
var upper = view.allSpans.length;
|
|
if (upper > 0) {
|
|
while ((upper - lower) > 1) {
|
|
var middle = Math.floor((upper + lower) / 2);
|
|
var lineStart = view.allSpans[middle].start;
|
|
if (lineStart < start) {
|
|
lower = middle;
|
|
} else if (lineStart > start) {
|
|
upper = middle;
|
|
} else {
|
|
lower = middle;
|
|
break;
|
|
}
|
|
}
|
|
var currentSpan = view.allSpans[lower];
|
|
var currentLineElement = currentSpan.parentNode;
|
|
if ((currentSpan.start <= start && start < currentSpan.end) ||
|
|
(currentSpan.start <= end && end < currentSpan.end)) {
|
|
if (firstSelect) {
|
|
makeContainerPosVisible(view.divElement, currentLineElement.offsetTop);
|
|
firstSelect = false;
|
|
}
|
|
view.codeSelection.select(currentSpan, selected);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
brokeredClear: function() {
|
|
view.codeSelection.clear();
|
|
},
|
|
};
|
|
|
|
view.codeSelection = new Selection(selectionHandler);
|
|
broker.addSelectionHandler(selectionHandler);
|
|
|
|
var mouseDown = false;
|
|
|
|
this.handleSpanMouseDown = function(e) {
|
|
e.stopPropagation();
|
|
if (!e.shiftKey) {
|
|
view.codeSelection.clear();
|
|
}
|
|
view.codeSelection.select(this, true);
|
|
mouseDown = true;
|
|
}
|
|
|
|
this.handleSpanMouseMove = function(e) {
|
|
if (mouseDown) {
|
|
view.codeSelection.extendTo(this);
|
|
}
|
|
}
|
|
|
|
this.handleCodeMouseDown = function(e) {
|
|
view.codeSelection.clear();
|
|
}
|
|
|
|
document.addEventListener('mouseup', function(e){
|
|
mouseDown = false;
|
|
}, false);
|
|
|
|
this.initializeCode(sourceText, sourcePosition);
|
|
}
|
|
|
|
CodeView.prototype.initializeCode = function(sourceText, sourcePosition) {
|
|
var view = this;
|
|
if (sourceText == "") {
|
|
var newHtml = "<pre class=\"prettyprint\"</pre>";
|
|
view.divElement.innerHTML = newHtml;
|
|
} else {
|
|
var newHtml = "<pre class=\"prettyprint linenums\">"
|
|
+ sourceText + "</pre>";
|
|
view.divElement.innerHTML = newHtml;
|
|
try {
|
|
// Wrap in try to work when offline.
|
|
PR.prettyPrint();
|
|
} catch (e) {
|
|
}
|
|
|
|
view.divElement.onmousedown = this.handleCodeMouseDown;
|
|
|
|
var base = sourcePosition;
|
|
var current = 0;
|
|
var lineListDiv = view.divElement.firstChild.firstChild.childNodes;
|
|
for (i=0; i < lineListDiv.length; i++) {
|
|
var currentLineElement = lineListDiv[i];
|
|
currentLineElement.id = "li" + i;
|
|
var pos = base + current;
|
|
currentLineElement.pos = pos;
|
|
var spans = currentLineElement.childNodes;
|
|
for (j=0; j < spans.length; ++j) {
|
|
var currentSpan = spans[j];
|
|
if (currentSpan.nodeType == 1) {
|
|
currentSpan.start = pos;
|
|
currentSpan.end = pos + currentSpan.textContent.length;
|
|
currentSpan.onmousedown = this.handleSpanMouseDown;
|
|
currentSpan.onmousemove = this.handleSpanMouseMove;
|
|
view.allSpans.push(currentSpan);
|
|
}
|
|
current += currentSpan.textContent.length;
|
|
pos = base + current;
|
|
}
|
|
while ((current < sourceText.length) && (
|
|
sourceText[current] == '\n' ||
|
|
sourceText[current] == '\r')) {
|
|
++current;
|
|
}
|
|
}
|
|
}
|
|
|
|
this.resizeToParent();
|
|
}
|
|
|
|
CodeView.prototype.resizeToParent = function() {
|
|
var view = this;
|
|
var documentElement = document.documentElement;
|
|
var y = view.divElement.parentNode.clientHeight || documentElement.clientHeight;
|
|
view.divElement.style.height = y + "px";
|
|
}
|