Web Inspector: Basic blocks highlighting should use line/column locations instead...
authormattbaker@apple.com <mattbaker@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 13 Jul 2018 22:27:30 +0000 (22:27 +0000)
committermattbaker@apple.com <mattbaker@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 13 Jul 2018 22:27:30 +0000 (22:27 +0000)
https://bugs.webkit.org/show_bug.cgi?id=187613
<rdar://problem/42131808>

Reviewed by Joseph Pecoraro.

* UserInterface/Controllers/BasicBlockAnnotator.js:
Basic blocks sent from the backend include offsets into the original
file, rather than line/column locations. In order to translate to positions
within CodeMirror, we need to calculate the original line and column
for each block.

(WI.BasicBlockAnnotator.prototype.insertAnnotations):
(WI.BasicBlockAnnotator.prototype._calculateBasicBlockPositions.offsetToPosition):
(WI.BasicBlockAnnotator.prototype._calculateBasicBlockPositions):
(WI.BasicBlockAnnotator.prototype._annotateBasicBlockExecutionRanges.):
(WI.BasicBlockAnnotator.prototype._annotateBasicBlockExecutionRanges):
(WI.BasicBlockAnnotator.prototype._highlightTextForBasicBlock):

* UserInterface/Models/SourceCodePosition.js:
(WI.SourceCodePosition.prototype.offsetColumn):

* UserInterface/Views/TextEditor.js:
(WI.TextEditor.prototype.getTextInRange):
(WI.TextEditor.prototype.addStyleToTextRange):
Better encapsulation for CodeMirror positions.

* UserInterface/Workers/Formatter/FormatterUtilities.js:
(get if):
Update String.prototype.lineEndings to support additional line separators.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@233820 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/UserInterface/Controllers/BasicBlockAnnotator.js
Source/WebInspectorUI/UserInterface/Models/SourceCodePosition.js
Source/WebInspectorUI/UserInterface/Views/TextEditor.js
Source/WebInspectorUI/UserInterface/Workers/Formatter/FormatterUtilities.js

index 5d5343e..1f011b1 100644 (file)
@@ -1,5 +1,38 @@
 2018-07-13  Matt Baker  <mattbaker@apple.com>
 
+        Web Inspector: Basic blocks highlighting should use line/column locations instead of offsets
+        https://bugs.webkit.org/show_bug.cgi?id=187613
+        <rdar://problem/42131808>
+
+        Reviewed by Joseph Pecoraro.
+
+        * UserInterface/Controllers/BasicBlockAnnotator.js:
+        Basic blocks sent from the backend include offsets into the original
+        file, rather than line/column locations. In order to translate to positions
+        within CodeMirror, we need to calculate the original line and column
+        for each block.
+
+        (WI.BasicBlockAnnotator.prototype.insertAnnotations):
+        (WI.BasicBlockAnnotator.prototype._calculateBasicBlockPositions.offsetToPosition):
+        (WI.BasicBlockAnnotator.prototype._calculateBasicBlockPositions):
+        (WI.BasicBlockAnnotator.prototype._annotateBasicBlockExecutionRanges.):
+        (WI.BasicBlockAnnotator.prototype._annotateBasicBlockExecutionRanges):
+        (WI.BasicBlockAnnotator.prototype._highlightTextForBasicBlock):
+
+        * UserInterface/Models/SourceCodePosition.js:
+        (WI.SourceCodePosition.prototype.offsetColumn):
+
+        * UserInterface/Views/TextEditor.js:
+        (WI.TextEditor.prototype.getTextInRange):
+        (WI.TextEditor.prototype.addStyleToTextRange):
+        Better encapsulation for CodeMirror positions.
+
+        * UserInterface/Workers/Formatter/FormatterUtilities.js:
+        (get if):
+        Update String.prototype.lineEndings to support additional line separators.
+
+2018-07-13  Matt Baker  <mattbaker@apple.com>
+
         Web Inspector: Execution highlighting in the frontend should be line/column-based
         https://bugs.webkit.org/show_bug.cgi?id=187532
         <rdar://problem/42035580>
