| Index: src/messages.js
|
| ===================================================================
|
| --- src/messages.js (revision 2123)
|
| +++ src/messages.js (working copy)
|
| @@ -230,7 +230,41 @@
|
| return MakeGenericError($Error, type, args);
|
| }
|
|
|
| +/**
|
| + * Find a line number given a specific source position.
|
| + * @param {number} position The source position.
|
| + * @return {number} 0 if input too small, -1 if input too large,
|
| + else the line number.
|
| + */
|
| +Script.prototype.lineFromPosition = function(position) {
|
| + var lower = 0;
|
| + var upper = this.lineCount() - 1;
|
|
|
| + // We'll never find invalid positions so bail right away.
|
| + if (position > this.line_ends[upper]) {
|
| + return -1;
|
| + }
|
| +
|
| + // This means we don't have to safe-guard indexing line_ends[i - 1].
|
| + if (position <= this.line_ends[0]) {
|
| + return 0;
|
| + }
|
| +
|
| + // Binary search to find line # from position range.
|
| + while (upper >= 1) {
|
| + var i = (lower + upper) >> 1;
|
| +
|
| + if (position > this.line_ends[i]) {
|
| + lower = i + 1;
|
| + } else if (position <= this.line_ends[i - 1]) {
|
| + upper = i - 1;
|
| + } else {
|
| + return i;
|
| + }
|
| + }
|
| + return -1;
|
| +}
|
| +
|
| /**
|
| * Get information on a specific source position.
|
| * @param {number} position The source position
|
| @@ -241,19 +275,7 @@
|
| */
|
| Script.prototype.locationFromPosition = function (position,
|
| include_resource_offset) {
|
| - var lineCount = this.lineCount();
|
| - var line = -1;
|
| - if (position <= this.line_ends[0]) {
|
| - line = 0;
|
| - } else {
|
| - for (var i = 1; i < lineCount; i++) {
|
| - if (this.line_ends[i - 1] < position && position <= this.line_ends[i]) {
|
| - line = i;
|
| - break;
|
| - }
|
| - }
|
| - }
|
| -
|
| + var line = this.lineFromPosition(position);
|
| if (line == -1) return null;
|
|
|
| // Determine start, end and column.
|
| @@ -308,16 +330,13 @@
|
| if (line == 0) {
|
| return this.locationFromPosition(offset_position + column, false);
|
| } else {
|
| - // Find the line where the offset position is located
|
| - var lineCount = this.lineCount();
|
| - var offset_line;
|
| - for (var i = 0; i < lineCount; i++) {
|
| - if (offset_position <= this.line_ends[i]) {
|
| - offset_line = i;
|
| - break;
|
| - }
|
| + // Find the line where the offset position is located.
|
| + var offset_line = this.lineFromPosition(offset_position);
|
| +
|
| + if (offset_line == -1 || offset_line + line >= this.lineCount()) {
|
| + return null;
|
| }
|
| - if (offset_line + line >= lineCount) return null;
|
| +
|
| return this.locationFromPosition(this.line_ends[offset_line + line - 1] + 1 + column); // line > 0 here.
|
| }
|
| }
|
|
|