OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 analyzer.src.dart.scanner.scanner; | 5 library analyzer.src.dart.scanner.scanner; |
6 | 6 |
7 import 'package:analyzer/error/error.dart'; | 7 import 'package:analyzer/error/error.dart'; |
8 import 'package:analyzer/error/listener.dart'; | 8 import 'package:analyzer/error/listener.dart'; |
9 import 'package:analyzer/src/dart/error/syntactic_errors.dart'; | 9 import 'package:analyzer/src/dart/error/syntactic_errors.dart'; |
10 import 'package:analyzer/src/dart/scanner/reader.dart'; | 10 import 'package:analyzer/src/dart/scanner/reader.dart'; |
11 import 'package:analyzer/src/generated/source.dart'; | 11 import 'package:analyzer/src/generated/source.dart'; |
| 12 import 'package:front_end/src/fasta/scanner.dart' as fasta; |
| 13 import 'package:front_end/src/fasta/scanner/abstract_scanner.dart' |
| 14 show fastaSupportsGenericMethodComments; |
| 15 import 'package:front_end/src/fasta/scanner/precedence.dart' as fasta; |
| 16 import 'package:front_end/src/scanner/errors.dart' show translateErrorToken; |
12 import 'package:front_end/src/scanner/scanner.dart' as fe; | 17 import 'package:front_end/src/scanner/scanner.dart' as fe; |
| 18 import 'package:front_end/src/scanner/token.dart' show Token; |
13 | 19 |
14 export 'package:analyzer/src/dart/error/syntactic_errors.dart'; | 20 export 'package:analyzer/src/dart/error/syntactic_errors.dart'; |
15 export 'package:front_end/src/scanner/scanner.dart' show KeywordState; | 21 export 'package:front_end/src/scanner/scanner.dart' show KeywordState; |
16 | 22 |
17 /** | 23 /** |
18 * The class `Scanner` implements a scanner for Dart code. | 24 * The class `Scanner` implements a scanner for Dart code. |
19 * | 25 * |
20 * The lexical structure of Dart is ambiguous without knowledge of the context | 26 * The lexical structure of Dart is ambiguous without knowledge of the context |
21 * in which a token is being scanned. For example, without context we cannot | 27 * in which a token is being scanned. For example, without context we cannot |
22 * determine whether source of the form "<<" should be scanned as a single | 28 * determine whether source of the form "<<" should be scanned as a single |
23 * left-shift operator or as two left angle brackets. This scanner does not have | 29 * left-shift operator or as two left angle brackets. This scanner does not have |
24 * any context, so it always resolves such conflicts by scanning the longest | 30 * any context, so it always resolves such conflicts by scanning the longest |
25 * possible token. | 31 * possible token. |
26 */ | 32 */ |
27 class Scanner extends fe.Scanner { | 33 class Scanner extends fe.Scanner { |
28 /** | 34 /** |
29 * The source being scanned. | 35 * The source being scanned. |
30 */ | 36 */ |
31 final Source source; | 37 final Source source; |
32 | 38 |
33 /** | 39 /** |
34 * The error listener that will be informed of any errors that are found | 40 * The error listener that will be informed of any errors that are found |
35 * during the scan. | 41 * during the scan. |
36 */ | 42 */ |
37 final AnalysisErrorListener _errorListener; | 43 final AnalysisErrorListener _errorListener; |
38 | 44 |
39 /** | 45 /** |
| 46 * A flag indicating whether the [Scanner] factory method |
| 47 * will return a fasta based scanner or an analyzer based scanner. |
| 48 */ |
| 49 static bool useFasta = false; |
| 50 |
| 51 /** |
40 * Initialize a newly created scanner to scan characters from the given | 52 * Initialize a newly created scanner to scan characters from the given |
41 * [source]. The given character [reader] will be used to read the characters | 53 * [source]. The given character [reader] will be used to read the characters |
42 * in the source. The given [_errorListener] will be informed of any errors | 54 * in the source. The given [_errorListener] will be informed of any errors |
43 * that are found. | 55 * that are found. |
44 */ | 56 */ |
45 Scanner(this.source, CharacterReader reader, this._errorListener) | 57 factory Scanner(Source source, CharacterReader reader, |
46 : super(reader); | 58 AnalysisErrorListener errorListener) => |
| 59 useFasta |
| 60 ? new _Scanner2(source, reader.getContents(), errorListener) |
| 61 : new Scanner._(source, reader, errorListener); |
| 62 |
| 63 Scanner._(this.source, CharacterReader reader, this._errorListener) |
| 64 : super.create(reader); |
47 | 65 |
48 @override | 66 @override |
49 void reportError( | 67 void reportError( |
| 68 ScannerErrorCode errorCode, int offset, List<Object> arguments) { |
| 69 _errorListener |
| 70 .onError(new AnalysisError(source, offset, 1, errorCode, arguments)); |
| 71 } |
| 72 } |
| 73 |
| 74 /** |
| 75 * Replacement scanner based on fasta. |
| 76 */ |
| 77 class _Scanner2 implements Scanner { |
| 78 @override |
| 79 final Source source; |
| 80 |
| 81 /** |
| 82 * The text to be scanned. |
| 83 */ |
| 84 final String _contents; |
| 85 |
| 86 /** |
| 87 * The error listener that will be informed of any errors that are found |
| 88 * during the scan. |
| 89 */ |
| 90 final AnalysisErrorListener _errorListener; |
| 91 |
| 92 /** |
| 93 * The flag specifying whether documentation comments should be parsed. |
| 94 */ |
| 95 bool _preserveComments = true; |
| 96 |
| 97 @override |
| 98 List<int> lineStarts; |
| 99 |
| 100 @override |
| 101 Token firstToken; |
| 102 |
| 103 @override |
| 104 bool scanGenericMethodComments = false; |
| 105 |
| 106 @override |
| 107 bool scanLazyAssignmentOperators = false; |
| 108 |
| 109 _Scanner2(this.source, this._contents, this._errorListener); |
| 110 |
| 111 @override |
| 112 void appendToken(Token token) { |
| 113 throw 'unsupported operation'; |
| 114 } |
| 115 |
| 116 @override |
| 117 int bigSwitch(int next) { |
| 118 throw 'unsupported operation'; |
| 119 } |
| 120 |
| 121 @override |
| 122 bool get hasUnmatchedGroups { |
| 123 throw 'unsupported operation'; |
| 124 } |
| 125 |
| 126 @override |
| 127 void recordStartOfLine() { |
| 128 throw 'unsupported operation'; |
| 129 } |
| 130 |
| 131 @override |
| 132 void reportError( |
50 ScannerErrorCode errorCode, int offset, List<Object> arguments) { | 133 ScannerErrorCode errorCode, int offset, List<Object> arguments) { |
51 _errorListener | 134 _errorListener |
52 .onError(new AnalysisError(source, offset, 1, errorCode, arguments)); | 135 .onError(new AnalysisError(source, offset, 1, errorCode, arguments)); |
53 } | 136 } |
| 137 |
| 138 @override |
| 139 void setSourceStart(int line, int column) { |
| 140 throw 'unsupported operation'; |
| 141 } |
| 142 |
| 143 @override |
| 144 Token get tail { |
| 145 throw 'unsupported operation'; |
| 146 } |
| 147 |
| 148 @override |
| 149 Token tokenize() { |
| 150 // Note: Fasta always supports lazy assignment operators (`&&=` and `||=`), |
| 151 // so we can ignore the `scanLazyAssignmentOperators` flag. |
| 152 if (scanGenericMethodComments && !fastaSupportsGenericMethodComments) { |
| 153 // Fasta doesn't support generic method comments. |
| 154 // TODO(danrubel): remove this once fasts support has been added. |
| 155 throw 'No generic method comment support in Fasta'; |
| 156 } |
| 157 fasta.ScannerResult result = |
| 158 fasta.scanString(_contents, includeComments: _preserveComments); |
| 159 // fasta pretends there is an additional line at EOF |
| 160 lineStarts = result.lineStarts.sublist(0, result.lineStarts.length - 1); |
| 161 fasta.Token token = result.tokens; |
| 162 // The default recovery strategy used by scanString |
| 163 // places all error tokens at the head of the stream. |
| 164 while (token.info == fasta.BAD_INPUT_INFO) { |
| 165 translateErrorToken(token, reportError); |
| 166 token = token.next; |
| 167 } |
| 168 firstToken = token; |
| 169 return firstToken; |
| 170 } |
| 171 |
| 172 @override |
| 173 set preserveComments(bool preserveComments) { |
| 174 this._preserveComments = preserveComments; |
| 175 } |
54 } | 176 } |
OLD | NEW |