index a7837ab..9ca9a22 100644 (file)
@@ -46,13 +46,49 @@ WI.BasicBlockAnnotator = class BasicBlockAnnotator extends WI.Annotator
     {
         if (!this.isActive())
             return;
-        this._annotateBasicBlockExecutionRanges();
+        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();
 
@@ -65,16 +101,18 @@ WI.BasicBlockAnnotator = class BasicBlockAnnotator extends WI.Annotator
             if (!this.isActive())
                 return;
 
-            var {startOffset, endOffset} = this.sourceCodeTextEditor.visibleRangeOffsets();
+            this._calculateBasicBlockPositions(basicBlocks, content);
+
+            let {startPosition, endPosition} = this.sourceCodeTextEditor.visibleRangePositions();
             basicBlocks = basicBlocks.filter(function(block) {
                 // Viewport: [--]
                 // Block:         [--]
-                if (block.startOffset > endOffset)
+                if (block.startPosition.isAfter(endPosition))
                     return false;
 
                 // Viewport:      [--]
                 // Block:    [--]
-                if (block.endOffset < startOffset)
+                if (block.endPosition.isBefore(startPosition))
                     return false;
 
                 return true;
@@ -103,13 +141,12 @@ WI.BasicBlockAnnotator = class BasicBlockAnnotator extends WI.Annotator
         console.assert(basicBlock.startOffset <= basicBlock.endOffset && basicBlock.startOffset >= 0 && basicBlock.endOffset >= 0, "" + basicBlock.startOffset + ":" + basicBlock.endOffset);
         console.assert(!basicBlock.hasExecuted);
 
-        var startPosition = this.sourceCodeTextEditor.originalOffsetToCurrentPosition(basicBlock.startOffset);
-        var endPosition = this.sourceCodeTextEditor.originalOffsetToCurrentPosition(basicBlock.endOffset);
+        let startPosition = this.sourceCodeTextEditor.originalPositionToCurrentPosition(basicBlock.startPosition);
+        let endPosition = this.sourceCodeTextEditor.originalPositionToCurrentPosition(basicBlock.endPosition);
         if (this._isTextRangeOnlyClosingBrace(startPosition, endPosition))
             return null;
 
-        var marker = this.sourceCodeTextEditor.addStyleToTextRange(startPosition, endPosition, WI.BasicBlockAnnotator.HasNotExecutedClassName);
-        return marker;
+        return this.sourceCodeTextEditor.addStyleToTextRange(startPosition, endPosition, WI.BasicBlockAnnotator.HasNotExecutedClassName);
     }
 
     _isTextRangeOnlyClosingBrace(startPosition, endPosition)
index 17a0a9f..7e3060f 100644 (file)
@@ -42,6 +42,12 @@ WI.SourceCodePosition = class SourceCodePosition
         return new WI.SourceCodePosition(this._lineNumber, this._columnNumber + delta);
     }
 
+    offsetColumn(delta)
+    {
+        console.assert(this._columnNumber + delta >= 0);
+        return new WI.SourceCodePosition(this._lineNumber, this._columnNumber + delta);
+    }
+
     equals(position)
     {
         return this._lineNumber === position.lineNumber && this._columnNumber === position.columnNumber;
index f24e8af..e5896fe 100644 (file)
@@ -467,13 +467,13 @@ WI.TextEditor = class TextEditor extends WI.View
 
     getTextInRange(startPosition, endPosition)
     {
-        return this._codeMirror.getRange(startPosition, endPosition);
+        return this._codeMirror.getRange(startPosition.toCodeMirror(), endPosition.toCodeMirror());
     }
 
     addStyleToTextRange(startPosition, endPosition, styleClassName)
     {
-        endPosition.ch += 1;
-        return this._codeMirror.getDoc().markText(startPosition, endPosition, {className: styleClassName, inclusiveLeft: true, inclusiveRight: true});
+        endPosition = endPosition.offsetColumn(1);
+        return this._codeMirror.getDoc().markText(startPosition.toCodeMirror(), endPosition.toCodeMirror(), {className: styleClassName, inclusiveLeft: true, inclusiveRight: true});
     }
 
     revealPosition(position, textRangeToSelect, forceUnformatted, noHighlight)
index 3d77c14..8a8946c 100644 (file)
@@ -38,11 +38,11 @@ Object.defineProperty(String.prototype, "lineEndings",
     value()
     {
         let lineEndings = [];
-
-        let index = this.indexOf("\n");
-        while (index !== -1) {
-            lineEndings.push(index);
-            index = this.indexOf("\n", index + 1);
+        let pattern = /\r\n?|\n/g;
+        let match = pattern.exec(this);
+        while (match) {
+            lineEndings.push(match.index);
+            match = pattern.exec(this)
         }
 
         lineEndings.push(this.length);