| // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | |
| // for details. All rights reserved. Use of this source code is governed by a | |
| // BSD-style license that can be found in the LICENSE file. | |
| library _fe_analyzer_shared.scanner.main; | |
| import 'dart:typed_data' show Uint8List; | |
| import 'io.dart' show readBytesFromFileSync; | |
| import 'scanner.dart' show ErrorToken, Token, scan; | |
| void scanAll( | |
| Map<Uri, Uint8List> files, { | |
| bool verbose = false, | |
| bool verify = false, | |
| }) { | |
| Stopwatch sw = new Stopwatch()..start(); | |
| int byteCount = 0; | |
| files.forEach((Uri uri, Uint8List bytes) { | |
| Token token = scan(bytes).tokens; | |
| if (verbose) printTokens(token); | |
| if (verify) verifyErrorTokens(token, uri); | |
| byteCount += bytes.length - 1; | |
| }); | |
| sw.stop(); | |
| print("Scanning files took: ${sw.elapsed}"); | |
| print("Bytes/ms: ${byteCount / sw.elapsedMilliseconds}"); | |
| } | |
| void printTokens(Token token) { | |
| while (!token.isEof) { | |
| print("${token.charOffset}: $token"); | |
| token = token.next!; | |
| } | |
| } | |
| /// Verify that the scanner recovery has moved all of the ErrorTokens | |
| /// to the beginning of the stream. If an out-of-order ErrorToken is | |
| /// found, then print some diagnostic information and throw an exception. | |
| void verifyErrorTokens(Token firstToken, Uri uri) { | |
| Token token = firstToken; | |
| while (token is ErrorToken) { | |
| token = token.next!; | |
| } | |
| while (!token.isEof) { | |
| if (token is ErrorToken) { | |
| print('Found out-of-order ErrorTokens when scanning:\n $uri'); | |
| // Rescan the token stream up to the error token to find the 10 tokens | |
| // before the out of order ErrorToken. | |
| Token errorToken = token; | |
| Token start = firstToken; | |
| int count = 0; | |
| token = firstToken; | |
| while (token != errorToken) { | |
| token = token.next!; | |
| if (count < 10) { | |
| ++count; | |
| } else { | |
| start = start.next!; | |
| } | |
| } | |
| // Print the out of order error token plus some tokens before and after. | |
| count = 0; | |
| token = start; | |
| while (count < 20 && !token.isEof) { | |
| print("${token.charOffset}: $token"); | |
| token = token.next!; | |
| ++count; | |
| } | |
| throw 'Out of order ErrorToken: $errorToken'; | |
| } | |
| token = token.next!; | |
| } | |
| } | |
| void mainEntryPoint(List<String> arguments) { | |
| Map<Uri, Uint8List> files = <Uri, Uint8List>{}; | |
| Stopwatch sw = new Stopwatch()..start(); | |
| bool verbose = const bool.fromEnvironment("printTokens"); | |
| bool verify = const bool.fromEnvironment('verifyErrorTokens'); | |
| for (String arg in arguments) { | |
| if (arg.startsWith('--')) { | |
| if (arg == '--print-tokens') { | |
| verbose = true; | |
| } else if (arg == '--verify-error-tokens') { | |
| verify = true; | |
| } else { | |
| print('Unrecognized option: $arg'); | |
| } | |
| continue; | |
| } | |
| Uri uri = Uri.base.resolve(arg); | |
| Uint8List bytes = readBytesFromFileSync(uri); | |
| files[uri] = bytes; | |
| } | |
| sw.stop(); | |
| print("Reading files took: ${sw.elapsed}"); | |
| scanAll(files, verbose: verbose, verify: verify); | |
| } |