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

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: Address comments. 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
« no previous file with comments | « pkg/front_end/lib/src/fasta/messages.dart ('k') | no next file » | 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..5cb1983464d25255fe038e6b64eca11bcb4aa9ea 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,73 @@ 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 nextLine = lineStarts[index + 1] - 1;
+ String result = cachedText.substring(lineStarts[index], nextLine);
+ if (result.endsWith("\r")) {
+ // Support for Windows text files.
+ result = result.substring(0, result.length - 1);
asgerf 2017/04/03 09:55:25 The 'nextLine' variable does not actually refer to
ahe 2017/04/03 14:57:08 Done.
+ }
+ return result;
+ }
+ // 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 1 and "
asgerf 2017/04/03 09:55:25 between 1 and -> between 0 and
ahe 2017/04/03 14:57:08 Done.
+ "${lineStarts.length}.");
+
+ 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.
« no previous file with comments | « pkg/front_end/lib/src/fasta/messages.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698