Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(86)

Unified Diff: pkg/kernel/lib/ast.dart

Issue 2788373002: Add Source.getTextLine and use it to display source snippets in error messages. (Closed)
Patch Set: Remove getLine, getColumn, and getLineText. Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/kernel/lib/ast.dart
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index 0112b5a7286a9cfd651dfbe5f032e6e43bbf8ae5..840dd1bfe3797f5efc18fc432b2cb0daf997a371 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -50,6 +50,8 @@
///
library kernel.ast;
+import 'dart:convert' show UTF8;
+
import 'visitor.dart';
export 'visitor.dart';
@@ -4107,22 +4109,7 @@ class Program extends TreeNode {
/// Translates an offset to line and column numbers in the given file.
Location getLocation(String file, int offset) {
- List<int> lines = uriToSource[file].lineStarts;
- int low = 0, high = lines.length - 1;
- while (low < high) {
- int mid = high - ((high - low) >> 1); // Get middle, rounding up.
- int pivot = lines[mid];
- if (pivot <= offset) {
- low = mid;
- } else {
- high = mid - 1;
- }
- }
- int lineIndex = low;
- int lineStart = lines[lineIndex];
- int lineNumber = 1 + lineIndex;
- int columnNumber = 1 + offset - lineStart;
- return new Location(file, lineNumber, columnNumber);
+ return uriToSource[file]?.getLocation(file, offset);
}
}
@@ -4228,9 +4215,71 @@ class _ChildReplacer extends Transformer {
class Source {
final List<int> lineStarts;
+
final List<int> source;
+ String cachedText;
+
Source(this.lineStarts, this.source);
+
+ /// Return the text corresponding to [line] which is a 1-based line
+ /// number. The returned line contains no line separators.
+ String getTextLine(int line) {
+ RangeError.checkValueInInterval(
+ line,
+ 1,
+ lineStarts.length,
+ "line",
+ "The value of 'line' ($line) must be between 1 and "
+ "${lineStarts.length}.");
+ if (source == null) return null;
+
+ cachedText ??= UTF8.decode(source, allowMalformed: true);
+ // -1 as line numbers start at 1.
+ int index = line - 1;
+ if (index + 1 == lineStarts.length) {
+ // Last line.
+ return cachedText.substring(lineStarts[index]);
+ } else if (index < lineStarts.length) {
+ // We subtract 1 from the next line for two reasons:
+ // 1. If the file isn't terminated by a newline, that index is invalid.
+ // 2. To remove the newline at the end of the line.
+ int endOfLine = lineStarts[index + 1] - 1;
+ if (endOfLine > index && cachedText[endOfLine - 1] == "\r") {
+ --endOfLine; // Windows line endings.
+ }
+ return cachedText.substring(lineStarts[index], endOfLine);
+ }
+ // This shouldn't happen: should have been caught by the range check above.
+ throw "Internal error";
+ }
+
+ /// Translates an offset to line and column numbers in the given file.
+ Location getLocation(String file, int offset) {
+ RangeError.checkValueInInterval(
+ offset,
+ 0,
+ lineStarts.last,
+ "offset",
+ "The value of 'offset' ($offset) must be between 0 and "
+ "${lineStarts.length}.");
asgerf 2017/04/04 08:53:05 length -> last
ahe 2017/04/05 11:34:23 Done.
+
+ int low = 0, high = lineStarts.length - 1;
+ while (low < high) {
+ int mid = high - ((high - low) >> 1); // Get middle, rounding up.
+ int pivot = lineStarts[mid];
+ if (pivot <= offset) {
+ low = mid;
+ } else {
+ high = mid - 1;
+ }
+ }
+ int lineIndex = low;
+ int lineStart = lineStarts[lineIndex];
+ int lineNumber = 1 + lineIndex;
+ int columnNumber = 1 + offset - lineStart;
+ return new Location(file, lineNumber, columnNumber);
+ }
}
/// Returns the [Reference] object for the given member.

Powered by Google App Engine
This is Rietveld 408576698