Added SDK
This commit is contained in:
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Apple Inc. All rights reserved.
|
||||
* Copyright (C) 2015 Saam Barati <saambarati1@gmail.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
WI.BasicBlockAnnotator = class BasicBlockAnnotator extends WI.Annotator
|
||||
{
|
||||
constructor(sourceCodeTextEditor, script)
|
||||
{
|
||||
super(sourceCodeTextEditor);
|
||||
|
||||
this._script = script;
|
||||
this._basicBlockMarkers = new Map; // Only contains unexecuted basic blocks.
|
||||
}
|
||||
|
||||
// Protected
|
||||
|
||||
clearAnnotations()
|
||||
{
|
||||
for (var key of this._basicBlockMarkers.keys())
|
||||
this._clearRangeForBasicBlockMarker(key);
|
||||
}
|
||||
|
||||
insertAnnotations()
|
||||
{
|
||||
if (!this.isActive())
|
||||
return;
|
||||
this._script.requestContent().then(this._annotateBasicBlockExecutionRanges.bind(this));
|
||||
}
|
||||
|
||||
// Private
|
||||
|
||||
_calculateBasicBlockPositions(basicBlocks, content)
|
||||
{
|
||||
if (!basicBlocks || !basicBlocks.length)
|
||||
return;
|
||||
|
||||
let lineEndings = [];
|
||||
let lineEndingLengths = [];
|
||||
let pattern = /\r\n?|\n/g;
|
||||
let match = pattern.exec(content);
|
||||
while (match) {
|
||||
lineEndings.push(match.index);
|
||||
lineEndingLengths.push(match[0].length);
|
||||
match = pattern.exec(content);
|
||||
}
|
||||
|
||||
function offsetToPosition(offset) {
|
||||
let lineNumber = lineEndings.upperBound(offset - 1);
|
||||
if (lineNumber) {
|
||||
let previousLine = lineNumber - 1;
|
||||
var columnNumber = offset - lineEndings[previousLine] - lineEndingLengths[previousLine];
|
||||
} else
|
||||
var columnNumber = offset;
|
||||
return new WI.SourceCodePosition(lineNumber, columnNumber);
|
||||
}
|
||||
|
||||
for (let block of basicBlocks) {
|
||||
block.startPosition = offsetToPosition(block.startOffset);
|
||||
block.endPosition = offsetToPosition(block.endOffset);
|
||||
}
|
||||
}
|
||||
|
||||
_annotateBasicBlockExecutionRanges()
|
||||
{
|
||||
let content = this._script.content;
|
||||
console.assert(content, "Missing script content for basic block annotations.");
|
||||
if (!content)
|
||||
return;
|
||||
|
||||
var sourceID = this._script.id;
|
||||
var startTime = Date.now();
|
||||
|
||||
this._script.target.RuntimeAgent.getBasicBlocks(sourceID, function(error, basicBlocks) {
|
||||
if (error) {
|
||||
console.error("Error in getting basic block locations: " + error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.isActive())
|
||||
return;
|
||||
|
||||
this._calculateBasicBlockPositions(basicBlocks, content);
|
||||
|
||||
let {startPosition, endPosition} = this.sourceCodeTextEditor.visibleRangePositions();
|
||||
basicBlocks = basicBlocks.filter(function(block) {
|
||||
// Viewport: [--]
|
||||
// Block: [--]
|
||||
if (block.startPosition.isAfter(endPosition))
|
||||
return false;
|
||||
|
||||
// Viewport: [--]
|
||||
// Block: [--]
|
||||
if (block.endPosition.isBefore(startPosition))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
for (var block of basicBlocks) {
|
||||
var key = block.startOffset + ":" + block.endOffset;
|
||||
var hasKey = this._basicBlockMarkers.has(key);
|
||||
var hasExecuted = block.hasExecuted;
|
||||
if (hasKey && hasExecuted)
|
||||
this._clearRangeForBasicBlockMarker(key);
|
||||
else if (!hasKey && !hasExecuted) {
|
||||
var marker = this._highlightTextForBasicBlock(block);
|
||||
this._basicBlockMarkers.set(key, marker);
|
||||
}
|
||||
}
|
||||
|
||||
var totalTime = Date.now() - startTime;
|
||||
var timeoutTime = Number.constrain(30 * totalTime, 500, 5000);
|
||||
this._timeoutIdentifier = setTimeout(this.insertAnnotations.bind(this), timeoutTime);
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
_highlightTextForBasicBlock(basicBlock)
|
||||
{
|
||||
console.assert(basicBlock.startOffset <= basicBlock.endOffset && basicBlock.startOffset >= 0 && basicBlock.endOffset >= 0, "" + basicBlock.startOffset + ":" + basicBlock.endOffset);
|
||||
console.assert(!basicBlock.hasExecuted);
|
||||
|
||||
let startPosition = this.sourceCodeTextEditor.originalPositionToCurrentPosition(basicBlock.startPosition);
|
||||
let endPosition = this.sourceCodeTextEditor.originalPositionToCurrentPosition(basicBlock.endPosition);
|
||||
if (this._isTextRangeOnlyClosingBrace(startPosition, endPosition))
|
||||
return null;
|
||||
|
||||
return this.sourceCodeTextEditor.addStyleToTextRange(startPosition, endPosition, WI.BasicBlockAnnotator.HasNotExecutedClassName);
|
||||
}
|
||||
|
||||
_isTextRangeOnlyClosingBrace(startPosition, endPosition)
|
||||
{
|
||||
var isOnlyClosingBrace = /^\s*\}$/;
|
||||
return isOnlyClosingBrace.test(this.sourceCodeTextEditor.getTextInRange(startPosition, endPosition));
|
||||
}
|
||||
|
||||
_clearRangeForBasicBlockMarker(key)
|
||||
{
|
||||
console.assert(this._basicBlockMarkers.has(key));
|
||||
var marker = this._basicBlockMarkers.get(key);
|
||||
if (marker)
|
||||
marker.clear();
|
||||
this._basicBlockMarkers.delete(key);
|
||||
}
|
||||
};
|
||||
|
||||
WI.BasicBlockAnnotator.HasNotExecutedClassName = "basic-block-has-not-executed";
|
||||
Reference in New Issue
Block a user