Index: pkg/compiler/lib/src/io/source_file.dart |
diff --git a/pkg/compiler/lib/src/io/source_file.dart b/pkg/compiler/lib/src/io/source_file.dart |
index 8b137c0610919f8c4345b7cec46939ed371d9c5c..1cf073c5aaf27ca1d4264e3c3d3a1acdef151105 100644 |
--- a/pkg/compiler/lib/src/io/source_file.dart |
+++ b/pkg/compiler/lib/src/io/source_file.dart |
@@ -8,6 +8,8 @@ import 'dart:convert' show UTF8; |
import 'dart:math'; |
import 'dart:typed_data' show Uint8List; |
+import 'package:kernel/ast.dart' as kernel show Location, Source; |
+ |
import 'line_column_provider.dart'; |
/** |
@@ -18,6 +20,13 @@ abstract class SourceFile implements LineColumnProvider { |
/// The absolute URI of the source file. |
Uri get uri; |
+ kernel.Source cachedKernelSource; |
+ |
+ kernel.Source get kernelSource { |
+ return cachedKernelSource ??= new kernel.Source( |
+ lineStarts, slowUtf8ZeroTerminatedBytes())..cachedText = slowText(); |
+ } |
+ |
/// The name of the file. |
/// |
/// This is [uri], maybe relativized to a more human-readable form. |
@@ -86,25 +95,7 @@ abstract class SourceFile implements LineColumnProvider { |
* representation of this source file. |
*/ |
int getLine(int position) { |
- List<int> starts = lineStarts; |
- if (position < 0 || starts.last <= position) { |
- throw 'bad position #$position in file $filename with ' |
- 'length ${length}.'; |
- } |
- int first = 0; |
- int count = starts.length; |
- while (count > 1) { |
- int step = count ~/ 2; |
- int middle = first + step; |
- int lineStart = starts[middle]; |
- if (position < lineStart) { |
- count = step; |
- } else { |
- first = middle; |
- count -= step; |
- } |
- } |
- return first; |
+ new kernel.Source(lineStarts, null).getLocation(null, position).line; |
} |
/** |
@@ -141,10 +132,12 @@ abstract class SourceFile implements LineColumnProvider { |
end = length; |
} |
- int lineStart = getLine(start); |
- int columnStart = getColumn(lineStart, start); |
- int lineEnd = getLine(end); |
- int columnEnd = getColumn(lineEnd, end); |
+ kernel.Location startLocation = kernelSource.getLocation(null, start); |
+ kernel.Location endLocation = kernelSource.getLocation(null, end); |
+ int lineStart = startLocation.line - 1; |
+ int columnStart = startLocation.column - 1; |
+ int lineEnd = startLocation.line - 1; |
+ int columnEnd = endLocation.column - 1; |
StringBuffer buf = new StringBuffer('${filename}:'); |
if (start != end || start != 0) { |
@@ -155,12 +148,12 @@ abstract class SourceFile implements LineColumnProvider { |
if (start != end && includeSourceLine) { |
if (lineStart == lineEnd) { |
- String textLine = getLineText(lineStart); |
+ String textLine = kernelSource.getTextLine(startLocation.line); |
int toColumn = min(columnStart + (end - start), textLine.length); |
buf.write(textLine.substring(0, columnStart)); |
buf.write(colorize(textLine.substring(columnStart, toColumn))); |
- buf.write(textLine.substring(toColumn)); |
+ buf.writeln(textLine.substring(toColumn)); |
int i = 0; |
for (; i < columnStart; i++) { |
@@ -172,15 +165,15 @@ abstract class SourceFile implements LineColumnProvider { |
} |
} else { |
for (int line = lineStart; line <= lineEnd; line++) { |
- String textLine = getLineText(line); |
+ String textLine = kernelSource.getTextLine(line + 1); |
if (line == lineStart) { |
buf.write(textLine.substring(0, columnStart)); |
- buf.write(colorize(textLine.substring(columnStart))); |
+ buf.writeln(colorize(textLine.substring(columnStart))); |
} else if (line == lineEnd) { |
buf.write(colorize(textLine.substring(0, columnEnd))); |
- buf.write(textLine.substring(columnEnd)); |
+ buf.writeln(textLine.substring(columnEnd)); |
} else { |
- buf.write(colorize(textLine)); |
+ buf.writeln(colorize(textLine)); |
} |
} |
} |
@@ -191,17 +184,9 @@ abstract class SourceFile implements LineColumnProvider { |
int get lines => lineStarts.length - 1; |
- /// Returns the text of line at the 0-based [index] within this source file. |
- String getLineText(int index) { |
- // +1 for 0-indexing, +1 again to avoid the last line of the file |
- if ((index + 2) < lineStarts.length) { |
- return slowSubstring(lineStarts[index], lineStarts[index + 1]); |
- } else if ((index + 1) < lineStarts.length) { |
- return '${slowSubstring(lineStarts[index], length)}\n'; |
- } else { |
- throw new ArgumentError("Line index $index is out of bounds."); |
- } |
- } |
+ /// Returns the text of line at the 0-based [index] within this source |
+ /// file. The returned line always ends with `"\n"`. |
+ String getLineText(int index) => kernelSource.getTextLine(line) + "\n"; |
} |
List<int> _zeroTerminateIfNecessary(List<int> bytes) { |