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

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: dartfmt Created 3 years, 8 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
« no previous file with comments | « pkg/front_end/lib/src/fasta/messages.dart ('k') | tests/compiler/dart2js/line_column_provider_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/kernel/lib/ast.dart
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index 0112b5a7286a9cfd651dfbe5f032e6e43bbf8ae5..9d00c1ec9eafc850511d80bc809db61a7ce9b441 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,63 @@ 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) {
+ _rangeCheck(line, 1, lineStarts.length, "line");
+ 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) {
+ _rangeCheck(offset, 0, lineStarts.last, "offset");
+ 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);
+ }
+}
+
+void _rangeCheck(int value, int min, int max, String name) {
+ RangeError.checkValueInInterval(value, min, max, name,
+ "The value of '$name' ($value) must be between $min and $max.");
sra1 2017/05/04 05:44:39 Please remove this interpolation. It is expensive
}
/// Returns the [Reference] object for the given member.
« no previous file with comments | « pkg/front_end/lib/src/fasta/messages.dart ('k') | tests/compiler/dart2js/line_column_provider_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698