| 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..2710be7f47e7505acf574958165653c77c73abc3 100644
|
| --- a/pkg/compiler/lib/src/io/source_file.dart
|
| +++ b/pkg/compiler/lib/src/io/source_file.dart
|
| @@ -8,46 +8,47 @@ import 'dart:convert' show UTF8;
|
| import 'dart:math';
|
| import 'dart:typed_data' show Uint8List;
|
|
|
| -import 'line_column_provider.dart';
|
| +import 'package:kernel/ast.dart' as kernel show Location, Source;
|
|
|
| -/**
|
| - * Represents a file of source code. The content can be either a [String] or
|
| - * a UTF-8 encoded [List<int>] of bytes.
|
| - */
|
| -abstract class SourceFile implements LineColumnProvider {
|
| +import 'location_provider.dart' show LocationProvider;
|
| +
|
| +/// Represents a file of source code. The content can be either a [String] or
|
| +/// a UTF-8 encoded [List<int>] of bytes.
|
| +abstract class SourceFile implements LocationProvider {
|
| /// 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.
|
| String get filename => uri.toString();
|
|
|
| - /** The text content of the file represented as a String. */
|
| + /// The text content of the file represented as a String
|
| String slowText();
|
|
|
| - /**
|
| - * The content of the file represented as a UTF-8 encoded [List<int>],
|
| - * terminated with a trailing 0 byte.
|
| - */
|
| + /// The content of the file represented as a UTF-8 encoded [List<int>],
|
| + /// terminated with a trailing 0 byte.
|
| List<int> slowUtf8ZeroTerminatedBytes();
|
|
|
| - /**
|
| - * The length of the string representation of this source file, i.e.,
|
| - * equivalent to [:slowText().length:], but faster.
|
| - */
|
| + /// The length of the string representation of this source file, i.e.,
|
| + /// equivalent to [:slowText().length:], but faster.
|
| int get length;
|
|
|
| - /**
|
| - * Sets the string length of this source file. For source files based on UTF-8
|
| - * byte arrays, the string length is computed and assigned by the scanner.
|
| - */
|
| + /// Sets the string length of this source file. For source files based on
|
| + /// UTF-8 byte arrays, the string length is computed and assigned by the
|
| + /// scanner.
|
| set length(int v);
|
|
|
| - /**
|
| - * A map from line numbers to offsets in the string text representation of
|
| - * this source file.
|
| - */
|
| + /// A map from line numbers to offsets in the string text representation of
|
| + /// this source file.
|
| List<int> get lineStarts {
|
| if (lineStartsCache == null) {
|
| // When reporting errors during scanning, the line numbers are not yet
|
| @@ -57,14 +58,12 @@ abstract class SourceFile implements LineColumnProvider {
|
| return lineStartsCache;
|
| }
|
|
|
| - /**
|
| - * Sets the line numbers map for this source file. This map is computed and
|
| - * assigned by the scanner, avoiding a separate traversal of the source file.
|
| - *
|
| - * The map contains one additional entry at the end of the file, as if the
|
| - * source file had one more empty line at the end. This simplifies the binary
|
| - * search in [getLine].
|
| - */
|
| + /// Sets the line numbers map for this source file. This map is computed and
|
| + /// assigned by the scanner, avoiding a separate traversal of the source file.
|
| + ///
|
| + /// The map contains one additional entry at the end of the file, as if the
|
| + /// source file had one more empty line at the end. This simplifies the binary
|
| + /// search in [getLocation].
|
| set lineStarts(List<int> v) => lineStartsCache = v;
|
|
|
| List<int> lineStartsCache;
|
| @@ -81,56 +80,21 @@ abstract class SourceFile implements LineColumnProvider {
|
| return starts;
|
| }
|
|
|
| - /**
|
| - * Returns the line number for the offset [position] in the string
|
| - * 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;
|
| - }
|
| -
|
| - /**
|
| - * Returns the column number for the offset [position] in the string
|
| - * representation of this source file.
|
| - */
|
| - int getColumn(int line, int position) {
|
| - return position - lineStarts[line];
|
| + kernel.Location getLocation(int offset) {
|
| + return kernelSource.getLocation(null, offset);
|
| }
|
|
|
| - /// Returns the offset for 0-based [line] and [column] numbers.
|
| - int getOffset(int line, int column) => lineStarts[line] + column;
|
| -
|
| String slowSubstring(int start, int end);
|
|
|
| - /**
|
| - * Create a pretty string representation for [message] from a character
|
| - * range `[start, end]` in this file.
|
| - *
|
| - * If [includeSourceLine] is `true` the first source line code line that
|
| - * contains the range will be included as well as marker characters ('^')
|
| - * underlining the range.
|
| - *
|
| - * Use [colorize] to wrap source code text and marker characters in color
|
| - * escape codes.
|
| - */
|
| + /// Create a pretty string representation for [message] from a character
|
| + /// range `[start, end]` in this file.
|
| + ///
|
| + /// If [includeSourceLine] is `true` the first source line code line that
|
| + /// contains the range will be included as well as marker characters ('^')
|
| + /// underlining the range.
|
| + ///
|
| + /// Use [colorize] to wrap source code text and marker characters in color
|
| + /// escape codes.
|
| String getLocationMessage(String message, int start, int end,
|
| {bool includeSourceLine: true, String colorize(String text)}) {
|
| if (colorize == null) {
|
| @@ -141,10 +105,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 = endLocation.line - 1;
|
| + int columnEnd = endLocation.column - 1;
|
|
|
| StringBuffer buf = new StringBuffer('${filename}:');
|
| if (start != end || start != 0) {
|
| @@ -155,12 +121,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 +138,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));
|
| }
|
| }
|
| }
|
| @@ -190,18 +156,6 @@ 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.");
|
| - }
|
| - }
|
| }
|
|
|
| List<int> _zeroTerminateIfNecessary(List<int> bytes) {
|
| @@ -215,15 +169,13 @@ List<int> _zeroTerminateIfNecessary(List<int> bytes) {
|
| class Utf8BytesSourceFile extends SourceFile {
|
| final Uri uri;
|
|
|
| - /** The UTF-8 encoded content of the source file. */
|
| + /// The UTF-8 encoded content of the source file.
|
| final List<int> zeroTerminatedContent;
|
|
|
| - /**
|
| - * Creates a Utf8BytesSourceFile.
|
| - *
|
| - * If possible, the given [content] should be zero-terminated. If it isn't,
|
| - * the constructor clones the content and adds a trailing 0.
|
| - */
|
| + /// Creates a Utf8BytesSourceFile.
|
| + ///
|
| + /// If possible, the given [content] should be zero-terminated. If it isn't,
|
| + /// the constructor clones the content and adds a trailing 0.
|
| Utf8BytesSourceFile(this.uri, List<int> content)
|
| : this.zeroTerminatedContent = _zeroTerminateIfNecessary(content);
|
|
|
|
|