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

Side by Side Diff: pkg/analyzer-experimental/lib/src/generated/scanner.dart

Issue 12502002: Update analyzer-experimental. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // This code was auto-generated, is not intended to be edited, and is subject to 1 // This code was auto-generated, is not intended to be edited, and is subject to
2 // significant change. Please see the README file for more information. 2 // significant change. Please see the README file for more information.
3 3
4 library engine.scanner; 4 library engine.scanner;
5 5
6 import 'dart:collection'; 6 import 'dart:collection';
7 import 'java_core.dart'; 7 import 'java_core.dart';
8 import 'source.dart'; 8 import 'source.dart';
9 import 'error.dart'; 9 import 'error.dart';
10 import 'instrumentation.dart'; 10 import 'instrumentation.dart';
11 11
12 /** 12 /**
13 * Instances of the abstract class {@code KeywordState} represent a state in a s tate machine used to
14 * scan keywords.
15 */
16 class KeywordState {
17 /**
18 * An empty transition table used by leaf states.
19 */
20 static List<KeywordState> _EMPTY_TABLE = new List<KeywordState>(26);
21 /**
22 * The initial state in the state machine.
23 */
24 static KeywordState KEYWORD_STATE = createKeywordStateTable();
25 /**
26 * Create the next state in the state machine where we have already recognized the subset of
27 * strings in the given array of strings starting at the given offset and havi ng the given length.
28 * All of these strings have a common prefix and the next character is at the given start index.
29 * @param start the index of the character in the strings used to transition t o a new state
30 * @param strings an array containing all of the strings that will be recogniz ed by the state
31 * machine
32 * @param offset the offset of the first string in the array that has the pref ix that is assumed
33 * to have been recognized by the time we reach the state being built
34 * @param length the number of strings in the array that pass through the stat e being built
35 * @return the state that was created
36 */
37 static KeywordState computeKeywordStateTable(int start, List<String> strings, int offset, int length12) {
38 List<KeywordState> result = new List<KeywordState>(26);
39 assert(length12 != 0);
40 int chunk = 0x0;
41 int chunkStart = -1;
42 bool isLeaf = false;
43 for (int i = offset; i < offset + length12; i++) {
44 if (strings[i].length == start) {
45 isLeaf = true;
46 }
47 if (strings[i].length > start) {
48 int c = strings[i].codeUnitAt(start);
49 if (chunk != c) {
50 if (chunkStart != -1) {
51 result[chunk - 0x61] = computeKeywordStateTable(start + 1, strings, chunkStart, i - chunkStart);
52 }
53 chunkStart = i;
54 chunk = c;
55 }
56 }
57 }
58 if (chunkStart != -1) {
59 assert(result[chunk - 0x61] == null);
60 result[chunk - 0x61] = computeKeywordStateTable(start + 1, strings, chunkS tart, offset + length12 - chunkStart);
61 } else {
62 assert(length12 == 1);
63 return new KeywordState(_EMPTY_TABLE, strings[offset]);
64 }
65 if (isLeaf) {
66 return new KeywordState(result, strings[offset]);
67 } else {
68 return new KeywordState(result, null);
69 }
70 }
71 /**
72 * Create the initial state in the state machine.
73 * @return the state that was created
74 */
75 static KeywordState createKeywordStateTable() {
76 List<Keyword> values2 = Keyword.values;
77 List<String> strings = new List<String>(values2.length);
78 for (int i = 0; i < values2.length; i++) {
79 strings[i] = values2[i].syntax;
80 }
81 strings.sort();
82 return computeKeywordStateTable(0, strings, 0, strings.length);
83 }
84 /**
85 * A table mapping characters to the states to which those characters will tra nsition. (The index
86 * into the array is the offset from the character {@code 'a'} to the transiti oning character.)
87 */
88 List<KeywordState> _table;
89 /**
90 * The keyword that is recognized by this state, or {@code null} if this state is not a terminal
91 * state.
92 */
93 Keyword _keyword2;
94 /**
95 * Initialize a newly created state to have the given transitions and to recog nize the keyword
96 * with the given syntax.
97 * @param table a table mapping characters to the states to which those charac ters will transition
98 * @param syntax the syntax of the keyword that is recognized by the state
99 */
100 KeywordState(List<KeywordState> table, String syntax) {
101 this._table = table;
102 this._keyword2 = (syntax == null) ? null : Keyword.keywords[syntax];
103 }
104 /**
105 * Return the keyword that was recognized by this state, or {@code null} if th is state does not
106 * recognized a keyword.
107 * @return the keyword that was matched by reaching this state
108 */
109 Keyword keyword() => _keyword2;
110 /**
111 * Return the state that follows this state on a transition of the given chara cter, or{@code null} if there is no valid state reachable from this state with s uch a transition.
112 * @param c the character used to transition from this state to another state
113 * @return the state that follows this state on a transition of the given char acter
114 */
115 KeywordState next(int c) => _table[c - 0x61];
116 }
117 /**
118 * The enumeration {@code ScannerErrorCode} defines the error codes used for err ors detected by the
119 * scanner.
120 */
121 class ScannerErrorCode implements ErrorCode {
122 static final ScannerErrorCode ILLEGAL_CHARACTER = new ScannerErrorCode('ILLEGA L_CHARACTER', 0, "Illegal character %x");
123 static final ScannerErrorCode MISSING_DIGIT = new ScannerErrorCode('MISSING_DI GIT', 1, "Decimal digit expected");
124 static final ScannerErrorCode MISSING_HEX_DIGIT = new ScannerErrorCode('MISSIN G_HEX_DIGIT', 2, "Hexidecimal digit expected");
125 static final ScannerErrorCode MISSING_QUOTE = new ScannerErrorCode('MISSING_QU OTE', 3, "Expected quote (' or \")");
126 static final ScannerErrorCode UNTERMINATED_MULTI_LINE_COMMENT = new ScannerErr orCode('UNTERMINATED_MULTI_LINE_COMMENT', 4, "Unterminated multi-line comment");
127 static final ScannerErrorCode UNTERMINATED_STRING_LITERAL = new ScannerErrorCo de('UNTERMINATED_STRING_LITERAL', 5, "Unterminated string literal");
128 static final List<ScannerErrorCode> values = [ILLEGAL_CHARACTER, MISSING_DIGIT , MISSING_HEX_DIGIT, MISSING_QUOTE, UNTERMINATED_MULTI_LINE_COMMENT, UNTERMINATE D_STRING_LITERAL];
129 final String __name;
130 final int __ordinal;
131 /**
132 * The message template used to create the message to be displayed for this er ror.
133 */
134 String _message;
135 /**
136 * Initialize a newly created error code to have the given message.
137 * @param message the message template used to create the message to be displa yed for this error
138 */
139 ScannerErrorCode(this.__name, this.__ordinal, String message) {
140 this._message = message;
141 }
142 ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
143 String get message => _message;
144 ErrorType get type => ErrorType.SYNTACTIC_ERROR;
145 bool needsRecompilation() => true;
146 String toString() => __name;
147 }
148 /**
149 * Instances of the class {@code TokenWithComment} represent a string token that is preceded by
150 * comments.
151 */
152 class StringTokenWithComment extends StringToken {
153 /**
154 * The first comment in the list of comments that precede this token.
155 */
156 Token _precedingComment;
157 /**
158 * Initialize a newly created token to have the given type and offset and to b e preceded by the
159 * comments reachable from the given comment.
160 * @param type the type of the token
161 * @param offset the offset from the beginning of the file to the first charac ter in the token
162 * @param precedingComment the first comment in the list of comments that prec ede this token
163 */
164 StringTokenWithComment(TokenType type, String value, int offset, Token precedi ngComment) : super(type, value, offset) {
165 this._precedingComment = precedingComment;
166 }
167 Token get precedingComments => _precedingComment;
168 }
169 /**
13 * The enumeration {@code Keyword} defines the keywords in the Dart programming language. 170 * The enumeration {@code Keyword} defines the keywords in the Dart programming language.
14 */ 171 */
15 class Keyword { 172 class Keyword {
16 static final Keyword ASSERT = new Keyword.con1('ASSERT', 0, "assert"); 173 static final Keyword ASSERT = new Keyword.con1('ASSERT', 0, "assert");
17 static final Keyword BREAK = new Keyword.con1('BREAK', 1, "break"); 174 static final Keyword BREAK = new Keyword.con1('BREAK', 1, "break");
18 static final Keyword CASE = new Keyword.con1('CASE', 2, "case"); 175 static final Keyword CASE = new Keyword.con1('CASE', 2, "case");
19 static final Keyword CATCH = new Keyword.con1('CATCH', 3, "catch"); 176 static final Keyword CATCH = new Keyword.con1('CATCH', 3, "catch");
20 static final Keyword CLASS = new Keyword.con1('CLASS', 4, "class"); 177 static final Keyword CLASS = new Keyword.con1('CLASS', 4, "class");
21 static final Keyword CONST = new Keyword.con1('CONST', 5, "const"); 178 static final Keyword CONST = new Keyword.con1('CONST', 5, "const");
22 static final Keyword CONTINUE = new Keyword.con1('CONTINUE', 6, "continue"); 179 static final Keyword CONTINUE = new Keyword.con1('CONTINUE', 6, "continue");
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 result[keyword._syntax] = keyword; 242 result[keyword._syntax] = keyword;
86 } 243 }
87 return result; 244 return result;
88 } 245 }
89 /** 246 /**
90 * Initialize a newly created keyword to have the given syntax. The keyword is not a 247 * Initialize a newly created keyword to have the given syntax. The keyword is not a
91 * pseudo-keyword. 248 * pseudo-keyword.
92 * @param syntax the lexeme for the keyword 249 * @param syntax the lexeme for the keyword
93 */ 250 */
94 Keyword.con1(String ___name, int ___ordinal, String syntax) { 251 Keyword.con1(String ___name, int ___ordinal, String syntax) {
95 _jtd_constructor_224_impl(___name, ___ordinal, syntax); 252 _jtd_constructor_259_impl(___name, ___ordinal, syntax);
96 } 253 }
97 _jtd_constructor_224_impl(String ___name, int ___ordinal, String syntax) { 254 _jtd_constructor_259_impl(String ___name, int ___ordinal, String syntax) {
98 _jtd_constructor_225_impl(___name, ___ordinal, syntax, false); 255 _jtd_constructor_260_impl(___name, ___ordinal, syntax, false);
99 } 256 }
100 /** 257 /**
101 * Initialize a newly created keyword to have the given syntax. The keyword is a pseudo-keyword if 258 * Initialize a newly created keyword to have the given syntax. The keyword is a pseudo-keyword if
102 * the given flag is {@code true}. 259 * the given flag is {@code true}.
103 * @param syntax the lexeme for the keyword 260 * @param syntax the lexeme for the keyword
104 * @param isPseudoKeyword {@code true} if this keyword is a pseudo-keyword 261 * @param isPseudoKeyword {@code true} if this keyword is a pseudo-keyword
105 */ 262 */
106 Keyword.con2(String ___name, int ___ordinal, String syntax2, bool isPseudoKeyw ord) { 263 Keyword.con2(String ___name, int ___ordinal, String syntax2, bool isPseudoKeyw ord) {
107 _jtd_constructor_225_impl(___name, ___ordinal, syntax2, isPseudoKeyword); 264 _jtd_constructor_260_impl(___name, ___ordinal, syntax2, isPseudoKeyword);
108 } 265 }
109 _jtd_constructor_225_impl(String ___name, int ___ordinal, String syntax2, bool isPseudoKeyword) { 266 _jtd_constructor_260_impl(String ___name, int ___ordinal, String syntax2, bool isPseudoKeyword) {
110 __name = ___name; 267 __name = ___name;
111 __ordinal = ___ordinal; 268 __ordinal = ___ordinal;
112 this._syntax = syntax2; 269 this._syntax = syntax2;
113 this._isPseudoKeyword2 = isPseudoKeyword; 270 this._isPseudoKeyword2 = isPseudoKeyword;
114 } 271 }
115 /** 272 /**
116 * Return the lexeme for the keyword. 273 * Return the lexeme for the keyword.
117 * @return the lexeme for the keyword 274 * @return the lexeme for the keyword
118 */ 275 */
119 String get syntax => _syntax; 276 String get syntax => _syntax;
120 /** 277 /**
121 * Return {@code true} if this keyword is a pseudo-keyword. Pseudo keywords ca n be used as 278 * Return {@code true} if this keyword is a pseudo-keyword. Pseudo keywords ca n be used as
122 * identifiers. 279 * identifiers.
123 * @return {@code true} if this keyword is a pseudo-keyword 280 * @return {@code true} if this keyword is a pseudo-keyword
124 */ 281 */
125 bool isPseudoKeyword() => _isPseudoKeyword2; 282 bool isPseudoKeyword() => _isPseudoKeyword2;
126 String toString() => __name; 283 String toString() => __name;
127 } 284 }
128 /** 285 /**
129 * Instances of the class {@code CharBufferScanner} implement a scanner that rea ds from a character
130 * buffer. The scanning logic is in the superclass.
131 */
132 class CharBufferScanner extends AbstractScanner {
133 /**
134 * The buffer from which characters will be read.
135 */
136 CharBuffer _buffer;
137 /**
138 * The number of characters in the buffer.
139 */
140 int _bufferLength = 0;
141 /**
142 * The index of the last character that was read.
143 */
144 int _charOffset = 0;
145 /**
146 * Initialize a newly created scanner to scan the characters in the given char acter buffer.
147 * @param source the source being scanned
148 * @param buffer the buffer from which characters will be read
149 * @param errorListener the error listener that will be informed of any errors that are found
150 */
151 CharBufferScanner(Source source, CharBuffer buffer, AnalysisErrorListener erro rListener) : super(source, errorListener) {
152 this._buffer = buffer;
153 this._bufferLength = buffer.length();
154 this._charOffset = -1;
155 }
156 int get offset => _charOffset;
157 int advance() {
158 if (_charOffset + 1 >= _bufferLength) {
159 return -1;
160 }
161 return _buffer.charAt(++_charOffset);
162 }
163 String getString(int start, int endDelta) => _buffer.subSequence(start, _charO ffset + 1 + endDelta).toString();
164 int peek() {
165 if (_charOffset + 1 >= _buffer.length()) {
166 return -1;
167 }
168 return _buffer.charAt(_charOffset + 1);
169 }
170 }
171 /**
172 * Instances of the class {@code TokenWithComment} represent a normal token that is preceded by
173 * comments.
174 */
175 class TokenWithComment extends Token {
176 /**
177 * The first comment in the list of comments that precede this token.
178 */
179 Token _precedingComment;
180 /**
181 * Initialize a newly created token to have the given type and offset and to b e preceded by the
182 * comments reachable from the given comment.
183 * @param type the type of the token
184 * @param offset the offset from the beginning of the file to the first charac ter in the token
185 * @param precedingComment the first comment in the list of comments that prec ede this token
186 */
187 TokenWithComment(TokenType type, int offset, Token precedingComment) : super(t ype, offset) {
188 this._precedingComment = precedingComment;
189 }
190 Token get precedingComments => _precedingComment;
191 }
192 /**
193 * Instances of the class {@code Token} represent a token that was scanned from the input. Each
194 * token knows which token follows it, acting as the head of a linked list of to kens.
195 */
196 class Token {
197 /**
198 * The type of the token.
199 */
200 TokenType _type;
201 /**
202 * The offset from the beginning of the file to the first character in the tok en.
203 */
204 int _offset = 0;
205 /**
206 * The previous token in the token stream.
207 */
208 Token _previous;
209 /**
210 * The next token in the token stream.
211 */
212 Token _next;
213 /**
214 * Initialize a newly created token to have the given type and offset.
215 * @param type the type of the token
216 * @param offset the offset from the beginning of the file to the first charac ter in the token
217 */
218 Token(TokenType type, int offset) {
219 this._type = type;
220 this._offset = offset;
221 }
222 /**
223 * Return the offset from the beginning of the file to the character after las t character of the
224 * token.
225 * @return the offset from the beginning of the file to the first character af ter last character
226 * of the token
227 */
228 int get end => _offset + length;
229 /**
230 * Return the number of characters in the node's source range.
231 * @return the number of characters in the node's source range
232 */
233 int get length => lexeme.length;
234 /**
235 * Return the lexeme that represents this token.
236 * @return the lexeme that represents this token
237 */
238 String get lexeme => _type.lexeme;
239 /**
240 * Return the next token in the token stream.
241 * @return the next token in the token stream
242 */
243 Token get next => _next;
244 /**
245 * Return the offset from the beginning of the file to the first character in the token.
246 * @return the offset from the beginning of the file to the first character in the token
247 */
248 int get offset => _offset;
249 /**
250 * Return the first comment in the list of comments that precede this token, o r {@code null} if
251 * there are no comments preceding this token. Additional comments can be reac hed by following the
252 * token stream using {@link #getNext()} until {@code null} is returned.
253 * @return the first comment in the list of comments that precede this token
254 */
255 Token get precedingComments => null;
256 /**
257 * Return the previous token in the token stream.
258 * @return the previous token in the token stream
259 */
260 Token get previous => _previous;
261 /**
262 * Return the type of the token.
263 * @return the type of the token
264 */
265 TokenType get type => _type;
266 /**
267 * Return {@code true} if this token represents an operator.
268 * @return {@code true} if this token represents an operator
269 */
270 bool isOperator() => _type.isOperator();
271 /**
272 * Return {@code true} if this token is a synthetic token. A synthetic token i s a token that was
273 * introduced by the parser in order to recover from an error in the code. Syn thetic tokens always
274 * have a length of zero ({@code 0}).
275 * @return {@code true} if this token is a synthetic token
276 */
277 bool isSynthetic() => length == 0;
278 /**
279 * Return {@code true} if this token represents an operator that can be define d by users.
280 * @return {@code true} if this token represents an operator that can be defin ed by users
281 */
282 bool isUserDefinableOperator() => _type.isUserDefinableOperator();
283 /**
284 * Set the next token in the token stream to the given token. This has the sid e-effect of setting
285 * this token to be the previous token for the given token.
286 * @param token the next token in the token stream
287 * @return the token that was passed in
288 */
289 Token setNext(Token token) {
290 _next = token;
291 token.previous = this;
292 return token;
293 }
294 /**
295 * Set the next token in the token stream to the given token without changing which token is the
296 * previous token for the given token.
297 * @param token the next token in the token stream
298 * @return the token that was passed in
299 */
300 Token setNextWithoutSettingPrevious(Token token) {
301 _next = token;
302 return token;
303 }
304 /**
305 * Set the offset from the beginning of the file to the first character in the token to the given
306 * offset.
307 * @param offset the offset from the beginning of the file to the first charac ter in the token
308 */
309 void set offset(int offset3) {
310 this._offset = offset3;
311 }
312 String toString() => lexeme;
313 /**
314 * Return the value of this token. For keyword tokens, this is the keyword ass ociated with the
315 * token, for other tokens it is the lexeme associated with the token.
316 * @return the value of this token
317 */
318 Object value() => _type.lexeme;
319 /**
320 * Set the previous token in the token stream to the given token.
321 * @param previous the previous token in the token stream
322 */
323 void set previous(Token previous2) {
324 this._previous = previous2;
325 }
326 }
327 /**
328 * Instances of the class {@code KeywordToken} represent a keyword in the langua ge.
329 */
330 class KeywordToken extends Token {
331 /**
332 * The keyword being represented by this token.
333 */
334 Keyword _keyword;
335 /**
336 * Initialize a newly created token to represent the given keyword.
337 * @param keyword the keyword being represented by this token
338 * @param offset the offset from the beginning of the file to the first charac ter in the token
339 */
340 KeywordToken(Keyword keyword, int offset) : super(TokenType.KEYWORD, offset) {
341 this._keyword = keyword;
342 }
343 /**
344 * Return the keyword being represented by this token.
345 * @return the keyword being represented by this token
346 */
347 Keyword get keyword => _keyword;
348 String get lexeme => _keyword.syntax;
349 Keyword value() => _keyword;
350 }
351 /**
352 * Instances of the class {@code StringToken} represent a token whose value is i ndependent of it's
353 * type.
354 */
355 class StringToken extends Token {
356 /**
357 * The lexeme represented by this token.
358 */
359 String _value2;
360 /**
361 * Initialize a newly created token to represent a token of the given type wit h the given value.
362 * @param type the type of the token
363 * @param value the lexeme represented by this token
364 * @param offset the offset from the beginning of the file to the first charac ter in the token
365 */
366 StringToken(TokenType type, String value, int offset) : super(type, offset) {
367 this._value2 = value;
368 }
369 String get lexeme => _value2;
370 String value() => _value2;
371 }
372 /**
373 * The enumeration {@code ScannerErrorCode} defines the error codes used for err ors detected by the
374 * scanner.
375 */
376 class ScannerErrorCode implements ErrorCode {
377 static final ScannerErrorCode ILLEGAL_CHARACTER = new ScannerErrorCode('ILLEGA L_CHARACTER', 0, "Illegal character %x");
378 static final ScannerErrorCode MISSING_DIGIT = new ScannerErrorCode('MISSING_DI GIT', 1, "Decimal digit expected");
379 static final ScannerErrorCode MISSING_HEX_DIGIT = new ScannerErrorCode('MISSIN G_HEX_DIGIT', 2, "Hexidecimal digit expected");
380 static final ScannerErrorCode MISSING_QUOTE = new ScannerErrorCode('MISSING_QU OTE', 3, "Expected quote (' or \")");
381 static final ScannerErrorCode UNTERMINATED_MULTI_LINE_COMMENT = new ScannerErr orCode('UNTERMINATED_MULTI_LINE_COMMENT', 4, "Unterminated multi-line comment");
382 static final ScannerErrorCode UNTERMINATED_STRING_LITERAL = new ScannerErrorCo de('UNTERMINATED_STRING_LITERAL', 5, "Unterminated string literal");
383 static final List<ScannerErrorCode> values = [ILLEGAL_CHARACTER, MISSING_DIGIT , MISSING_HEX_DIGIT, MISSING_QUOTE, UNTERMINATED_MULTI_LINE_COMMENT, UNTERMINATE D_STRING_LITERAL];
384 final String __name;
385 final int __ordinal;
386 /**
387 * The message template used to create the message to be displayed for this er ror.
388 */
389 String _message;
390 /**
391 * Initialize a newly created error code to have the given message.
392 * @param message the message template used to create the message to be displa yed for this error
393 */
394 ScannerErrorCode(this.__name, this.__ordinal, String message) {
395 this._message = message;
396 }
397 ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
398 String get message => _message;
399 ErrorType get type => ErrorType.SYNTACTIC_ERROR;
400 bool needsRecompilation() => true;
401 String toString() => __name;
402 }
403 /**
404 * Instances of the class {@code BeginTokenWithComment} represent a begin token that is preceded by
405 * comments.
406 */
407 class BeginTokenWithComment extends BeginToken {
408 /**
409 * The first comment in the list of comments that precede this token.
410 */
411 Token _precedingComment;
412 /**
413 * Initialize a newly created token to have the given type and offset and to b e preceded by the
414 * comments reachable from the given comment.
415 * @param type the type of the token
416 * @param offset the offset from the beginning of the file to the first charac ter in the token
417 * @param precedingComment the first comment in the list of comments that prec ede this token
418 */
419 BeginTokenWithComment(TokenType type, int offset, Token precedingComment) : su per(type, offset) {
420 this._precedingComment = precedingComment;
421 }
422 Token get precedingComments => _precedingComment;
423 }
424 /**
425 * The enumeration {@code TokenType} defines the types of tokens that can be ret urned by the
426 * scanner.
427 */
428 class TokenType {
429 /**
430 * The type of the token that marks the end of the input.
431 */
432 static final TokenType EOF = new TokenType_EOF('EOF', 0, null, "");
433 static final TokenType DOUBLE = new TokenType.con1('DOUBLE', 1);
434 static final TokenType HEXADECIMAL = new TokenType.con1('HEXADECIMAL', 2);
435 static final TokenType IDENTIFIER = new TokenType.con1('IDENTIFIER', 3);
436 static final TokenType INT = new TokenType.con1('INT', 4);
437 static final TokenType KEYWORD = new TokenType.con1('KEYWORD', 5);
438 static final TokenType MULTI_LINE_COMMENT = new TokenType.con1('MULTI_LINE_COM MENT', 6);
439 static final TokenType SCRIPT_TAG = new TokenType.con1('SCRIPT_TAG', 7);
440 static final TokenType SINGLE_LINE_COMMENT = new TokenType.con1('SINGLE_LINE_C OMMENT', 8);
441 static final TokenType STRING = new TokenType.con1('STRING', 9);
442 static final TokenType AMPERSAND = new TokenType.con2('AMPERSAND', 10, TokenCl ass.BITWISE_AND_OPERATOR, "&");
443 static final TokenType AMPERSAND_AMPERSAND = new TokenType.con2('AMPERSAND_AMP ERSAND', 11, TokenClass.LOGICAL_AND_OPERATOR, "&&");
444 static final TokenType AMPERSAND_EQ = new TokenType.con2('AMPERSAND_EQ', 12, T okenClass.ASSIGNMENT_OPERATOR, "&=");
445 static final TokenType AT = new TokenType.con2('AT', 13, null, "@");
446 static final TokenType BANG = new TokenType.con2('BANG', 14, TokenClass.UNARY_ PREFIX_OPERATOR, "!");
447 static final TokenType BANG_EQ = new TokenType.con2('BANG_EQ', 15, TokenClass. EQUALITY_OPERATOR, "!=");
448 static final TokenType BAR = new TokenType.con2('BAR', 16, TokenClass.BITWISE_ OR_OPERATOR, "|");
449 static final TokenType BAR_BAR = new TokenType.con2('BAR_BAR', 17, TokenClass. LOGICAL_OR_OPERATOR, "||");
450 static final TokenType BAR_EQ = new TokenType.con2('BAR_EQ', 18, TokenClass.AS SIGNMENT_OPERATOR, "|=");
451 static final TokenType COLON = new TokenType.con2('COLON', 19, null, ":");
452 static final TokenType COMMA = new TokenType.con2('COMMA', 20, null, ",");
453 static final TokenType CARET = new TokenType.con2('CARET', 21, TokenClass.BITW ISE_XOR_OPERATOR, "^");
454 static final TokenType CARET_EQ = new TokenType.con2('CARET_EQ', 22, TokenClas s.ASSIGNMENT_OPERATOR, "^=");
455 static final TokenType CLOSE_CURLY_BRACKET = new TokenType.con2('CLOSE_CURLY_B RACKET', 23, null, "}");
456 static final TokenType CLOSE_PAREN = new TokenType.con2('CLOSE_PAREN', 24, nul l, ")");
457 static final TokenType CLOSE_SQUARE_BRACKET = new TokenType.con2('CLOSE_SQUARE _BRACKET', 25, null, "]");
458 static final TokenType EQ = new TokenType.con2('EQ', 26, TokenClass.ASSIGNMENT _OPERATOR, "=");
459 static final TokenType EQ_EQ = new TokenType.con2('EQ_EQ', 27, TokenClass.EQUA LITY_OPERATOR, "==");
460 static final TokenType FUNCTION = new TokenType.con2('FUNCTION', 28, null, "=> ");
461 static final TokenType GT = new TokenType.con2('GT', 29, TokenClass.RELATIONAL _OPERATOR, ">");
462 static final TokenType GT_EQ = new TokenType.con2('GT_EQ', 30, TokenClass.RELA TIONAL_OPERATOR, ">=");
463 static final TokenType GT_GT = new TokenType.con2('GT_GT', 31, TokenClass.SHIF T_OPERATOR, ">>");
464 static final TokenType GT_GT_EQ = new TokenType.con2('GT_GT_EQ', 32, TokenClas s.ASSIGNMENT_OPERATOR, ">>=");
465 static final TokenType HASH = new TokenType.con2('HASH', 33, null, "#");
466 static final TokenType INDEX = new TokenType.con2('INDEX', 34, TokenClass.UNAR Y_POSTFIX_OPERATOR, "[]");
467 static final TokenType INDEX_EQ = new TokenType.con2('INDEX_EQ', 35, TokenClas s.UNARY_POSTFIX_OPERATOR, "[]=");
468 static final TokenType IS = new TokenType.con2('IS', 36, TokenClass.RELATIONAL _OPERATOR, "is");
469 static final TokenType LT = new TokenType.con2('LT', 37, TokenClass.RELATIONAL _OPERATOR, "<");
470 static final TokenType LT_EQ = new TokenType.con2('LT_EQ', 38, TokenClass.RELA TIONAL_OPERATOR, "<=");
471 static final TokenType LT_LT = new TokenType.con2('LT_LT', 39, TokenClass.SHIF T_OPERATOR, "<<");
472 static final TokenType LT_LT_EQ = new TokenType.con2('LT_LT_EQ', 40, TokenClas s.ASSIGNMENT_OPERATOR, "<<=");
473 static final TokenType MINUS = new TokenType.con2('MINUS', 41, TokenClass.ADDI TIVE_OPERATOR, "-");
474 static final TokenType MINUS_EQ = new TokenType.con2('MINUS_EQ', 42, TokenClas s.ASSIGNMENT_OPERATOR, "-=");
475 static final TokenType MINUS_MINUS = new TokenType.con2('MINUS_MINUS', 43, Tok enClass.UNARY_PREFIX_OPERATOR, "--");
476 static final TokenType OPEN_CURLY_BRACKET = new TokenType.con2('OPEN_CURLY_BRA CKET', 44, null, "{");
477 static final TokenType OPEN_PAREN = new TokenType.con2('OPEN_PAREN', 45, Token Class.UNARY_POSTFIX_OPERATOR, "(");
478 static final TokenType OPEN_SQUARE_BRACKET = new TokenType.con2('OPEN_SQUARE_B RACKET', 46, TokenClass.UNARY_POSTFIX_OPERATOR, "[");
479 static final TokenType PERCENT = new TokenType.con2('PERCENT', 47, TokenClass. MULTIPLICATIVE_OPERATOR, "%");
480 static final TokenType PERCENT_EQ = new TokenType.con2('PERCENT_EQ', 48, Token Class.ASSIGNMENT_OPERATOR, "%=");
481 static final TokenType PERIOD = new TokenType.con2('PERIOD', 49, TokenClass.UN ARY_POSTFIX_OPERATOR, ".");
482 static final TokenType PERIOD_PERIOD = new TokenType.con2('PERIOD_PERIOD', 50, TokenClass.CASCADE_OPERATOR, "..");
483 static final TokenType PLUS = new TokenType.con2('PLUS', 51, TokenClass.ADDITI VE_OPERATOR, "+");
484 static final TokenType PLUS_EQ = new TokenType.con2('PLUS_EQ', 52, TokenClass. ASSIGNMENT_OPERATOR, "+=");
485 static final TokenType PLUS_PLUS = new TokenType.con2('PLUS_PLUS', 53, TokenCl ass.UNARY_PREFIX_OPERATOR, "++");
486 static final TokenType QUESTION = new TokenType.con2('QUESTION', 54, TokenClas s.CONDITIONAL_OPERATOR, "?");
487 static final TokenType SEMICOLON = new TokenType.con2('SEMICOLON', 55, null, " ;");
488 static final TokenType SLASH = new TokenType.con2('SLASH', 56, TokenClass.MULT IPLICATIVE_OPERATOR, "/");
489 static final TokenType SLASH_EQ = new TokenType.con2('SLASH_EQ', 57, TokenClas s.ASSIGNMENT_OPERATOR, "/=");
490 static final TokenType STAR = new TokenType.con2('STAR', 58, TokenClass.MULTIP LICATIVE_OPERATOR, "*");
491 static final TokenType STAR_EQ = new TokenType.con2('STAR_EQ', 59, TokenClass. ASSIGNMENT_OPERATOR, "*=");
492 static final TokenType STRING_INTERPOLATION_EXPRESSION = new TokenType.con2('S TRING_INTERPOLATION_EXPRESSION', 60, null, "\${");
493 static final TokenType STRING_INTERPOLATION_IDENTIFIER = new TokenType.con2('S TRING_INTERPOLATION_IDENTIFIER', 61, null, "\$");
494 static final TokenType TILDE = new TokenType.con2('TILDE', 62, TokenClass.UNAR Y_PREFIX_OPERATOR, "~");
495 static final TokenType TILDE_SLASH = new TokenType.con2('TILDE_SLASH', 63, Tok enClass.MULTIPLICATIVE_OPERATOR, "~/");
496 static final TokenType TILDE_SLASH_EQ = new TokenType.con2('TILDE_SLASH_EQ', 6 4, TokenClass.ASSIGNMENT_OPERATOR, "~/=");
497 static final TokenType BACKPING = new TokenType.con2('BACKPING', 65, null, "`" );
498 static final TokenType BACKSLASH = new TokenType.con2('BACKSLASH', 66, null, " \\");
499 static final TokenType PERIOD_PERIOD_PERIOD = new TokenType.con2('PERIOD_PERIO D_PERIOD', 67, null, "...");
500 static final List<TokenType> values = [EOF, DOUBLE, HEXADECIMAL, IDENTIFIER, I NT, KEYWORD, MULTI_LINE_COMMENT, SCRIPT_TAG, SINGLE_LINE_COMMENT, STRING, AMPERS AND, AMPERSAND_AMPERSAND, AMPERSAND_EQ, AT, BANG, BANG_EQ, BAR, BAR_BAR, BAR_EQ, COLON, COMMA, CARET, CARET_EQ, CLOSE_CURLY_BRACKET, CLOSE_PAREN, CLOSE_SQUARE_B RACKET, EQ, EQ_EQ, FUNCTION, GT, GT_EQ, GT_GT, GT_GT_EQ, HASH, INDEX, INDEX_EQ, IS, LT, LT_EQ, LT_LT, LT_LT_EQ, MINUS, MINUS_EQ, MINUS_MINUS, OPEN_CURLY_BRACKET , OPEN_PAREN, OPEN_SQUARE_BRACKET, PERCENT, PERCENT_EQ, PERIOD, PERIOD_PERIOD, P LUS, PLUS_EQ, PLUS_PLUS, QUESTION, SEMICOLON, SLASH, SLASH_EQ, STAR, STAR_EQ, ST RING_INTERPOLATION_EXPRESSION, STRING_INTERPOLATION_IDENTIFIER, TILDE, TILDE_SLA SH, TILDE_SLASH_EQ, BACKPING, BACKSLASH, PERIOD_PERIOD_PERIOD];
501 String __name;
502 int __ordinal = 0;
503 /**
504 * The class of the token.
505 */
506 TokenClass _tokenClass;
507 /**
508 * The lexeme that defines this type of token, or {@code null} if there is mor e than one possible
509 * lexeme for this type of token.
510 */
511 String _lexeme;
512 TokenType.con1(String ___name, int ___ordinal) {
513 _jtd_constructor_236_impl(___name, ___ordinal);
514 }
515 _jtd_constructor_236_impl(String ___name, int ___ordinal) {
516 _jtd_constructor_237_impl(___name, ___ordinal, TokenClass.NO_CLASS, null);
517 }
518 TokenType.con2(String ___name, int ___ordinal, TokenClass tokenClass2, String lexeme2) {
519 _jtd_constructor_237_impl(___name, ___ordinal, tokenClass2, lexeme2);
520 }
521 _jtd_constructor_237_impl(String ___name, int ___ordinal, TokenClass tokenClas s2, String lexeme2) {
522 __name = ___name;
523 __ordinal = ___ordinal;
524 this._tokenClass = tokenClass2 == null ? TokenClass.NO_CLASS : tokenClass2;
525 this._lexeme = lexeme2;
526 }
527 /**
528 * Return the lexeme that defines this type of token, or {@code null} if there is more than one
529 * possible lexeme for this type of token.
530 * @return the lexeme that defines this type of token
531 */
532 String get lexeme => _lexeme;
533 /**
534 * Return the precedence of the token, or {@code 0} if the token does not repr esent an operator.
535 * @return the precedence of the token
536 */
537 int get precedence => _tokenClass.precedence;
538 /**
539 * Return {@code true} if this type of token represents an additive operator.
540 * @return {@code true} if this type of token represents an additive operator
541 */
542 bool isAdditiveOperator() => identical(_tokenClass, TokenClass.ADDITIVE_OPERAT OR);
543 /**
544 * Return {@code true} if this type of token represents an assignment operator .
545 * @return {@code true} if this type of token represents an assignment operato r
546 */
547 bool isAssignmentOperator() => identical(_tokenClass, TokenClass.ASSIGNMENT_OP ERATOR);
548 /**
549 * Return {@code true} if this type of token represents an associative operato r. An associative
550 * operator is an operator for which the following equality is true:{@code (a * b) * c == a * (b * c)}. In other words, if the result of applying the operator to
551 * multiple operands does not depend on the order in which those applications occur.
552 * <p>
553 * Note: This method considers the logical-and and logical-or operators to be associative, even
554 * though the order in which the application of those operators can have an ef fect because
555 * evaluation of the right-hand operand is conditional.
556 * @return {@code true} if this type of token represents an associative operat or
557 */
558 bool isAssociativeOperator() => identical(this, AMPERSAND) || identical(this, AMPERSAND_AMPERSAND) || identical(this, BAR) || identical(this, BAR_BAR) || iden tical(this, CARET) || identical(this, PLUS) || identical(this, STAR);
559 /**
560 * Return {@code true} if this type of token represents an equality operator.
561 * @return {@code true} if this type of token represents an equality operator
562 */
563 bool isEqualityOperator() => identical(_tokenClass, TokenClass.EQUALITY_OPERAT OR);
564 /**
565 * Return {@code true} if this type of token represents an increment operator.
566 * @return {@code true} if this type of token represents an increment operator
567 */
568 bool isIncrementOperator() => identical(_lexeme, "++") || identical(_lexeme, " --");
569 /**
570 * Return {@code true} if this type of token represents a multiplicative opera tor.
571 * @return {@code true} if this type of token represents a multiplicative oper ator
572 */
573 bool isMultiplicativeOperator() => identical(_tokenClass, TokenClass.MULTIPLIC ATIVE_OPERATOR);
574 /**
575 * Return {@code true} if this token type represents an operator.
576 * @return {@code true} if this token type represents an operator
577 */
578 bool isOperator() => _tokenClass != TokenClass.NO_CLASS && this != OPEN_PAREN && this != OPEN_SQUARE_BRACKET && this != PERIOD;
579 /**
580 * Return {@code true} if this type of token represents a relational operator.
581 * @return {@code true} if this type of token represents a relational operator
582 */
583 bool isRelationalOperator() => identical(_tokenClass, TokenClass.RELATIONAL_OP ERATOR);
584 /**
585 * Return {@code true} if this type of token represents a shift operator.
586 * @return {@code true} if this type of token represents a shift operator
587 */
588 bool isShiftOperator() => identical(_tokenClass, TokenClass.SHIFT_OPERATOR);
589 /**
590 * Return {@code true} if this type of token represents a unary postfix operat or.
591 * @return {@code true} if this type of token represents a unary postfix opera tor
592 */
593 bool isUnaryPostfixOperator() => identical(_tokenClass, TokenClass.UNARY_POSTF IX_OPERATOR);
594 /**
595 * Return {@code true} if this type of token represents a unary prefix operato r.
596 * @return {@code true} if this type of token represents a unary prefix operat or
597 */
598 bool isUnaryPrefixOperator() => identical(_tokenClass, TokenClass.UNARY_PREFIX _OPERATOR);
599 /**
600 * Return {@code true} if this token type represents an operator that can be d efined by users.
601 * @return {@code true} if this token type represents an operator that can be defined by users
602 */
603 bool isUserDefinableOperator() => identical(_lexeme, "==") || identical(_lexem e, "~") || identical(_lexeme, "[]") || identical(_lexeme, "[]=") || identical(_l exeme, "*") || identical(_lexeme, "/") || identical(_lexeme, "%") || identical(_ lexeme, "~/") || identical(_lexeme, "+") || identical(_lexeme, "-") || identical (_lexeme, "<<") || identical(_lexeme, ">>") || identical(_lexeme, ">=") || ident ical(_lexeme, ">") || identical(_lexeme, "<=") || identical(_lexeme, "<") || ide ntical(_lexeme, "&") || identical(_lexeme, "^") || identical(_lexeme, "|");
604 String toString() => __name;
605 }
606 class TokenType_EOF extends TokenType {
607 TokenType_EOF(String ___name, int ___ordinal, TokenClass arg0, String arg1) : super.con2(___name, ___ordinal, arg0, arg1);
608 String toString() => "-eof-";
609 }
610 /**
611 * Instances of the class {@code TokenWithComment} represent a string token that is preceded by
612 * comments.
613 */
614 class StringTokenWithComment extends StringToken {
615 /**
616 * The first comment in the list of comments that precede this token.
617 */
618 Token _precedingComment;
619 /**
620 * Initialize a newly created token to have the given type and offset and to b e preceded by the
621 * comments reachable from the given comment.
622 * @param type the type of the token
623 * @param offset the offset from the beginning of the file to the first charac ter in the token
624 * @param precedingComment the first comment in the list of comments that prec ede this token
625 */
626 StringTokenWithComment(TokenType type, String value, int offset, Token precedi ngComment) : super(type, value, offset) {
627 this._precedingComment = precedingComment;
628 }
629 Token get precedingComments => _precedingComment;
630 }
631 /**
632 * Instances of the class {@code BeginToken} represent the opening half of a gro uping pair of
633 * tokens. This is used for curly brackets ('{'), parentheses ('('), and square brackets ('[').
634 */
635 class BeginToken extends Token {
636 /**
637 * The token that corresponds to this token.
638 */
639 Token _endToken;
640 /**
641 * Initialize a newly created token representing the opening half of a groupin g pair of tokens.
642 * @param type the type of the token
643 * @param offset the offset from the beginning of the file to the first charac ter in the token
644 */
645 BeginToken(TokenType type, int offset) : super(type, offset) {
646 assert((identical(type, TokenType.OPEN_CURLY_BRACKET) || identical(type, Tok enType.OPEN_PAREN) || identical(type, TokenType.OPEN_SQUARE_BRACKET) || identica l(type, TokenType.STRING_INTERPOLATION_EXPRESSION)));
647 }
648 /**
649 * Return the token that corresponds to this token.
650 * @return the token that corresponds to this token
651 */
652 Token get endToken => _endToken;
653 /**
654 * Set the token that corresponds to this token to the given token.
655 * @param token the token that corresponds to this token
656 */
657 void set endToken(Token token) {
658 this._endToken = token;
659 }
660 }
661 /**
662 * The enumeration {@code TokenClass} represents classes (or groups) of tokens w ith a similar use.
663 */
664 class TokenClass {
665 /**
666 * A value used to indicate that the token type is not part of any specific cl ass of token.
667 */
668 static final TokenClass NO_CLASS = new TokenClass.con1('NO_CLASS', 0);
669 /**
670 * A value used to indicate that the token type is an additive operator.
671 */
672 static final TokenClass ADDITIVE_OPERATOR = new TokenClass.con2('ADDITIVE_OPER ATOR', 1, 12);
673 /**
674 * A value used to indicate that the token type is an assignment operator.
675 */
676 static final TokenClass ASSIGNMENT_OPERATOR = new TokenClass.con2('ASSIGNMENT_ OPERATOR', 2, 1);
677 /**
678 * A value used to indicate that the token type is a bitwise-and operator.
679 */
680 static final TokenClass BITWISE_AND_OPERATOR = new TokenClass.con2('BITWISE_AN D_OPERATOR', 3, 8);
681 /**
682 * A value used to indicate that the token type is a bitwise-or operator.
683 */
684 static final TokenClass BITWISE_OR_OPERATOR = new TokenClass.con2('BITWISE_OR_ OPERATOR', 4, 6);
685 /**
686 * A value used to indicate that the token type is a bitwise-xor operator.
687 */
688 static final TokenClass BITWISE_XOR_OPERATOR = new TokenClass.con2('BITWISE_XO R_OPERATOR', 5, 7);
689 /**
690 * A value used to indicate that the token type is a cascade operator.
691 */
692 static final TokenClass CASCADE_OPERATOR = new TokenClass.con2('CASCADE_OPERAT OR', 6, 2);
693 /**
694 * A value used to indicate that the token type is a conditional operator.
695 */
696 static final TokenClass CONDITIONAL_OPERATOR = new TokenClass.con2('CONDITIONA L_OPERATOR', 7, 3);
697 /**
698 * A value used to indicate that the token type is an equality operator.
699 */
700 static final TokenClass EQUALITY_OPERATOR = new TokenClass.con2('EQUALITY_OPER ATOR', 8, 9);
701 /**
702 * A value used to indicate that the token type is a logical-and operator.
703 */
704 static final TokenClass LOGICAL_AND_OPERATOR = new TokenClass.con2('LOGICAL_AN D_OPERATOR', 9, 5);
705 /**
706 * A value used to indicate that the token type is a logical-or operator.
707 */
708 static final TokenClass LOGICAL_OR_OPERATOR = new TokenClass.con2('LOGICAL_OR_ OPERATOR', 10, 4);
709 /**
710 * A value used to indicate that the token type is a multiplicative operator.
711 */
712 static final TokenClass MULTIPLICATIVE_OPERATOR = new TokenClass.con2('MULTIPL ICATIVE_OPERATOR', 11, 13);
713 /**
714 * A value used to indicate that the token type is a relational operator.
715 */
716 static final TokenClass RELATIONAL_OPERATOR = new TokenClass.con2('RELATIONAL_ OPERATOR', 12, 10);
717 /**
718 * A value used to indicate that the token type is a shift operator.
719 */
720 static final TokenClass SHIFT_OPERATOR = new TokenClass.con2('SHIFT_OPERATOR', 13, 11);
721 /**
722 * A value used to indicate that the token type is a unary operator.
723 */
724 static final TokenClass UNARY_POSTFIX_OPERATOR = new TokenClass.con2('UNARY_PO STFIX_OPERATOR', 14, 15);
725 /**
726 * A value used to indicate that the token type is a unary operator.
727 */
728 static final TokenClass UNARY_PREFIX_OPERATOR = new TokenClass.con2('UNARY_PRE FIX_OPERATOR', 15, 14);
729 static final List<TokenClass> values = [NO_CLASS, ADDITIVE_OPERATOR, ASSIGNMEN T_OPERATOR, BITWISE_AND_OPERATOR, BITWISE_OR_OPERATOR, BITWISE_XOR_OPERATOR, CAS CADE_OPERATOR, CONDITIONAL_OPERATOR, EQUALITY_OPERATOR, LOGICAL_AND_OPERATOR, LO GICAL_OR_OPERATOR, MULTIPLICATIVE_OPERATOR, RELATIONAL_OPERATOR, SHIFT_OPERATOR, UNARY_POSTFIX_OPERATOR, UNARY_PREFIX_OPERATOR];
730 String __name;
731 int __ordinal = 0;
732 /**
733 * The precedence of tokens of this class, or {@code 0} if the such tokens do not represent an
734 * operator.
735 */
736 int _precedence = 0;
737 TokenClass.con1(String ___name, int ___ordinal) {
738 _jtd_constructor_234_impl(___name, ___ordinal);
739 }
740 _jtd_constructor_234_impl(String ___name, int ___ordinal) {
741 _jtd_constructor_235_impl(___name, ___ordinal, 0);
742 }
743 TokenClass.con2(String ___name, int ___ordinal, int precedence2) {
744 _jtd_constructor_235_impl(___name, ___ordinal, precedence2);
745 }
746 _jtd_constructor_235_impl(String ___name, int ___ordinal, int precedence2) {
747 __name = ___name;
748 __ordinal = ___ordinal;
749 this._precedence = precedence2;
750 }
751 /**
752 * Return the precedence of tokens of this class, or {@code 0} if the such tok ens do not represent
753 * an operator.
754 * @return the precedence of tokens of this class
755 */
756 int get precedence => _precedence;
757 String toString() => __name;
758 }
759 /**
760 * Instances of the class {@code StringScanner} implement a scanner that reads f rom a string. The
761 * scanning logic is in the superclass.
762 */
763 class StringScanner extends AbstractScanner {
764 /**
765 * The offset from the beginning of the file to the beginning of the source be ing scanned.
766 */
767 int _offsetDelta = 0;
768 /**
769 * The string from which characters will be read.
770 */
771 String _string;
772 /**
773 * The number of characters in the string.
774 */
775 int _stringLength = 0;
776 /**
777 * The index, relative to the string, of the last character that was read.
778 */
779 int _charOffset = 0;
780 /**
781 * Initialize a newly created scanner to scan the characters in the given stri ng.
782 * @param source the source being scanned
783 * @param string the string from which characters will be read
784 * @param errorListener the error listener that will be informed of any errors that are found
785 */
786 StringScanner(Source source, String string, AnalysisErrorListener errorListene r) : super(source, errorListener) {
787 this._offsetDelta = 0;
788 this._string = string;
789 this._stringLength = string.length;
790 this._charOffset = -1;
791 }
792 int get offset => _offsetDelta + _charOffset;
793 /**
794 * Record that the source begins on the given line and column at the given off set. The line starts
795 * for lines before the given line will not be correct.
796 * <p>
797 * This method must be invoked at most one time and must be invoked before sca nning begins. The
798 * values provided must be sensible. The results are undefined if these condit ions are violated.
799 * @param line the one-based index of the line containing the first character of the source
800 * @param column the one-based index of the column in which the first characte r of the source
801 * occurs
802 * @param offset the zero-based offset from the beginning of the larger contex t to the first
803 * character of the source
804 */
805 void setSourceStart(int line, int column, int offset) {
806 if (line < 1 || column < 1 || offset < 0 || (line + column - 2) >= offset) {
807 return;
808 }
809 _offsetDelta = 1;
810 for (int i = 2; i < line; i++) {
811 recordStartOfLine();
812 }
813 _offsetDelta = offset - column + 1;
814 recordStartOfLine();
815 _offsetDelta = offset;
816 }
817 int advance() {
818 if (_charOffset + 1 >= _stringLength) {
819 return -1;
820 }
821 return _string.codeUnitAt(++_charOffset);
822 }
823 String getString(int start, int endDelta) => _string.substring(start - _offset Delta, _charOffset + 1 + endDelta);
824 int peek() {
825 if (_charOffset + 1 >= _string.length) {
826 return -1;
827 }
828 return _string.codeUnitAt(_charOffset + 1);
829 }
830 }
831 /**
832 * The abstract class {@code AbstractScanner} implements a scanner for Dart code . Subclasses are 286 * The abstract class {@code AbstractScanner} implements a scanner for Dart code . Subclasses are
833 * required to implement the interface used to access the characters being scann ed. 287 * required to implement the interface used to access the characters being scann ed.
834 * <p> 288 * <p>
835 * The lexical structure of Dart is ambiguous without knowledge of the context i n which a token is 289 * The lexical structure of Dart is ambiguous without knowledge of the context i n which a token is
836 * being scanned. For example, without context we cannot determine whether sourc e of the form "<<" 290 * being scanned. For example, without context we cannot determine whether sourc e of the form "<<"
837 * should be scanned as a single left-shift operator or as two left angle bracke ts. This scanner 291 * should be scanned as a single left-shift operator or as two left angle bracke ts. This scanner
838 * does not have any context, so it always resolves such conflicts by scanning t he longest possible 292 * does not have any context, so it always resolves such conflicts by scanning t he longest possible
839 * token. 293 * token.
840 */ 294 */
841 abstract class AbstractScanner { 295 abstract class AbstractScanner {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
913 /** 367 /**
914 * Return {@code true} if any unmatched groups were found during the parse. 368 * Return {@code true} if any unmatched groups were found during the parse.
915 * @return {@code true} if any unmatched groups were found during the parse 369 * @return {@code true} if any unmatched groups were found during the parse
916 */ 370 */
917 bool hasUnmatchedGroups() => _hasUnmatchedGroups2; 371 bool hasUnmatchedGroups() => _hasUnmatchedGroups2;
918 /** 372 /**
919 * Scan the source code to produce a list of tokens representing the source. 373 * Scan the source code to produce a list of tokens representing the source.
920 * @return the first token in the list of tokens that were produced 374 * @return the first token in the list of tokens that were produced
921 */ 375 */
922 Token tokenize() { 376 Token tokenize() {
923 int startTime = System.currentTimeMillis();
924 int next = advance(); 377 int next = advance();
925 while (next != -1) { 378 while (next != -1) {
926 next = bigSwitch(next); 379 next = bigSwitch(next);
927 } 380 }
928 appendEofToken(); 381 appendEofToken();
929 int endTime = System.currentTimeMillis();
930 Instrumentation.metric2("Engine-Scanner", endTime - startTime).with3("chars" , offset).log();
931 return firstToken(); 382 return firstToken();
932 } 383 }
933 /** 384 /**
934 * Advance the current position and return the character at the new current po sition. 385 * Advance the current position and return the character at the new current po sition.
935 * @return the character at the new current position 386 * @return the character at the new current position
936 */ 387 */
937 int advance(); 388 int advance();
938 /** 389 /**
939 * Return the substring of the source code between the start offset and the mo dified current 390 * Return the substring of the source code between the start offset and the mo dified current
940 * position. The current position is modified by adding the end delta. 391 * position. The current position is modified by adding the end delta.
(...skipping 28 matching lines...) Expand all
969 _groupingStack.add(token); 420 _groupingStack.add(token);
970 } 421 }
971 void appendCommentToken(TokenType type, String value) { 422 void appendCommentToken(TokenType type, String value) {
972 if (_firstComment == null) { 423 if (_firstComment == null) {
973 _firstComment = new StringToken(type, value, _tokenStart); 424 _firstComment = new StringToken(type, value, _tokenStart);
974 _lastComment = _firstComment; 425 _lastComment = _firstComment;
975 } else { 426 } else {
976 _lastComment = _lastComment.setNext(new StringToken(type, value, _tokenSta rt)); 427 _lastComment = _lastComment.setNext(new StringToken(type, value, _tokenSta rt));
977 } 428 }
978 } 429 }
979 void appendEndToken(TokenType type26, TokenType beginType) { 430 void appendEndToken(TokenType type31, TokenType beginType) {
980 Token token; 431 Token token;
981 if (_firstComment == null) { 432 if (_firstComment == null) {
982 token = new Token(type26, _tokenStart); 433 token = new Token(type31, _tokenStart);
983 } else { 434 } else {
984 token = new TokenWithComment(type26, _tokenStart, _firstComment); 435 token = new TokenWithComment(type31, _tokenStart, _firstComment);
985 _firstComment = null; 436 _firstComment = null;
986 _lastComment = null; 437 _lastComment = null;
987 } 438 }
988 _tail = _tail.setNext(token); 439 _tail = _tail.setNext(token);
989 int last = _groupingStack.length - 1; 440 int last = _groupingStack.length - 1;
990 if (last >= 0) { 441 if (last >= 0) {
991 BeginToken begin = _groupingStack[last]; 442 BeginToken begin = _groupingStack[last];
992 if (identical(begin.type, beginType)) { 443 if (identical(begin.type, beginType)) {
993 begin.endToken = token; 444 begin.endToken = token;
994 _groupingStack.removeAt(last); 445 _groupingStack.removeAt(last);
(...skipping 741 matching lines...) Expand 10 before | Expand all | Expand 10 after
1736 next = advance(); 1187 next = advance();
1737 if (next == 0x2F) { 1188 if (next == 0x2F) {
1738 return select(0x3D, TokenType.TILDE_SLASH_EQ, TokenType.TILDE_SLASH); 1189 return select(0x3D, TokenType.TILDE_SLASH_EQ, TokenType.TILDE_SLASH);
1739 } else { 1190 } else {
1740 appendToken(TokenType.TILDE); 1191 appendToken(TokenType.TILDE);
1741 return next; 1192 return next;
1742 } 1193 }
1743 } 1194 }
1744 } 1195 }
1745 /** 1196 /**
1197 * Instances of the class {@code StringToken} represent a token whose value is i ndependent of it's
1198 * type.
1199 */
1200 class StringToken extends Token {
1201 /**
1202 * The lexeme represented by this token.
1203 */
1204 String _value2;
1205 /**
1206 * Initialize a newly created token to represent a token of the given type wit h the given value.
1207 * @param type the type of the token
1208 * @param value the lexeme represented by this token
1209 * @param offset the offset from the beginning of the file to the first charac ter in the token
1210 */
1211 StringToken(TokenType type, String value, int offset) : super(type, offset) {
1212 this._value2 = value;
1213 }
1214 String get lexeme => _value2;
1215 String value() => _value2;
1216 }
1217 /**
1218 * Instances of the class {@code CharBufferScanner} implement a scanner that rea ds from a character
1219 * buffer. The scanning logic is in the superclass.
1220 */
1221 class CharBufferScanner extends AbstractScanner {
1222 /**
1223 * The buffer from which characters will be read.
1224 */
1225 CharBuffer _buffer;
1226 /**
1227 * The number of characters in the buffer.
1228 */
1229 int _bufferLength = 0;
1230 /**
1231 * The index of the last character that was read.
1232 */
1233 int _charOffset = 0;
1234 /**
1235 * Initialize a newly created scanner to scan the characters in the given char acter buffer.
1236 * @param source the source being scanned
1237 * @param buffer the buffer from which characters will be read
1238 * @param errorListener the error listener that will be informed of any errors that are found
1239 */
1240 CharBufferScanner(Source source, CharBuffer buffer, AnalysisErrorListener erro rListener) : super(source, errorListener) {
1241 this._buffer = buffer;
1242 this._bufferLength = buffer.length();
1243 this._charOffset = -1;
1244 }
1245 int get offset => _charOffset;
1246 int advance() {
1247 if (_charOffset + 1 >= _bufferLength) {
1248 return -1;
1249 }
1250 return _buffer.charAt(++_charOffset);
1251 }
1252 String getString(int start, int endDelta) => _buffer.subSequence(start, _charO ffset + 1 + endDelta).toString();
1253 int peek() {
1254 if (_charOffset + 1 >= _buffer.length()) {
1255 return -1;
1256 }
1257 return _buffer.charAt(_charOffset + 1);
1258 }
1259 }
1260 /**
1261 * Instances of the class {@code TokenWithComment} represent a normal token that is preceded by
1262 * comments.
1263 */
1264 class TokenWithComment extends Token {
1265 /**
1266 * The first comment in the list of comments that precede this token.
1267 */
1268 Token _precedingComment;
1269 /**
1270 * Initialize a newly created token to have the given type and offset and to b e preceded by the
1271 * comments reachable from the given comment.
1272 * @param type the type of the token
1273 * @param offset the offset from the beginning of the file to the first charac ter in the token
1274 * @param precedingComment the first comment in the list of comments that prec ede this token
1275 */
1276 TokenWithComment(TokenType type, int offset, Token precedingComment) : super(t ype, offset) {
1277 this._precedingComment = precedingComment;
1278 }
1279 Token get precedingComments => _precedingComment;
1280 }
1281 /**
1282 * Instances of the class {@code Token} represent a token that was scanned from the input. Each
1283 * token knows which token follows it, acting as the head of a linked list of to kens.
1284 */
1285 class Token {
1286 /**
1287 * The type of the token.
1288 */
1289 TokenType _type;
1290 /**
1291 * The offset from the beginning of the file to the first character in the tok en.
1292 */
1293 int _offset = 0;
1294 /**
1295 * The previous token in the token stream.
1296 */
1297 Token _previous;
1298 /**
1299 * The next token in the token stream.
1300 */
1301 Token _next;
1302 /**
1303 * Initialize a newly created token to have the given type and offset.
1304 * @param type the type of the token
1305 * @param offset the offset from the beginning of the file to the first charac ter in the token
1306 */
1307 Token(TokenType type, int offset) {
1308 this._type = type;
1309 this._offset = offset;
1310 }
1311 /**
1312 * Return the offset from the beginning of the file to the character after las t character of the
1313 * token.
1314 * @return the offset from the beginning of the file to the first character af ter last character
1315 * of the token
1316 */
1317 int get end => _offset + length;
1318 /**
1319 * Return the number of characters in the node's source range.
1320 * @return the number of characters in the node's source range
1321 */
1322 int get length => lexeme.length;
1323 /**
1324 * Return the lexeme that represents this token.
1325 * @return the lexeme that represents this token
1326 */
1327 String get lexeme => _type.lexeme;
1328 /**
1329 * Return the next token in the token stream.
1330 * @return the next token in the token stream
1331 */
1332 Token get next => _next;
1333 /**
1334 * Return the offset from the beginning of the file to the first character in the token.
1335 * @return the offset from the beginning of the file to the first character in the token
1336 */
1337 int get offset => _offset;
1338 /**
1339 * Return the first comment in the list of comments that precede this token, o r {@code null} if
1340 * there are no comments preceding this token. Additional comments can be reac hed by following the
1341 * token stream using {@link #getNext()} until {@code null} is returned.
1342 * @return the first comment in the list of comments that precede this token
1343 */
1344 Token get precedingComments => null;
1345 /**
1346 * Return the previous token in the token stream.
1347 * @return the previous token in the token stream
1348 */
1349 Token get previous => _previous;
1350 /**
1351 * Return the type of the token.
1352 * @return the type of the token
1353 */
1354 TokenType get type => _type;
1355 /**
1356 * Return {@code true} if this token represents an operator.
1357 * @return {@code true} if this token represents an operator
1358 */
1359 bool isOperator() => _type.isOperator();
1360 /**
1361 * Return {@code true} if this token is a synthetic token. A synthetic token i s a token that was
1362 * introduced by the parser in order to recover from an error in the code. Syn thetic tokens always
1363 * have a length of zero ({@code 0}).
1364 * @return {@code true} if this token is a synthetic token
1365 */
1366 bool isSynthetic() => length == 0;
1367 /**
1368 * Return {@code true} if this token represents an operator that can be define d by users.
1369 * @return {@code true} if this token represents an operator that can be defin ed by users
1370 */
1371 bool isUserDefinableOperator() => _type.isUserDefinableOperator();
1372 /**
1373 * Set the next token in the token stream to the given token. This has the sid e-effect of setting
1374 * this token to be the previous token for the given token.
1375 * @param token the next token in the token stream
1376 * @return the token that was passed in
1377 */
1378 Token setNext(Token token) {
1379 _next = token;
1380 token.previous = this;
1381 return token;
1382 }
1383 /**
1384 * Set the next token in the token stream to the given token without changing which token is the
1385 * previous token for the given token.
1386 * @param token the next token in the token stream
1387 * @return the token that was passed in
1388 */
1389 Token setNextWithoutSettingPrevious(Token token) {
1390 _next = token;
1391 return token;
1392 }
1393 /**
1394 * Set the offset from the beginning of the file to the first character in the token to the given
1395 * offset.
1396 * @param offset the offset from the beginning of the file to the first charac ter in the token
1397 */
1398 void set offset(int offset4) {
1399 this._offset = offset4;
1400 }
1401 String toString() => lexeme;
1402 /**
1403 * Return the value of this token. For keyword tokens, this is the keyword ass ociated with the
1404 * token, for other tokens it is the lexeme associated with the token.
1405 * @return the value of this token
1406 */
1407 Object value() => _type.lexeme;
1408 /**
1409 * Set the previous token in the token stream to the given token.
1410 * @param previous the previous token in the token stream
1411 */
1412 void set previous(Token previous3) {
1413 this._previous = previous3;
1414 }
1415 }
1416 /**
1417 * Instances of the class {@code StringScanner} implement a scanner that reads f rom a string. The
1418 * scanning logic is in the superclass.
1419 */
1420 class StringScanner extends AbstractScanner {
1421 /**
1422 * The offset from the beginning of the file to the beginning of the source be ing scanned.
1423 */
1424 int _offsetDelta = 0;
1425 /**
1426 * The string from which characters will be read.
1427 */
1428 String _string;
1429 /**
1430 * The number of characters in the string.
1431 */
1432 int _stringLength = 0;
1433 /**
1434 * The index, relative to the string, of the last character that was read.
1435 */
1436 int _charOffset = 0;
1437 /**
1438 * Initialize a newly created scanner to scan the characters in the given stri ng.
1439 * @param source the source being scanned
1440 * @param string the string from which characters will be read
1441 * @param errorListener the error listener that will be informed of any errors that are found
1442 */
1443 StringScanner(Source source, String string, AnalysisErrorListener errorListene r) : super(source, errorListener) {
1444 this._offsetDelta = 0;
1445 this._string = string;
1446 this._stringLength = string.length;
1447 this._charOffset = -1;
1448 }
1449 int get offset => _offsetDelta + _charOffset;
1450 /**
1451 * Record that the source begins on the given line and column at the given off set. The line starts
1452 * for lines before the given line will not be correct.
1453 * <p>
1454 * This method must be invoked at most one time and must be invoked before sca nning begins. The
1455 * values provided must be sensible. The results are undefined if these condit ions are violated.
1456 * @param line the one-based index of the line containing the first character of the source
1457 * @param column the one-based index of the column in which the first characte r of the source
1458 * occurs
1459 * @param offset the zero-based offset from the beginning of the larger contex t to the first
1460 * character of the source
1461 */
1462 void setSourceStart(int line, int column, int offset) {
1463 if (line < 1 || column < 1 || offset < 0 || (line + column - 2) >= offset) {
1464 return;
1465 }
1466 _offsetDelta = 1;
1467 for (int i = 2; i < line; i++) {
1468 recordStartOfLine();
1469 }
1470 _offsetDelta = offset - column + 1;
1471 recordStartOfLine();
1472 _offsetDelta = offset;
1473 }
1474 int advance() {
1475 if (_charOffset + 1 >= _stringLength) {
1476 return -1;
1477 }
1478 return _string.codeUnitAt(++_charOffset);
1479 }
1480 String getString(int start, int endDelta) => _string.substring(start - _offset Delta, _charOffset + 1 + endDelta);
1481 int peek() {
1482 if (_charOffset + 1 >= _string.length) {
1483 return -1;
1484 }
1485 return _string.codeUnitAt(_charOffset + 1);
1486 }
1487 }
1488 /**
1489 * Instances of the class {@code BeginTokenWithComment} represent a begin token that is preceded by
1490 * comments.
1491 */
1492 class BeginTokenWithComment extends BeginToken {
1493 /**
1494 * The first comment in the list of comments that precede this token.
1495 */
1496 Token _precedingComment;
1497 /**
1498 * Initialize a newly created token to have the given type and offset and to b e preceded by the
1499 * comments reachable from the given comment.
1500 * @param type the type of the token
1501 * @param offset the offset from the beginning of the file to the first charac ter in the token
1502 * @param precedingComment the first comment in the list of comments that prec ede this token
1503 */
1504 BeginTokenWithComment(TokenType type, int offset, Token precedingComment) : su per(type, offset) {
1505 this._precedingComment = precedingComment;
1506 }
1507 Token get precedingComments => _precedingComment;
1508 }
1509 /**
1510 * Instances of the class {@code KeywordToken} represent a keyword in the langua ge.
1511 */
1512 class KeywordToken extends Token {
1513 /**
1514 * The keyword being represented by this token.
1515 */
1516 Keyword _keyword;
1517 /**
1518 * Initialize a newly created token to represent the given keyword.
1519 * @param keyword the keyword being represented by this token
1520 * @param offset the offset from the beginning of the file to the first charac ter in the token
1521 */
1522 KeywordToken(Keyword keyword, int offset) : super(TokenType.KEYWORD, offset) {
1523 this._keyword = keyword;
1524 }
1525 /**
1526 * Return the keyword being represented by this token.
1527 * @return the keyword being represented by this token
1528 */
1529 Keyword get keyword => _keyword;
1530 String get lexeme => _keyword.syntax;
1531 Keyword value() => _keyword;
1532 }
1533 /**
1534 * Instances of the class {@code BeginToken} represent the opening half of a gro uping pair of
1535 * tokens. This is used for curly brackets ('{'), parentheses ('('), and square brackets ('[').
1536 */
1537 class BeginToken extends Token {
1538 /**
1539 * The token that corresponds to this token.
1540 */
1541 Token _endToken;
1542 /**
1543 * Initialize a newly created token representing the opening half of a groupin g pair of tokens.
1544 * @param type the type of the token
1545 * @param offset the offset from the beginning of the file to the first charac ter in the token
1546 */
1547 BeginToken(TokenType type, int offset) : super(type, offset) {
1548 assert((identical(type, TokenType.OPEN_CURLY_BRACKET) || identical(type, Tok enType.OPEN_PAREN) || identical(type, TokenType.OPEN_SQUARE_BRACKET) || identica l(type, TokenType.STRING_INTERPOLATION_EXPRESSION)));
1549 }
1550 /**
1551 * Return the token that corresponds to this token.
1552 * @return the token that corresponds to this token
1553 */
1554 Token get endToken => _endToken;
1555 /**
1556 * Set the token that corresponds to this token to the given token.
1557 * @param token the token that corresponds to this token
1558 */
1559 void set endToken(Token token) {
1560 this._endToken = token;
1561 }
1562 }
1563 /**
1564 * The enumeration {@code TokenClass} represents classes (or groups) of tokens w ith a similar use.
1565 */
1566 class TokenClass {
1567 /**
1568 * A value used to indicate that the token type is not part of any specific cl ass of token.
1569 */
1570 static final TokenClass NO_CLASS = new TokenClass.con1('NO_CLASS', 0);
1571 /**
1572 * A value used to indicate that the token type is an additive operator.
1573 */
1574 static final TokenClass ADDITIVE_OPERATOR = new TokenClass.con2('ADDITIVE_OPER ATOR', 1, 12);
1575 /**
1576 * A value used to indicate that the token type is an assignment operator.
1577 */
1578 static final TokenClass ASSIGNMENT_OPERATOR = new TokenClass.con2('ASSIGNMENT_ OPERATOR', 2, 1);
1579 /**
1580 * A value used to indicate that the token type is a bitwise-and operator.
1581 */
1582 static final TokenClass BITWISE_AND_OPERATOR = new TokenClass.con2('BITWISE_AN D_OPERATOR', 3, 8);
1583 /**
1584 * A value used to indicate that the token type is a bitwise-or operator.
1585 */
1586 static final TokenClass BITWISE_OR_OPERATOR = new TokenClass.con2('BITWISE_OR_ OPERATOR', 4, 6);
1587 /**
1588 * A value used to indicate that the token type is a bitwise-xor operator.
1589 */
1590 static final TokenClass BITWISE_XOR_OPERATOR = new TokenClass.con2('BITWISE_XO R_OPERATOR', 5, 7);
1591 /**
1592 * A value used to indicate that the token type is a cascade operator.
1593 */
1594 static final TokenClass CASCADE_OPERATOR = new TokenClass.con2('CASCADE_OPERAT OR', 6, 2);
1595 /**
1596 * A value used to indicate that the token type is a conditional operator.
1597 */
1598 static final TokenClass CONDITIONAL_OPERATOR = new TokenClass.con2('CONDITIONA L_OPERATOR', 7, 3);
1599 /**
1600 * A value used to indicate that the token type is an equality operator.
1601 */
1602 static final TokenClass EQUALITY_OPERATOR = new TokenClass.con2('EQUALITY_OPER ATOR', 8, 9);
1603 /**
1604 * A value used to indicate that the token type is a logical-and operator.
1605 */
1606 static final TokenClass LOGICAL_AND_OPERATOR = new TokenClass.con2('LOGICAL_AN D_OPERATOR', 9, 5);
1607 /**
1608 * A value used to indicate that the token type is a logical-or operator.
1609 */
1610 static final TokenClass LOGICAL_OR_OPERATOR = new TokenClass.con2('LOGICAL_OR_ OPERATOR', 10, 4);
1611 /**
1612 * A value used to indicate that the token type is a multiplicative operator.
1613 */
1614 static final TokenClass MULTIPLICATIVE_OPERATOR = new TokenClass.con2('MULTIPL ICATIVE_OPERATOR', 11, 13);
1615 /**
1616 * A value used to indicate that the token type is a relational operator.
1617 */
1618 static final TokenClass RELATIONAL_OPERATOR = new TokenClass.con2('RELATIONAL_ OPERATOR', 12, 10);
1619 /**
1620 * A value used to indicate that the token type is a shift operator.
1621 */
1622 static final TokenClass SHIFT_OPERATOR = new TokenClass.con2('SHIFT_OPERATOR', 13, 11);
1623 /**
1624 * A value used to indicate that the token type is a unary operator.
1625 */
1626 static final TokenClass UNARY_POSTFIX_OPERATOR = new TokenClass.con2('UNARY_PO STFIX_OPERATOR', 14, 15);
1627 /**
1628 * A value used to indicate that the token type is a unary operator.
1629 */
1630 static final TokenClass UNARY_PREFIX_OPERATOR = new TokenClass.con2('UNARY_PRE FIX_OPERATOR', 15, 14);
1631 static final List<TokenClass> values = [NO_CLASS, ADDITIVE_OPERATOR, ASSIGNMEN T_OPERATOR, BITWISE_AND_OPERATOR, BITWISE_OR_OPERATOR, BITWISE_XOR_OPERATOR, CAS CADE_OPERATOR, CONDITIONAL_OPERATOR, EQUALITY_OPERATOR, LOGICAL_AND_OPERATOR, LO GICAL_OR_OPERATOR, MULTIPLICATIVE_OPERATOR, RELATIONAL_OPERATOR, SHIFT_OPERATOR, UNARY_POSTFIX_OPERATOR, UNARY_PREFIX_OPERATOR];
1632 String __name;
1633 int __ordinal = 0;
1634 /**
1635 * The precedence of tokens of this class, or {@code 0} if the such tokens do not represent an
1636 * operator.
1637 */
1638 int _precedence = 0;
1639 TokenClass.con1(String ___name, int ___ordinal) {
1640 _jtd_constructor_269_impl(___name, ___ordinal);
1641 }
1642 _jtd_constructor_269_impl(String ___name, int ___ordinal) {
1643 _jtd_constructor_270_impl(___name, ___ordinal, 0);
1644 }
1645 TokenClass.con2(String ___name, int ___ordinal, int precedence2) {
1646 _jtd_constructor_270_impl(___name, ___ordinal, precedence2);
1647 }
1648 _jtd_constructor_270_impl(String ___name, int ___ordinal, int precedence2) {
1649 __name = ___name;
1650 __ordinal = ___ordinal;
1651 this._precedence = precedence2;
1652 }
1653 /**
1654 * Return the precedence of tokens of this class, or {@code 0} if the such tok ens do not represent
1655 * an operator.
1656 * @return the precedence of tokens of this class
1657 */
1658 int get precedence => _precedence;
1659 String toString() => __name;
1660 }
1661 /**
1746 * Instances of the class {@code KeywordTokenWithComment} implement a keyword to ken that is preceded 1662 * Instances of the class {@code KeywordTokenWithComment} implement a keyword to ken that is preceded
1747 * by comments. 1663 * by comments.
1748 */ 1664 */
1749 class KeywordTokenWithComment extends KeywordToken { 1665 class KeywordTokenWithComment extends KeywordToken {
1750 /** 1666 /**
1751 * The first comment in the list of comments that precede this token. 1667 * The first comment in the list of comments that precede this token.
1752 */ 1668 */
1753 Token _precedingComment; 1669 Token _precedingComment;
1754 /** 1670 /**
1755 * Initialize a newly created token to to represent the given keyword and to b e preceded by the 1671 * Initialize a newly created token to to represent the given keyword and to b e preceded by the
1756 * comments reachable from the given comment. 1672 * comments reachable from the given comment.
1757 * @param keyword the keyword being represented by this token 1673 * @param keyword the keyword being represented by this token
1758 * @param offset the offset from the beginning of the file to the first charac ter in the token 1674 * @param offset the offset from the beginning of the file to the first charac ter in the token
1759 * @param precedingComment the first comment in the list of comments that prec ede this token 1675 * @param precedingComment the first comment in the list of comments that prec ede this token
1760 */ 1676 */
1761 KeywordTokenWithComment(Keyword keyword, int offset, Token precedingComment) : super(keyword, offset) { 1677 KeywordTokenWithComment(Keyword keyword, int offset, Token precedingComment) : super(keyword, offset) {
1762 this._precedingComment = precedingComment; 1678 this._precedingComment = precedingComment;
1763 } 1679 }
1764 Token get precedingComments => _precedingComment; 1680 Token get precedingComments => _precedingComment;
1765 } 1681 }
1766 /** 1682 /**
1767 * Instances of the abstract class {@code KeywordState} represent a state in a s tate machine used to 1683 * The enumeration {@code TokenType} defines the types of tokens that can be ret urned by the
1768 * scan keywords. 1684 * scanner.
1769 */ 1685 */
1770 class KeywordState { 1686 class TokenType {
1771 /** 1687 /**
1772 * An empty transition table used by leaf states. 1688 * The type of the token that marks the end of the input.
1773 */ 1689 */
1774 static List<KeywordState> _EMPTY_TABLE = new List<KeywordState>(26); 1690 static final TokenType EOF = new TokenType_EOF('EOF', 0, null, "");
1691 static final TokenType DOUBLE = new TokenType.con1('DOUBLE', 1);
1692 static final TokenType HEXADECIMAL = new TokenType.con1('HEXADECIMAL', 2);
1693 static final TokenType IDENTIFIER = new TokenType.con1('IDENTIFIER', 3);
1694 static final TokenType INT = new TokenType.con1('INT', 4);
1695 static final TokenType KEYWORD = new TokenType.con1('KEYWORD', 5);
1696 static final TokenType MULTI_LINE_COMMENT = new TokenType.con1('MULTI_LINE_COM MENT', 6);
1697 static final TokenType SCRIPT_TAG = new TokenType.con1('SCRIPT_TAG', 7);
1698 static final TokenType SINGLE_LINE_COMMENT = new TokenType.con1('SINGLE_LINE_C OMMENT', 8);
1699 static final TokenType STRING = new TokenType.con1('STRING', 9);
1700 static final TokenType AMPERSAND = new TokenType.con2('AMPERSAND', 10, TokenCl ass.BITWISE_AND_OPERATOR, "&");
1701 static final TokenType AMPERSAND_AMPERSAND = new TokenType.con2('AMPERSAND_AMP ERSAND', 11, TokenClass.LOGICAL_AND_OPERATOR, "&&");
1702 static final TokenType AMPERSAND_EQ = new TokenType.con2('AMPERSAND_EQ', 12, T okenClass.ASSIGNMENT_OPERATOR, "&=");
1703 static final TokenType AT = new TokenType.con2('AT', 13, null, "@");
1704 static final TokenType BANG = new TokenType.con2('BANG', 14, TokenClass.UNARY_ PREFIX_OPERATOR, "!");
1705 static final TokenType BANG_EQ = new TokenType.con2('BANG_EQ', 15, TokenClass. EQUALITY_OPERATOR, "!=");
1706 static final TokenType BAR = new TokenType.con2('BAR', 16, TokenClass.BITWISE_ OR_OPERATOR, "|");
1707 static final TokenType BAR_BAR = new TokenType.con2('BAR_BAR', 17, TokenClass. LOGICAL_OR_OPERATOR, "||");
1708 static final TokenType BAR_EQ = new TokenType.con2('BAR_EQ', 18, TokenClass.AS SIGNMENT_OPERATOR, "|=");
1709 static final TokenType COLON = new TokenType.con2('COLON', 19, null, ":");
1710 static final TokenType COMMA = new TokenType.con2('COMMA', 20, null, ",");
1711 static final TokenType CARET = new TokenType.con2('CARET', 21, TokenClass.BITW ISE_XOR_OPERATOR, "^");
1712 static final TokenType CARET_EQ = new TokenType.con2('CARET_EQ', 22, TokenClas s.ASSIGNMENT_OPERATOR, "^=");
1713 static final TokenType CLOSE_CURLY_BRACKET = new TokenType.con2('CLOSE_CURLY_B RACKET', 23, null, "}");
1714 static final TokenType CLOSE_PAREN = new TokenType.con2('CLOSE_PAREN', 24, nul l, ")");
1715 static final TokenType CLOSE_SQUARE_BRACKET = new TokenType.con2('CLOSE_SQUARE _BRACKET', 25, null, "]");
1716 static final TokenType EQ = new TokenType.con2('EQ', 26, TokenClass.ASSIGNMENT _OPERATOR, "=");
1717 static final TokenType EQ_EQ = new TokenType.con2('EQ_EQ', 27, TokenClass.EQUA LITY_OPERATOR, "==");
1718 static final TokenType FUNCTION = new TokenType.con2('FUNCTION', 28, null, "=> ");
1719 static final TokenType GT = new TokenType.con2('GT', 29, TokenClass.RELATIONAL _OPERATOR, ">");
1720 static final TokenType GT_EQ = new TokenType.con2('GT_EQ', 30, TokenClass.RELA TIONAL_OPERATOR, ">=");
1721 static final TokenType GT_GT = new TokenType.con2('GT_GT', 31, TokenClass.SHIF T_OPERATOR, ">>");
1722 static final TokenType GT_GT_EQ = new TokenType.con2('GT_GT_EQ', 32, TokenClas s.ASSIGNMENT_OPERATOR, ">>=");
1723 static final TokenType HASH = new TokenType.con2('HASH', 33, null, "#");
1724 static final TokenType INDEX = new TokenType.con2('INDEX', 34, TokenClass.UNAR Y_POSTFIX_OPERATOR, "[]");
1725 static final TokenType INDEX_EQ = new TokenType.con2('INDEX_EQ', 35, TokenClas s.UNARY_POSTFIX_OPERATOR, "[]=");
1726 static final TokenType IS = new TokenType.con2('IS', 36, TokenClass.RELATIONAL _OPERATOR, "is");
1727 static final TokenType LT = new TokenType.con2('LT', 37, TokenClass.RELATIONAL _OPERATOR, "<");
1728 static final TokenType LT_EQ = new TokenType.con2('LT_EQ', 38, TokenClass.RELA TIONAL_OPERATOR, "<=");
1729 static final TokenType LT_LT = new TokenType.con2('LT_LT', 39, TokenClass.SHIF T_OPERATOR, "<<");
1730 static final TokenType LT_LT_EQ = new TokenType.con2('LT_LT_EQ', 40, TokenClas s.ASSIGNMENT_OPERATOR, "<<=");
1731 static final TokenType MINUS = new TokenType.con2('MINUS', 41, TokenClass.ADDI TIVE_OPERATOR, "-");
1732 static final TokenType MINUS_EQ = new TokenType.con2('MINUS_EQ', 42, TokenClas s.ASSIGNMENT_OPERATOR, "-=");
1733 static final TokenType MINUS_MINUS = new TokenType.con2('MINUS_MINUS', 43, Tok enClass.UNARY_PREFIX_OPERATOR, "--");
1734 static final TokenType OPEN_CURLY_BRACKET = new TokenType.con2('OPEN_CURLY_BRA CKET', 44, null, "{");
1735 static final TokenType OPEN_PAREN = new TokenType.con2('OPEN_PAREN', 45, Token Class.UNARY_POSTFIX_OPERATOR, "(");
1736 static final TokenType OPEN_SQUARE_BRACKET = new TokenType.con2('OPEN_SQUARE_B RACKET', 46, TokenClass.UNARY_POSTFIX_OPERATOR, "[");
1737 static final TokenType PERCENT = new TokenType.con2('PERCENT', 47, TokenClass. MULTIPLICATIVE_OPERATOR, "%");
1738 static final TokenType PERCENT_EQ = new TokenType.con2('PERCENT_EQ', 48, Token Class.ASSIGNMENT_OPERATOR, "%=");
1739 static final TokenType PERIOD = new TokenType.con2('PERIOD', 49, TokenClass.UN ARY_POSTFIX_OPERATOR, ".");
1740 static final TokenType PERIOD_PERIOD = new TokenType.con2('PERIOD_PERIOD', 50, TokenClass.CASCADE_OPERATOR, "..");
1741 static final TokenType PLUS = new TokenType.con2('PLUS', 51, TokenClass.ADDITI VE_OPERATOR, "+");
1742 static final TokenType PLUS_EQ = new TokenType.con2('PLUS_EQ', 52, TokenClass. ASSIGNMENT_OPERATOR, "+=");
1743 static final TokenType PLUS_PLUS = new TokenType.con2('PLUS_PLUS', 53, TokenCl ass.UNARY_PREFIX_OPERATOR, "++");
1744 static final TokenType QUESTION = new TokenType.con2('QUESTION', 54, TokenClas s.CONDITIONAL_OPERATOR, "?");
1745 static final TokenType SEMICOLON = new TokenType.con2('SEMICOLON', 55, null, " ;");
1746 static final TokenType SLASH = new TokenType.con2('SLASH', 56, TokenClass.MULT IPLICATIVE_OPERATOR, "/");
1747 static final TokenType SLASH_EQ = new TokenType.con2('SLASH_EQ', 57, TokenClas s.ASSIGNMENT_OPERATOR, "/=");
1748 static final TokenType STAR = new TokenType.con2('STAR', 58, TokenClass.MULTIP LICATIVE_OPERATOR, "*");
1749 static final TokenType STAR_EQ = new TokenType.con2('STAR_EQ', 59, TokenClass. ASSIGNMENT_OPERATOR, "*=");
1750 static final TokenType STRING_INTERPOLATION_EXPRESSION = new TokenType.con2('S TRING_INTERPOLATION_EXPRESSION', 60, null, "\${");
1751 static final TokenType STRING_INTERPOLATION_IDENTIFIER = new TokenType.con2('S TRING_INTERPOLATION_IDENTIFIER', 61, null, "\$");
1752 static final TokenType TILDE = new TokenType.con2('TILDE', 62, TokenClass.UNAR Y_PREFIX_OPERATOR, "~");
1753 static final TokenType TILDE_SLASH = new TokenType.con2('TILDE_SLASH', 63, Tok enClass.MULTIPLICATIVE_OPERATOR, "~/");
1754 static final TokenType TILDE_SLASH_EQ = new TokenType.con2('TILDE_SLASH_EQ', 6 4, TokenClass.ASSIGNMENT_OPERATOR, "~/=");
1755 static final TokenType BACKPING = new TokenType.con2('BACKPING', 65, null, "`" );
1756 static final TokenType BACKSLASH = new TokenType.con2('BACKSLASH', 66, null, " \\");
1757 static final TokenType PERIOD_PERIOD_PERIOD = new TokenType.con2('PERIOD_PERIO D_PERIOD', 67, null, "...");
1758 static final List<TokenType> values = [EOF, DOUBLE, HEXADECIMAL, IDENTIFIER, I NT, KEYWORD, MULTI_LINE_COMMENT, SCRIPT_TAG, SINGLE_LINE_COMMENT, STRING, AMPERS AND, AMPERSAND_AMPERSAND, AMPERSAND_EQ, AT, BANG, BANG_EQ, BAR, BAR_BAR, BAR_EQ, COLON, COMMA, CARET, CARET_EQ, CLOSE_CURLY_BRACKET, CLOSE_PAREN, CLOSE_SQUARE_B RACKET, EQ, EQ_EQ, FUNCTION, GT, GT_EQ, GT_GT, GT_GT_EQ, HASH, INDEX, INDEX_EQ, IS, LT, LT_EQ, LT_LT, LT_LT_EQ, MINUS, MINUS_EQ, MINUS_MINUS, OPEN_CURLY_BRACKET , OPEN_PAREN, OPEN_SQUARE_BRACKET, PERCENT, PERCENT_EQ, PERIOD, PERIOD_PERIOD, P LUS, PLUS_EQ, PLUS_PLUS, QUESTION, SEMICOLON, SLASH, SLASH_EQ, STAR, STAR_EQ, ST RING_INTERPOLATION_EXPRESSION, STRING_INTERPOLATION_IDENTIFIER, TILDE, TILDE_SLA SH, TILDE_SLASH_EQ, BACKPING, BACKSLASH, PERIOD_PERIOD_PERIOD];
1759 String __name;
1760 int __ordinal = 0;
1775 /** 1761 /**
1776 * The initial state in the state machine. 1762 * The class of the token.
1777 */ 1763 */
1778 static KeywordState KEYWORD_STATE = createKeywordStateTable(); 1764 TokenClass _tokenClass;
1779 /** 1765 /**
1780 * Create the next state in the state machine where we have already recognized the subset of 1766 * The lexeme that defines this type of token, or {@code null} if there is mor e than one possible
1781 * strings in the given array of strings starting at the given offset and havi ng the given length. 1767 * lexeme for this type of token.
1782 * All of these strings have a common prefix and the next character is at the given start index.
1783 * @param start the index of the character in the strings used to transition t o a new state
1784 * @param strings an array containing all of the strings that will be recogniz ed by the state
1785 * machine
1786 * @param offset the offset of the first string in the array that has the pref ix that is assumed
1787 * to have been recognized by the time we reach the state being built
1788 * @param length the number of strings in the array that pass through the stat e being built
1789 * @return the state that was created
1790 */ 1768 */
1791 static KeywordState computeKeywordStateTable(int start, List<String> strings, int offset, int length12) { 1769 String _lexeme;
1792 List<KeywordState> result = new List<KeywordState>(26); 1770 TokenType.con1(String ___name, int ___ordinal) {
1793 assert(length12 != 0); 1771 _jtd_constructor_271_impl(___name, ___ordinal);
1794 int chunk = 0x0; 1772 }
1795 int chunkStart = -1; 1773 _jtd_constructor_271_impl(String ___name, int ___ordinal) {
1796 bool isLeaf = false; 1774 _jtd_constructor_272_impl(___name, ___ordinal, TokenClass.NO_CLASS, null);
1797 for (int i = offset; i < offset + length12; i++) { 1775 }
1798 if (strings[i].length == start) { 1776 TokenType.con2(String ___name, int ___ordinal, TokenClass tokenClass2, String lexeme2) {
1799 isLeaf = true; 1777 _jtd_constructor_272_impl(___name, ___ordinal, tokenClass2, lexeme2);
1800 } 1778 }
1801 if (strings[i].length > start) { 1779 _jtd_constructor_272_impl(String ___name, int ___ordinal, TokenClass tokenClas s2, String lexeme2) {
1802 int c = strings[i].codeUnitAt(start); 1780 __name = ___name;
1803 if (chunk != c) { 1781 __ordinal = ___ordinal;
1804 if (chunkStart != -1) { 1782 this._tokenClass = tokenClass2 == null ? TokenClass.NO_CLASS : tokenClass2;
1805 result[chunk - 0x61] = computeKeywordStateTable(start + 1, strings, chunkStart, i - chunkStart); 1783 this._lexeme = lexeme2;
1806 }
1807 chunkStart = i;
1808 chunk = c;
1809 }
1810 }
1811 }
1812 if (chunkStart != -1) {
1813 assert(result[chunk - 0x61] == null);
1814 result[chunk - 0x61] = computeKeywordStateTable(start + 1, strings, chunkS tart, offset + length12 - chunkStart);
1815 } else {
1816 assert(length12 == 1);
1817 return new KeywordState(_EMPTY_TABLE, strings[offset]);
1818 }
1819 if (isLeaf) {
1820 return new KeywordState(result, strings[offset]);
1821 } else {
1822 return new KeywordState(result, null);
1823 }
1824 } 1784 }
1825 /** 1785 /**
1826 * Create the initial state in the state machine. 1786 * Return the lexeme that defines this type of token, or {@code null} if there is more than one
1827 * @return the state that was created 1787 * possible lexeme for this type of token.
1788 * @return the lexeme that defines this type of token
1828 */ 1789 */
1829 static KeywordState createKeywordStateTable() { 1790 String get lexeme => _lexeme;
1830 List<Keyword> values2 = Keyword.values;
1831 List<String> strings = new List<String>(values2.length);
1832 for (int i = 0; i < values2.length; i++) {
1833 strings[i] = values2[i].syntax;
1834 }
1835 strings.sort();
1836 return computeKeywordStateTable(0, strings, 0, strings.length);
1837 }
1838 /** 1791 /**
1839 * A table mapping characters to the states to which those characters will tra nsition. (The index 1792 * Return the precedence of the token, or {@code 0} if the token does not repr esent an operator.
1840 * into the array is the offset from the character {@code 'a'} to the transiti oning character.) 1793 * @return the precedence of the token
1841 */ 1794 */
1842 List<KeywordState> _table; 1795 int get precedence => _tokenClass.precedence;
1843 /** 1796 /**
1844 * The keyword that is recognized by this state, or {@code null} if this state is not a terminal 1797 * Return {@code true} if this type of token represents an additive operator.
1845 * state. 1798 * @return {@code true} if this type of token represents an additive operator
1846 */ 1799 */
1847 Keyword _keyword2; 1800 bool isAdditiveOperator() => identical(_tokenClass, TokenClass.ADDITIVE_OPERAT OR);
1848 /** 1801 /**
1849 * Initialize a newly created state to have the given transitions and to recog nize the keyword 1802 * Return {@code true} if this type of token represents an assignment operator .
1850 * with the given syntax. 1803 * @return {@code true} if this type of token represents an assignment operato r
1851 * @param table a table mapping characters to the states to which those charac ters will transition
1852 * @param syntax the syntax of the keyword that is recognized by the state
1853 */ 1804 */
1854 KeywordState(List<KeywordState> table, String syntax) { 1805 bool isAssignmentOperator() => identical(_tokenClass, TokenClass.ASSIGNMENT_OP ERATOR);
1855 this._table = table;
1856 this._keyword2 = (syntax == null) ? null : Keyword.keywords[syntax];
1857 }
1858 /** 1806 /**
1859 * Return the keyword that was recognized by this state, or {@code null} if th is state does not 1807 * Return {@code true} if this type of token represents an associative operato r. An associative
1860 * recognized a keyword. 1808 * operator is an operator for which the following equality is true:{@code (a * b) * c == a * (b * c)}. In other words, if the result of applying the operator to
1861 * @return the keyword that was matched by reaching this state 1809 * multiple operands does not depend on the order in which those applications occur.
1810 * <p>
1811 * Note: This method considers the logical-and and logical-or operators to be associative, even
1812 * though the order in which the application of those operators can have an ef fect because
1813 * evaluation of the right-hand operand is conditional.
1814 * @return {@code true} if this type of token represents an associative operat or
1862 */ 1815 */
1863 Keyword keyword() => _keyword2; 1816 bool isAssociativeOperator() => identical(this, AMPERSAND) || identical(this, AMPERSAND_AMPERSAND) || identical(this, BAR) || identical(this, BAR_BAR) || iden tical(this, CARET) || identical(this, PLUS) || identical(this, STAR);
1864 /** 1817 /**
1865 * Return the state that follows this state on a transition of the given chara cter, or{@code null} if there is no valid state reachable from this state with s uch a transition. 1818 * Return {@code true} if this type of token represents an equality operator.
1866 * @param c the character used to transition from this state to another state 1819 * @return {@code true} if this type of token represents an equality operator
1867 * @return the state that follows this state on a transition of the given char acter
1868 */ 1820 */
1869 KeywordState next(int c) => _table[c - 0x61]; 1821 bool isEqualityOperator() => identical(_tokenClass, TokenClass.EQUALITY_OPERAT OR);
1822 /**
1823 * Return {@code true} if this type of token represents an increment operator.
1824 * @return {@code true} if this type of token represents an increment operator
1825 */
1826 bool isIncrementOperator() => identical(_lexeme, "++") || identical(_lexeme, " --");
1827 /**
1828 * Return {@code true} if this type of token represents a multiplicative opera tor.
1829 * @return {@code true} if this type of token represents a multiplicative oper ator
1830 */
1831 bool isMultiplicativeOperator() => identical(_tokenClass, TokenClass.MULTIPLIC ATIVE_OPERATOR);
1832 /**
1833 * Return {@code true} if this token type represents an operator.
1834 * @return {@code true} if this token type represents an operator
1835 */
1836 bool isOperator() => _tokenClass != TokenClass.NO_CLASS && this != OPEN_PAREN && this != OPEN_SQUARE_BRACKET && this != PERIOD;
1837 /**
1838 * Return {@code true} if this type of token represents a relational operator.
1839 * @return {@code true} if this type of token represents a relational operator
1840 */
1841 bool isRelationalOperator() => identical(_tokenClass, TokenClass.RELATIONAL_OP ERATOR);
1842 /**
1843 * Return {@code true} if this type of token represents a shift operator.
1844 * @return {@code true} if this type of token represents a shift operator
1845 */
1846 bool isShiftOperator() => identical(_tokenClass, TokenClass.SHIFT_OPERATOR);
1847 /**
1848 * Return {@code true} if this type of token represents a unary postfix operat or.
1849 * @return {@code true} if this type of token represents a unary postfix opera tor
1850 */
1851 bool isUnaryPostfixOperator() => identical(_tokenClass, TokenClass.UNARY_POSTF IX_OPERATOR);
1852 /**
1853 * Return {@code true} if this type of token represents a unary prefix operato r.
1854 * @return {@code true} if this type of token represents a unary prefix operat or
1855 */
1856 bool isUnaryPrefixOperator() => identical(_tokenClass, TokenClass.UNARY_PREFIX _OPERATOR);
1857 /**
1858 * Return {@code true} if this token type represents an operator that can be d efined by users.
1859 * @return {@code true} if this token type represents an operator that can be defined by users
1860 */
1861 bool isUserDefinableOperator() => identical(_lexeme, "==") || identical(_lexem e, "~") || identical(_lexeme, "[]") || identical(_lexeme, "[]=") || identical(_l exeme, "*") || identical(_lexeme, "/") || identical(_lexeme, "%") || identical(_ lexeme, "~/") || identical(_lexeme, "+") || identical(_lexeme, "-") || identical (_lexeme, "<<") || identical(_lexeme, ">>") || identical(_lexeme, ">=") || ident ical(_lexeme, ">") || identical(_lexeme, "<=") || identical(_lexeme, "<") || ide ntical(_lexeme, "&") || identical(_lexeme, "^") || identical(_lexeme, "|");
1862 String toString() => __name;
1870 } 1863 }
1864 class TokenType_EOF extends TokenType {
1865 TokenType_EOF(String ___name, int ___ordinal, TokenClass arg0, String arg1) : super.con2(___name, ___ordinal, arg0, arg1);
1866 String toString() => "-eof-";
1867 }
OLDNEW
« no previous file with comments | « pkg/analyzer-experimental/lib/src/generated/resolver.dart ('k') | pkg/analyzer-experimental/lib/src/generated/sdk.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698