Index: pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart |
diff --git a/pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart b/pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart |
index f4de827c7fa5399a8d90e8207653e0b2503b8d77..9b6e8a7b8b3822fedc503e601cf6217be338bd5b 100644 |
--- a/pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart |
+++ b/pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart |
@@ -4,6 +4,13 @@ |
library fasta.scanner.abstract_scanner; |
+import 'dart:collection' show |
+ ListMixin; |
+ |
+import 'dart:typed_data' show |
+ Uint16List, |
+ Uint32List; |
+ |
import '../scanner.dart' show |
ErrorToken, |
Scanner, |
@@ -55,9 +62,10 @@ abstract class AbstractScanner implements Scanner { |
*/ |
Token tail; |
- final List<int> lineStarts = <int>[0]; |
+ final List<int> lineStarts; |
- AbstractScanner(this.includeComments) { |
+ AbstractScanner(this.includeComments, {int numberOfBytesHint}) |
+ : lineStarts = new LineStarts(numberOfBytesHint) { |
this.tail = this.tokens; |
} |
@@ -1165,3 +1173,80 @@ PrecedenceInfo closeBraceInfoFor(BeginGroupToken begin) { |
r'${': CLOSE_CURLY_BRACKET_INFO, |
}[begin.value]; |
} |
+ |
+class LineStarts extends Object with ListMixin<int> { |
+ List<int> array; |
+ int arrayLength = 0; |
+ |
+ LineStarts(int numberOfBytesHint) { |
+ // Let's assume the average Dart file is 300 bytes. |
+ if (numberOfBytesHint == null) numberOfBytesHint = 300; |
+ |
+ // Let's assume we have on average 22 bytes per line. |
+ final int expectedNumberOfLines = 1 + (numberOfBytesHint ~/ 22); |
+ |
+ if (numberOfBytesHint > 65535) { |
+ array = new Uint32List(expectedNumberOfLines); |
+ } else { |
+ array = new Uint16List(expectedNumberOfLines); |
+ } |
+ |
+ // The first line starts at character offset 0. |
+ add(0); |
+ } |
+ |
+ // Implement abstract members used by [ListMixin] |
+ |
+ int get length => arrayLength; |
+ |
+ int operator[](int index) { |
+ assert(index < arrayLength); |
+ return array[index]; |
+ } |
+ |
+ void set length(int newLength) { |
+ if (newLength > array.length) { |
+ grow(newLength); |
+ } |
+ arrayLength = newLength; |
+ } |
+ |
+ void operator[]=(int index, int value) { |
+ if (value > 65535 && array is! Uint32List) { |
+ switchToUint32(array.length); |
+ } |
+ array[index] = value; |
+ } |
+ |
+ // Specialize methods from [ListMixin]. |
+ void add(int value) { |
+ if (arrayLength >= array.length) { |
+ grow(0); |
+ } |
+ if (value > 65535 && array is! Uint32List) { |
+ switchToUint32(array.length); |
+ } |
+ array[arrayLength++] = value; |
+ } |
+ |
+ // Helper methods. |
+ |
+ void grow(int newLengthMinimum) { |
+ int newLength = array.length * 2; |
+ if (newLength < newLengthMinimum) newLength = newLengthMinimum; |
+ |
+ if (array is Uint16List) { |
+ final newArray = new Uint16List(newLength); |
+ newArray.setRange(0, arrayLength, array); |
+ array = newArray; |
+ } else { |
+ switchToUint32(newLength); |
+ } |
+ } |
+ |
+ void switchToUint32(int newLength) { |
+ final newArray = new Uint32List(newLength); |
+ newArray.setRange(0, arrayLength, array); |
+ array = newArray; |
+ } |
+} |