OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library fasta.scanner.abstract_scanner; | 5 library fasta.scanner.abstract_scanner; |
6 | 6 |
7 import 'dart:collection' show | |
8 ListMixin; | |
9 | |
10 import 'dart:typed_data' show | |
11 Uint16List, | |
12 Uint32List; | |
13 | |
7 import '../scanner.dart' show | 14 import '../scanner.dart' show |
8 ErrorToken, | 15 ErrorToken, |
9 Scanner, | 16 Scanner, |
10 buildUnexpectedCharacterToken; | 17 buildUnexpectedCharacterToken; |
11 | 18 |
12 import 'error_token.dart' show | 19 import 'error_token.dart' show |
13 UnmatchedToken, | 20 UnmatchedToken, |
14 UnterminatedToken; | 21 UnterminatedToken; |
15 | 22 |
16 import 'keyword.dart' show | 23 import 'keyword.dart' show |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
48 * is not exposed to clients of the scanner, which are expected to invoke | 55 * is not exposed to clients of the scanner, which are expected to invoke |
49 * [firstToken] to access the token stream. | 56 * [firstToken] to access the token stream. |
50 */ | 57 */ |
51 final Token tokens = new SymbolToken(EOF_INFO, -1); | 58 final Token tokens = new SymbolToken(EOF_INFO, -1); |
52 | 59 |
53 /** | 60 /** |
54 * A pointer to the last scanned token. | 61 * A pointer to the last scanned token. |
55 */ | 62 */ |
56 Token tail; | 63 Token tail; |
57 | 64 |
58 final List<int> lineStarts = <int>[0]; | 65 final List<int> lineStarts; |
59 | 66 |
60 AbstractScanner(this.includeComments) { | 67 AbstractScanner(this.includeComments, {int numberOfBytesHint}) |
68 : lineStarts = new LineStarts(numberOfBytesHint) { | |
61 this.tail = this.tokens; | 69 this.tail = this.tokens; |
62 } | 70 } |
63 | 71 |
64 /** | 72 /** |
65 * Advances and returns the next character. | 73 * Advances and returns the next character. |
66 * | 74 * |
67 * If the next character is non-ASCII, then the returned value depends on the | 75 * If the next character is non-ASCII, then the returned value depends on the |
68 * scanner implementation. The [Utf8BytesScanner] returns a UTF-8 byte, while | 76 * scanner implementation. The [Utf8BytesScanner] returns a UTF-8 byte, while |
69 * the [StringScanner] returns a UTF-16 code unit. | 77 * the [StringScanner] returns a UTF-16 code unit. |
70 * | 78 * |
(...skipping 1087 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1158 | 1166 |
1159 PrecedenceInfo closeBraceInfoFor(BeginGroupToken begin) { | 1167 PrecedenceInfo closeBraceInfoFor(BeginGroupToken begin) { |
1160 return const { | 1168 return const { |
1161 '(': CLOSE_PAREN_INFO, | 1169 '(': CLOSE_PAREN_INFO, |
1162 '[': CLOSE_SQUARE_BRACKET_INFO, | 1170 '[': CLOSE_SQUARE_BRACKET_INFO, |
1163 '{': CLOSE_CURLY_BRACKET_INFO, | 1171 '{': CLOSE_CURLY_BRACKET_INFO, |
1164 '<': GT_INFO, | 1172 '<': GT_INFO, |
1165 r'${': CLOSE_CURLY_BRACKET_INFO, | 1173 r'${': CLOSE_CURLY_BRACKET_INFO, |
1166 }[begin.value]; | 1174 }[begin.value]; |
1167 } | 1175 } |
1176 | |
1177 class LineStarts extends Object with ListMixin<int> { | |
1178 List<int> array; | |
1179 int arrayLength = 0; | |
1180 | |
1181 LineStarts(int numberOfBytesHint) { | |
1182 // Let's assume the average Dart file is 300 bytes. | |
1183 if (numberOfBytesHint == null) numberOfBytesHint = 300; | |
1184 | |
1185 // Let's assume we have on average 22 bytes per line. | |
1186 final int expectedNumberOfLines = 1 + (numberOfBytesHint ~/ 22); | |
1187 | |
1188 // We don't use the hint to indicate whether we might need a Uint32List to | |
1189 // represent the offsets, since it's very unlikly to have more than 2^16-1 | |
1190 // characters. | |
ahe
2017/02/23 12:47:35
I don't understand this comment. It seems like you
kustermann
2017/02/24 14:24:49
Sorry that was a left over, will remove it.
| |
1191 if (numberOfBytesHint > 65535) { | |
1192 array = new Uint32List(expectedNumberOfLines); | |
1193 } else { | |
1194 array = new Uint16List(expectedNumberOfLines); | |
1195 } | |
1196 | |
1197 // The first line starts at character offset 0. | |
1198 add(0); | |
1199 } | |
1200 | |
1201 // Implement abstract members used by [ListMixin] | |
1202 | |
1203 int get length => arrayLength; | |
1204 | |
1205 int operator[](int index) { | |
1206 assert(index < arrayLength); | |
1207 return array[index]; | |
1208 } | |
1209 | |
1210 void set length(int newLength) { | |
1211 if (newLength > array.length) { | |
1212 grow(newLength); | |
1213 } | |
1214 arrayLength = newLength; | |
1215 } | |
1216 | |
1217 void operator[]=(int index, int value) { | |
1218 if (value > 65535 && array is! Uint32List) { | |
1219 switchToUint32(array.length); | |
1220 } | |
1221 array[index] = value; | |
1222 } | |
1223 | |
1224 // Specialize methods from [ListMixin]. | |
1225 void add(int value) { | |
1226 if (arrayLength >= array.length) { | |
1227 grow(0); | |
1228 } | |
1229 if (value > 65535 && array is! Uint32List) { | |
1230 switchToUint32(array.length); | |
1231 } | |
1232 array[arrayLength++] = value; | |
1233 } | |
1234 | |
1235 // Helper methods. | |
1236 | |
1237 void grow(int newLengthMinimum) { | |
1238 int newLength = array.length * 2; | |
1239 if (newLength < newLengthMinimum) newLength = newLengthMinimum; | |
1240 | |
1241 if (array is Uint16List) { | |
1242 final newArray = new Uint16List(newLength); | |
1243 newArray.setRange(0, arrayLength, array); | |
1244 array = newArray; | |
1245 } else { | |
1246 switchToUint32(newLength); | |
1247 } | |
1248 } | |
1249 | |
1250 void switchToUint32(int newLength) { | |
1251 final newArray = new Uint32List(newLength); | |
1252 newArray.setRange(0, arrayLength, array); | |
1253 array = newArray; | |
1254 } | |
1255 } | |
OLD | NEW |