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

Side by Side Diff: pkg/analyzer_experimental/lib/src/generated/parser.dart

Issue 17932005: New analyzer_experimental snapshot. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Disable resolver tests Created 7 years, 6 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 library engine.parser; 3 library engine.parser;
4 import 'dart:collection'; 4 import 'dart:collection';
5 import 'java_core.dart'; 5 import 'java_core.dart';
6 import 'java_engine.dart'; 6 import 'java_engine.dart';
7 import 'instrumentation.dart'; 7 import 'instrumentation.dart';
8 import 'error.dart'; 8 import 'error.dart';
9 import 'source.dart'; 9 import 'source.dart';
10 import 'scanner.dart'; 10 import 'scanner.dart';
11 import 'ast.dart'; 11 import 'ast.dart';
12 import 'utilities_dart.dart'; 12 import 'utilities_dart.dart';
13 /** 13 /**
14 * Instances of the class `CommentAndMetadata` implement a simple data-holder fo r a method 14 * Instances of the class `CommentAndMetadata` implement a simple data-holder fo r a method
15 * that needs to return multiple values. 15 * that needs to return multiple values.
16 *
16 * @coverage dart.engine.parser 17 * @coverage dart.engine.parser
17 */ 18 */
18 class CommentAndMetadata { 19 class CommentAndMetadata {
19 20
20 /** 21 /**
21 * The documentation comment that was parsed, or `null` if none was given. 22 * The documentation comment that was parsed, or `null` if none was given.
22 */ 23 */
23 Comment _comment; 24 Comment _comment;
24 25
25 /** 26 /**
26 * The metadata that was parsed. 27 * The metadata that was parsed.
27 */ 28 */
28 List<Annotation> _metadata; 29 List<Annotation> _metadata;
29 30
30 /** 31 /**
31 * Initialize a newly created holder with the given data. 32 * Initialize a newly created holder with the given data.
33 *
32 * @param comment the documentation comment that was parsed 34 * @param comment the documentation comment that was parsed
33 * @param metadata the metadata that was parsed 35 * @param metadata the metadata that was parsed
34 */ 36 */
35 CommentAndMetadata(Comment comment, List<Annotation> metadata) { 37 CommentAndMetadata(Comment comment, List<Annotation> metadata) {
36 this._comment = comment; 38 this._comment = comment;
37 this._metadata = metadata; 39 this._metadata = metadata;
38 } 40 }
39 41
40 /** 42 /**
41 * Return the documentation comment that was parsed, or `null` if none was giv en. 43 * Return the documentation comment that was parsed, or `null` if none was giv en.
44 *
42 * @return the documentation comment that was parsed 45 * @return the documentation comment that was parsed
43 */ 46 */
44 Comment get comment => _comment; 47 Comment get comment => _comment;
45 48
46 /** 49 /**
47 * Return the metadata that was parsed. If there was no metadata, then the lis t will be empty. 50 * Return the metadata that was parsed. If there was no metadata, then the lis t will be empty.
51 *
48 * @return the metadata that was parsed 52 * @return the metadata that was parsed
49 */ 53 */
50 List<Annotation> get metadata => _metadata; 54 List<Annotation> get metadata => _metadata;
51 } 55 }
52 /** 56 /**
53 * Instances of the class `FinalConstVarOrType` implement a simple data-holder f or a method 57 * Instances of the class `FinalConstVarOrType` implement a simple data-holder f or a method
54 * that needs to return multiple values. 58 * that needs to return multiple values.
59 *
55 * @coverage dart.engine.parser 60 * @coverage dart.engine.parser
56 */ 61 */
57 class FinalConstVarOrType { 62 class FinalConstVarOrType {
58 63
59 /** 64 /**
60 * The 'final', 'const' or 'var' keyword, or `null` if none was given. 65 * The 'final', 'const' or 'var' keyword, or `null` if none was given.
61 */ 66 */
62 Token _keyword; 67 Token _keyword;
63 68
64 /** 69 /**
65 * The type, of `null` if no type was specified. 70 * The type, of `null` if no type was specified.
66 */ 71 */
67 TypeName _type; 72 TypeName _type;
68 73
69 /** 74 /**
70 * Initialize a newly created holder with the given data. 75 * Initialize a newly created holder with the given data.
76 *
71 * @param keyword the 'final', 'const' or 'var' keyword 77 * @param keyword the 'final', 'const' or 'var' keyword
72 * @param type the type 78 * @param type the type
73 */ 79 */
74 FinalConstVarOrType(Token keyword, TypeName type) { 80 FinalConstVarOrType(Token keyword, TypeName type) {
75 this._keyword = keyword; 81 this._keyword = keyword;
76 this._type = type; 82 this._type = type;
77 } 83 }
78 84
79 /** 85 /**
80 * Return the 'final', 'const' or 'var' keyword, or `null` if none was given. 86 * Return the 'final', 'const' or 'var' keyword, or `null` if none was given.
87 *
81 * @return the 'final', 'const' or 'var' keyword 88 * @return the 'final', 'const' or 'var' keyword
82 */ 89 */
83 Token get keyword => _keyword; 90 Token get keyword => _keyword;
84 91
85 /** 92 /**
86 * Return the type, of `null` if no type was specified. 93 * Return the type, of `null` if no type was specified.
94 *
87 * @return the type 95 * @return the type
88 */ 96 */
89 TypeName get type => _type; 97 TypeName get type => _type;
90 } 98 }
91 /** 99 /**
92 * Instances of the class `Modifiers` implement a simple data-holder for a metho d that needs 100 * Instances of the class `Modifiers` implement a simple data-holder for a metho d that needs
93 * to return multiple values. 101 * to return multiple values.
102 *
94 * @coverage dart.engine.parser 103 * @coverage dart.engine.parser
95 */ 104 */
96 class Modifiers { 105 class Modifiers {
97 106
98 /** 107 /**
99 * The token representing the keyword 'abstract', or `null` if the keyword was not found. 108 * The token representing the keyword 'abstract', or `null` if the keyword was not found.
100 */ 109 */
101 Token _abstractKeyword; 110 Token _abstractKeyword;
102 111
103 /** 112 /**
(...skipping 22 matching lines...) Expand all
126 Token _staticKeyword; 135 Token _staticKeyword;
127 136
128 /** 137 /**
129 * The token representing the keyword 'var', or `null` if the keyword was not found. 138 * The token representing the keyword 'var', or `null` if the keyword was not found.
130 */ 139 */
131 Token _varKeyword; 140 Token _varKeyword;
132 141
133 /** 142 /**
134 * Return the token representing the keyword 'abstract', or `null` if the keyw ord was not 143 * Return the token representing the keyword 'abstract', or `null` if the keyw ord was not
135 * found. 144 * found.
145 *
136 * @return the token representing the keyword 'abstract' 146 * @return the token representing the keyword 'abstract'
137 */ 147 */
138 Token get abstractKeyword => _abstractKeyword; 148 Token get abstractKeyword => _abstractKeyword;
139 149
140 /** 150 /**
141 * Return the token representing the keyword 'const', or `null` if the keyword was not 151 * Return the token representing the keyword 'const', or `null` if the keyword was not
142 * found. 152 * found.
153 *
143 * @return the token representing the keyword 'const' 154 * @return the token representing the keyword 'const'
144 */ 155 */
145 Token get constKeyword => _constKeyword; 156 Token get constKeyword => _constKeyword;
146 157
147 /** 158 /**
148 * Return the token representing the keyword 'external', or `null` if the keyw ord was not 159 * Return the token representing the keyword 'external', or `null` if the keyw ord was not
149 * found. 160 * found.
161 *
150 * @return the token representing the keyword 'external' 162 * @return the token representing the keyword 'external'
151 */ 163 */
152 Token get externalKeyword => _externalKeyword; 164 Token get externalKeyword => _externalKeyword;
153 165
154 /** 166 /**
155 * Return the token representing the keyword 'factory', or `null` if the keywo rd was not 167 * Return the token representing the keyword 'factory', or `null` if the keywo rd was not
156 * found. 168 * found.
169 *
157 * @return the token representing the keyword 'factory' 170 * @return the token representing the keyword 'factory'
158 */ 171 */
159 Token get factoryKeyword => _factoryKeyword; 172 Token get factoryKeyword => _factoryKeyword;
160 173
161 /** 174 /**
162 * Return the token representing the keyword 'final', or `null` if the keyword was not 175 * Return the token representing the keyword 'final', or `null` if the keyword was not
163 * found. 176 * found.
177 *
164 * @return the token representing the keyword 'final' 178 * @return the token representing the keyword 'final'
165 */ 179 */
166 Token get finalKeyword => _finalKeyword; 180 Token get finalKeyword => _finalKeyword;
167 181
168 /** 182 /**
169 * Return the token representing the keyword 'static', or `null` if the keywor d was not 183 * Return the token representing the keyword 'static', or `null` if the keywor d was not
170 * found. 184 * found.
185 *
171 * @return the token representing the keyword 'static' 186 * @return the token representing the keyword 'static'
172 */ 187 */
173 Token get staticKeyword => _staticKeyword; 188 Token get staticKeyword => _staticKeyword;
174 189
175 /** 190 /**
176 * Return the token representing the keyword 'var', or `null` if the keyword w as not found. 191 * Return the token representing the keyword 'var', or `null` if the keyword w as not found.
192 *
177 * @return the token representing the keyword 'var' 193 * @return the token representing the keyword 'var'
178 */ 194 */
179 Token get varKeyword => _varKeyword; 195 Token get varKeyword => _varKeyword;
180 196
181 /** 197 /**
182 * Set the token representing the keyword 'abstract' to the given token. 198 * Set the token representing the keyword 'abstract' to the given token.
199 *
183 * @param abstractKeyword the token representing the keyword 'abstract' 200 * @param abstractKeyword the token representing the keyword 'abstract'
184 */ 201 */
185 void set abstractKeyword(Token abstractKeyword2) { 202 void set abstractKeyword(Token abstractKeyword2) {
186 this._abstractKeyword = abstractKeyword2; 203 this._abstractKeyword = abstractKeyword2;
187 } 204 }
188 205
189 /** 206 /**
190 * Set the token representing the keyword 'const' to the given token. 207 * Set the token representing the keyword 'const' to the given token.
208 *
191 * @param constKeyword the token representing the keyword 'const' 209 * @param constKeyword the token representing the keyword 'const'
192 */ 210 */
193 void set constKeyword(Token constKeyword2) { 211 void set constKeyword(Token constKeyword2) {
194 this._constKeyword = constKeyword2; 212 this._constKeyword = constKeyword2;
195 } 213 }
196 214
197 /** 215 /**
198 * Set the token representing the keyword 'external' to the given token. 216 * Set the token representing the keyword 'external' to the given token.
217 *
199 * @param externalKeyword the token representing the keyword 'external' 218 * @param externalKeyword the token representing the keyword 'external'
200 */ 219 */
201 void set externalKeyword(Token externalKeyword2) { 220 void set externalKeyword(Token externalKeyword2) {
202 this._externalKeyword = externalKeyword2; 221 this._externalKeyword = externalKeyword2;
203 } 222 }
204 223
205 /** 224 /**
206 * Set the token representing the keyword 'factory' to the given token. 225 * Set the token representing the keyword 'factory' to the given token.
226 *
207 * @param factoryKeyword the token representing the keyword 'factory' 227 * @param factoryKeyword the token representing the keyword 'factory'
208 */ 228 */
209 void set factoryKeyword(Token factoryKeyword2) { 229 void set factoryKeyword(Token factoryKeyword2) {
210 this._factoryKeyword = factoryKeyword2; 230 this._factoryKeyword = factoryKeyword2;
211 } 231 }
212 232
213 /** 233 /**
214 * Set the token representing the keyword 'final' to the given token. 234 * Set the token representing the keyword 'final' to the given token.
235 *
215 * @param finalKeyword the token representing the keyword 'final' 236 * @param finalKeyword the token representing the keyword 'final'
216 */ 237 */
217 void set finalKeyword(Token finalKeyword2) { 238 void set finalKeyword(Token finalKeyword2) {
218 this._finalKeyword = finalKeyword2; 239 this._finalKeyword = finalKeyword2;
219 } 240 }
220 241
221 /** 242 /**
222 * Set the token representing the keyword 'static' to the given token. 243 * Set the token representing the keyword 'static' to the given token.
244 *
223 * @param staticKeyword the token representing the keyword 'static' 245 * @param staticKeyword the token representing the keyword 'static'
224 */ 246 */
225 void set staticKeyword(Token staticKeyword2) { 247 void set staticKeyword(Token staticKeyword2) {
226 this._staticKeyword = staticKeyword2; 248 this._staticKeyword = staticKeyword2;
227 } 249 }
228 250
229 /** 251 /**
230 * Set the token representing the keyword 'var' to the given token. 252 * Set the token representing the keyword 'var' to the given token.
253 *
231 * @param varKeyword the token representing the keyword 'var' 254 * @param varKeyword the token representing the keyword 'var'
232 */ 255 */
233 void set varKeyword(Token varKeyword2) { 256 void set varKeyword(Token varKeyword2) {
234 this._varKeyword = varKeyword2; 257 this._varKeyword = varKeyword2;
235 } 258 }
236 String toString() { 259 String toString() {
237 JavaStringBuilder builder = new JavaStringBuilder(); 260 JavaStringBuilder builder = new JavaStringBuilder();
238 bool needsSpace = appendKeyword(builder, false, _abstractKeyword); 261 bool needsSpace = appendKeyword(builder, false, _abstractKeyword);
239 needsSpace = appendKeyword(builder, needsSpace, _constKeyword); 262 needsSpace = appendKeyword(builder, needsSpace, _constKeyword);
240 needsSpace = appendKeyword(builder, needsSpace, _externalKeyword); 263 needsSpace = appendKeyword(builder, needsSpace, _externalKeyword);
241 needsSpace = appendKeyword(builder, needsSpace, _factoryKeyword); 264 needsSpace = appendKeyword(builder, needsSpace, _factoryKeyword);
242 needsSpace = appendKeyword(builder, needsSpace, _finalKeyword); 265 needsSpace = appendKeyword(builder, needsSpace, _finalKeyword);
243 needsSpace = appendKeyword(builder, needsSpace, _staticKeyword); 266 needsSpace = appendKeyword(builder, needsSpace, _staticKeyword);
244 appendKeyword(builder, needsSpace, _varKeyword); 267 appendKeyword(builder, needsSpace, _varKeyword);
245 return builder.toString(); 268 return builder.toString();
246 } 269 }
247 270
248 /** 271 /**
249 * If the given keyword is not `null`, append it to the given builder, prefixi ng it with a 272 * If the given keyword is not `null`, append it to the given builder, prefixi ng it with a
250 * space if needed. 273 * space if needed.
274 *
251 * @param builder the builder to which the keyword will be appended 275 * @param builder the builder to which the keyword will be appended
252 * @param needsSpace `true` if the keyword needs to be prefixed with a space 276 * @param needsSpace `true` if the keyword needs to be prefixed with a space
253 * @param keyword the keyword to be appended 277 * @param keyword the keyword to be appended
254 * @return `true` if subsequent keywords need to be prefixed with a space 278 * @return `true` if subsequent keywords need to be prefixed with a space
255 */ 279 */
256 bool appendKeyword(JavaStringBuilder builder, bool needsSpace, Token keyword) { 280 bool appendKeyword(JavaStringBuilder builder, bool needsSpace, Token keyword) {
257 if (keyword != null) { 281 if (keyword != null) {
258 if (needsSpace) { 282 if (needsSpace) {
259 builder.appendChar(0x20); 283 builder.appendChar(0x20);
260 } 284 }
261 builder.append(keyword.lexeme); 285 builder.append(keyword.lexeme);
262 return true; 286 return true;
263 } 287 }
264 return needsSpace; 288 return needsSpace;
265 } 289 }
266 } 290 }
267 /** 291 /**
268 * Instances of the class `Parser` are used to parse tokens into an AST structur e. 292 * Instances of the class `Parser` are used to parse tokens into an AST structur e.
293 *
269 * @coverage dart.engine.parser 294 * @coverage dart.engine.parser
270 */ 295 */
271 class Parser { 296 class Parser {
272 297
273 /** 298 /**
274 * The source being parsed. 299 * The source being parsed.
275 */ 300 */
276 Source _source; 301 Source _source;
277 302
278 /** 303 /**
(...skipping 16 matching lines...) Expand all
295 */ 320 */
296 bool _inSwitch = false; 321 bool _inSwitch = false;
297 static String _HIDE = "hide"; 322 static String _HIDE = "hide";
298 static String _OF = "of"; 323 static String _OF = "of";
299 static String _ON = "on"; 324 static String _ON = "on";
300 static String _SHOW = "show"; 325 static String _SHOW = "show";
301 static String _NATIVE = "native"; 326 static String _NATIVE = "native";
302 327
303 /** 328 /**
304 * Initialize a newly created parser. 329 * Initialize a newly created parser.
330 *
305 * @param source the source being parsed 331 * @param source the source being parsed
306 * @param errorListener the error listener that will be informed of any errors that are found 332 * @param errorListener the error listener that will be informed of any errors that are found
307 * during the parse 333 * during the parse
308 */ 334 */
309 Parser(Source source, AnalysisErrorListener errorListener) { 335 Parser(Source source, AnalysisErrorListener errorListener) {
310 this._source = source; 336 this._source = source;
311 this._errorListener = errorListener; 337 this._errorListener = errorListener;
312 } 338 }
313 339
314 /** 340 /**
315 * Parse a compilation unit, starting with the given token. 341 * Parse a compilation unit, starting with the given token.
342 *
316 * @param token the first token of the compilation unit 343 * @param token the first token of the compilation unit
317 * @return the compilation unit that was parsed 344 * @return the compilation unit that was parsed
318 */ 345 */
319 CompilationUnit parseCompilationUnit(Token token) { 346 CompilationUnit parseCompilationUnit(Token token) {
320 InstrumentationBuilder instrumentation = Instrumentation.builder2("dart.engi ne.Parser.parseCompilationUnit"); 347 InstrumentationBuilder instrumentation = Instrumentation.builder2("dart.engi ne.Parser.parseCompilationUnit");
321 try { 348 try {
322 _currentToken = token; 349 _currentToken = token;
323 return parseCompilationUnit2(); 350 return parseCompilationUnit2();
324 } finally { 351 } finally {
325 instrumentation.log(); 352 instrumentation.log();
326 } 353 }
327 } 354 }
328 355
329 /** 356 /**
330 * Parse an expression, starting with the given token. 357 * Parse an expression, starting with the given token.
358 *
331 * @param token the first token of the expression 359 * @param token the first token of the expression
332 * @return the expression that was parsed, or `null` if the tokens do not repr esent a 360 * @return the expression that was parsed, or `null` if the tokens do not repr esent a
333 * recognizable expression 361 * recognizable expression
334 */ 362 */
335 Expression parseExpression(Token token) { 363 Expression parseExpression(Token token) {
336 InstrumentationBuilder instrumentation = Instrumentation.builder2("dart.engi ne.Parser.parseExpression"); 364 InstrumentationBuilder instrumentation = Instrumentation.builder2("dart.engi ne.Parser.parseExpression");
337 try { 365 try {
338 _currentToken = token; 366 _currentToken = token;
339 return parseExpression2(); 367 return parseExpression2();
340 } finally { 368 } finally {
341 instrumentation.log(); 369 instrumentation.log();
342 } 370 }
343 } 371 }
344 372
345 /** 373 /**
346 * Parse a statement, starting with the given token. 374 * Parse a statement, starting with the given token.
375 *
347 * @param token the first token of the statement 376 * @param token the first token of the statement
348 * @return the statement that was parsed, or `null` if the tokens do not repre sent a 377 * @return the statement that was parsed, or `null` if the tokens do not repre sent a
349 * recognizable statement 378 * recognizable statement
350 */ 379 */
351 Statement parseStatement(Token token) { 380 Statement parseStatement(Token token) {
352 InstrumentationBuilder instrumentation = Instrumentation.builder2("dart.engi ne.Parser.parseStatement"); 381 InstrumentationBuilder instrumentation = Instrumentation.builder2("dart.engi ne.Parser.parseStatement");
353 try { 382 try {
354 _currentToken = token; 383 _currentToken = token;
355 return parseStatement2(); 384 return parseStatement2();
356 } finally { 385 } finally {
357 instrumentation.log(); 386 instrumentation.log();
358 } 387 }
359 } 388 }
360 389
361 /** 390 /**
362 * Parse a sequence of statements, starting with the given token. 391 * Parse a sequence of statements, starting with the given token.
392 *
363 * @param token the first token of the sequence of statement 393 * @param token the first token of the sequence of statement
364 * @return the statements that were parsed, or `null` if the tokens do not rep resent a 394 * @return the statements that were parsed, or `null` if the tokens do not rep resent a
365 * recognizable sequence of statements 395 * recognizable sequence of statements
366 */ 396 */
367 List<Statement> parseStatements(Token token) { 397 List<Statement> parseStatements(Token token) {
368 InstrumentationBuilder instrumentation = Instrumentation.builder2("dart.engi ne.Parser.parseStatements"); 398 InstrumentationBuilder instrumentation = Instrumentation.builder2("dart.engi ne.Parser.parseStatements");
369 try { 399 try {
370 _currentToken = token; 400 _currentToken = token;
371 return parseStatements2(); 401 return parseStatements2();
372 } finally { 402 } finally {
373 instrumentation.log(); 403 instrumentation.log();
374 } 404 }
375 } 405 }
376 void set currentToken(Token currentToken2) { 406 void set currentToken(Token currentToken2) {
377 this._currentToken = currentToken2; 407 this._currentToken = currentToken2;
378 } 408 }
379 409
380 /** 410 /**
381 * Advance to the next token in the token stream. 411 * Advance to the next token in the token stream.
382 */ 412 */
383 void advance() { 413 void advance() {
384 _currentToken = _currentToken.next; 414 _currentToken = _currentToken.next;
385 } 415 }
386 416
387 /** 417 /**
388 * Append the character equivalent of the given scalar value to the given buil der. Use the start 418 * Append the character equivalent of the given scalar value to the given buil der. Use the start
389 * and end indices to report an error, and don't append anything to the builde r, if the scalar 419 * and end indices to report an error, and don't append anything to the builde r, if the scalar
390 * value is invalid. 420 * value is invalid.
421 *
391 * @param builder the builder to which the scalar value is to be appended 422 * @param builder the builder to which the scalar value is to be appended
392 * @param escapeSequence the escape sequence that was parsed to produce the sc alar value 423 * @param escapeSequence the escape sequence that was parsed to produce the sc alar value
393 * @param scalarValue the value to be appended 424 * @param scalarValue the value to be appended
394 * @param startIndex the index of the first character representing the scalar value 425 * @param startIndex the index of the first character representing the scalar value
395 * @param endIndex the index of the last character representing the scalar val ue 426 * @param endIndex the index of the last character representing the scalar val ue
396 */ 427 */
397 void appendScalarValue(JavaStringBuilder builder, String escapeSequence, int s calarValue, int startIndex, int endIndex) { 428 void appendScalarValue(JavaStringBuilder builder, String escapeSequence, int s calarValue, int startIndex, int endIndex) {
398 if (scalarValue < 0 || scalarValue > Character.MAX_CODE_POINT || (scalarValu e >= 0xD800 && scalarValue <= 0xDFFF)) { 429 if (scalarValue < 0 || scalarValue > Character.MAX_CODE_POINT || (scalarValu e >= 0xD800 && scalarValue <= 0xDFFF)) {
399 reportError7(ParserErrorCode.INVALID_CODE_POINT, [escapeSequence]); 430 reportError7(ParserErrorCode.INVALID_CODE_POINT, [escapeSequence]);
400 return; 431 return;
401 } 432 }
402 if (scalarValue < Character.MAX_VALUE) { 433 if (scalarValue < Character.MAX_VALUE) {
403 builder.appendChar((scalarValue as int)); 434 builder.appendChar((scalarValue as int));
404 } else { 435 } else {
405 builder.append(Character.toChars(scalarValue)); 436 builder.append(Character.toChars(scalarValue));
406 } 437 }
407 } 438 }
408 439
409 /** 440 /**
410 * Compute the content of a string with the given literal representation. 441 * Compute the content of a string with the given literal representation.
442 *
411 * @param lexeme the literal representation of the string 443 * @param lexeme the literal representation of the string
412 * @return the actual value of the string 444 * @return the actual value of the string
413 */ 445 */
414 String computeStringValue(String lexeme) { 446 String computeStringValue(String lexeme) {
415 if (lexeme.startsWith("r\"\"\"") || lexeme.startsWith("r'''")) { 447 if (lexeme.startsWith("r\"\"\"") || lexeme.startsWith("r'''")) {
416 if (lexeme.length > 4) { 448 if (lexeme.length > 4) {
417 return lexeme.substring(4, lexeme.length - 3); 449 return lexeme.substring(4, lexeme.length - 3);
418 } 450 }
419 } else if (lexeme.startsWith("r\"") || lexeme.startsWith("r'")) { 451 } else if (lexeme.startsWith("r\"") || lexeme.startsWith("r'")) {
420 if (lexeme.length > 2) { 452 if (lexeme.length > 2) {
(...skipping 15 matching lines...) Expand all
436 JavaStringBuilder builder = new JavaStringBuilder(); 468 JavaStringBuilder builder = new JavaStringBuilder();
437 int index = start; 469 int index = start;
438 while (index < end) { 470 while (index < end) {
439 index = translateCharacter(builder, lexeme, index); 471 index = translateCharacter(builder, lexeme, index);
440 } 472 }
441 return builder.toString(); 473 return builder.toString();
442 } 474 }
443 475
444 /** 476 /**
445 * Convert the given method declaration into the nearest valid top-level funct ion declaration. 477 * Convert the given method declaration into the nearest valid top-level funct ion declaration.
478 *
446 * @param method the method to be converted 479 * @param method the method to be converted
447 * @return the function declaration that most closely captures the components of the given method 480 * @return the function declaration that most closely captures the components of the given method
448 * declaration 481 * declaration
449 */ 482 */
450 FunctionDeclaration convertToFunctionDeclaration(MethodDeclaration method) => new FunctionDeclaration.full(method.documentationComment, method.metadata, metho d.externalKeyword, method.returnType, method.propertyKeyword, method.name, new F unctionExpression.full(method.parameters, method.body)); 483 FunctionDeclaration convertToFunctionDeclaration(MethodDeclaration method) => new FunctionDeclaration.full(method.documentationComment, method.metadata, metho d.externalKeyword, method.returnType, method.propertyKeyword, method.name, new F unctionExpression.full(method.parameters, method.body));
451 484
452 /** 485 /**
453 * Return `true` if the current token could be the start of a compilation unit member. This 486 * Return `true` if the current token could be the start of a compilation unit member. This
454 * method is used for recovery purposes to decide when to stop skipping tokens after finding an 487 * method is used for recovery purposes to decide when to stop skipping tokens after finding an
455 * error while parsing a compilation unit member. 488 * error while parsing a compilation unit member.
489 *
456 * @return `true` if the current token could be the start of a compilation uni t member 490 * @return `true` if the current token could be the start of a compilation uni t member
457 */ 491 */
458 bool couldBeStartOfCompilationUnitMember() { 492 bool couldBeStartOfCompilationUnitMember() {
459 if ((matches(Keyword.IMPORT) || matches(Keyword.EXPORT) || matches(Keyword.L IBRARY) || matches(Keyword.PART)) && !matches4(peek(), TokenType.PERIOD) && !mat ches4(peek(), TokenType.LT)) { 493 if ((matches(Keyword.IMPORT) || matches(Keyword.EXPORT) || matches(Keyword.L IBRARY) || matches(Keyword.PART)) && !matches4(peek(), TokenType.PERIOD) && !mat ches4(peek(), TokenType.LT)) {
460 return true; 494 return true;
461 } else if (matches(Keyword.CLASS)) { 495 } else if (matches(Keyword.CLASS)) {
462 return true; 496 return true;
463 } else if (matches(Keyword.TYPEDEF) && !matches4(peek(), TokenType.PERIOD) & & !matches4(peek(), TokenType.LT)) { 497 } else if (matches(Keyword.TYPEDEF) && !matches4(peek(), TokenType.PERIOD) & & !matches4(peek(), TokenType.LT)) {
464 return true; 498 return true;
465 } else if (matches(Keyword.VOID) || ((matches(Keyword.GET) || matches(Keywor d.SET)) && matchesIdentifier2(peek())) || (matches(Keyword.OPERATOR) && isOperat or(peek()))) { 499 } else if (matches(Keyword.VOID) || ((matches(Keyword.GET) || matches(Keywor d.SET)) && matchesIdentifier2(peek())) || (matches(Keyword.OPERATOR) && isOperat or(peek()))) {
466 return true; 500 return true;
467 } else if (matchesIdentifier()) { 501 } else if (matchesIdentifier()) {
468 if (matches4(peek(), TokenType.OPEN_PAREN)) { 502 if (matches4(peek(), TokenType.OPEN_PAREN)) {
469 return true; 503 return true;
470 } 504 }
471 Token token = skipReturnType(_currentToken); 505 Token token = skipReturnType(_currentToken);
472 if (token == null) { 506 if (token == null) {
473 return false; 507 return false;
474 } 508 }
475 if (matches(Keyword.GET) || matches(Keyword.SET) || (matches(Keyword.OPERA TOR) && isOperator(peek())) || matchesIdentifier()) { 509 if (matches(Keyword.GET) || matches(Keyword.SET) || (matches(Keyword.OPERA TOR) && isOperator(peek())) || matchesIdentifier()) {
476 return true; 510 return true;
477 } 511 }
478 } 512 }
479 return false; 513 return false;
480 } 514 }
481 515
482 /** 516 /**
483 * Create a synthetic identifier. 517 * Create a synthetic identifier.
518 *
484 * @return the synthetic identifier that was created 519 * @return the synthetic identifier that was created
485 */ 520 */
486 SimpleIdentifier createSyntheticIdentifier() => new SimpleIdentifier.full(crea teSyntheticToken2(TokenType.IDENTIFIER)); 521 SimpleIdentifier createSyntheticIdentifier() => new SimpleIdentifier.full(crea teSyntheticToken2(TokenType.IDENTIFIER));
487 522
488 /** 523 /**
489 * Create a synthetic string literal. 524 * Create a synthetic string literal.
525 *
490 * @return the synthetic string literal that was created 526 * @return the synthetic string literal that was created
491 */ 527 */
492 SimpleStringLiteral createSyntheticStringLiteral() => new SimpleStringLiteral. full(createSyntheticToken2(TokenType.STRING), ""); 528 SimpleStringLiteral createSyntheticStringLiteral() => new SimpleStringLiteral. full(createSyntheticToken2(TokenType.STRING), "");
493 529
494 /** 530 /**
495 * Create a synthetic token representing the given keyword. 531 * Create a synthetic token representing the given keyword.
532 *
496 * @return the synthetic token that was created 533 * @return the synthetic token that was created
497 */ 534 */
498 Token createSyntheticToken(Keyword keyword) => new KeywordToken_10(keyword, _c urrentToken.offset); 535 Token createSyntheticToken(Keyword keyword) => new KeywordToken_11(keyword, _c urrentToken.offset);
499 536
500 /** 537 /**
501 * Create a synthetic token with the given type. 538 * Create a synthetic token with the given type.
539 *
502 * @return the synthetic token that was created 540 * @return the synthetic token that was created
503 */ 541 */
504 Token createSyntheticToken2(TokenType type) => new StringToken(type, "", _curr entToken.offset); 542 Token createSyntheticToken2(TokenType type) => new StringToken(type, "", _curr entToken.offset);
505 543
506 /** 544 /**
507 * Check that the given expression is assignable and report an error if it isn 't. 545 * Check that the given expression is assignable and report an error if it isn 't.
546 *
508 * <pre> 547 * <pre>
509 * assignableExpression ::= 548 * assignableExpression ::=
510 * primary (arguments* assignableSelector)+ 549 * primary (arguments* assignableSelector)+
511 * | 'super' assignableSelector 550 * | 'super' assignableSelector
512 * | identifier 551 * | identifier
552 *
513 * assignableSelector ::= 553 * assignableSelector ::=
514 * '\[' expression '\]' 554 * '[' expression ']'
515 * | '.' identifier 555 * | '.' identifier
516 * </pre> 556 * </pre>
557 *
517 * @param expression the expression being checked 558 * @param expression the expression being checked
518 */ 559 */
519 void ensureAssignable(Expression expression) { 560 void ensureAssignable(Expression expression) {
520 if (expression != null && !expression.isAssignable) { 561 if (expression != null && !expression.isAssignable) {
521 reportError7(ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, []); 562 reportError7(ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, []);
522 } 563 }
523 } 564 }
524 565
525 /** 566 /**
526 * If the current token is a keyword matching the given string, return it afte r advancing to the 567 * If the current token is a keyword matching the given string, return it afte r advancing to the
527 * next token. Otherwise report an error and return the current token without advancing. 568 * next token. Otherwise report an error and return the current token without advancing.
569 *
528 * @param keyword the keyword that is expected 570 * @param keyword the keyword that is expected
529 * @return the token that matched the given type 571 * @return the token that matched the given type
530 */ 572 */
531 Token expect(Keyword keyword) { 573 Token expect(Keyword keyword) {
532 if (matches(keyword)) { 574 if (matches(keyword)) {
533 return andAdvance; 575 return andAdvance;
534 } 576 }
535 reportError7(ParserErrorCode.EXPECTED_TOKEN, [keyword.syntax]); 577 reportError7(ParserErrorCode.EXPECTED_TOKEN, [keyword.syntax]);
536 return _currentToken; 578 return _currentToken;
537 } 579 }
538 580
539 /** 581 /**
540 * If the current token has the expected type, return it after advancing to th e next token. 582 * If the current token has the expected type, return it after advancing to th e next token.
541 * Otherwise report an error and return the current token without advancing. 583 * Otherwise report an error and return the current token without advancing.
584 *
542 * @param type the type of token that is expected 585 * @param type the type of token that is expected
543 * @return the token that matched the given type 586 * @return the token that matched the given type
544 */ 587 */
545 Token expect2(TokenType type) { 588 Token expect2(TokenType type) {
546 if (matches5(type)) { 589 if (matches5(type)) {
547 return andAdvance; 590 return andAdvance;
548 } 591 }
549 if (identical(type, TokenType.SEMICOLON)) { 592 if (identical(type, TokenType.SEMICOLON)) {
550 reportError8(ParserErrorCode.EXPECTED_TOKEN, _currentToken.previous, [type .lexeme]); 593 reportError8(ParserErrorCode.EXPECTED_TOKEN, _currentToken.previous, [type .lexeme]);
551 } else { 594 } else {
552 reportError7(ParserErrorCode.EXPECTED_TOKEN, [type.lexeme]); 595 reportError7(ParserErrorCode.EXPECTED_TOKEN, [type.lexeme]);
553 } 596 }
554 return _currentToken; 597 return _currentToken;
555 } 598 }
556 599
557 /** 600 /**
558 * Search the given list of ranges for a range that contains the given index. Return the range 601 * Search the given list of ranges for a range that contains the given index. Return the range
559 * that was found, or `null` if none of the ranges contain the index. 602 * that was found, or `null` if none of the ranges contain the index.
603 *
560 * @param ranges the ranges to be searched 604 * @param ranges the ranges to be searched
561 * @param index the index contained in the returned range 605 * @param index the index contained in the returned range
562 * @return the range that was found 606 * @return the range that was found
563 */ 607 */
564 List<int> findRange(List<List<int>> ranges, int index) { 608 List<int> findRange(List<List<int>> ranges, int index) {
565 for (List<int> range in ranges) { 609 for (List<int> range in ranges) {
566 if (range[0] <= index && index <= range[1]) { 610 if (range[0] <= index && index <= range[1]) {
567 return range; 611 return range;
568 } else if (index < range[0]) { 612 } else if (index < range[0]) {
569 return null; 613 return null;
570 } 614 }
571 } 615 }
572 return null; 616 return null;
573 } 617 }
574 618
575 /** 619 /**
576 * Advance to the next token in the token stream, making it the new current to ken. 620 * Advance to the next token in the token stream, making it the new current to ken.
621 *
577 * @return the token that was current before this method was invoked 622 * @return the token that was current before this method was invoked
578 */ 623 */
579 Token get andAdvance { 624 Token get andAdvance {
580 Token token = _currentToken; 625 Token token = _currentToken;
581 advance(); 626 advance();
582 return token; 627 return token;
583 } 628 }
584 629
585 /** 630 /**
586 * Return a list of the ranges of characters in the given comment string that should be treated as 631 * Return a list of the ranges of characters in the given comment string that should be treated as
587 * code blocks. 632 * code blocks.
633 *
588 * @param comment the comment being processed 634 * @param comment the comment being processed
589 * @return the ranges of characters that should be treated as code blocks 635 * @return the ranges of characters that should be treated as code blocks
590 */ 636 */
591 List<List<int>> getCodeBlockRanges(String comment) { 637 List<List<int>> getCodeBlockRanges(String comment) {
592 List<List<int>> ranges = new List<List<int>>(); 638 List<List<int>> ranges = new List<List<int>>();
593 int length = comment.length; 639 int length = comment.length;
594 int index = 0; 640 int index = 0;
595 if (comment.startsWith("/**") || comment.startsWith("///")) { 641 if (comment.startsWith("/**") || comment.startsWith("///")) {
596 index = 3; 642 index = 3;
597 } 643 }
(...skipping 22 matching lines...) Expand all
620 } else { 666 } else {
621 index = index + 1; 667 index = index + 1;
622 } 668 }
623 } 669 }
624 return ranges; 670 return ranges;
625 } 671 }
626 672
627 /** 673 /**
628 * Return the end token associated with the given begin token, or `null` if ei ther the given 674 * Return the end token associated with the given begin token, or `null` if ei ther the given
629 * token is not a begin token or it does not have an end token associated with it. 675 * token is not a begin token or it does not have an end token associated with it.
676 *
630 * @param beginToken the token that is expected to have an end token associate d with it 677 * @param beginToken the token that is expected to have an end token associate d with it
631 * @return the end token associated with the begin token 678 * @return the end token associated with the begin token
632 */ 679 */
633 Token getEndToken(Token beginToken) { 680 Token getEndToken(Token beginToken) {
634 if (beginToken is BeginToken) { 681 if (beginToken is BeginToken) {
635 return ((beginToken as BeginToken)).endToken; 682 return ((beginToken as BeginToken)).endToken;
636 } 683 }
637 return null; 684 return null;
638 } 685 }
639 686
640 /** 687 /**
641 * Return `true` if the current token is the first token of a return type that is followed 688 * Return `true` if the current token is the first token of a return type that is followed
642 * by an identifier, possibly followed by a list of type parameters, followed by a 689 * by an identifier, possibly followed by a list of type parameters, followed by a
643 * left-parenthesis. This is used by parseTypeAlias to determine whether or no t to parse a return 690 * left-parenthesis. This is used by parseTypeAlias to determine whether or no t to parse a return
644 * type. 691 * type.
692 *
645 * @return `true` if we can successfully parse the rest of a type alias if we first parse a 693 * @return `true` if we can successfully parse the rest of a type alias if we first parse a
646 * return type. 694 * return type.
647 */ 695 */
648 bool hasReturnTypeInTypeAlias() { 696 bool hasReturnTypeInTypeAlias() {
649 Token next = skipReturnType(_currentToken); 697 Token next = skipReturnType(_currentToken);
650 if (next == null) { 698 if (next == null) {
651 return false; 699 return false;
652 } 700 }
653 return matchesIdentifier2(next); 701 return matchesIdentifier2(next);
654 } 702 }
655 703
656 /** 704 /**
657 * Return `true` if the current token appears to be the beginning of a functio n declaration. 705 * Return `true` if the current token appears to be the beginning of a functio n declaration.
706 *
658 * @return `true` if the current token appears to be the beginning of a functi on declaration 707 * @return `true` if the current token appears to be the beginning of a functi on declaration
659 */ 708 */
660 bool isFunctionDeclaration() { 709 bool isFunctionDeclaration() {
661 if (matches(Keyword.VOID)) { 710 if (matches(Keyword.VOID)) {
662 return true; 711 return true;
663 } 712 }
664 Token afterReturnType = skipTypeName(_currentToken); 713 Token afterReturnType = skipTypeName(_currentToken);
665 if (afterReturnType == null) { 714 if (afterReturnType == null) {
666 afterReturnType = _currentToken; 715 afterReturnType = _currentToken;
667 } 716 }
668 Token afterIdentifier = skipSimpleIdentifier(afterReturnType); 717 Token afterIdentifier = skipSimpleIdentifier(afterReturnType);
669 if (afterIdentifier == null) { 718 if (afterIdentifier == null) {
670 afterIdentifier = skipSimpleIdentifier(_currentToken); 719 afterIdentifier = skipSimpleIdentifier(_currentToken);
671 } 720 }
672 if (afterIdentifier == null) { 721 if (afterIdentifier == null) {
673 return false; 722 return false;
674 } 723 }
675 return isFunctionExpression(afterIdentifier); 724 return isFunctionExpression(afterIdentifier);
676 } 725 }
677 726
678 /** 727 /**
679 * Return `true` if the given token appears to be the beginning of a function expression. 728 * Return `true` if the given token appears to be the beginning of a function expression.
729 *
680 * @param startToken the token that might be the start of a function expressio n 730 * @param startToken the token that might be the start of a function expressio n
681 * @return `true` if the given token appears to be the beginning of a function expression 731 * @return `true` if the given token appears to be the beginning of a function expression
682 */ 732 */
683 bool isFunctionExpression(Token startToken) { 733 bool isFunctionExpression(Token startToken) {
684 Token afterParameters = skipFormalParameterList(startToken); 734 Token afterParameters = skipFormalParameterList(startToken);
685 if (afterParameters == null) { 735 if (afterParameters == null) {
686 return false; 736 return false;
687 } 737 }
688 return matchesAny(afterParameters, [TokenType.OPEN_CURLY_BRACKET, TokenType. FUNCTION]); 738 return matchesAny(afterParameters, [TokenType.OPEN_CURLY_BRACKET, TokenType. FUNCTION]);
689 } 739 }
690 740
691 /** 741 /**
692 * Return `true` if the given character is a valid hexadecimal digit. 742 * Return `true` if the given character is a valid hexadecimal digit.
743 *
693 * @param character the character being tested 744 * @param character the character being tested
694 * @return `true` if the character is a valid hexadecimal digit 745 * @return `true` if the character is a valid hexadecimal digit
695 */ 746 */
696 bool isHexDigit(int character) => (0x30 <= character && character <= 0x39) || (0x41 <= character && character <= 0x46) || (0x61 <= character && character <= 0 x66); 747 bool isHexDigit(int character) => (0x30 <= character && character <= 0x39) || (0x41 <= character && character <= 0x46) || (0x61 <= character && character <= 0 x66);
697 748
698 /** 749 /**
699 * Return `true` if the current token is the first token in an initialized var iable 750 * Return `true` if the current token is the first token in an initialized var iable
700 * declaration rather than an expression. This method assumes that we have alr eady skipped past 751 * declaration rather than an expression. This method assumes that we have alr eady skipped past
701 * any metadata that might be associated with the declaration. 752 * any metadata that might be associated with the declaration.
753 *
702 * <pre> 754 * <pre>
703 * initializedVariableDeclaration ::= 755 * initializedVariableDeclaration ::=
704 * declaredIdentifier ('=' expression)? (',' initializedIdentifier) 756 * declaredIdentifier ('=' expression)? (',' initializedIdentifier)*
757 *
705 * declaredIdentifier ::= 758 * declaredIdentifier ::=
706 * metadata finalConstVarOrType identifier 759 * metadata finalConstVarOrType identifier
760 *
707 * finalConstVarOrType ::= 761 * finalConstVarOrType ::=
708 * 'final' type? 762 * 'final' type?
709 * | 'const' type? 763 * | 'const' type?
710 * | 'var' 764 * | 'var'
711 * | type 765 * | type
766 *
712 * type ::= 767 * type ::=
713 * qualified typeArguments? 768 * qualified typeArguments?
769 *
714 * initializedIdentifier ::= 770 * initializedIdentifier ::=
715 * identifier ('=' expression)? 771 * identifier ('=' expression)?
716 * </pre> 772 * </pre>
773 *
717 * @return `true` if the current token is the first token in an initialized va riable 774 * @return `true` if the current token is the first token in an initialized va riable
718 * declaration 775 * declaration
719 */ 776 */
720 bool isInitializedVariableDeclaration() { 777 bool isInitializedVariableDeclaration() {
721 if (matches(Keyword.FINAL) || matches(Keyword.VAR)) { 778 if (matches(Keyword.FINAL) || matches(Keyword.VAR)) {
722 return true; 779 return true;
723 } 780 }
724 if (matches(Keyword.CONST)) { 781 if (matches(Keyword.CONST)) {
725 return !matchesAny(peek(), [TokenType.LT, TokenType.OPEN_CURLY_BRACKET, To kenType.OPEN_SQUARE_BRACKET, TokenType.INDEX]); 782 return !matchesAny(peek(), [TokenType.LT, TokenType.OPEN_CURLY_BRACKET, To kenType.OPEN_SQUARE_BRACKET, TokenType.INDEX]);
726 } 783 }
727 Token token = skipTypeName(_currentToken); 784 Token token = skipTypeName(_currentToken);
728 if (token == null) { 785 if (token == null) {
729 return false; 786 return false;
730 } 787 }
731 token = skipSimpleIdentifier(token); 788 token = skipSimpleIdentifier(token);
732 if (token == null) { 789 if (token == null) {
733 return false; 790 return false;
734 } 791 }
735 TokenType type = token.type; 792 TokenType type = token.type;
736 return identical(type, TokenType.EQ) || identical(type, TokenType.COMMA) || identical(type, TokenType.SEMICOLON) || matches3(token, Keyword.IN); 793 return identical(type, TokenType.EQ) || identical(type, TokenType.COMMA) || identical(type, TokenType.SEMICOLON) || matches3(token, Keyword.IN);
737 } 794 }
738 795
739 /** 796 /**
740 * Given that we have just found bracketed text within a comment, look to see whether that text is 797 * Given that we have just found bracketed text within a comment, look to see whether that text is
741 * (a) followed by a parenthesized link address, (b) followed by a colon, or ( c) followed by 798 * (a) followed by a parenthesized link address, (b) followed by a colon, or ( c) followed by
742 * optional whitespace and another square bracket. 799 * optional whitespace and another square bracket.
743 * 800 *
744 * This method uses the syntax described by the <a 801 * This method uses the syntax described by the <a
745 * href="http://daringfireball.net/projects/markdown/syntax">markdown</a> proj ect. 802 * href="http://daringfireball.net/projects/markdown/syntax">markdown</a> proj ect.
803 *
746 * @param comment the comment text in which the bracketed text was found 804 * @param comment the comment text in which the bracketed text was found
747 * @param rightIndex the index of the right bracket 805 * @param rightIndex the index of the right bracket
748 * @return `true` if the bracketed text is followed by a link address 806 * @return `true` if the bracketed text is followed by a link address
749 */ 807 */
750 bool isLinkText(String comment, int rightIndex) { 808 bool isLinkText(String comment, int rightIndex) {
751 int length = comment.length; 809 int length = comment.length;
752 int index = rightIndex + 1; 810 int index = rightIndex + 1;
753 if (index >= length) { 811 if (index >= length) {
754 return false; 812 return false;
755 } 813 }
756 int nextChar = comment.codeUnitAt(index); 814 int nextChar = comment.codeUnitAt(index);
757 if (nextChar == 0x28 || nextChar == 0x3A) { 815 if (nextChar == 0x28 || nextChar == 0x3A) {
758 return true; 816 return true;
759 } 817 }
760 while (Character.isWhitespace(nextChar)) { 818 while (Character.isWhitespace(nextChar)) {
761 index = index + 1; 819 index = index + 1;
762 if (index >= length) { 820 if (index >= length) {
763 return false; 821 return false;
764 } 822 }
765 nextChar = comment.codeUnitAt(index); 823 nextChar = comment.codeUnitAt(index);
766 } 824 }
767 return nextChar == 0x5B; 825 return nextChar == 0x5B;
768 } 826 }
769 827
770 /** 828 /**
771 * Return `true` if the given token appears to be the beginning of an operator declaration. 829 * Return `true` if the given token appears to be the beginning of an operator declaration.
830 *
772 * @param startToken the token that might be the start of an operator declarat ion 831 * @param startToken the token that might be the start of an operator declarat ion
773 * @return `true` if the given token appears to be the beginning of an operato r declaration 832 * @return `true` if the given token appears to be the beginning of an operato r declaration
774 */ 833 */
775 bool isOperator(Token startToken) { 834 bool isOperator(Token startToken) {
776 if (startToken.isOperator) { 835 if (startToken.isOperator) {
777 Token token = startToken.next; 836 Token token = startToken.next;
778 while (token.isOperator) { 837 while (token.isOperator) {
779 token = token.next; 838 token = token.next;
780 } 839 }
781 return matches4(token, TokenType.OPEN_PAREN); 840 return matches4(token, TokenType.OPEN_PAREN);
782 } 841 }
783 return false; 842 return false;
784 } 843 }
785 844
786 /** 845 /**
787 * Return `true` if the current token appears to be the beginning of a switch member. 846 * Return `true` if the current token appears to be the beginning of a switch member.
847 *
788 * @return `true` if the current token appears to be the beginning of a switch member 848 * @return `true` if the current token appears to be the beginning of a switch member
789 */ 849 */
790 bool isSwitchMember() { 850 bool isSwitchMember() {
791 Token token = _currentToken; 851 Token token = _currentToken;
792 while (matches4(token, TokenType.IDENTIFIER) && matches4(token.next, TokenTy pe.COLON)) { 852 while (matches4(token, TokenType.IDENTIFIER) && matches4(token.next, TokenTy pe.COLON)) {
793 token = token.next.next; 853 token = token.next.next;
794 } 854 }
795 if (identical(token.type, TokenType.KEYWORD)) { 855 if (identical(token.type, TokenType.KEYWORD)) {
796 Keyword keyword = ((token as KeywordToken)).keyword; 856 Keyword keyword = ((token as KeywordToken)).keyword;
797 return identical(keyword, Keyword.CASE) || identical(keyword, Keyword.DEFA ULT); 857 return identical(keyword, Keyword.CASE) || identical(keyword, Keyword.DEFA ULT);
798 } 858 }
799 return false; 859 return false;
800 } 860 }
801 861
802 /** 862 /**
803 * Compare the given tokens to find the token that appears first in the source being parsed. That 863 * Compare the given tokens to find the token that appears first in the source being parsed. That
804 * is, return the left-most of all of the tokens. The arguments are allowed to be `null`. 864 * is, return the left-most of all of the tokens. The arguments are allowed to be `null`.
805 * Return the token with the smallest offset, or `null` if there are no argume nts or if all 865 * Return the token with the smallest offset, or `null` if there are no argume nts or if all
806 * of the arguments are `null`. 866 * of the arguments are `null`.
867 *
807 * @param tokens the tokens being compared 868 * @param tokens the tokens being compared
808 * @return the token with the smallest offset 869 * @return the token with the smallest offset
809 */ 870 */
810 Token lexicallyFirst(List<Token> tokens) { 871 Token lexicallyFirst(List<Token> tokens) {
811 Token first = null; 872 Token first = null;
812 int firstOffset = 2147483647; 873 int firstOffset = 2147483647;
813 for (Token token in tokens) { 874 for (Token token in tokens) {
814 if (token != null) { 875 if (token != null) {
815 int offset = token.offset; 876 int offset = token.offset;
816 if (offset < firstOffset) { 877 if (offset < firstOffset) {
817 first = token; 878 first = token;
818 firstOffset = offset; 879 firstOffset = offset;
819 } 880 }
820 } 881 }
821 } 882 }
822 return first; 883 return first;
823 } 884 }
824 885
825 /** 886 /**
826 * Return `true` if the current token matches the given keyword. 887 * Return `true` if the current token matches the given keyword.
888 *
827 * @param keyword the keyword that can optionally appear in the current locati on 889 * @param keyword the keyword that can optionally appear in the current locati on
828 * @return `true` if the current token matches the given keyword 890 * @return `true` if the current token matches the given keyword
829 */ 891 */
830 bool matches(Keyword keyword) => matches3(_currentToken, keyword); 892 bool matches(Keyword keyword) => matches3(_currentToken, keyword);
831 893
832 /** 894 /**
833 * Return `true` if the current token matches the given identifier. 895 * Return `true` if the current token matches the given identifier.
896 *
834 * @param identifier the identifier that can optionally appear in the current location 897 * @param identifier the identifier that can optionally appear in the current location
835 * @return `true` if the current token matches the given identifier 898 * @return `true` if the current token matches the given identifier
836 */ 899 */
837 bool matches2(String identifier) => identical(_currentToken.type, TokenType.ID ENTIFIER) && _currentToken.lexeme == identifier; 900 bool matches2(String identifier) => identical(_currentToken.type, TokenType.ID ENTIFIER) && _currentToken.lexeme == identifier;
838 901
839 /** 902 /**
840 * Return `true` if the given token matches the given keyword. 903 * Return `true` if the given token matches the given keyword.
904 *
841 * @param token the token being tested 905 * @param token the token being tested
842 * @param keyword the keyword that is being tested for 906 * @param keyword the keyword that is being tested for
843 * @return `true` if the given token matches the given keyword 907 * @return `true` if the given token matches the given keyword
844 */ 908 */
845 bool matches3(Token token, Keyword keyword2) => identical(token.type, TokenTyp e.KEYWORD) && identical(((token as KeywordToken)).keyword, keyword2); 909 bool matches3(Token token, Keyword keyword2) => identical(token.type, TokenTyp e.KEYWORD) && identical(((token as KeywordToken)).keyword, keyword2);
846 910
847 /** 911 /**
848 * Return `true` if the given token has the given type. 912 * Return `true` if the given token has the given type.
913 *
849 * @param token the token being tested 914 * @param token the token being tested
850 * @param type the type of token that is being tested for 915 * @param type the type of token that is being tested for
851 * @return `true` if the given token has the given type 916 * @return `true` if the given token has the given type
852 */ 917 */
853 bool matches4(Token token, TokenType type2) => identical(token.type, type2); 918 bool matches4(Token token, TokenType type2) => identical(token.type, type2);
854 919
855 /** 920 /**
856 * Return `true` if the current token has the given type. Note that this metho d, unlike 921 * Return `true` if the current token has the given type. Note that this metho d, unlike
857 * other variants, will modify the token stream if possible to match a wider r ange of tokens. In 922 * other variants, will modify the token stream if possible to match a wider r ange of tokens. In
858 * particular, if we are attempting to match a '>' and the next token is eithe r a '>>' or '>>>', 923 * particular, if we are attempting to match a '>' and the next token is eithe r a '>>' or '>>>',
859 * the token stream will be re-written and `true` will be returned. 924 * the token stream will be re-written and `true` will be returned.
925 *
860 * @param type the type of token that can optionally appear in the current loc ation 926 * @param type the type of token that can optionally appear in the current loc ation
861 * @return `true` if the current token has the given type 927 * @return `true` if the current token has the given type
862 */ 928 */
863 bool matches5(TokenType type2) { 929 bool matches5(TokenType type2) {
864 TokenType currentType = _currentToken.type; 930 TokenType currentType = _currentToken.type;
865 if (currentType != type2) { 931 if (currentType != type2) {
866 if (identical(type2, TokenType.GT)) { 932 if (identical(type2, TokenType.GT)) {
867 if (identical(currentType, TokenType.GT_GT)) { 933 if (identical(currentType, TokenType.GT_GT)) {
868 int offset = _currentToken.offset; 934 int offset = _currentToken.offset;
869 Token first = new Token(TokenType.GT, offset); 935 Token first = new Token(TokenType.GT, offset);
(...skipping 25 matching lines...) Expand all
895 return true; 961 return true;
896 } 962 }
897 } 963 }
898 return false; 964 return false;
899 } 965 }
900 return true; 966 return true;
901 } 967 }
902 968
903 /** 969 /**
904 * Return `true` if the given token has any one of the given types. 970 * Return `true` if the given token has any one of the given types.
971 *
905 * @param token the token being tested 972 * @param token the token being tested
906 * @param types the types of token that are being tested for 973 * @param types the types of token that are being tested for
907 * @return `true` if the given token has any of the given types 974 * @return `true` if the given token has any of the given types
908 */ 975 */
909 bool matchesAny(Token token, List<TokenType> types) { 976 bool matchesAny(Token token, List<TokenType> types) {
910 TokenType actualType = token.type; 977 TokenType actualType = token.type;
911 for (TokenType type in types) { 978 for (TokenType type in types) {
912 if (identical(actualType, type)) { 979 if (identical(actualType, type)) {
913 return true; 980 return true;
914 } 981 }
915 } 982 }
916 return false; 983 return false;
917 } 984 }
918 985
919 /** 986 /**
920 * Return `true` if the current token is a valid identifier. Valid identifiers include 987 * Return `true` if the current token is a valid identifier. Valid identifiers include
921 * built-in identifiers (pseudo-keywords). 988 * built-in identifiers (pseudo-keywords).
989 *
922 * @return `true` if the current token is a valid identifier 990 * @return `true` if the current token is a valid identifier
923 */ 991 */
924 bool matchesIdentifier() => matchesIdentifier2(_currentToken); 992 bool matchesIdentifier() => matchesIdentifier2(_currentToken);
925 993
926 /** 994 /**
927 * Return `true` if the given token is a valid identifier. Valid identifiers i nclude 995 * Return `true` if the given token is a valid identifier. Valid identifiers i nclude
928 * built-in identifiers (pseudo-keywords). 996 * built-in identifiers (pseudo-keywords).
997 *
929 * @return `true` if the given token is a valid identifier 998 * @return `true` if the given token is a valid identifier
930 */ 999 */
931 bool matchesIdentifier2(Token token) => matches4(token, TokenType.IDENTIFIER) || (matches4(token, TokenType.KEYWORD) && ((token as KeywordToken)).keyword.isPs eudoKeyword); 1000 bool matchesIdentifier2(Token token) => matches4(token, TokenType.IDENTIFIER) || (matches4(token, TokenType.KEYWORD) && ((token as KeywordToken)).keyword.isPs eudoKeyword);
932 1001
933 /** 1002 /**
934 * If the current token has the given type, then advance to the next token and return `true`. Otherwise, return `false` without advancing. 1003 * If the current token has the given type, then advance to the next token and return `true`
1004 * . Otherwise, return `false` without advancing.
1005 *
935 * @param type the type of token that can optionally appear in the current loc ation 1006 * @param type the type of token that can optionally appear in the current loc ation
936 * @return `true` if the current token has the given type 1007 * @return `true` if the current token has the given type
937 */ 1008 */
938 bool optional(TokenType type) { 1009 bool optional(TokenType type) {
939 if (matches5(type)) { 1010 if (matches5(type)) {
940 advance(); 1011 advance();
941 return true; 1012 return true;
942 } 1013 }
943 return false; 1014 return false;
944 } 1015 }
945 1016
946 /** 1017 /**
947 * Parse an additive expression. 1018 * Parse an additive expression.
1019 *
948 * <pre> 1020 * <pre>
949 * additiveExpression ::= 1021 * additiveExpression ::=
950 * multiplicativeExpression (additiveOperator multiplicativeExpression) 1022 * multiplicativeExpression (additiveOperator multiplicativeExpression)*
951 * | 'super' (additiveOperator multiplicativeExpression)+ 1023 * | 'super' (additiveOperator multiplicativeExpression)+
952 * </pre> 1024 * </pre>
1025 *
953 * @return the additive expression that was parsed 1026 * @return the additive expression that was parsed
954 */ 1027 */
955 Expression parseAdditiveExpression() { 1028 Expression parseAdditiveExpression() {
956 Expression expression; 1029 Expression expression;
957 if (matches(Keyword.SUPER) && _currentToken.next.type.isAdditiveOperator) { 1030 if (matches(Keyword.SUPER) && _currentToken.next.type.isAdditiveOperator) {
958 expression = new SuperExpression.full(andAdvance); 1031 expression = new SuperExpression.full(andAdvance);
959 } else { 1032 } else {
960 expression = parseMultiplicativeExpression(); 1033 expression = parseMultiplicativeExpression();
961 } 1034 }
962 while (_currentToken.type.isAdditiveOperator) { 1035 while (_currentToken.type.isAdditiveOperator) {
963 Token operator = andAdvance; 1036 Token operator = andAdvance;
964 expression = new BinaryExpression.full(expression, operator, parseMultipli cativeExpression()); 1037 expression = new BinaryExpression.full(expression, operator, parseMultipli cativeExpression());
965 } 1038 }
966 return expression; 1039 return expression;
967 } 1040 }
968 1041
969 /** 1042 /**
970 * Parse an annotation. 1043 * Parse an annotation.
1044 *
971 * <pre> 1045 * <pre>
972 * annotation ::= 1046 * annotation ::=
973 * '@' qualified ('.' identifier)? arguments? 1047 * '@' qualified ('.' identifier)? arguments?
974 * </pre> 1048 * </pre>
1049 *
975 * @return the annotation that was parsed 1050 * @return the annotation that was parsed
976 */ 1051 */
977 Annotation parseAnnotation() { 1052 Annotation parseAnnotation() {
978 Token atSign = expect2(TokenType.AT); 1053 Token atSign = expect2(TokenType.AT);
979 Identifier name = parsePrefixedIdentifier(); 1054 Identifier name = parsePrefixedIdentifier();
980 Token period = null; 1055 Token period = null;
981 SimpleIdentifier constructorName = null; 1056 SimpleIdentifier constructorName = null;
982 if (matches5(TokenType.PERIOD)) { 1057 if (matches5(TokenType.PERIOD)) {
983 period = andAdvance; 1058 period = andAdvance;
984 constructorName = parseSimpleIdentifier(); 1059 constructorName = parseSimpleIdentifier();
985 } 1060 }
986 ArgumentList arguments = null; 1061 ArgumentList arguments = null;
987 if (matches5(TokenType.OPEN_PAREN)) { 1062 if (matches5(TokenType.OPEN_PAREN)) {
988 arguments = parseArgumentList(); 1063 arguments = parseArgumentList();
989 } 1064 }
990 return new Annotation.full(atSign, name, period, constructorName, arguments) ; 1065 return new Annotation.full(atSign, name, period, constructorName, arguments) ;
991 } 1066 }
992 1067
993 /** 1068 /**
994 * Parse an argument. 1069 * Parse an argument.
1070 *
995 * <pre> 1071 * <pre>
996 * argument ::= 1072 * argument ::=
997 * namedArgument 1073 * namedArgument
998 * | expression 1074 * | expression
1075 *
999 * namedArgument ::= 1076 * namedArgument ::=
1000 * label expression 1077 * label expression
1001 * </pre> 1078 * </pre>
1079 *
1002 * @return the argument that was parsed 1080 * @return the argument that was parsed
1003 */ 1081 */
1004 Expression parseArgument() { 1082 Expression parseArgument() {
1005 if (matchesIdentifier() && matches4(peek(), TokenType.COLON)) { 1083 if (matchesIdentifier() && matches4(peek(), TokenType.COLON)) {
1006 SimpleIdentifier label = new SimpleIdentifier.full(andAdvance); 1084 SimpleIdentifier label = new SimpleIdentifier.full(andAdvance);
1007 Label name = new Label.full(label, andAdvance); 1085 Label name = new Label.full(label, andAdvance);
1008 return new NamedExpression.full(name, parseExpression2()); 1086 return new NamedExpression.full(name, parseExpression2());
1009 } else { 1087 } else {
1010 return parseExpression2(); 1088 return parseExpression2();
1011 } 1089 }
1012 } 1090 }
1013 1091
1014 /** 1092 /**
1015 * Parse an argument definition test. 1093 * Parse an argument definition test.
1094 *
1016 * <pre> 1095 * <pre>
1017 * argumentDefinitionTest ::= 1096 * argumentDefinitionTest ::=
1018 * '?' identifier 1097 * '?' identifier
1019 * </pre> 1098 * </pre>
1099 *
1020 * @return the argument definition test that was parsed 1100 * @return the argument definition test that was parsed
1021 */ 1101 */
1022 ArgumentDefinitionTest parseArgumentDefinitionTest() { 1102 ArgumentDefinitionTest parseArgumentDefinitionTest() {
1023 Token question = expect2(TokenType.QUESTION); 1103 Token question = expect2(TokenType.QUESTION);
1024 SimpleIdentifier identifier = parseSimpleIdentifier(); 1104 SimpleIdentifier identifier = parseSimpleIdentifier();
1025 return new ArgumentDefinitionTest.full(question, identifier); 1105 return new ArgumentDefinitionTest.full(question, identifier);
1026 } 1106 }
1027 1107
1028 /** 1108 /**
1029 * Parse a list of arguments. 1109 * Parse a list of arguments.
1110 *
1030 * <pre> 1111 * <pre>
1031 * arguments ::= 1112 * arguments ::=
1032 * '(' argumentList? ')' 1113 * '(' argumentList? ')'
1114 *
1033 * argumentList ::= 1115 * argumentList ::=
1034 * namedArgument (',' namedArgument) 1116 * namedArgument (',' namedArgument)*
1035 * | expressionList (',' namedArgument) 1117 * | expressionList (',' namedArgument)*
1036 * </pre> 1118 * </pre>
1119 *
1037 * @return the argument list that was parsed 1120 * @return the argument list that was parsed
1038 */ 1121 */
1039 ArgumentList parseArgumentList() { 1122 ArgumentList parseArgumentList() {
1040 Token leftParenthesis = expect2(TokenType.OPEN_PAREN); 1123 Token leftParenthesis = expect2(TokenType.OPEN_PAREN);
1041 List<Expression> arguments = new List<Expression>(); 1124 List<Expression> arguments = new List<Expression>();
1042 if (matches5(TokenType.CLOSE_PAREN)) { 1125 if (matches5(TokenType.CLOSE_PAREN)) {
1043 return new ArgumentList.full(leftParenthesis, arguments, andAdvance); 1126 return new ArgumentList.full(leftParenthesis, arguments, andAdvance);
1044 } 1127 }
1045 Expression argument = parseArgument(); 1128 Expression argument = parseArgument();
1046 arguments.add(argument); 1129 arguments.add(argument);
(...skipping 10 matching lines...) Expand all
1057 } else if (argument is NamedExpression) { 1140 } else if (argument is NamedExpression) {
1058 foundNamedArgument = true; 1141 foundNamedArgument = true;
1059 } 1142 }
1060 } 1143 }
1061 Token rightParenthesis = expect2(TokenType.CLOSE_PAREN); 1144 Token rightParenthesis = expect2(TokenType.CLOSE_PAREN);
1062 return new ArgumentList.full(leftParenthesis, arguments, rightParenthesis); 1145 return new ArgumentList.full(leftParenthesis, arguments, rightParenthesis);
1063 } 1146 }
1064 1147
1065 /** 1148 /**
1066 * Parse an assert statement. 1149 * Parse an assert statement.
1150 *
1067 * <pre> 1151 * <pre>
1068 * assertStatement ::= 1152 * assertStatement ::=
1069 * 'assert' '(' conditionalExpression ')' ';' 1153 * 'assert' '(' conditionalExpression ')' ';'
1070 * </pre> 1154 * </pre>
1155 *
1071 * @return the assert statement 1156 * @return the assert statement
1072 */ 1157 */
1073 AssertStatement parseAssertStatement() { 1158 AssertStatement parseAssertStatement() {
1074 Token keyword = expect(Keyword.ASSERT); 1159 Token keyword = expect(Keyword.ASSERT);
1075 Token leftParen = expect2(TokenType.OPEN_PAREN); 1160 Token leftParen = expect2(TokenType.OPEN_PAREN);
1076 Expression expression = parseConditionalExpression(); 1161 Expression expression = parseConditionalExpression();
1077 Token rightParen = expect2(TokenType.CLOSE_PAREN); 1162 Token rightParen = expect2(TokenType.CLOSE_PAREN);
1078 Token semicolon = expect2(TokenType.SEMICOLON); 1163 Token semicolon = expect2(TokenType.SEMICOLON);
1079 return new AssertStatement.full(keyword, leftParen, expression, rightParen, semicolon); 1164 return new AssertStatement.full(keyword, leftParen, expression, rightParen, semicolon);
1080 } 1165 }
1081 1166
1082 /** 1167 /**
1083 * Parse an assignable expression. 1168 * Parse an assignable expression.
1169 *
1084 * <pre> 1170 * <pre>
1085 * assignableExpression ::= 1171 * assignableExpression ::=
1086 * primary (arguments* assignableSelector)+ 1172 * primary (arguments* assignableSelector)+
1087 * | 'super' assignableSelector 1173 * | 'super' assignableSelector
1088 * | identifier 1174 * | identifier
1089 * </pre> 1175 * </pre>
1176 *
1090 * @param primaryAllowed `true` if the expression is allowed to be a primary w ithout any 1177 * @param primaryAllowed `true` if the expression is allowed to be a primary w ithout any
1091 * assignable selector 1178 * assignable selector
1092 * @return the assignable expression that was parsed 1179 * @return the assignable expression that was parsed
1093 */ 1180 */
1094 Expression parseAssignableExpression(bool primaryAllowed) { 1181 Expression parseAssignableExpression(bool primaryAllowed) {
1095 if (matches(Keyword.SUPER)) { 1182 if (matches(Keyword.SUPER)) {
1096 return parseAssignableSelector(new SuperExpression.full(andAdvance), false ); 1183 return parseAssignableSelector(new SuperExpression.full(andAdvance), false );
1097 } 1184 }
1098 Expression expression = parsePrimaryExpression(); 1185 Expression expression = parsePrimaryExpression();
1099 bool isOptional = primaryAllowed || expression is SimpleIdentifier; 1186 bool isOptional = primaryAllowed || expression is SimpleIdentifier;
1100 while (true) { 1187 while (true) {
1101 while (matches5(TokenType.OPEN_PAREN)) { 1188 while (matches5(TokenType.OPEN_PAREN)) {
(...skipping 21 matching lines...) Expand all
1123 } 1210 }
1124 return expression; 1211 return expression;
1125 } 1212 }
1126 expression = selectorExpression; 1213 expression = selectorExpression;
1127 isOptional = true; 1214 isOptional = true;
1128 } 1215 }
1129 } 1216 }
1130 1217
1131 /** 1218 /**
1132 * Parse an assignable selector. 1219 * Parse an assignable selector.
1220 *
1133 * <pre> 1221 * <pre>
1134 * assignableSelector ::= 1222 * assignableSelector ::=
1135 * '\[' expression '\]' 1223 * '[' expression ']'
1136 * | '.' identifier 1224 * | '.' identifier
1137 * </pre> 1225 * </pre>
1226 *
1138 * @param prefix the expression preceding the selector 1227 * @param prefix the expression preceding the selector
1139 * @param optional `true` if the selector is optional 1228 * @param optional `true` if the selector is optional
1140 * @return the assignable selector that was parsed 1229 * @return the assignable selector that was parsed
1141 */ 1230 */
1142 Expression parseAssignableSelector(Expression prefix, bool optional) { 1231 Expression parseAssignableSelector(Expression prefix, bool optional) {
1143 if (matches5(TokenType.OPEN_SQUARE_BRACKET)) { 1232 if (matches5(TokenType.OPEN_SQUARE_BRACKET)) {
1144 Token leftBracket = andAdvance; 1233 Token leftBracket = andAdvance;
1145 Expression index = parseExpression2(); 1234 Expression index = parseExpression2();
1146 Token rightBracket = expect2(TokenType.CLOSE_SQUARE_BRACKET); 1235 Token rightBracket = expect2(TokenType.CLOSE_SQUARE_BRACKET);
1147 return new IndexExpression.forTarget_full(prefix, leftBracket, index, righ tBracket); 1236 return new IndexExpression.forTarget_full(prefix, leftBracket, index, righ tBracket);
1148 } else if (matches5(TokenType.PERIOD)) { 1237 } else if (matches5(TokenType.PERIOD)) {
1149 Token period = andAdvance; 1238 Token period = andAdvance;
1150 return new PropertyAccess.full(prefix, period, parseSimpleIdentifier()); 1239 return new PropertyAccess.full(prefix, period, parseSimpleIdentifier());
1151 } else { 1240 } else {
1152 if (!optional) { 1241 if (!optional) {
1153 reportError7(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, []); 1242 reportError7(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, []);
1154 } 1243 }
1155 return prefix; 1244 return prefix;
1156 } 1245 }
1157 } 1246 }
1158 1247
1159 /** 1248 /**
1160 * Parse a bitwise and expression. 1249 * Parse a bitwise and expression.
1250 *
1161 * <pre> 1251 * <pre>
1162 * bitwiseAndExpression ::= 1252 * bitwiseAndExpression ::=
1163 * equalityExpression ('&' equalityExpression) 1253 * equalityExpression ('&' equalityExpression)*
1164 * | 'super' ('&' equalityExpression)+ 1254 * | 'super' ('&' equalityExpression)+
1165 * </pre> 1255 * </pre>
1256 *
1166 * @return the bitwise and expression that was parsed 1257 * @return the bitwise and expression that was parsed
1167 */ 1258 */
1168 Expression parseBitwiseAndExpression() { 1259 Expression parseBitwiseAndExpression() {
1169 Expression expression; 1260 Expression expression;
1170 if (matches(Keyword.SUPER) && matches4(peek(), TokenType.AMPERSAND)) { 1261 if (matches(Keyword.SUPER) && matches4(peek(), TokenType.AMPERSAND)) {
1171 expression = new SuperExpression.full(andAdvance); 1262 expression = new SuperExpression.full(andAdvance);
1172 } else { 1263 } else {
1173 expression = parseEqualityExpression(); 1264 expression = parseEqualityExpression();
1174 } 1265 }
1175 while (matches5(TokenType.AMPERSAND)) { 1266 while (matches5(TokenType.AMPERSAND)) {
1176 Token operator = andAdvance; 1267 Token operator = andAdvance;
1177 expression = new BinaryExpression.full(expression, operator, parseEquality Expression()); 1268 expression = new BinaryExpression.full(expression, operator, parseEquality Expression());
1178 } 1269 }
1179 return expression; 1270 return expression;
1180 } 1271 }
1181 1272
1182 /** 1273 /**
1183 * Parse a bitwise or expression. 1274 * Parse a bitwise or expression.
1275 *
1184 * <pre> 1276 * <pre>
1185 * bitwiseOrExpression ::= 1277 * bitwiseOrExpression ::=
1186 * bitwiseXorExpression ('|' bitwiseXorExpression) 1278 * bitwiseXorExpression ('|' bitwiseXorExpression)*
1187 * | 'super' ('|' bitwiseXorExpression)+ 1279 * | 'super' ('|' bitwiseXorExpression)+
1188 * </pre> 1280 * </pre>
1281 *
1189 * @return the bitwise or expression that was parsed 1282 * @return the bitwise or expression that was parsed
1190 */ 1283 */
1191 Expression parseBitwiseOrExpression() { 1284 Expression parseBitwiseOrExpression() {
1192 Expression expression; 1285 Expression expression;
1193 if (matches(Keyword.SUPER) && matches4(peek(), TokenType.BAR)) { 1286 if (matches(Keyword.SUPER) && matches4(peek(), TokenType.BAR)) {
1194 expression = new SuperExpression.full(andAdvance); 1287 expression = new SuperExpression.full(andAdvance);
1195 } else { 1288 } else {
1196 expression = parseBitwiseXorExpression(); 1289 expression = parseBitwiseXorExpression();
1197 } 1290 }
1198 while (matches5(TokenType.BAR)) { 1291 while (matches5(TokenType.BAR)) {
1199 Token operator = andAdvance; 1292 Token operator = andAdvance;
1200 expression = new BinaryExpression.full(expression, operator, parseBitwiseX orExpression()); 1293 expression = new BinaryExpression.full(expression, operator, parseBitwiseX orExpression());
1201 } 1294 }
1202 return expression; 1295 return expression;
1203 } 1296 }
1204 1297
1205 /** 1298 /**
1206 * Parse a bitwise exclusive-or expression. 1299 * Parse a bitwise exclusive-or expression.
1300 *
1207 * <pre> 1301 * <pre>
1208 * bitwiseXorExpression ::= 1302 * bitwiseXorExpression ::=
1209 * bitwiseAndExpression ('^' bitwiseAndExpression) 1303 * bitwiseAndExpression ('^' bitwiseAndExpression)*
1210 * | 'super' ('^' bitwiseAndExpression)+ 1304 * | 'super' ('^' bitwiseAndExpression)+
1211 * </pre> 1305 * </pre>
1306 *
1212 * @return the bitwise exclusive-or expression that was parsed 1307 * @return the bitwise exclusive-or expression that was parsed
1213 */ 1308 */
1214 Expression parseBitwiseXorExpression() { 1309 Expression parseBitwiseXorExpression() {
1215 Expression expression; 1310 Expression expression;
1216 if (matches(Keyword.SUPER) && matches4(peek(), TokenType.CARET)) { 1311 if (matches(Keyword.SUPER) && matches4(peek(), TokenType.CARET)) {
1217 expression = new SuperExpression.full(andAdvance); 1312 expression = new SuperExpression.full(andAdvance);
1218 } else { 1313 } else {
1219 expression = parseBitwiseAndExpression(); 1314 expression = parseBitwiseAndExpression();
1220 } 1315 }
1221 while (matches5(TokenType.CARET)) { 1316 while (matches5(TokenType.CARET)) {
1222 Token operator = andAdvance; 1317 Token operator = andAdvance;
1223 expression = new BinaryExpression.full(expression, operator, parseBitwiseA ndExpression()); 1318 expression = new BinaryExpression.full(expression, operator, parseBitwiseA ndExpression());
1224 } 1319 }
1225 return expression; 1320 return expression;
1226 } 1321 }
1227 1322
1228 /** 1323 /**
1229 * Parse a block. 1324 * Parse a block.
1325 *
1230 * <pre> 1326 * <pre>
1231 * block ::= 1327 * block ::=
1232 * '{' statements '}' 1328 * '{' statements '}'
1233 * </pre> 1329 * </pre>
1330 *
1234 * @return the block that was parsed 1331 * @return the block that was parsed
1235 */ 1332 */
1236 Block parseBlock() { 1333 Block parseBlock() {
1237 Token leftBracket = expect2(TokenType.OPEN_CURLY_BRACKET); 1334 Token leftBracket = expect2(TokenType.OPEN_CURLY_BRACKET);
1238 List<Statement> statements = new List<Statement>(); 1335 List<Statement> statements = new List<Statement>();
1239 Token statementStart = _currentToken; 1336 Token statementStart = _currentToken;
1240 while (!matches5(TokenType.EOF) && !matches5(TokenType.CLOSE_CURLY_BRACKET)) { 1337 while (!matches5(TokenType.EOF) && !matches5(TokenType.CLOSE_CURLY_BRACKET)) {
1241 Statement statement = parseStatement2(); 1338 Statement statement = parseStatement2();
1242 if (statement != null) { 1339 if (statement != null) {
1243 statements.add(statement); 1340 statements.add(statement);
1244 } 1341 }
1245 if (identical(_currentToken, statementStart)) { 1342 if (identical(_currentToken, statementStart)) {
1246 reportError8(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentT oken.lexeme]); 1343 reportError8(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentT oken.lexeme]);
1247 advance(); 1344 advance();
1248 } 1345 }
1249 statementStart = _currentToken; 1346 statementStart = _currentToken;
1250 } 1347 }
1251 Token rightBracket = expect2(TokenType.CLOSE_CURLY_BRACKET); 1348 Token rightBracket = expect2(TokenType.CLOSE_CURLY_BRACKET);
1252 return new Block.full(leftBracket, statements, rightBracket); 1349 return new Block.full(leftBracket, statements, rightBracket);
1253 } 1350 }
1254 1351
1255 /** 1352 /**
1256 * Parse a break statement. 1353 * Parse a break statement.
1354 *
1257 * <pre> 1355 * <pre>
1258 * breakStatement ::= 1356 * breakStatement ::=
1259 * 'break' identifier? ';' 1357 * 'break' identifier? ';'
1260 * </pre> 1358 * </pre>
1359 *
1261 * @return the break statement that was parsed 1360 * @return the break statement that was parsed
1262 */ 1361 */
1263 Statement parseBreakStatement() { 1362 Statement parseBreakStatement() {
1264 Token breakKeyword = expect(Keyword.BREAK); 1363 Token breakKeyword = expect(Keyword.BREAK);
1265 SimpleIdentifier label = null; 1364 SimpleIdentifier label = null;
1266 if (matchesIdentifier()) { 1365 if (matchesIdentifier()) {
1267 label = parseSimpleIdentifier(); 1366 label = parseSimpleIdentifier();
1268 } 1367 }
1269 if (!_inLoop && !_inSwitch && label == null) { 1368 if (!_inLoop && !_inSwitch && label == null) {
1270 reportError8(ParserErrorCode.BREAK_OUTSIDE_OF_LOOP, breakKeyword, []); 1369 reportError8(ParserErrorCode.BREAK_OUTSIDE_OF_LOOP, breakKeyword, []);
1271 } 1370 }
1272 Token semicolon = expect2(TokenType.SEMICOLON); 1371 Token semicolon = expect2(TokenType.SEMICOLON);
1273 return new BreakStatement.full(breakKeyword, label, semicolon); 1372 return new BreakStatement.full(breakKeyword, label, semicolon);
1274 } 1373 }
1275 1374
1276 /** 1375 /**
1277 * Parse a cascade section. 1376 * Parse a cascade section.
1377 *
1278 * <pre> 1378 * <pre>
1279 * cascadeSection ::= 1379 * cascadeSection ::=
1280 * '..' (cascadeSelector arguments*) (assignableSelector arguments*)* cascadeA ssignment? 1380 * '..' (cascadeSelector arguments*) (assignableSelector arguments*)* casc adeAssignment?
1381 *
1281 * cascadeSelector ::= 1382 * cascadeSelector ::=
1282 * '\[' expression '\]' 1383 * '[' expression ']'
1283 * | identifier 1384 * | identifier
1385 *
1284 * cascadeAssignment ::= 1386 * cascadeAssignment ::=
1285 * assignmentOperator expressionWithoutCascade 1387 * assignmentOperator expressionWithoutCascade
1286 * </pre> 1388 * </pre>
1389 *
1287 * @return the expression representing the cascaded method invocation 1390 * @return the expression representing the cascaded method invocation
1288 */ 1391 */
1289 Expression parseCascadeSection() { 1392 Expression parseCascadeSection() {
1290 Token period = expect2(TokenType.PERIOD_PERIOD); 1393 Token period = expect2(TokenType.PERIOD_PERIOD);
1291 Expression expression = null; 1394 Expression expression = null;
1292 SimpleIdentifier functionName = null; 1395 SimpleIdentifier functionName = null;
1293 if (matchesIdentifier()) { 1396 if (matchesIdentifier()) {
1294 functionName = parseSimpleIdentifier(); 1397 functionName = parseSimpleIdentifier();
1295 } else if (identical(_currentToken.type, TokenType.OPEN_SQUARE_BRACKET)) { 1398 } else if (identical(_currentToken.type, TokenType.OPEN_SQUARE_BRACKET)) {
1296 Token leftBracket = andAdvance; 1399 Token leftBracket = andAdvance;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1333 if (_currentToken.type.isAssignmentOperator) { 1436 if (_currentToken.type.isAssignmentOperator) {
1334 Token operator = andAdvance; 1437 Token operator = andAdvance;
1335 ensureAssignable(expression); 1438 ensureAssignable(expression);
1336 expression = new AssignmentExpression.full(expression, operator, parseExpr essionWithoutCascade()); 1439 expression = new AssignmentExpression.full(expression, operator, parseExpr essionWithoutCascade());
1337 } 1440 }
1338 return expression; 1441 return expression;
1339 } 1442 }
1340 1443
1341 /** 1444 /**
1342 * Parse a class declaration. 1445 * Parse a class declaration.
1446 *
1343 * <pre> 1447 * <pre>
1344 * classDeclaration ::= 1448 * classDeclaration ::=
1345 * metadata 'abstract'? 'class' name typeParameterList? (extendsClause withCla use?)? implementsClause? '{' classMembers '}' 1449 * metadata 'abstract'? 'class' name typeParameterList? (extendsClause wit hClause?)? implementsClause? '{' classMembers '}'
1346 * </pre> 1450 * </pre>
1451 *
1347 * @param commentAndMetadata the metadata to be associated with the member 1452 * @param commentAndMetadata the metadata to be associated with the member
1348 * @param abstractKeyword the token for the keyword 'abstract', or `null` if t he keyword was 1453 * @param abstractKeyword the token for the keyword 'abstract', or `null` if t he keyword was
1349 * not given 1454 * not given
1350 * @return the class declaration that was parsed 1455 * @return the class declaration that was parsed
1351 */ 1456 */
1352 ClassDeclaration parseClassDeclaration(CommentAndMetadata commentAndMetadata, Token abstractKeyword) { 1457 ClassDeclaration parseClassDeclaration(CommentAndMetadata commentAndMetadata, Token abstractKeyword) {
1353 Token keyword = expect(Keyword.CLASS); 1458 Token keyword = expect(Keyword.CLASS);
1354 SimpleIdentifier name = parseSimpleIdentifier(); 1459 SimpleIdentifier name = parseSimpleIdentifier();
1355 String className = name.name; 1460 String className = name.name;
1356 TypeParameterList typeParameters = null; 1461 TypeParameterList typeParameters = null;
1357 if (matches5(TokenType.LT)) { 1462 if (matches5(TokenType.LT)) {
1358 typeParameters = parseTypeParameterList(); 1463 typeParameters = parseTypeParameterList();
1359 } 1464 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1412 } else { 1517 } else {
1413 leftBracket = createSyntheticToken2(TokenType.OPEN_CURLY_BRACKET); 1518 leftBracket = createSyntheticToken2(TokenType.OPEN_CURLY_BRACKET);
1414 rightBracket = createSyntheticToken2(TokenType.CLOSE_CURLY_BRACKET); 1519 rightBracket = createSyntheticToken2(TokenType.CLOSE_CURLY_BRACKET);
1415 reportError7(ParserErrorCode.MISSING_CLASS_BODY, []); 1520 reportError7(ParserErrorCode.MISSING_CLASS_BODY, []);
1416 } 1521 }
1417 return new ClassDeclaration.full(commentAndMetadata.comment, commentAndMetad ata.metadata, abstractKeyword, keyword, name, typeParameters, extendsClause, wit hClause, implementsClause, leftBracket, members, rightBracket); 1522 return new ClassDeclaration.full(commentAndMetadata.comment, commentAndMetad ata.metadata, abstractKeyword, keyword, name, typeParameters, extendsClause, wit hClause, implementsClause, leftBracket, members, rightBracket);
1418 } 1523 }
1419 1524
1420 /** 1525 /**
1421 * Parse a class member. 1526 * Parse a class member.
1527 *
1422 * <pre> 1528 * <pre>
1423 * classMemberDefinition ::= 1529 * classMemberDefinition ::=
1424 * declaration ';' 1530 * declaration ';'
1425 * | methodSignature functionBody 1531 * | methodSignature functionBody
1426 * </pre> 1532 * </pre>
1533 *
1427 * @param className the name of the class containing the member being parsed 1534 * @param className the name of the class containing the member being parsed
1428 * @return the class member that was parsed, or `null` if what was found was n ot a valid 1535 * @return the class member that was parsed, or `null` if what was found was n ot a valid
1429 * class member 1536 * class member
1430 */ 1537 */
1431 ClassMember parseClassMember(String className) { 1538 ClassMember parseClassMember(String className) {
1432 CommentAndMetadata commentAndMetadata = parseCommentAndMetadata(); 1539 CommentAndMetadata commentAndMetadata = parseCommentAndMetadata();
1433 Modifiers modifiers = parseModifiers(); 1540 Modifiers modifiers = parseModifiers();
1434 if (matches(Keyword.VOID)) { 1541 if (matches(Keyword.VOID)) {
1435 TypeName returnType = parseReturnType(); 1542 TypeName returnType = parseReturnType();
1436 if (matches(Keyword.GET) && matchesIdentifier2(peek())) { 1543 if (matches(Keyword.GET) && matchesIdentifier2(peek())) {
1437 validateModifiersForGetterOrSetterOrMethod(modifiers); 1544 validateModifiersForGetterOrSetterOrMethod(modifiers);
1438 return parseGetter(commentAndMetadata, modifiers.externalKeyword, modifi ers.staticKeyword, returnType); 1545 return parseGetter(commentAndMetadata, modifiers.externalKeyword, modifi ers.staticKeyword, returnType);
1439 } else if (matches(Keyword.SET) && matchesIdentifier2(peek())) { 1546 } else if (matches(Keyword.SET) && matchesIdentifier2(peek())) {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1521 } 1628 }
1522 validateModifiersForGetterOrSetterOrMethod(modifiers); 1629 validateModifiersForGetterOrSetterOrMethod(modifiers);
1523 validateFormalParameterList(parameters); 1630 validateFormalParameterList(parameters);
1524 return parseMethodDeclaration2(commentAndMetadata, modifiers.externalKeywo rd, modifiers.staticKeyword, type, methodName, parameters); 1631 return parseMethodDeclaration2(commentAndMetadata, modifiers.externalKeywo rd, modifiers.staticKeyword, type, methodName, parameters);
1525 } 1632 }
1526 return parseInitializedIdentifierList(commentAndMetadata, modifiers.staticKe yword, validateModifiersForField(modifiers), type); 1633 return parseInitializedIdentifierList(commentAndMetadata, modifiers.staticKe yword, validateModifiersForField(modifiers), type);
1527 } 1634 }
1528 1635
1529 /** 1636 /**
1530 * Parse a list of class members. 1637 * Parse a list of class members.
1638 *
1531 * <pre> 1639 * <pre>
1532 * classMembers ::= 1640 * classMembers ::=
1533 * (metadata memberDefinition) 1641 * (metadata memberDefinition)*
1534 * </pre> 1642 * </pre>
1643 *
1535 * @param className the name of the class whose members are being parsed 1644 * @param className the name of the class whose members are being parsed
1536 * @param closingBracket the closing bracket for the class, or `null` if the c losing bracket 1645 * @param closingBracket the closing bracket for the class, or `null` if the c losing bracket
1537 * is missing 1646 * is missing
1538 * @return the list of class members that were parsed 1647 * @return the list of class members that were parsed
1539 */ 1648 */
1540 List<ClassMember> parseClassMembers(String className, Token closingBracket) { 1649 List<ClassMember> parseClassMembers(String className, Token closingBracket) {
1541 List<ClassMember> members = new List<ClassMember>(); 1650 List<ClassMember> members = new List<ClassMember>();
1542 Token memberStart = _currentToken; 1651 Token memberStart = _currentToken;
1543 while (!matches5(TokenType.EOF) && !matches5(TokenType.CLOSE_CURLY_BRACKET) && (closingBracket != null || (!matches(Keyword.CLASS) && !matches(Keyword.TYPED EF)))) { 1652 while (!matches5(TokenType.EOF) && !matches5(TokenType.CLOSE_CURLY_BRACKET) && (closingBracket != null || (!matches(Keyword.CLASS) && !matches(Keyword.TYPED EF)))) {
1544 if (matches5(TokenType.SEMICOLON)) { 1653 if (matches5(TokenType.SEMICOLON)) {
1545 reportError8(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentT oken.lexeme]); 1654 reportError8(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentT oken.lexeme]);
1546 advance(); 1655 advance();
1547 } else { 1656 } else {
1548 ClassMember member = parseClassMember(className); 1657 ClassMember member = parseClassMember(className);
1549 if (member != null) { 1658 if (member != null) {
1550 members.add(member); 1659 members.add(member);
1551 } 1660 }
1552 } 1661 }
1553 if (identical(_currentToken, memberStart)) { 1662 if (identical(_currentToken, memberStart)) {
1554 reportError8(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentT oken.lexeme]); 1663 reportError8(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentT oken.lexeme]);
1555 advance(); 1664 advance();
1556 } 1665 }
1557 memberStart = _currentToken; 1666 memberStart = _currentToken;
1558 } 1667 }
1559 return members; 1668 return members;
1560 } 1669 }
1561 1670
1562 /** 1671 /**
1563 * Parse a class type alias. 1672 * Parse a class type alias.
1673 *
1564 * <pre> 1674 * <pre>
1565 * classTypeAlias ::= 1675 * classTypeAlias ::=
1566 * identifier typeParameters? '=' 'abstract'? mixinApplication 1676 * identifier typeParameters? '=' 'abstract'? mixinApplication
1677 *
1567 * mixinApplication ::= 1678 * mixinApplication ::=
1568 * type withClause implementsClause? ';' 1679 * type withClause implementsClause? ';'
1569 * </pre> 1680 * </pre>
1681 *
1570 * @param commentAndMetadata the metadata to be associated with the member 1682 * @param commentAndMetadata the metadata to be associated with the member
1571 * @param keyword the token representing the 'typedef' keyword 1683 * @param keyword the token representing the 'typedef' keyword
1572 * @return the class type alias that was parsed 1684 * @return the class type alias that was parsed
1573 */ 1685 */
1574 ClassTypeAlias parseClassTypeAlias(CommentAndMetadata commentAndMetadata, Toke n keyword) { 1686 ClassTypeAlias parseClassTypeAlias(CommentAndMetadata commentAndMetadata, Toke n keyword) {
1575 SimpleIdentifier className = parseSimpleIdentifier(); 1687 SimpleIdentifier className = parseSimpleIdentifier();
1576 TypeParameterList typeParameters = null; 1688 TypeParameterList typeParameters = null;
1577 if (matches5(TokenType.LT)) { 1689 if (matches5(TokenType.LT)) {
1578 typeParameters = parseTypeParameterList(); 1690 typeParameters = parseTypeParameterList();
1579 } 1691 }
(...skipping 23 matching lines...) Expand all
1603 } else { 1715 } else {
1604 reportError8(ParserErrorCode.EXPECTED_TOKEN, _currentToken.previous, [To kenType.SEMICOLON.lexeme]); 1716 reportError8(ParserErrorCode.EXPECTED_TOKEN, _currentToken.previous, [To kenType.SEMICOLON.lexeme]);
1605 } 1717 }
1606 semicolon = createSyntheticToken2(TokenType.SEMICOLON); 1718 semicolon = createSyntheticToken2(TokenType.SEMICOLON);
1607 } 1719 }
1608 return new ClassTypeAlias.full(commentAndMetadata.comment, commentAndMetadat a.metadata, keyword, className, typeParameters, equals, abstractKeyword, supercl ass, withClause, implementsClause, semicolon); 1720 return new ClassTypeAlias.full(commentAndMetadata.comment, commentAndMetadat a.metadata, keyword, className, typeParameters, equals, abstractKeyword, supercl ass, withClause, implementsClause, semicolon);
1609 } 1721 }
1610 1722
1611 /** 1723 /**
1612 * Parse a list of combinators in a directive. 1724 * Parse a list of combinators in a directive.
1725 *
1613 * <pre> 1726 * <pre>
1614 * combinator ::= 1727 * combinator ::=
1615 * 'show' identifier (',' identifier) 1728 * 'show' identifier (',' identifier)*
1616 * | 'hide' identifier (',' identifier) 1729 * | 'hide' identifier (',' identifier)*
1617 * </pre> 1730 * </pre>
1731 *
1618 * @return the combinators that were parsed 1732 * @return the combinators that were parsed
1619 */ 1733 */
1620 List<Combinator> parseCombinators() { 1734 List<Combinator> parseCombinators() {
1621 List<Combinator> combinators = new List<Combinator>(); 1735 List<Combinator> combinators = new List<Combinator>();
1622 while (matches2(_SHOW) || matches2(_HIDE)) { 1736 while (matches2(_SHOW) || matches2(_HIDE)) {
1623 Token keyword = expect2(TokenType.IDENTIFIER); 1737 Token keyword = expect2(TokenType.IDENTIFIER);
1624 if (keyword.lexeme == _SHOW) { 1738 if (keyword.lexeme == _SHOW) {
1625 List<SimpleIdentifier> shownNames = parseIdentifierList(); 1739 List<SimpleIdentifier> shownNames = parseIdentifierList();
1626 combinators.add(new ShowCombinator.full(keyword, shownNames)); 1740 combinators.add(new ShowCombinator.full(keyword, shownNames));
1627 } else { 1741 } else {
1628 List<SimpleIdentifier> hiddenNames = parseIdentifierList(); 1742 List<SimpleIdentifier> hiddenNames = parseIdentifierList();
1629 combinators.add(new HideCombinator.full(keyword, hiddenNames)); 1743 combinators.add(new HideCombinator.full(keyword, hiddenNames));
1630 } 1744 }
1631 } 1745 }
1632 return combinators; 1746 return combinators;
1633 } 1747 }
1634 1748
1635 /** 1749 /**
1636 * Parse the documentation comment and metadata preceeding a declaration. This method allows any 1750 * Parse the documentation comment and metadata preceeding a declaration. This method allows any
1637 * number of documentation comments to occur before, after or between the meta data, but only 1751 * number of documentation comments to occur before, after or between the meta data, but only
1638 * returns the last (right-most) documentation comment that is found. 1752 * returns the last (right-most) documentation comment that is found.
1753 *
1639 * <pre> 1754 * <pre>
1640 * metadata ::= 1755 * metadata ::=
1641 * annotation 1756 * annotation*
1642 * </pre> 1757 * </pre>
1758 *
1643 * @return the documentation comment and metadata that were parsed 1759 * @return the documentation comment and metadata that were parsed
1644 */ 1760 */
1645 CommentAndMetadata parseCommentAndMetadata() { 1761 CommentAndMetadata parseCommentAndMetadata() {
1646 Comment comment = parseDocumentationComment(); 1762 Comment comment = parseDocumentationComment();
1647 List<Annotation> metadata = new List<Annotation>(); 1763 List<Annotation> metadata = new List<Annotation>();
1648 while (matches5(TokenType.AT)) { 1764 while (matches5(TokenType.AT)) {
1649 metadata.add(parseAnnotation()); 1765 metadata.add(parseAnnotation());
1650 Comment optionalComment = parseDocumentationComment(); 1766 Comment optionalComment = parseDocumentationComment();
1651 if (optionalComment != null) { 1767 if (optionalComment != null) {
1652 comment = optionalComment; 1768 comment = optionalComment;
1653 } 1769 }
1654 } 1770 }
1655 return new CommentAndMetadata(comment, metadata); 1771 return new CommentAndMetadata(comment, metadata);
1656 } 1772 }
1657 1773
1658 /** 1774 /**
1659 * Parse a comment reference from the source between square brackets. 1775 * Parse a comment reference from the source between square brackets.
1776 *
1660 * <pre> 1777 * <pre>
1661 * commentReference ::= 1778 * commentReference ::=
1662 * 'new'? prefixedIdentifier 1779 * 'new'? prefixedIdentifier
1663 * </pre> 1780 * </pre>
1781 *
1664 * @param referenceSource the source occurring between the square brackets wit hin a documentation 1782 * @param referenceSource the source occurring between the square brackets wit hin a documentation
1665 * comment 1783 * comment
1666 * @param sourceOffset the offset of the first character of the reference sour ce 1784 * @param sourceOffset the offset of the first character of the reference sour ce
1667 * @return the comment reference that was parsed, or `null` if no reference co uld be found 1785 * @return the comment reference that was parsed, or `null` if no reference co uld be found
1668 */ 1786 */
1669 CommentReference parseCommentReference(String referenceSource, int sourceOffse t) { 1787 CommentReference parseCommentReference(String referenceSource, int sourceOffse t) {
1670 if (referenceSource.length == 0) { 1788 if (referenceSource.length == 0) {
1671 return null; 1789 return null;
1672 } 1790 }
1673 try { 1791 try {
1674 List<bool> errorFound = [false]; 1792 List<bool> errorFound = [false];
1675 AnalysisErrorListener listener = new AnalysisErrorListener_11(errorFound); 1793 AnalysisErrorListener listener = new AnalysisErrorListener_12(errorFound);
1676 StringScanner scanner = new StringScanner(null, referenceSource, listener) ; 1794 StringScanner scanner = new StringScanner(null, referenceSource, listener) ;
1677 scanner.setSourceStart(1, 1, sourceOffset); 1795 scanner.setSourceStart(1, 1, sourceOffset);
1678 Token firstToken = scanner.tokenize(); 1796 Token firstToken = scanner.tokenize();
1679 if (errorFound[0]) { 1797 if (errorFound[0]) {
1680 return null; 1798 return null;
1681 } 1799 }
1682 Token newKeyword = null; 1800 Token newKeyword = null;
1683 if (matches3(firstToken, Keyword.NEW)) { 1801 if (matches3(firstToken, Keyword.NEW)) {
1684 newKeyword = firstToken; 1802 newKeyword = firstToken;
1685 firstToken = firstToken.next; 1803 firstToken = firstToken.next;
(...skipping 17 matching lines...) Expand all
1703 } else if (matches3(firstToken, Keyword.THIS) || matches3(firstToken, Keyw ord.NULL) || matches3(firstToken, Keyword.TRUE) || matches3(firstToken, Keyword. FALSE)) { 1821 } else if (matches3(firstToken, Keyword.THIS) || matches3(firstToken, Keyw ord.NULL) || matches3(firstToken, Keyword.TRUE) || matches3(firstToken, Keyword. FALSE)) {
1704 return null; 1822 return null;
1705 } 1823 }
1706 } catch (exception) { 1824 } catch (exception) {
1707 } 1825 }
1708 return null; 1826 return null;
1709 } 1827 }
1710 1828
1711 /** 1829 /**
1712 * Parse all of the comment references occurring in the given array of documen tation comments. 1830 * Parse all of the comment references occurring in the given array of documen tation comments.
1831 *
1713 * <pre> 1832 * <pre>
1714 * commentReference ::= 1833 * commentReference ::=
1715 * '\[' 'new'? qualified '\]' libraryReference? 1834 * '[' 'new'? qualified ']' libraryReference?
1835 *
1716 * libraryReference ::= 1836 * libraryReference ::=
1717 * '(' stringLiteral ')' 1837 * '(' stringLiteral ')'
1718 * </pre> 1838 * </pre>
1839 *
1719 * @param tokens the comment tokens representing the documentation comments to be parsed 1840 * @param tokens the comment tokens representing the documentation comments to be parsed
1720 * @return the comment references that were parsed 1841 * @return the comment references that were parsed
1721 */ 1842 */
1722 List<CommentReference> parseCommentReferences(List<Token> tokens) { 1843 List<CommentReference> parseCommentReferences(List<Token> tokens) {
1723 List<CommentReference> references = new List<CommentReference>(); 1844 List<CommentReference> references = new List<CommentReference>();
1724 for (Token token in tokens) { 1845 for (Token token in tokens) {
1725 String comment = token.lexeme; 1846 String comment = token.lexeme;
1726 int length = comment.length; 1847 int length = comment.length;
1727 List<List<int>> codeBlockRanges = getCodeBlockRanges(comment); 1848 List<List<int>> codeBlockRanges = getCodeBlockRanges(comment);
1728 int leftIndex = comment.indexOf('['); 1849 int leftIndex = comment.indexOf('[');
(...skipping 21 matching lines...) Expand all
1750 } 1871 }
1751 } 1872 }
1752 } 1873 }
1753 return references; 1874 return references;
1754 } 1875 }
1755 1876
1756 /** 1877 /**
1757 * Parse a compilation unit. 1878 * Parse a compilation unit.
1758 * 1879 *
1759 * Specified: 1880 * Specified:
1881 *
1760 * <pre> 1882 * <pre>
1761 * compilationUnit ::= 1883 * compilationUnit ::=
1762 * scriptTag? directive* topLevelDeclaration 1884 * scriptTag? directive* topLevelDeclaration*
1763 * </pre> 1885 * </pre>
1764 * Actual: 1886 * Actual:
1887 *
1765 * <pre> 1888 * <pre>
1766 * compilationUnit ::= 1889 * compilationUnit ::=
1767 * scriptTag? topLevelElement 1890 * scriptTag? topLevelElement*
1891 *
1768 * topLevelElement ::= 1892 * topLevelElement ::=
1769 * directive 1893 * directive
1770 * | topLevelDeclaration 1894 * | topLevelDeclaration
1771 * </pre> 1895 * </pre>
1896 *
1772 * @return the compilation unit that was parsed 1897 * @return the compilation unit that was parsed
1773 */ 1898 */
1774 CompilationUnit parseCompilationUnit2() { 1899 CompilationUnit parseCompilationUnit2() {
1775 Token firstToken = _currentToken; 1900 Token firstToken = _currentToken;
1776 ScriptTag scriptTag = null; 1901 ScriptTag scriptTag = null;
1777 if (matches5(TokenType.SCRIPT_TAG)) { 1902 if (matches5(TokenType.SCRIPT_TAG)) {
1778 scriptTag = new ScriptTag.full(andAdvance); 1903 scriptTag = new ScriptTag.full(andAdvance);
1779 } 1904 }
1780 bool libraryDirectiveFound = false; 1905 bool libraryDirectiveFound = false;
1781 bool partOfDirectiveFound = false; 1906 bool partOfDirectiveFound = false;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1841 advance(); 1966 advance();
1842 } 1967 }
1843 } 1968 }
1844 memberStart = _currentToken; 1969 memberStart = _currentToken;
1845 } 1970 }
1846 return new CompilationUnit.full(firstToken, scriptTag, directives, declarati ons, _currentToken); 1971 return new CompilationUnit.full(firstToken, scriptTag, directives, declarati ons, _currentToken);
1847 } 1972 }
1848 1973
1849 /** 1974 /**
1850 * Parse a compilation unit member. 1975 * Parse a compilation unit member.
1976 *
1851 * <pre> 1977 * <pre>
1852 * compilationUnitMember ::= 1978 * compilationUnitMember ::=
1853 * classDefinition 1979 * classDefinition
1854 * | functionTypeAlias 1980 * | functionTypeAlias
1855 * | external functionSignature 1981 * | external functionSignature
1856 * | external getterSignature 1982 * | external getterSignature
1857 * | external setterSignature 1983 * | external setterSignature
1858 * | functionSignature functionBody 1984 * | functionSignature functionBody
1859 * | returnType? getOrSet identifier formalParameterList functionBody 1985 * | returnType? getOrSet identifier formalParameterList functionBody
1860 * | (final | const) type? staticFinalDeclarationList ';' 1986 * | (final | const) type? staticFinalDeclarationList ';'
1861 * | variableDeclaration ';' 1987 * | variableDeclaration ';'
1862 * </pre> 1988 * </pre>
1989 *
1863 * @param commentAndMetadata the metadata to be associated with the member 1990 * @param commentAndMetadata the metadata to be associated with the member
1864 * @return the compilation unit member that was parsed, or `null` if what was parsed could 1991 * @return the compilation unit member that was parsed, or `null` if what was parsed could
1865 * not be represented as a compilation unit member 1992 * not be represented as a compilation unit member
1866 */ 1993 */
1867 CompilationUnitMember parseCompilationUnitMember(CommentAndMetadata commentAnd Metadata) { 1994 CompilationUnitMember parseCompilationUnitMember(CommentAndMetadata commentAnd Metadata) {
1868 Modifiers modifiers = parseModifiers(); 1995 Modifiers modifiers = parseModifiers();
1869 if (matches(Keyword.CLASS)) { 1996 if (matches(Keyword.CLASS)) {
1870 return parseClassDeclaration(commentAndMetadata, validateModifiersForClass (modifiers)); 1997 return parseClassDeclaration(commentAndMetadata, validateModifiersForClass (modifiers));
1871 } else if (matches(Keyword.TYPEDEF) && !matches4(peek(), TokenType.PERIOD) & & !matches4(peek(), TokenType.LT)) { 1998 } else if (matches(Keyword.TYPEDEF) && !matches4(peek(), TokenType.PERIOD) & & !matches4(peek(), TokenType.LT)) {
1872 validateModifiersForTypedef(modifiers); 1999 validateModifiersForTypedef(modifiers);
1873 return parseTypeAlias(commentAndMetadata); 2000 return parseTypeAlias(commentAndMetadata);
1874 } 2001 }
1875 if (matches(Keyword.VOID)) { 2002 if (matches(Keyword.VOID)) {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1924 } 2051 }
1925 if (matchesAny(peek(), [TokenType.OPEN_PAREN, TokenType.FUNCTION, TokenType. OPEN_CURLY_BRACKET])) { 2052 if (matchesAny(peek(), [TokenType.OPEN_PAREN, TokenType.FUNCTION, TokenType. OPEN_CURLY_BRACKET])) {
1926 validateModifiersForTopLevelFunction(modifiers); 2053 validateModifiersForTopLevelFunction(modifiers);
1927 return parseFunctionDeclaration(commentAndMetadata, modifiers.externalKeyw ord, returnType); 2054 return parseFunctionDeclaration(commentAndMetadata, modifiers.externalKeyw ord, returnType);
1928 } 2055 }
1929 return new TopLevelVariableDeclaration.full(commentAndMetadata.comment, comm entAndMetadata.metadata, parseVariableDeclarationList2(null, validateModifiersFo rTopLevelVariable(modifiers), returnType), expect2(TokenType.SEMICOLON)); 2056 return new TopLevelVariableDeclaration.full(commentAndMetadata.comment, comm entAndMetadata.metadata, parseVariableDeclarationList2(null, validateModifiersFo rTopLevelVariable(modifiers), returnType), expect2(TokenType.SEMICOLON));
1930 } 2057 }
1931 2058
1932 /** 2059 /**
1933 * Parse a conditional expression. 2060 * Parse a conditional expression.
2061 *
1934 * <pre> 2062 * <pre>
1935 * conditionalExpression ::= 2063 * conditionalExpression ::=
1936 * logicalOrExpression ('?' expressionWithoutCascade ':' expressionWithoutCasc ade)? 2064 * logicalOrExpression ('?' expressionWithoutCascade ':' expressionWithout Cascade)?
1937 * </pre> 2065 * </pre>
2066 *
1938 * @return the conditional expression that was parsed 2067 * @return the conditional expression that was parsed
1939 */ 2068 */
1940 Expression parseConditionalExpression() { 2069 Expression parseConditionalExpression() {
1941 Expression condition = parseLogicalOrExpression(); 2070 Expression condition = parseLogicalOrExpression();
1942 if (!matches5(TokenType.QUESTION)) { 2071 if (!matches5(TokenType.QUESTION)) {
1943 return condition; 2072 return condition;
1944 } 2073 }
1945 Token question = andAdvance; 2074 Token question = andAdvance;
1946 Expression thenExpression = parseExpressionWithoutCascade(); 2075 Expression thenExpression = parseExpressionWithoutCascade();
1947 Token colon = expect2(TokenType.COLON); 2076 Token colon = expect2(TokenType.COLON);
1948 Expression elseExpression = parseExpressionWithoutCascade(); 2077 Expression elseExpression = parseExpressionWithoutCascade();
1949 return new ConditionalExpression.full(condition, question, thenExpression, c olon, elseExpression); 2078 return new ConditionalExpression.full(condition, question, thenExpression, c olon, elseExpression);
1950 } 2079 }
1951 2080
1952 /** 2081 /**
1953 * Parse a const expression. 2082 * Parse a const expression.
2083 *
1954 * <pre> 2084 * <pre>
1955 * constExpression ::= 2085 * constExpression ::=
1956 * instanceCreationExpression 2086 * instanceCreationExpression
1957 * | listLiteral 2087 * | listLiteral
1958 * | mapLiteral 2088 * | mapLiteral
1959 * </pre> 2089 * </pre>
2090 *
1960 * @return the const expression that was parsed 2091 * @return the const expression that was parsed
1961 */ 2092 */
1962 Expression parseConstExpression() { 2093 Expression parseConstExpression() {
1963 Token keyword = expect(Keyword.CONST); 2094 Token keyword = expect(Keyword.CONST);
1964 if (matches5(TokenType.OPEN_SQUARE_BRACKET) || matches5(TokenType.INDEX)) { 2095 if (matches5(TokenType.OPEN_SQUARE_BRACKET) || matches5(TokenType.INDEX)) {
1965 return parseListLiteral(keyword, null); 2096 return parseListLiteral(keyword, null);
1966 } else if (matches5(TokenType.OPEN_CURLY_BRACKET)) { 2097 } else if (matches5(TokenType.OPEN_CURLY_BRACKET)) {
1967 return parseMapLiteral(keyword, null); 2098 return parseMapLiteral(keyword, null);
1968 } else if (matches5(TokenType.LT)) { 2099 } else if (matches5(TokenType.LT)) {
1969 return parseListOrMapLiteral(keyword); 2100 return parseListOrMapLiteral(keyword);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
2015 } else if (!bodyAllowed) { 2146 } else if (!bodyAllowed) {
2016 reportError(ParserErrorCode.EXTERNAL_CONSTRUCTOR_WITH_BODY, body, []); 2147 reportError(ParserErrorCode.EXTERNAL_CONSTRUCTOR_WITH_BODY, body, []);
2017 } 2148 }
2018 } 2149 }
2019 } 2150 }
2020 return new ConstructorDeclaration.full(commentAndMetadata.comment, commentAn dMetadata.metadata, externalKeyword, constKeyword, factoryKeyword, returnType, p eriod, name, parameters, separator, initializers, redirectedConstructor, body); 2151 return new ConstructorDeclaration.full(commentAndMetadata.comment, commentAn dMetadata.metadata, externalKeyword, constKeyword, factoryKeyword, returnType, p eriod, name, parameters, separator, initializers, redirectedConstructor, body);
2021 } 2152 }
2022 2153
2023 /** 2154 /**
2024 * Parse a field initializer within a constructor. 2155 * Parse a field initializer within a constructor.
2156 *
2025 * <pre> 2157 * <pre>
2026 * fieldInitializer: 2158 * fieldInitializer:
2027 * ('this' '.')? identifier '=' conditionalExpression cascadeSection 2159 * ('this' '.')? identifier '=' conditionalExpression cascadeSection*
2028 * </pre> 2160 * </pre>
2161 *
2029 * @return the field initializer that was parsed 2162 * @return the field initializer that was parsed
2030 */ 2163 */
2031 ConstructorFieldInitializer parseConstructorFieldInitializer() { 2164 ConstructorFieldInitializer parseConstructorFieldInitializer() {
2032 Token keyword = null; 2165 Token keyword = null;
2033 Token period = null; 2166 Token period = null;
2034 if (matches(Keyword.THIS)) { 2167 if (matches(Keyword.THIS)) {
2035 keyword = andAdvance; 2168 keyword = andAdvance;
2036 period = expect2(TokenType.PERIOD); 2169 period = expect2(TokenType.PERIOD);
2037 } 2170 }
2038 SimpleIdentifier fieldName = parseSimpleIdentifier(); 2171 SimpleIdentifier fieldName = parseSimpleIdentifier();
2039 Token equals = expect2(TokenType.EQ); 2172 Token equals = expect2(TokenType.EQ);
2040 Expression expression = parseConditionalExpression(); 2173 Expression expression = parseConditionalExpression();
2041 TokenType tokenType = _currentToken.type; 2174 TokenType tokenType = _currentToken.type;
2042 if (identical(tokenType, TokenType.PERIOD_PERIOD)) { 2175 if (identical(tokenType, TokenType.PERIOD_PERIOD)) {
2043 List<Expression> cascadeSections = new List<Expression>(); 2176 List<Expression> cascadeSections = new List<Expression>();
2044 while (identical(tokenType, TokenType.PERIOD_PERIOD)) { 2177 while (identical(tokenType, TokenType.PERIOD_PERIOD)) {
2045 Expression section = parseCascadeSection(); 2178 Expression section = parseCascadeSection();
2046 if (section != null) { 2179 if (section != null) {
2047 cascadeSections.add(section); 2180 cascadeSections.add(section);
2048 } 2181 }
2049 tokenType = _currentToken.type; 2182 tokenType = _currentToken.type;
2050 } 2183 }
2051 expression = new CascadeExpression.full(expression, cascadeSections); 2184 expression = new CascadeExpression.full(expression, cascadeSections);
2052 } 2185 }
2053 return new ConstructorFieldInitializer.full(keyword, period, fieldName, equa ls, expression); 2186 return new ConstructorFieldInitializer.full(keyword, period, fieldName, equa ls, expression);
2054 } 2187 }
2055 2188
2056 /** 2189 /**
2057 * Parse the name of a constructor. 2190 * Parse the name of a constructor.
2191 *
2058 * <pre> 2192 * <pre>
2059 * constructorName: 2193 * constructorName:
2060 * type ('.' identifier)? 2194 * type ('.' identifier)?
2061 * </pre> 2195 * </pre>
2196 *
2062 * @return the constructor name that was parsed 2197 * @return the constructor name that was parsed
2063 */ 2198 */
2064 ConstructorName parseConstructorName() { 2199 ConstructorName parseConstructorName() {
2065 TypeName type = parseTypeName(); 2200 TypeName type = parseTypeName();
2066 Token period = null; 2201 Token period = null;
2067 SimpleIdentifier name = null; 2202 SimpleIdentifier name = null;
2068 if (matches5(TokenType.PERIOD)) { 2203 if (matches5(TokenType.PERIOD)) {
2069 period = andAdvance; 2204 period = andAdvance;
2070 name = parseSimpleIdentifier(); 2205 name = parseSimpleIdentifier();
2071 } 2206 }
2072 return new ConstructorName.full(type, period, name); 2207 return new ConstructorName.full(type, period, name);
2073 } 2208 }
2074 2209
2075 /** 2210 /**
2076 * Parse a continue statement. 2211 * Parse a continue statement.
2212 *
2077 * <pre> 2213 * <pre>
2078 * continueStatement ::= 2214 * continueStatement ::=
2079 * 'continue' identifier? ';' 2215 * 'continue' identifier? ';'
2080 * </pre> 2216 * </pre>
2217 *
2081 * @return the continue statement that was parsed 2218 * @return the continue statement that was parsed
2082 */ 2219 */
2083 Statement parseContinueStatement() { 2220 Statement parseContinueStatement() {
2084 Token continueKeyword = expect(Keyword.CONTINUE); 2221 Token continueKeyword = expect(Keyword.CONTINUE);
2085 if (!_inLoop && !_inSwitch) { 2222 if (!_inLoop && !_inSwitch) {
2086 reportError8(ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP, continueKeyword, [] ); 2223 reportError8(ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP, continueKeyword, [] );
2087 } 2224 }
2088 SimpleIdentifier label = null; 2225 SimpleIdentifier label = null;
2089 if (matchesIdentifier()) { 2226 if (matchesIdentifier()) {
2090 label = parseSimpleIdentifier(); 2227 label = parseSimpleIdentifier();
2091 } 2228 }
2092 if (_inSwitch && !_inLoop && label == null) { 2229 if (_inSwitch && !_inLoop && label == null) {
2093 reportError8(ParserErrorCode.CONTINUE_WITHOUT_LABEL_IN_CASE, continueKeywo rd, []); 2230 reportError8(ParserErrorCode.CONTINUE_WITHOUT_LABEL_IN_CASE, continueKeywo rd, []);
2094 } 2231 }
2095 Token semicolon = expect2(TokenType.SEMICOLON); 2232 Token semicolon = expect2(TokenType.SEMICOLON);
2096 return new ContinueStatement.full(continueKeyword, label, semicolon); 2233 return new ContinueStatement.full(continueKeyword, label, semicolon);
2097 } 2234 }
2098 2235
2099 /** 2236 /**
2100 * Parse a directive. 2237 * Parse a directive.
2238 *
2101 * <pre> 2239 * <pre>
2102 * directive ::= 2240 * directive ::=
2103 * exportDirective 2241 * exportDirective
2104 * | libraryDirective 2242 * | libraryDirective
2105 * | importDirective 2243 * | importDirective
2106 * | partDirective 2244 * | partDirective
2107 * </pre> 2245 * </pre>
2246 *
2108 * @param commentAndMetadata the metadata to be associated with the directive 2247 * @param commentAndMetadata the metadata to be associated with the directive
2109 * @return the directive that was parsed 2248 * @return the directive that was parsed
2110 */ 2249 */
2111 Directive parseDirective(CommentAndMetadata commentAndMetadata) { 2250 Directive parseDirective(CommentAndMetadata commentAndMetadata) {
2112 if (matches(Keyword.IMPORT)) { 2251 if (matches(Keyword.IMPORT)) {
2113 return parseImportDirective(commentAndMetadata); 2252 return parseImportDirective(commentAndMetadata);
2114 } else if (matches(Keyword.EXPORT)) { 2253 } else if (matches(Keyword.EXPORT)) {
2115 return parseExportDirective(commentAndMetadata); 2254 return parseExportDirective(commentAndMetadata);
2116 } else if (matches(Keyword.LIBRARY)) { 2255 } else if (matches(Keyword.LIBRARY)) {
2117 return parseLibraryDirective(commentAndMetadata); 2256 return parseLibraryDirective(commentAndMetadata);
2118 } else if (matches(Keyword.PART)) { 2257 } else if (matches(Keyword.PART)) {
2119 return parsePartDirective(commentAndMetadata); 2258 return parsePartDirective(commentAndMetadata);
2120 } else { 2259 } else {
2121 throw new IllegalStateException("parseDirective invoked in an invalid stat e; currentToken = ${_currentToken}"); 2260 throw new IllegalStateException("parseDirective invoked in an invalid stat e; currentToken = ${_currentToken}");
2122 } 2261 }
2123 } 2262 }
2124 2263
2125 /** 2264 /**
2126 * Parse a documentation comment. 2265 * Parse a documentation comment.
2266 *
2127 * <pre> 2267 * <pre>
2128 * documentationComment ::= 2268 * documentationComment ::=
2129 * multiLineComment? 2269 * multiLineComment?
2130 * | singleLineComment 2270 * | singleLineComment*
2131 * </pre> 2271 * </pre>
2272 *
2132 * @return the documentation comment that was parsed, or `null` if there was n o comment 2273 * @return the documentation comment that was parsed, or `null` if there was n o comment
2133 */ 2274 */
2134 Comment parseDocumentationComment() { 2275 Comment parseDocumentationComment() {
2135 List<Token> commentTokens = new List<Token>(); 2276 List<Token> commentTokens = new List<Token>();
2136 Token commentToken = _currentToken.precedingComments; 2277 Token commentToken = _currentToken.precedingComments;
2137 while (commentToken != null) { 2278 while (commentToken != null) {
2138 if (identical(commentToken.type, TokenType.SINGLE_LINE_COMMENT)) { 2279 if (identical(commentToken.type, TokenType.SINGLE_LINE_COMMENT)) {
2139 if (commentToken.lexeme.startsWith("///")) { 2280 if (commentToken.lexeme.startsWith("///")) {
2140 if (commentTokens.length == 1 && commentTokens[0].lexeme.startsWith("/ **")) { 2281 if (commentTokens.length == 1 && commentTokens[0].lexeme.startsWith("/ **")) {
2141 commentTokens.clear(); 2282 commentTokens.clear();
(...skipping 11 matching lines...) Expand all
2153 if (commentTokens.isEmpty) { 2294 if (commentTokens.isEmpty) {
2154 return null; 2295 return null;
2155 } 2296 }
2156 List<Token> tokens = new List.from(commentTokens); 2297 List<Token> tokens = new List.from(commentTokens);
2157 List<CommentReference> references = parseCommentReferences(tokens); 2298 List<CommentReference> references = parseCommentReferences(tokens);
2158 return Comment.createDocumentationComment2(tokens, references); 2299 return Comment.createDocumentationComment2(tokens, references);
2159 } 2300 }
2160 2301
2161 /** 2302 /**
2162 * Parse a do statement. 2303 * Parse a do statement.
2304 *
2163 * <pre> 2305 * <pre>
2164 * doStatement ::= 2306 * doStatement ::=
2165 * 'do' statement 'while' '(' expression ')' ';' 2307 * 'do' statement 'while' '(' expression ')' ';'
2166 * </pre> 2308 * </pre>
2309 *
2167 * @return the do statement that was parsed 2310 * @return the do statement that was parsed
2168 */ 2311 */
2169 Statement parseDoStatement() { 2312 Statement parseDoStatement() {
2170 bool wasInLoop = _inLoop; 2313 bool wasInLoop = _inLoop;
2171 _inLoop = true; 2314 _inLoop = true;
2172 try { 2315 try {
2173 Token doKeyword = expect(Keyword.DO); 2316 Token doKeyword = expect(Keyword.DO);
2174 Statement body = parseStatement2(); 2317 Statement body = parseStatement2();
2175 Token whileKeyword = expect(Keyword.WHILE); 2318 Token whileKeyword = expect(Keyword.WHILE);
2176 Token leftParenthesis = expect2(TokenType.OPEN_PAREN); 2319 Token leftParenthesis = expect2(TokenType.OPEN_PAREN);
2177 Expression condition = parseExpression2(); 2320 Expression condition = parseExpression2();
2178 Token rightParenthesis = expect2(TokenType.CLOSE_PAREN); 2321 Token rightParenthesis = expect2(TokenType.CLOSE_PAREN);
2179 Token semicolon = expect2(TokenType.SEMICOLON); 2322 Token semicolon = expect2(TokenType.SEMICOLON);
2180 return new DoStatement.full(doKeyword, body, whileKeyword, leftParenthesis , condition, rightParenthesis, semicolon); 2323 return new DoStatement.full(doKeyword, body, whileKeyword, leftParenthesis , condition, rightParenthesis, semicolon);
2181 } finally { 2324 } finally {
2182 _inLoop = wasInLoop; 2325 _inLoop = wasInLoop;
2183 } 2326 }
2184 } 2327 }
2185 2328
2186 /** 2329 /**
2187 * Parse an empty statement. 2330 * Parse an empty statement.
2331 *
2188 * <pre> 2332 * <pre>
2189 * emptyStatement ::= 2333 * emptyStatement ::=
2190 * ';' 2334 * ';'
2191 * </pre> 2335 * </pre>
2336 *
2192 * @return the empty statement that was parsed 2337 * @return the empty statement that was parsed
2193 */ 2338 */
2194 Statement parseEmptyStatement() => new EmptyStatement.full(andAdvance); 2339 Statement parseEmptyStatement() => new EmptyStatement.full(andAdvance);
2195 2340
2196 /** 2341 /**
2197 * Parse an equality expression. 2342 * Parse an equality expression.
2343 *
2198 * <pre> 2344 * <pre>
2199 * equalityExpression ::= 2345 * equalityExpression ::=
2200 * relationalExpression (equalityOperator relationalExpression)? 2346 * relationalExpression (equalityOperator relationalExpression)?
2201 * | 'super' equalityOperator relationalExpression 2347 * | 'super' equalityOperator relationalExpression
2202 * </pre> 2348 * </pre>
2349 *
2203 * @return the equality expression that was parsed 2350 * @return the equality expression that was parsed
2204 */ 2351 */
2205 Expression parseEqualityExpression() { 2352 Expression parseEqualityExpression() {
2206 Expression expression; 2353 Expression expression;
2207 if (matches(Keyword.SUPER) && _currentToken.next.type.isEqualityOperator) { 2354 if (matches(Keyword.SUPER) && _currentToken.next.type.isEqualityOperator) {
2208 expression = new SuperExpression.full(andAdvance); 2355 expression = new SuperExpression.full(andAdvance);
2209 } else { 2356 } else {
2210 expression = parseRelationalExpression(); 2357 expression = parseRelationalExpression();
2211 } 2358 }
2212 while (_currentToken.type.isEqualityOperator) { 2359 while (_currentToken.type.isEqualityOperator) {
2213 Token operator = andAdvance; 2360 Token operator = andAdvance;
2214 expression = new BinaryExpression.full(expression, operator, parseRelation alExpression()); 2361 expression = new BinaryExpression.full(expression, operator, parseRelation alExpression());
2215 } 2362 }
2216 return expression; 2363 return expression;
2217 } 2364 }
2218 2365
2219 /** 2366 /**
2220 * Parse an export directive. 2367 * Parse an export directive.
2368 *
2221 * <pre> 2369 * <pre>
2222 * exportDirective ::= 2370 * exportDirective ::=
2223 * metadata 'export' stringLiteral combinator*';' 2371 * metadata 'export' stringLiteral combinator*';'
2224 * </pre> 2372 * </pre>
2373 *
2225 * @param commentAndMetadata the metadata to be associated with the directive 2374 * @param commentAndMetadata the metadata to be associated with the directive
2226 * @return the export directive that was parsed 2375 * @return the export directive that was parsed
2227 */ 2376 */
2228 ExportDirective parseExportDirective(CommentAndMetadata commentAndMetadata) { 2377 ExportDirective parseExportDirective(CommentAndMetadata commentAndMetadata) {
2229 Token exportKeyword = expect(Keyword.EXPORT); 2378 Token exportKeyword = expect(Keyword.EXPORT);
2230 StringLiteral libraryUri = parseStringLiteral(); 2379 StringLiteral libraryUri = parseStringLiteral();
2231 List<Combinator> combinators = parseCombinators(); 2380 List<Combinator> combinators = parseCombinators();
2232 Token semicolon = expect2(TokenType.SEMICOLON); 2381 Token semicolon = expect2(TokenType.SEMICOLON);
2233 return new ExportDirective.full(commentAndMetadata.comment, commentAndMetada ta.metadata, exportKeyword, libraryUri, combinators, semicolon); 2382 return new ExportDirective.full(commentAndMetadata.comment, commentAndMetada ta.metadata, exportKeyword, libraryUri, combinators, semicolon);
2234 } 2383 }
2235 2384
2236 /** 2385 /**
2237 * Parse an expression that does not contain any cascades. 2386 * Parse an expression that does not contain any cascades.
2387 *
2238 * <pre> 2388 * <pre>
2239 * expression ::= 2389 * expression ::=
2240 * assignableExpression assignmentOperator expression 2390 * assignableExpression assignmentOperator expression
2241 * | conditionalExpression cascadeSection 2391 * | conditionalExpression cascadeSection*
2242 * | throwExpression 2392 * | throwExpression
2243 * </pre> 2393 * </pre>
2394 *
2244 * @return the expression that was parsed 2395 * @return the expression that was parsed
2245 */ 2396 */
2246 Expression parseExpression2() { 2397 Expression parseExpression2() {
2247 if (matches(Keyword.THROW)) { 2398 if (matches(Keyword.THROW)) {
2248 return parseThrowExpression(); 2399 return parseThrowExpression();
2249 } else if (matches(Keyword.RETHROW)) { 2400 } else if (matches(Keyword.RETHROW)) {
2250 return parseRethrowExpression(); 2401 return parseRethrowExpression();
2251 } 2402 }
2252 Expression expression = parseConditionalExpression(); 2403 Expression expression = parseConditionalExpression();
2253 TokenType tokenType = _currentToken.type; 2404 TokenType tokenType = _currentToken.type;
(...skipping 10 matching lines...) Expand all
2264 } else if (tokenType.isAssignmentOperator) { 2415 } else if (tokenType.isAssignmentOperator) {
2265 Token operator = andAdvance; 2416 Token operator = andAdvance;
2266 ensureAssignable(expression); 2417 ensureAssignable(expression);
2267 return new AssignmentExpression.full(expression, operator, parseExpression 2()); 2418 return new AssignmentExpression.full(expression, operator, parseExpression 2());
2268 } 2419 }
2269 return expression; 2420 return expression;
2270 } 2421 }
2271 2422
2272 /** 2423 /**
2273 * Parse a list of expressions. 2424 * Parse a list of expressions.
2425 *
2274 * <pre> 2426 * <pre>
2275 * expressionList ::= 2427 * expressionList ::=
2276 * expression (',' expression) 2428 * expression (',' expression)*
2277 * </pre> 2429 * </pre>
2430 *
2278 * @return the expression that was parsed 2431 * @return the expression that was parsed
2279 */ 2432 */
2280 List<Expression> parseExpressionList() { 2433 List<Expression> parseExpressionList() {
2281 List<Expression> expressions = new List<Expression>(); 2434 List<Expression> expressions = new List<Expression>();
2282 expressions.add(parseExpression2()); 2435 expressions.add(parseExpression2());
2283 while (optional(TokenType.COMMA)) { 2436 while (optional(TokenType.COMMA)) {
2284 expressions.add(parseExpression2()); 2437 expressions.add(parseExpression2());
2285 } 2438 }
2286 return expressions; 2439 return expressions;
2287 } 2440 }
2288 2441
2289 /** 2442 /**
2290 * Parse an expression that does not contain any cascades. 2443 * Parse an expression that does not contain any cascades.
2444 *
2291 * <pre> 2445 * <pre>
2292 * expressionWithoutCascade ::= 2446 * expressionWithoutCascade ::=
2293 * assignableExpression assignmentOperator expressionWithoutCascade 2447 * assignableExpression assignmentOperator expressionWithoutCascade
2294 * | conditionalExpression 2448 * | conditionalExpression
2295 * | throwExpressionWithoutCascade 2449 * | throwExpressionWithoutCascade
2296 * </pre> 2450 * </pre>
2451 *
2297 * @return the expression that was parsed 2452 * @return the expression that was parsed
2298 */ 2453 */
2299 Expression parseExpressionWithoutCascade() { 2454 Expression parseExpressionWithoutCascade() {
2300 if (matches(Keyword.THROW)) { 2455 if (matches(Keyword.THROW)) {
2301 return parseThrowExpressionWithoutCascade(); 2456 return parseThrowExpressionWithoutCascade();
2302 } else if (matches(Keyword.RETHROW)) { 2457 } else if (matches(Keyword.RETHROW)) {
2303 return parseRethrowExpression(); 2458 return parseRethrowExpression();
2304 } 2459 }
2305 Expression expression = parseConditionalExpression(); 2460 Expression expression = parseConditionalExpression();
2306 if (_currentToken.type.isAssignmentOperator) { 2461 if (_currentToken.type.isAssignmentOperator) {
2307 Token operator = andAdvance; 2462 Token operator = andAdvance;
2308 ensureAssignable(expression); 2463 ensureAssignable(expression);
2309 expression = new AssignmentExpression.full(expression, operator, parseExpr essionWithoutCascade()); 2464 expression = new AssignmentExpression.full(expression, operator, parseExpr essionWithoutCascade());
2310 } 2465 }
2311 return expression; 2466 return expression;
2312 } 2467 }
2313 2468
2314 /** 2469 /**
2315 * Parse a class extends clause. 2470 * Parse a class extends clause.
2471 *
2316 * <pre> 2472 * <pre>
2317 * classExtendsClause ::= 2473 * classExtendsClause ::=
2318 * 'extends' type 2474 * 'extends' type
2319 * </pre> 2475 * </pre>
2476 *
2320 * @return the class extends clause that was parsed 2477 * @return the class extends clause that was parsed
2321 */ 2478 */
2322 ExtendsClause parseExtendsClause() { 2479 ExtendsClause parseExtendsClause() {
2323 Token keyword = expect(Keyword.EXTENDS); 2480 Token keyword = expect(Keyword.EXTENDS);
2324 TypeName superclass = parseTypeName(); 2481 TypeName superclass = parseTypeName();
2325 return new ExtendsClause.full(keyword, superclass); 2482 return new ExtendsClause.full(keyword, superclass);
2326 } 2483 }
2327 2484
2328 /** 2485 /**
2329 * Parse the 'final', 'const', 'var' or type preceding a variable declaration. 2486 * Parse the 'final', 'const', 'var' or type preceding a variable declaration.
2487 *
2330 * <pre> 2488 * <pre>
2331 * finalConstVarOrType ::= 2489 * finalConstVarOrType ::=
2332 * | 'final' type? 2490 * | 'final' type?
2333 * | 'const' type? 2491 * | 'const' type?
2334 * | 'var' 2492 * | 'var'
2335 * | type 2493 * | type
2336 * </pre> 2494 * </pre>
2495 *
2337 * @param optional `true` if the keyword and type are optional 2496 * @param optional `true` if the keyword and type are optional
2338 * @return the 'final', 'const', 'var' or type that was parsed 2497 * @return the 'final', 'const', 'var' or type that was parsed
2339 */ 2498 */
2340 FinalConstVarOrType parseFinalConstVarOrType(bool optional) { 2499 FinalConstVarOrType parseFinalConstVarOrType(bool optional) {
2341 Token keyword = null; 2500 Token keyword = null;
2342 TypeName type = null; 2501 TypeName type = null;
2343 if (matches(Keyword.FINAL) || matches(Keyword.CONST)) { 2502 if (matches(Keyword.FINAL) || matches(Keyword.CONST)) {
2344 keyword = andAdvance; 2503 keyword = andAdvance;
2345 if (matchesIdentifier2(peek()) || matches4(peek(), TokenType.LT) || matche s3(peek(), Keyword.THIS) || (matches4(peek(), TokenType.PERIOD) && matchesIdenti fier2(peek2(2)) && (matchesIdentifier2(peek2(3)) || matches4(peek2(3), TokenType .LT) || matches3(peek2(3), Keyword.THIS)))) { 2504 if (matchesIdentifier2(peek()) || matches4(peek(), TokenType.LT) || matche s3(peek(), Keyword.THIS) || (matches4(peek(), TokenType.PERIOD) && matchesIdenti fier2(peek2(2)) && (matchesIdentifier2(peek2(3)) || matches4(peek2(3), TokenType .LT) || matches3(peek2(3), Keyword.THIS)))) {
2346 type = parseTypeName(); 2505 type = parseTypeName();
2347 } 2506 }
2348 } else if (matches(Keyword.VAR)) { 2507 } else if (matches(Keyword.VAR)) {
2349 keyword = andAdvance; 2508 keyword = andAdvance;
2350 } else { 2509 } else {
2351 if (matchesIdentifier2(peek()) || matches4(peek(), TokenType.LT) || matche s3(peek(), Keyword.THIS) || (matches4(peek(), TokenType.PERIOD) && matchesIdenti fier2(peek2(2)) && (matchesIdentifier2(peek2(3)) || matches4(peek2(3), TokenType .LT) || matches3(peek2(3), Keyword.THIS)))) { 2510 if (matchesIdentifier2(peek()) || matches4(peek(), TokenType.LT) || matche s3(peek(), Keyword.THIS) || (matches4(peek(), TokenType.PERIOD) && matchesIdenti fier2(peek2(2)) && (matchesIdentifier2(peek2(3)) || matches4(peek2(3), TokenType .LT) || matches3(peek2(3), Keyword.THIS)))) {
2352 type = parseReturnType(); 2511 type = parseReturnType();
2353 } else if (!optional) { 2512 } else if (!optional) {
2354 reportError7(ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, []); 2513 reportError7(ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, []);
2355 } 2514 }
2356 } 2515 }
2357 return new FinalConstVarOrType(keyword, type); 2516 return new FinalConstVarOrType(keyword, type);
2358 } 2517 }
2359 2518
2360 /** 2519 /**
2361 * Parse a formal parameter. At most one of `isOptional` and `isNamed` can be` true`. 2520 * Parse a formal parameter. At most one of `isOptional` and `isNamed` can be
2521 * `true`.
2522 *
2362 * <pre> 2523 * <pre>
2363 * defaultFormalParameter ::= 2524 * defaultFormalParameter ::=
2364 * normalFormalParameter ('=' expression)? 2525 * normalFormalParameter ('=' expression)?
2526 *
2365 * defaultNamedParameter ::= 2527 * defaultNamedParameter ::=
2366 * normalFormalParameter (':' expression)? 2528 * normalFormalParameter (':' expression)?
2367 * </pre> 2529 * </pre>
2530 *
2368 * @param kind the kind of parameter being expected based on the presence or a bsence of group 2531 * @param kind the kind of parameter being expected based on the presence or a bsence of group
2369 * delimiters 2532 * delimiters
2370 * @return the formal parameter that was parsed 2533 * @return the formal parameter that was parsed
2371 */ 2534 */
2372 FormalParameter parseFormalParameter(ParameterKind kind) { 2535 FormalParameter parseFormalParameter(ParameterKind kind) {
2373 NormalFormalParameter parameter = parseNormalFormalParameter(); 2536 NormalFormalParameter parameter = parseNormalFormalParameter();
2374 if (matches5(TokenType.EQ)) { 2537 if (matches5(TokenType.EQ)) {
2375 Token seperator = andAdvance; 2538 Token seperator = andAdvance;
2376 Expression defaultValue = parseExpression2(); 2539 Expression defaultValue = parseExpression2();
2377 if (identical(kind, ParameterKind.NAMED)) { 2540 if (identical(kind, ParameterKind.NAMED)) {
2378 reportError8(ParserErrorCode.WRONG_SEPARATOR_FOR_NAMED_PARAMETER, sepera tor, []); 2541 reportError8(ParserErrorCode.WRONG_SEPARATOR_FOR_NAMED_PARAMETER, sepera tor, []);
2379 } else if (identical(kind, ParameterKind.REQUIRED)) { 2542 } else if (identical(kind, ParameterKind.REQUIRED)) {
(...skipping 10 matching lines...) Expand all
2390 } 2553 }
2391 return new DefaultFormalParameter.full(parameter, kind, seperator, default Value); 2554 return new DefaultFormalParameter.full(parameter, kind, seperator, default Value);
2392 } else if (kind != ParameterKind.REQUIRED) { 2555 } else if (kind != ParameterKind.REQUIRED) {
2393 return new DefaultFormalParameter.full(parameter, kind, null, null); 2556 return new DefaultFormalParameter.full(parameter, kind, null, null);
2394 } 2557 }
2395 return parameter; 2558 return parameter;
2396 } 2559 }
2397 2560
2398 /** 2561 /**
2399 * Parse a list of formal parameters. 2562 * Parse a list of formal parameters.
2563 *
2400 * <pre> 2564 * <pre>
2401 * formalParameterList ::= 2565 * formalParameterList ::=
2402 * '(' ')' 2566 * '(' ')'
2403 * | '(' normalFormalParameters (',' optionalFormalParameters)? ')' 2567 * | '(' normalFormalParameters (',' optionalFormalParameters)? ')'
2404 * | '(' optionalFormalParameters ')' 2568 * | '(' optionalFormalParameters ')'
2569 *
2405 * normalFormalParameters ::= 2570 * normalFormalParameters ::=
2406 * normalFormalParameter (',' normalFormalParameter) 2571 * normalFormalParameter (',' normalFormalParameter)*
2572 *
2407 * optionalFormalParameters ::= 2573 * optionalFormalParameters ::=
2408 * optionalPositionalFormalParameters 2574 * optionalPositionalFormalParameters
2409 * | namedFormalParameters 2575 * | namedFormalParameters
2576 *
2410 * optionalPositionalFormalParameters ::= 2577 * optionalPositionalFormalParameters ::=
2411 * '\[' defaultFormalParameter (',' defaultFormalParameter)* '\]' 2578 * '[' defaultFormalParameter (',' defaultFormalParameter)* ']'
2579 *
2412 * namedFormalParameters ::= 2580 * namedFormalParameters ::=
2413 * '{' defaultNamedParameter (',' defaultNamedParameter)* '}' 2581 * '{' defaultNamedParameter (',' defaultNamedParameter)* '}'
2414 * </pre> 2582 * </pre>
2583 *
2415 * @return the formal parameters that were parsed 2584 * @return the formal parameters that were parsed
2416 */ 2585 */
2417 FormalParameterList parseFormalParameterList() { 2586 FormalParameterList parseFormalParameterList() {
2418 Token leftParenthesis = expect2(TokenType.OPEN_PAREN); 2587 Token leftParenthesis = expect2(TokenType.OPEN_PAREN);
2419 if (matches5(TokenType.CLOSE_PAREN)) { 2588 if (matches5(TokenType.CLOSE_PAREN)) {
2420 return new FormalParameterList.full(leftParenthesis, null, null, null, and Advance); 2589 return new FormalParameterList.full(leftParenthesis, null, null, null, and Advance);
2421 } 2590 }
2422 List<FormalParameter> parameters = new List<FormalParameter>(); 2591 List<FormalParameter> parameters = new List<FormalParameter>();
2423 List<FormalParameter> normalParameters = new List<FormalParameter>(); 2592 List<FormalParameter> normalParameters = new List<FormalParameter>();
2424 List<FormalParameter> positionalParameters = new List<FormalParameter>(); 2593 List<FormalParameter> positionalParameters = new List<FormalParameter>();
2425 List<FormalParameter> namedParameters = new List<FormalParameter>(); 2594 List<FormalParameter> namedParameters = new List<FormalParameter>();
2426 List<FormalParameter> currentParameters = normalParameters; 2595 List<FormalParameter> currentParameters = normalParameters;
2427 Token leftSquareBracket = null; 2596 Token leftSquareBracket = null;
2428 Token rightSquareBracket = null; 2597 Token rightSquareBracket = null;
2429 Token leftCurlyBracket = null; 2598 Token leftCurlyBracket = null;
2430 Token rightCurlyBracket = null; 2599 Token rightCurlyBracket = null;
2431 ParameterKind kind = ParameterKind.REQUIRED; 2600 ParameterKind kind = ParameterKind.REQUIRED;
2432 bool firstParameter = true; 2601 bool firstParameter = true;
2433 bool reportedMuliplePositionalGroups = false; 2602 bool reportedMuliplePositionalGroups = false;
2434 bool reportedMulipleNamedGroups = false; 2603 bool reportedMulipleNamedGroups = false;
2435 bool reportedMixedGroups = false; 2604 bool reportedMixedGroups = false;
2605 bool wasOptionalParameter = false;
2436 Token initialToken = null; 2606 Token initialToken = null;
2437 do { 2607 do {
2438 if (firstParameter) { 2608 if (firstParameter) {
2439 firstParameter = false; 2609 firstParameter = false;
2440 } else if (!optional(TokenType.COMMA)) { 2610 } else if (!optional(TokenType.COMMA)) {
2441 if (getEndToken(leftParenthesis) != null) { 2611 if (getEndToken(leftParenthesis) != null) {
2442 reportError7(ParserErrorCode.EXPECTED_TOKEN, [TokenType.COMMA.lexeme]) ; 2612 reportError7(ParserErrorCode.EXPECTED_TOKEN, [TokenType.COMMA.lexeme]) ;
2443 } else { 2613 } else {
2444 reportError8(ParserErrorCode.MISSING_CLOSING_PARENTHESIS, _currentToke n.previous, []); 2614 reportError8(ParserErrorCode.MISSING_CLOSING_PARENTHESIS, _currentToke n.previous, []);
2445 break; 2615 break;
2446 } 2616 }
2447 } 2617 }
2448 initialToken = _currentToken; 2618 initialToken = _currentToken;
2449 if (matches5(TokenType.OPEN_SQUARE_BRACKET)) { 2619 if (matches5(TokenType.OPEN_SQUARE_BRACKET)) {
2620 wasOptionalParameter = true;
2450 if (leftSquareBracket != null && !reportedMuliplePositionalGroups) { 2621 if (leftSquareBracket != null && !reportedMuliplePositionalGroups) {
2451 reportError7(ParserErrorCode.MULTIPLE_POSITIONAL_PARAMETER_GROUPS, []) ; 2622 reportError7(ParserErrorCode.MULTIPLE_POSITIONAL_PARAMETER_GROUPS, []) ;
2452 reportedMuliplePositionalGroups = true; 2623 reportedMuliplePositionalGroups = true;
2453 } 2624 }
2454 if (leftCurlyBracket != null && !reportedMixedGroups) { 2625 if (leftCurlyBracket != null && !reportedMixedGroups) {
2455 reportError7(ParserErrorCode.MIXED_PARAMETER_GROUPS, []); 2626 reportError7(ParserErrorCode.MIXED_PARAMETER_GROUPS, []);
2456 reportedMixedGroups = true; 2627 reportedMixedGroups = true;
2457 } 2628 }
2458 leftSquareBracket = andAdvance; 2629 leftSquareBracket = andAdvance;
2459 currentParameters = positionalParameters; 2630 currentParameters = positionalParameters;
2460 kind = ParameterKind.POSITIONAL; 2631 kind = ParameterKind.POSITIONAL;
2461 } else if (matches5(TokenType.OPEN_CURLY_BRACKET)) { 2632 } else if (matches5(TokenType.OPEN_CURLY_BRACKET)) {
2633 wasOptionalParameter = true;
2462 if (leftCurlyBracket != null && !reportedMulipleNamedGroups) { 2634 if (leftCurlyBracket != null && !reportedMulipleNamedGroups) {
2463 reportError7(ParserErrorCode.MULTIPLE_NAMED_PARAMETER_GROUPS, []); 2635 reportError7(ParserErrorCode.MULTIPLE_NAMED_PARAMETER_GROUPS, []);
2464 reportedMulipleNamedGroups = true; 2636 reportedMulipleNamedGroups = true;
2465 } 2637 }
2466 if (leftSquareBracket != null && !reportedMixedGroups) { 2638 if (leftSquareBracket != null && !reportedMixedGroups) {
2467 reportError7(ParserErrorCode.MIXED_PARAMETER_GROUPS, []); 2639 reportError7(ParserErrorCode.MIXED_PARAMETER_GROUPS, []);
2468 reportedMixedGroups = true; 2640 reportedMixedGroups = true;
2469 } 2641 }
2470 leftCurlyBracket = andAdvance; 2642 leftCurlyBracket = andAdvance;
2471 currentParameters = namedParameters; 2643 currentParameters = namedParameters;
2472 kind = ParameterKind.NAMED; 2644 kind = ParameterKind.NAMED;
2473 } 2645 }
2474 FormalParameter parameter = parseFormalParameter(kind); 2646 FormalParameter parameter = parseFormalParameter(kind);
2475 parameters.add(parameter); 2647 parameters.add(parameter);
2476 currentParameters.add(parameter); 2648 currentParameters.add(parameter);
2649 if (identical(kind, ParameterKind.REQUIRED) && wasOptionalParameter) {
2650 reportError(ParserErrorCode.NORMAL_BEFORE_OPTIONAL_PARAMETERS, parameter , []);
2651 }
2477 if (matches5(TokenType.CLOSE_SQUARE_BRACKET)) { 2652 if (matches5(TokenType.CLOSE_SQUARE_BRACKET)) {
2478 rightSquareBracket = andAdvance; 2653 rightSquareBracket = andAdvance;
2479 currentParameters = normalParameters; 2654 currentParameters = normalParameters;
2480 if (leftSquareBracket == null) { 2655 if (leftSquareBracket == null) {
2481 if (leftCurlyBracket != null) { 2656 if (leftCurlyBracket != null) {
2482 reportError7(ParserErrorCode.WRONG_TERMINATOR_FOR_PARAMETER_GROUP, [ "}"]); 2657 reportError7(ParserErrorCode.WRONG_TERMINATOR_FOR_PARAMETER_GROUP, [ "}"]);
2483 rightCurlyBracket = rightSquareBracket; 2658 rightCurlyBracket = rightSquareBracket;
2484 rightSquareBracket = null; 2659 rightSquareBracket = null;
2485 } else { 2660 } else {
2486 reportError7(ParserErrorCode.UNEXPECTED_TERMINATOR_FOR_PARAMETER_GRO UP, ["["]); 2661 reportError7(ParserErrorCode.UNEXPECTED_TERMINATOR_FOR_PARAMETER_GRO UP, ["["]);
(...skipping 26 matching lines...) Expand all
2513 leftSquareBracket = leftCurlyBracket; 2688 leftSquareBracket = leftCurlyBracket;
2514 } 2689 }
2515 if (rightSquareBracket == null) { 2690 if (rightSquareBracket == null) {
2516 rightSquareBracket = rightCurlyBracket; 2691 rightSquareBracket = rightCurlyBracket;
2517 } 2692 }
2518 return new FormalParameterList.full(leftParenthesis, parameters, leftSquareB racket, rightSquareBracket, rightParenthesis); 2693 return new FormalParameterList.full(leftParenthesis, parameters, leftSquareB racket, rightSquareBracket, rightParenthesis);
2519 } 2694 }
2520 2695
2521 /** 2696 /**
2522 * Parse a for statement. 2697 * Parse a for statement.
2698 *
2523 * <pre> 2699 * <pre>
2524 * forStatement ::= 2700 * forStatement ::=
2525 * 'for' '(' forLoopParts ')' statement 2701 * 'for' '(' forLoopParts ')' statement
2702 *
2526 * forLoopParts ::= 2703 * forLoopParts ::=
2527 * forInitializerStatement expression? ';' expressionList? 2704 * forInitializerStatement expression? ';' expressionList?
2528 * | declaredIdentifier 'in' expression 2705 * | declaredIdentifier 'in' expression
2529 * | identifier 'in' expression 2706 * | identifier 'in' expression
2707 *
2530 * forInitializerStatement ::= 2708 * forInitializerStatement ::=
2531 * localVariableDeclaration ';' 2709 * localVariableDeclaration ';'
2532 * | expression? ';' 2710 * | expression? ';'
2533 * </pre> 2711 * </pre>
2712 *
2534 * @return the for statement that was parsed 2713 * @return the for statement that was parsed
2535 */ 2714 */
2536 Statement parseForStatement() { 2715 Statement parseForStatement() {
2537 bool wasInLoop = _inLoop; 2716 bool wasInLoop = _inLoop;
2538 _inLoop = true; 2717 _inLoop = true;
2539 try { 2718 try {
2540 Token forKeyword = expect(Keyword.FOR); 2719 Token forKeyword = expect(Keyword.FOR);
2541 Token leftParenthesis = expect2(TokenType.OPEN_PAREN); 2720 Token leftParenthesis = expect2(TokenType.OPEN_PAREN);
2542 VariableDeclarationList variableList = null; 2721 VariableDeclarationList variableList = null;
2543 Expression initialization = null; 2722 Expression initialization = null;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2588 Token rightParenthesis = expect2(TokenType.CLOSE_PAREN); 2767 Token rightParenthesis = expect2(TokenType.CLOSE_PAREN);
2589 Statement body = parseStatement2(); 2768 Statement body = parseStatement2();
2590 return new ForStatement.full(forKeyword, leftParenthesis, variableList, in itialization, leftSeparator, condition, rightSeparator, updaters, rightParenthes is, body); 2769 return new ForStatement.full(forKeyword, leftParenthesis, variableList, in itialization, leftSeparator, condition, rightSeparator, updaters, rightParenthes is, body);
2591 } finally { 2770 } finally {
2592 _inLoop = wasInLoop; 2771 _inLoop = wasInLoop;
2593 } 2772 }
2594 } 2773 }
2595 2774
2596 /** 2775 /**
2597 * Parse a function body. 2776 * Parse a function body.
2777 *
2598 * <pre> 2778 * <pre>
2599 * functionBody ::= 2779 * functionBody ::=
2600 * '=>' expression ';' 2780 * '=>' expression ';'
2601 * | block 2781 * | block
2782 *
2602 * functionExpressionBody ::= 2783 * functionExpressionBody ::=
2603 * '=>' expression 2784 * '=>' expression
2604 * | block 2785 * | block
2605 * </pre> 2786 * </pre>
2787 *
2606 * @param mayBeEmpty `true` if the function body is allowed to be empty 2788 * @param mayBeEmpty `true` if the function body is allowed to be empty
2607 * @param emptyErrorCode the error code to report if function body expecte, bu t not found 2789 * @param emptyErrorCode the error code to report if function body expecte, bu t not found
2608 * @param inExpression `true` if the function body is being parsed as part of an expression 2790 * @param inExpression `true` if the function body is being parsed as part of an expression
2609 * and therefore does not have a terminating semicolon 2791 * and therefore does not have a terminating semicolon
2610 * @return the function body that was parsed 2792 * @return the function body that was parsed
2611 */ 2793 */
2612 FunctionBody parseFunctionBody(bool mayBeEmpty, ParserErrorCode emptyErrorCode , bool inExpression) { 2794 FunctionBody parseFunctionBody(bool mayBeEmpty, ParserErrorCode emptyErrorCode , bool inExpression) {
2613 bool wasInLoop = _inLoop; 2795 bool wasInLoop = _inLoop;
2614 bool wasInSwitch = _inSwitch; 2796 bool wasInSwitch = _inSwitch;
2615 _inLoop = false; 2797 _inLoop = false;
2616 _inSwitch = false; 2798 _inSwitch = false;
2617 try { 2799 try {
2618 if (matches5(TokenType.SEMICOLON)) { 2800 if (matches5(TokenType.SEMICOLON)) {
2619 if (!mayBeEmpty) { 2801 if (!mayBeEmpty) {
(...skipping 22 matching lines...) Expand all
2642 return new EmptyFunctionBody.full(createSyntheticToken2(TokenType.SEMICO LON)); 2824 return new EmptyFunctionBody.full(createSyntheticToken2(TokenType.SEMICO LON));
2643 } 2825 }
2644 } finally { 2826 } finally {
2645 _inLoop = wasInLoop; 2827 _inLoop = wasInLoop;
2646 _inSwitch = wasInSwitch; 2828 _inSwitch = wasInSwitch;
2647 } 2829 }
2648 } 2830 }
2649 2831
2650 /** 2832 /**
2651 * Parse a function declaration. 2833 * Parse a function declaration.
2834 *
2652 * <pre> 2835 * <pre>
2653 * functionDeclaration ::= 2836 * functionDeclaration ::=
2654 * functionSignature functionBody 2837 * functionSignature functionBody
2655 * | returnType? getOrSet identifier formalParameterList functionBody 2838 * | returnType? getOrSet identifier formalParameterList functionBody
2656 * </pre> 2839 * </pre>
2840 *
2657 * @param commentAndMetadata the documentation comment and metadata to be asso ciated with the 2841 * @param commentAndMetadata the documentation comment and metadata to be asso ciated with the
2658 * declaration 2842 * declaration
2659 * @param externalKeyword the 'external' keyword, or `null` if the function is not external 2843 * @param externalKeyword the 'external' keyword, or `null` if the function is not external
2660 * @param returnType the return type, or `null` if there is no return type 2844 * @param returnType the return type, or `null` if there is no return type
2661 * @param isStatement `true` if the function declaration is being parsed as a statement 2845 * @param isStatement `true` if the function declaration is being parsed as a statement
2662 * @return the function declaration that was parsed 2846 * @return the function declaration that was parsed
2663 */ 2847 */
2664 FunctionDeclaration parseFunctionDeclaration(CommentAndMetadata commentAndMeta data, Token externalKeyword, TypeName returnType) { 2848 FunctionDeclaration parseFunctionDeclaration(CommentAndMetadata commentAndMeta data, Token externalKeyword, TypeName returnType) {
2665 Token keyword = null; 2849 Token keyword = null;
2666 bool isGetter = false; 2850 bool isGetter = false;
2667 if (matches(Keyword.GET) && !matches4(peek(), TokenType.OPEN_PAREN)) { 2851 if (matches(Keyword.GET) && !matches4(peek(), TokenType.OPEN_PAREN)) {
2668 keyword = andAdvance; 2852 keyword = andAdvance;
(...skipping 18 matching lines...) Expand all
2687 if (externalKeyword == null) { 2871 if (externalKeyword == null) {
2688 body = parseFunctionBody(false, ParserErrorCode.MISSING_FUNCTION_BODY, fal se); 2872 body = parseFunctionBody(false, ParserErrorCode.MISSING_FUNCTION_BODY, fal se);
2689 } else { 2873 } else {
2690 body = new EmptyFunctionBody.full(expect2(TokenType.SEMICOLON)); 2874 body = new EmptyFunctionBody.full(expect2(TokenType.SEMICOLON));
2691 } 2875 }
2692 return new FunctionDeclaration.full(commentAndMetadata.comment, commentAndMe tadata.metadata, externalKeyword, returnType, keyword, name, new FunctionExpress ion.full(parameters, body)); 2876 return new FunctionDeclaration.full(commentAndMetadata.comment, commentAndMe tadata.metadata, externalKeyword, returnType, keyword, name, new FunctionExpress ion.full(parameters, body));
2693 } 2877 }
2694 2878
2695 /** 2879 /**
2696 * Parse a function declaration statement. 2880 * Parse a function declaration statement.
2881 *
2697 * <pre> 2882 * <pre>
2698 * functionDeclarationStatement ::= 2883 * functionDeclarationStatement ::=
2699 * functionSignature functionBody 2884 * functionSignature functionBody
2700 * </pre> 2885 * </pre>
2886 *
2701 * @return the function declaration statement that was parsed 2887 * @return the function declaration statement that was parsed
2702 */ 2888 */
2703 Statement parseFunctionDeclarationStatement() => parseFunctionDeclarationState ment2(parseCommentAndMetadata(), parseOptionalReturnType()); 2889 Statement parseFunctionDeclarationStatement() {
2890 Modifiers modifiers = parseModifiers();
2891 validateModifiersForFunctionDeclarationStatement(modifiers);
2892 return parseFunctionDeclarationStatement2(parseCommentAndMetadata(), parseOp tionalReturnType());
2893 }
2704 2894
2705 /** 2895 /**
2706 * Parse a function declaration statement. 2896 * Parse a function declaration statement.
2897 *
2707 * <pre> 2898 * <pre>
2708 * functionDeclarationStatement ::= 2899 * functionDeclarationStatement ::=
2709 * functionSignature functionBody 2900 * functionSignature functionBody
2710 * </pre> 2901 * </pre>
2902 *
2711 * @param commentAndMetadata the documentation comment and metadata to be asso ciated with the 2903 * @param commentAndMetadata the documentation comment and metadata to be asso ciated with the
2712 * declaration 2904 * declaration
2713 * @param returnType the return type, or `null` if there is no return type 2905 * @param returnType the return type, or `null` if there is no return type
2714 * @return the function declaration statement that was parsed 2906 * @return the function declaration statement that was parsed
2715 */ 2907 */
2716 Statement parseFunctionDeclarationStatement2(CommentAndMetadata commentAndMeta data, TypeName returnType) => new FunctionDeclarationStatement.full(parseFunctio nDeclaration(commentAndMetadata, null, returnType)); 2908 Statement parseFunctionDeclarationStatement2(CommentAndMetadata commentAndMeta data, TypeName returnType) => new FunctionDeclarationStatement.full(parseFunctio nDeclaration(commentAndMetadata, null, returnType));
2717 2909
2718 /** 2910 /**
2719 * Parse a function expression. 2911 * Parse a function expression.
2912 *
2720 * <pre> 2913 * <pre>
2721 * functionExpression ::= 2914 * functionExpression ::=
2722 * formalParameterList functionExpressionBody 2915 * formalParameterList functionExpressionBody
2723 * </pre> 2916 * </pre>
2917 *
2724 * @return the function expression that was parsed 2918 * @return the function expression that was parsed
2725 */ 2919 */
2726 FunctionExpression parseFunctionExpression() { 2920 FunctionExpression parseFunctionExpression() {
2727 FormalParameterList parameters = parseFormalParameterList(); 2921 FormalParameterList parameters = parseFormalParameterList();
2728 validateFormalParameterList(parameters); 2922 validateFormalParameterList(parameters);
2729 FunctionBody body = parseFunctionBody(false, ParserErrorCode.MISSING_FUNCTIO N_BODY, true); 2923 FunctionBody body = parseFunctionBody(false, ParserErrorCode.MISSING_FUNCTIO N_BODY, true);
2730 return new FunctionExpression.full(parameters, body); 2924 return new FunctionExpression.full(parameters, body);
2731 } 2925 }
2732 2926
2733 /** 2927 /**
2734 * Parse a function type alias. 2928 * Parse a function type alias.
2929 *
2735 * <pre> 2930 * <pre>
2736 * functionTypeAlias ::= 2931 * functionTypeAlias ::=
2737 * functionPrefix typeParameterList? formalParameterList ';' 2932 * functionPrefix typeParameterList? formalParameterList ';'
2933 *
2738 * functionPrefix ::= 2934 * functionPrefix ::=
2739 * returnType? name 2935 * returnType? name
2740 * </pre> 2936 * </pre>
2937 *
2741 * @param commentAndMetadata the metadata to be associated with the member 2938 * @param commentAndMetadata the metadata to be associated with the member
2742 * @param keyword the token representing the 'typedef' keyword 2939 * @param keyword the token representing the 'typedef' keyword
2743 * @return the function type alias that was parsed 2940 * @return the function type alias that was parsed
2744 */ 2941 */
2745 FunctionTypeAlias parseFunctionTypeAlias(CommentAndMetadata commentAndMetadata , Token keyword) { 2942 FunctionTypeAlias parseFunctionTypeAlias(CommentAndMetadata commentAndMetadata , Token keyword) {
2746 TypeName returnType = null; 2943 TypeName returnType = null;
2747 if (hasReturnTypeInTypeAlias()) { 2944 if (hasReturnTypeInTypeAlias()) {
2748 returnType = parseReturnType(); 2945 returnType = parseReturnType();
2749 } 2946 }
2750 SimpleIdentifier name = parseSimpleIdentifier(); 2947 SimpleIdentifier name = parseSimpleIdentifier();
(...skipping 11 matching lines...) Expand all
2762 return new FunctionTypeAlias.full(commentAndMetadata.comment, commentAndMe tadata.metadata, keyword, returnType, name, typeParameters, new FormalParameterL ist.full(createSyntheticToken2(TokenType.OPEN_PAREN), null, null, null, createSy ntheticToken2(TokenType.CLOSE_PAREN)), createSyntheticToken2(TokenType.SEMICOLON )); 2959 return new FunctionTypeAlias.full(commentAndMetadata.comment, commentAndMe tadata.metadata, keyword, returnType, name, typeParameters, new FormalParameterL ist.full(createSyntheticToken2(TokenType.OPEN_PAREN), null, null, null, createSy ntheticToken2(TokenType.CLOSE_PAREN)), createSyntheticToken2(TokenType.SEMICOLON ));
2763 } 2960 }
2764 FormalParameterList parameters = parseFormalParameterList(); 2961 FormalParameterList parameters = parseFormalParameterList();
2765 validateFormalParameterList(parameters); 2962 validateFormalParameterList(parameters);
2766 Token semicolon = expect2(TokenType.SEMICOLON); 2963 Token semicolon = expect2(TokenType.SEMICOLON);
2767 return new FunctionTypeAlias.full(commentAndMetadata.comment, commentAndMeta data.metadata, keyword, returnType, name, typeParameters, parameters, semicolon) ; 2964 return new FunctionTypeAlias.full(commentAndMetadata.comment, commentAndMeta data.metadata, keyword, returnType, name, typeParameters, parameters, semicolon) ;
2768 } 2965 }
2769 2966
2770 /** 2967 /**
2771 * Parse a getter. 2968 * Parse a getter.
2969 *
2772 * <pre> 2970 * <pre>
2773 * getter ::= 2971 * getter ::=
2774 * getterSignature functionBody? 2972 * getterSignature functionBody?
2973 *
2775 * getterSignature ::= 2974 * getterSignature ::=
2776 * 'external'? 'static'? returnType? 'get' identifier 2975 * 'external'? 'static'? returnType? 'get' identifier
2777 * </pre> 2976 * </pre>
2977 *
2778 * @param commentAndMetadata the documentation comment and metadata to be asso ciated with the 2978 * @param commentAndMetadata the documentation comment and metadata to be asso ciated with the
2779 * declaration 2979 * declaration
2780 * @param externalKeyword the 'external' token 2980 * @param externalKeyword the 'external' token
2781 * @param staticKeyword the static keyword, or `null` if the getter is not sta tic 2981 * @param staticKeyword the static keyword, or `null` if the getter is not sta tic
2782 * @param the return type that has already been parsed, or `null` if there was no return 2982 * @param the return type that has already been parsed, or `null` if there was no return
2783 * type 2983 * type
2784 * @return the getter that was parsed 2984 * @return the getter that was parsed
2785 */ 2985 */
2786 MethodDeclaration parseGetter(CommentAndMetadata commentAndMetadata, Token ext ernalKeyword, Token staticKeyword, TypeName returnType) { 2986 MethodDeclaration parseGetter(CommentAndMetadata commentAndMetadata, Token ext ernalKeyword, Token staticKeyword, TypeName returnType) {
2787 Token propertyKeyword = expect(Keyword.GET); 2987 Token propertyKeyword = expect(Keyword.GET);
2788 SimpleIdentifier name = parseSimpleIdentifier(); 2988 SimpleIdentifier name = parseSimpleIdentifier();
2789 if (matches5(TokenType.OPEN_PAREN) && matches4(peek(), TokenType.CLOSE_PAREN )) { 2989 if (matches5(TokenType.OPEN_PAREN) && matches4(peek(), TokenType.CLOSE_PAREN )) {
2790 reportError7(ParserErrorCode.GETTER_WITH_PARAMETERS, []); 2990 reportError7(ParserErrorCode.GETTER_WITH_PARAMETERS, []);
2791 advance(); 2991 advance();
2792 advance(); 2992 advance();
2793 } 2993 }
2794 FunctionBody body = parseFunctionBody(externalKeyword != null || staticKeywo rd == null, ParserErrorCode.STATIC_GETTER_WITHOUT_BODY, false); 2994 FunctionBody body = parseFunctionBody(externalKeyword != null || staticKeywo rd == null, ParserErrorCode.STATIC_GETTER_WITHOUT_BODY, false);
2795 if (externalKeyword != null && body is! EmptyFunctionBody) { 2995 if (externalKeyword != null && body is! EmptyFunctionBody) {
2796 reportError7(ParserErrorCode.EXTERNAL_GETTER_WITH_BODY, []); 2996 reportError7(ParserErrorCode.EXTERNAL_GETTER_WITH_BODY, []);
2797 } 2997 }
2798 return new MethodDeclaration.full(commentAndMetadata.comment, commentAndMeta data.metadata, externalKeyword, staticKeyword, returnType, propertyKeyword, null , name, null, body); 2998 return new MethodDeclaration.full(commentAndMetadata.comment, commentAndMeta data.metadata, externalKeyword, staticKeyword, returnType, propertyKeyword, null , name, null, body);
2799 } 2999 }
2800 3000
2801 /** 3001 /**
2802 * Parse a list of identifiers. 3002 * Parse a list of identifiers.
3003 *
2803 * <pre> 3004 * <pre>
2804 * identifierList ::= 3005 * identifierList ::=
2805 * identifier (',' identifier) 3006 * identifier (',' identifier)*
2806 * </pre> 3007 * </pre>
3008 *
2807 * @return the list of identifiers that were parsed 3009 * @return the list of identifiers that were parsed
2808 */ 3010 */
2809 List<SimpleIdentifier> parseIdentifierList() { 3011 List<SimpleIdentifier> parseIdentifierList() {
2810 List<SimpleIdentifier> identifiers = new List<SimpleIdentifier>(); 3012 List<SimpleIdentifier> identifiers = new List<SimpleIdentifier>();
2811 identifiers.add(parseSimpleIdentifier()); 3013 identifiers.add(parseSimpleIdentifier());
2812 while (matches5(TokenType.COMMA)) { 3014 while (matches5(TokenType.COMMA)) {
2813 advance(); 3015 advance();
2814 identifiers.add(parseSimpleIdentifier()); 3016 identifiers.add(parseSimpleIdentifier());
2815 } 3017 }
2816 return identifiers; 3018 return identifiers;
2817 } 3019 }
2818 3020
2819 /** 3021 /**
2820 * Parse an if statement. 3022 * Parse an if statement.
3023 *
2821 * <pre> 3024 * <pre>
2822 * ifStatement ::= 3025 * ifStatement ::=
2823 * 'if' '(' expression ')' statement ('else' statement)? 3026 * 'if' '(' expression ')' statement ('else' statement)?
2824 * </pre> 3027 * </pre>
3028 *
2825 * @return the if statement that was parsed 3029 * @return the if statement that was parsed
2826 */ 3030 */
2827 Statement parseIfStatement() { 3031 Statement parseIfStatement() {
2828 Token ifKeyword = expect(Keyword.IF); 3032 Token ifKeyword = expect(Keyword.IF);
2829 Token leftParenthesis = expect2(TokenType.OPEN_PAREN); 3033 Token leftParenthesis = expect2(TokenType.OPEN_PAREN);
2830 Expression condition = parseExpression2(); 3034 Expression condition = parseExpression2();
2831 Token rightParenthesis = expect2(TokenType.CLOSE_PAREN); 3035 Token rightParenthesis = expect2(TokenType.CLOSE_PAREN);
2832 Statement thenStatement = parseStatement2(); 3036 Statement thenStatement = parseStatement2();
2833 Token elseKeyword = null; 3037 Token elseKeyword = null;
2834 Statement elseStatement = null; 3038 Statement elseStatement = null;
2835 if (matches(Keyword.ELSE)) { 3039 if (matches(Keyword.ELSE)) {
2836 elseKeyword = andAdvance; 3040 elseKeyword = andAdvance;
2837 elseStatement = parseStatement2(); 3041 elseStatement = parseStatement2();
2838 } 3042 }
2839 return new IfStatement.full(ifKeyword, leftParenthesis, condition, rightPare nthesis, thenStatement, elseKeyword, elseStatement); 3043 return new IfStatement.full(ifKeyword, leftParenthesis, condition, rightPare nthesis, thenStatement, elseKeyword, elseStatement);
2840 } 3044 }
2841 3045
2842 /** 3046 /**
2843 * Parse an implements clause. 3047 * Parse an implements clause.
3048 *
2844 * <pre> 3049 * <pre>
2845 * implementsClause ::= 3050 * implementsClause ::=
2846 * 'implements' type (',' type) 3051 * 'implements' type (',' type)*
2847 * </pre> 3052 * </pre>
3053 *
2848 * @return the implements clause that was parsed 3054 * @return the implements clause that was parsed
2849 */ 3055 */
2850 ImplementsClause parseImplementsClause() { 3056 ImplementsClause parseImplementsClause() {
2851 Token keyword = expect(Keyword.IMPLEMENTS); 3057 Token keyword = expect(Keyword.IMPLEMENTS);
2852 List<TypeName> interfaces = new List<TypeName>(); 3058 List<TypeName> interfaces = new List<TypeName>();
2853 interfaces.add(parseTypeName()); 3059 interfaces.add(parseTypeName());
2854 while (optional(TokenType.COMMA)) { 3060 while (optional(TokenType.COMMA)) {
2855 interfaces.add(parseTypeName()); 3061 interfaces.add(parseTypeName());
2856 } 3062 }
2857 return new ImplementsClause.full(keyword, interfaces); 3063 return new ImplementsClause.full(keyword, interfaces);
2858 } 3064 }
2859 3065
2860 /** 3066 /**
2861 * Parse an import directive. 3067 * Parse an import directive.
3068 *
2862 * <pre> 3069 * <pre>
2863 * importDirective ::= 3070 * importDirective ::=
2864 * metadata 'import' stringLiteral ('as' identifier)? combinator*';' 3071 * metadata 'import' stringLiteral ('as' identifier)? combinator*';'
2865 * </pre> 3072 * </pre>
3073 *
2866 * @param commentAndMetadata the metadata to be associated with the directive 3074 * @param commentAndMetadata the metadata to be associated with the directive
2867 * @return the import directive that was parsed 3075 * @return the import directive that was parsed
2868 */ 3076 */
2869 ImportDirective parseImportDirective(CommentAndMetadata commentAndMetadata) { 3077 ImportDirective parseImportDirective(CommentAndMetadata commentAndMetadata) {
2870 Token importKeyword = expect(Keyword.IMPORT); 3078 Token importKeyword = expect(Keyword.IMPORT);
2871 StringLiteral libraryUri = parseStringLiteral(); 3079 StringLiteral libraryUri = parseStringLiteral();
2872 Token asToken = null; 3080 Token asToken = null;
2873 SimpleIdentifier prefix = null; 3081 SimpleIdentifier prefix = null;
2874 if (matches(Keyword.AS)) { 3082 if (matches(Keyword.AS)) {
2875 asToken = andAdvance; 3083 asToken = andAdvance;
2876 prefix = parseSimpleIdentifier(); 3084 prefix = parseSimpleIdentifier();
2877 } 3085 }
2878 List<Combinator> combinators = parseCombinators(); 3086 List<Combinator> combinators = parseCombinators();
2879 Token semicolon = expect2(TokenType.SEMICOLON); 3087 Token semicolon = expect2(TokenType.SEMICOLON);
2880 return new ImportDirective.full(commentAndMetadata.comment, commentAndMetada ta.metadata, importKeyword, libraryUri, asToken, prefix, combinators, semicolon) ; 3088 return new ImportDirective.full(commentAndMetadata.comment, commentAndMetada ta.metadata, importKeyword, libraryUri, asToken, prefix, combinators, semicolon) ;
2881 } 3089 }
2882 3090
2883 /** 3091 /**
2884 * Parse a list of initialized identifiers. 3092 * Parse a list of initialized identifiers.
3093 *
2885 * <pre> 3094 * <pre>
2886 * ?? ::= 3095 * ?? ::=
2887 * 'static'? ('var' | type) initializedIdentifierList ';' 3096 * 'static'? ('var' | type) initializedIdentifierList ';'
2888 * | 'final' type? initializedIdentifierList ';' 3097 * | 'final' type? initializedIdentifierList ';'
3098 *
2889 * initializedIdentifierList ::= 3099 * initializedIdentifierList ::=
2890 * initializedIdentifier (',' initializedIdentifier) 3100 * initializedIdentifier (',' initializedIdentifier)*
3101 *
2891 * initializedIdentifier ::= 3102 * initializedIdentifier ::=
2892 * identifier ('=' expression)? 3103 * identifier ('=' expression)?
2893 * </pre> 3104 * </pre>
3105 *
2894 * @param commentAndMetadata the documentation comment and metadata to be asso ciated with the 3106 * @param commentAndMetadata the documentation comment and metadata to be asso ciated with the
2895 * declaration 3107 * declaration
2896 * @param staticKeyword the static keyword, or `null` if the getter is not sta tic 3108 * @param staticKeyword the static keyword, or `null` if the getter is not sta tic
2897 * @param keyword the token representing the 'final', 'const' or 'var' keyword , or `null` if 3109 * @param keyword the token representing the 'final', 'const' or 'var' keyword , or `null` if
2898 * there is no keyword 3110 * there is no keyword
2899 * @param type the type that has already been parsed, or `null` if 'var' was p rovided 3111 * @param type the type that has already been parsed, or `null` if 'var' was p rovided
2900 * @return the getter that was parsed 3112 * @return the getter that was parsed
2901 */ 3113 */
2902 FieldDeclaration parseInitializedIdentifierList(CommentAndMetadata commentAndM etadata, Token staticKeyword, Token keyword, TypeName type) { 3114 FieldDeclaration parseInitializedIdentifierList(CommentAndMetadata commentAndM etadata, Token staticKeyword, Token keyword, TypeName type) {
2903 VariableDeclarationList fieldList = parseVariableDeclarationList2(null, keyw ord, type); 3115 VariableDeclarationList fieldList = parseVariableDeclarationList2(null, keyw ord, type);
2904 return new FieldDeclaration.full(commentAndMetadata.comment, commentAndMetad ata.metadata, staticKeyword, fieldList, expect2(TokenType.SEMICOLON)); 3116 return new FieldDeclaration.full(commentAndMetadata.comment, commentAndMetad ata.metadata, staticKeyword, fieldList, expect2(TokenType.SEMICOLON));
2905 } 3117 }
2906 3118
2907 /** 3119 /**
2908 * Parse an instance creation expression. 3120 * Parse an instance creation expression.
3121 *
2909 * <pre> 3122 * <pre>
2910 * instanceCreationExpression ::= 3123 * instanceCreationExpression ::=
2911 * ('new' | 'const') type ('.' identifier)? argumentList 3124 * ('new' | 'const') type ('.' identifier)? argumentList
2912 * </pre> 3125 * </pre>
3126 *
2913 * @param keyword the 'new' or 'const' keyword that introduces the expression 3127 * @param keyword the 'new' or 'const' keyword that introduces the expression
2914 * @return the instance creation expression that was parsed 3128 * @return the instance creation expression that was parsed
2915 */ 3129 */
2916 InstanceCreationExpression parseInstanceCreationExpression(Token keyword) { 3130 InstanceCreationExpression parseInstanceCreationExpression(Token keyword) {
2917 ConstructorName constructorName = parseConstructorName(); 3131 ConstructorName constructorName = parseConstructorName();
2918 ArgumentList argumentList = parseArgumentList(); 3132 ArgumentList argumentList = parseArgumentList();
2919 return new InstanceCreationExpression.full(keyword, constructorName, argumen tList); 3133 return new InstanceCreationExpression.full(keyword, constructorName, argumen tList);
2920 } 3134 }
2921 3135
2922 /** 3136 /**
2923 * Parse a library directive. 3137 * Parse a library directive.
3138 *
2924 * <pre> 3139 * <pre>
2925 * libraryDirective ::= 3140 * libraryDirective ::=
2926 * metadata 'library' identifier ';' 3141 * metadata 'library' identifier ';'
2927 * </pre> 3142 * </pre>
3143 *
2928 * @param commentAndMetadata the metadata to be associated with the directive 3144 * @param commentAndMetadata the metadata to be associated with the directive
2929 * @return the library directive that was parsed 3145 * @return the library directive that was parsed
2930 */ 3146 */
2931 LibraryDirective parseLibraryDirective(CommentAndMetadata commentAndMetadata) { 3147 LibraryDirective parseLibraryDirective(CommentAndMetadata commentAndMetadata) {
2932 Token keyword = expect(Keyword.LIBRARY); 3148 Token keyword = expect(Keyword.LIBRARY);
2933 LibraryIdentifier libraryName = parseLibraryName(ParserErrorCode.MISSING_NAM E_IN_LIBRARY_DIRECTIVE, keyword); 3149 LibraryIdentifier libraryName = parseLibraryName(ParserErrorCode.MISSING_NAM E_IN_LIBRARY_DIRECTIVE, keyword);
2934 Token semicolon = expect2(TokenType.SEMICOLON); 3150 Token semicolon = expect2(TokenType.SEMICOLON);
2935 return new LibraryDirective.full(commentAndMetadata.comment, commentAndMetad ata.metadata, keyword, libraryName, semicolon); 3151 return new LibraryDirective.full(commentAndMetadata.comment, commentAndMetad ata.metadata, keyword, libraryName, semicolon);
2936 } 3152 }
2937 3153
2938 /** 3154 /**
2939 * Parse a library identifier. 3155 * Parse a library identifier.
3156 *
2940 * <pre> 3157 * <pre>
2941 * libraryIdentifier ::= 3158 * libraryIdentifier ::=
2942 * identifier ('.' identifier) 3159 * identifier ('.' identifier)*
2943 * </pre> 3160 * </pre>
3161 *
2944 * @return the library identifier that was parsed 3162 * @return the library identifier that was parsed
2945 */ 3163 */
2946 LibraryIdentifier parseLibraryIdentifier() { 3164 LibraryIdentifier parseLibraryIdentifier() {
2947 List<SimpleIdentifier> components = new List<SimpleIdentifier>(); 3165 List<SimpleIdentifier> components = new List<SimpleIdentifier>();
2948 components.add(parseSimpleIdentifier()); 3166 components.add(parseSimpleIdentifier());
2949 while (matches5(TokenType.PERIOD)) { 3167 while (matches5(TokenType.PERIOD)) {
2950 advance(); 3168 advance();
2951 components.add(parseSimpleIdentifier()); 3169 components.add(parseSimpleIdentifier());
2952 } 3170 }
2953 return new LibraryIdentifier.full(components); 3171 return new LibraryIdentifier.full(components);
2954 } 3172 }
2955 3173
2956 /** 3174 /**
2957 * Parse a library name. 3175 * Parse a library name.
3176 *
2958 * <pre> 3177 * <pre>
2959 * libraryName ::= 3178 * libraryName ::=
2960 * libraryIdentifier 3179 * libraryIdentifier
2961 * </pre> 3180 * </pre>
3181 *
2962 * @param missingNameError the error code to be used if the library name is mi ssing 3182 * @param missingNameError the error code to be used if the library name is mi ssing
2963 * @param missingNameToken the token associated with the error produced if the library name is 3183 * @param missingNameToken the token associated with the error produced if the library name is
2964 * missing 3184 * missing
2965 * @return the library name that was parsed 3185 * @return the library name that was parsed
2966 */ 3186 */
2967 LibraryIdentifier parseLibraryName(ParserErrorCode missingNameError, Token mis singNameToken) { 3187 LibraryIdentifier parseLibraryName(ParserErrorCode missingNameError, Token mis singNameToken) {
2968 if (matchesIdentifier()) { 3188 if (matchesIdentifier()) {
2969 return parseLibraryIdentifier(); 3189 return parseLibraryIdentifier();
2970 } else if (matches5(TokenType.STRING)) { 3190 } else if (matches5(TokenType.STRING)) {
2971 StringLiteral string = parseStringLiteral(); 3191 StringLiteral string = parseStringLiteral();
2972 reportError(ParserErrorCode.NON_IDENTIFIER_LIBRARY_NAME, string, []); 3192 reportError(ParserErrorCode.NON_IDENTIFIER_LIBRARY_NAME, string, []);
2973 } else { 3193 } else {
2974 reportError8(missingNameError, missingNameToken, []); 3194 reportError8(missingNameError, missingNameToken, []);
2975 } 3195 }
2976 List<SimpleIdentifier> components = new List<SimpleIdentifier>(); 3196 List<SimpleIdentifier> components = new List<SimpleIdentifier>();
2977 components.add(createSyntheticIdentifier()); 3197 components.add(createSyntheticIdentifier());
2978 return new LibraryIdentifier.full(components); 3198 return new LibraryIdentifier.full(components);
2979 } 3199 }
2980 3200
2981 /** 3201 /**
2982 * Parse a list literal. 3202 * Parse a list literal.
3203 *
2983 * <pre> 3204 * <pre>
2984 * listLiteral ::= 3205 * listLiteral ::=
2985 * 'const'? typeArguments? '\[' (expressionList ','?)? '\]' 3206 * 'const'? typeArguments? '[' (expressionList ','?)? ']'
2986 * </pre> 3207 * </pre>
3208 *
2987 * @param modifier the 'const' modifier appearing before the literal, or `null ` if there is 3209 * @param modifier the 'const' modifier appearing before the literal, or `null ` if there is
2988 * no modifier 3210 * no modifier
2989 * @param typeArguments the type arguments appearing before the literal, or `n ull` if there 3211 * @param typeArguments the type arguments appearing before the literal, or `n ull` if there
2990 * are no type arguments 3212 * are no type arguments
2991 * @return the list literal that was parsed 3213 * @return the list literal that was parsed
2992 */ 3214 */
2993 ListLiteral parseListLiteral(Token modifier, TypeArgumentList typeArguments) { 3215 ListLiteral parseListLiteral(Token modifier, TypeArgumentList typeArguments) {
2994 if (matches5(TokenType.INDEX)) { 3216 if (matches5(TokenType.INDEX)) {
2995 BeginToken leftBracket = new BeginToken(TokenType.OPEN_SQUARE_BRACKET, _cu rrentToken.offset); 3217 BeginToken leftBracket = new BeginToken(TokenType.OPEN_SQUARE_BRACKET, _cu rrentToken.offset);
2996 Token rightBracket = new Token(TokenType.CLOSE_SQUARE_BRACKET, _currentTok en.offset + 1); 3218 Token rightBracket = new Token(TokenType.CLOSE_SQUARE_BRACKET, _currentTok en.offset + 1);
2997 leftBracket.endToken = rightBracket; 3219 leftBracket.endToken = rightBracket;
2998 rightBracket.setNext(_currentToken.next); 3220 rightBracket.setNext(_currentToken.next);
2999 leftBracket.setNext(rightBracket); 3221 leftBracket.setNext(rightBracket);
3000 _currentToken.previous.setNext(leftBracket); 3222 _currentToken.previous.setNext(leftBracket);
(...skipping 11 matching lines...) Expand all
3012 return new ListLiteral.full(modifier, typeArguments, leftBracket, elemen ts, andAdvance); 3234 return new ListLiteral.full(modifier, typeArguments, leftBracket, elemen ts, andAdvance);
3013 } 3235 }
3014 elements.add(parseExpression2()); 3236 elements.add(parseExpression2());
3015 } 3237 }
3016 Token rightBracket = expect2(TokenType.CLOSE_SQUARE_BRACKET); 3238 Token rightBracket = expect2(TokenType.CLOSE_SQUARE_BRACKET);
3017 return new ListLiteral.full(modifier, typeArguments, leftBracket, elements, rightBracket); 3239 return new ListLiteral.full(modifier, typeArguments, leftBracket, elements, rightBracket);
3018 } 3240 }
3019 3241
3020 /** 3242 /**
3021 * Parse a list or map literal. 3243 * Parse a list or map literal.
3244 *
3022 * <pre> 3245 * <pre>
3023 * listOrMapLiteral ::= 3246 * listOrMapLiteral ::=
3024 * listLiteral 3247 * listLiteral
3025 * | mapLiteral 3248 * | mapLiteral
3026 * </pre> 3249 * </pre>
3250 *
3027 * @param modifier the 'const' modifier appearing before the literal, or `null ` if there is 3251 * @param modifier the 'const' modifier appearing before the literal, or `null ` if there is
3028 * no modifier 3252 * no modifier
3029 * @return the list or map literal that was parsed 3253 * @return the list or map literal that was parsed
3030 */ 3254 */
3031 TypedLiteral parseListOrMapLiteral(Token modifier) { 3255 TypedLiteral parseListOrMapLiteral(Token modifier) {
3032 TypeArgumentList typeArguments = null; 3256 TypeArgumentList typeArguments = null;
3033 if (matches5(TokenType.LT)) { 3257 if (matches5(TokenType.LT)) {
3034 typeArguments = parseTypeArgumentList(); 3258 typeArguments = parseTypeArgumentList();
3035 } 3259 }
3036 if (matches5(TokenType.OPEN_CURLY_BRACKET)) { 3260 if (matches5(TokenType.OPEN_CURLY_BRACKET)) {
3037 return parseMapLiteral(modifier, typeArguments); 3261 return parseMapLiteral(modifier, typeArguments);
3038 } else if (matches5(TokenType.OPEN_SQUARE_BRACKET) || matches5(TokenType.IND EX)) { 3262 } else if (matches5(TokenType.OPEN_SQUARE_BRACKET) || matches5(TokenType.IND EX)) {
3039 return parseListLiteral(modifier, typeArguments); 3263 return parseListLiteral(modifier, typeArguments);
3040 } 3264 }
3041 reportError7(ParserErrorCode.EXPECTED_LIST_OR_MAP_LITERAL, []); 3265 reportError7(ParserErrorCode.EXPECTED_LIST_OR_MAP_LITERAL, []);
3042 return new ListLiteral.full(modifier, typeArguments, createSyntheticToken2(T okenType.OPEN_SQUARE_BRACKET), null, createSyntheticToken2(TokenType.CLOSE_SQUAR E_BRACKET)); 3266 return new ListLiteral.full(modifier, typeArguments, createSyntheticToken2(T okenType.OPEN_SQUARE_BRACKET), null, createSyntheticToken2(TokenType.CLOSE_SQUAR E_BRACKET));
3043 } 3267 }
3044 3268
3045 /** 3269 /**
3046 * Parse a logical and expression. 3270 * Parse a logical and expression.
3271 *
3047 * <pre> 3272 * <pre>
3048 * logicalAndExpression ::= 3273 * logicalAndExpression ::=
3049 * bitwiseOrExpression ('&&' bitwiseOrExpression) 3274 * bitwiseOrExpression ('&&' bitwiseOrExpression)*
3050 * </pre> 3275 * </pre>
3276 *
3051 * @return the logical and expression that was parsed 3277 * @return the logical and expression that was parsed
3052 */ 3278 */
3053 Expression parseLogicalAndExpression() { 3279 Expression parseLogicalAndExpression() {
3054 Expression expression = parseBitwiseOrExpression(); 3280 Expression expression = parseBitwiseOrExpression();
3055 while (matches5(TokenType.AMPERSAND_AMPERSAND)) { 3281 while (matches5(TokenType.AMPERSAND_AMPERSAND)) {
3056 Token operator = andAdvance; 3282 Token operator = andAdvance;
3057 expression = new BinaryExpression.full(expression, operator, parseBitwiseO rExpression()); 3283 expression = new BinaryExpression.full(expression, operator, parseBitwiseO rExpression());
3058 } 3284 }
3059 return expression; 3285 return expression;
3060 } 3286 }
3061 3287
3062 /** 3288 /**
3063 * Parse a logical or expression. 3289 * Parse a logical or expression.
3290 *
3064 * <pre> 3291 * <pre>
3065 * logicalOrExpression ::= 3292 * logicalOrExpression ::=
3066 * logicalAndExpression ('||' logicalAndExpression) 3293 * logicalAndExpression ('||' logicalAndExpression)*
3067 * </pre> 3294 * </pre>
3295 *
3068 * @return the logical or expression that was parsed 3296 * @return the logical or expression that was parsed
3069 */ 3297 */
3070 Expression parseLogicalOrExpression() { 3298 Expression parseLogicalOrExpression() {
3071 Expression expression = parseLogicalAndExpression(); 3299 Expression expression = parseLogicalAndExpression();
3072 while (matches5(TokenType.BAR_BAR)) { 3300 while (matches5(TokenType.BAR_BAR)) {
3073 Token operator = andAdvance; 3301 Token operator = andAdvance;
3074 expression = new BinaryExpression.full(expression, operator, parseLogicalA ndExpression()); 3302 expression = new BinaryExpression.full(expression, operator, parseLogicalA ndExpression());
3075 } 3303 }
3076 return expression; 3304 return expression;
3077 } 3305 }
3078 3306
3079 /** 3307 /**
3080 * Parse a map literal. 3308 * Parse a map literal.
3309 *
3081 * <pre> 3310 * <pre>
3082 * mapLiteral ::= 3311 * mapLiteral ::=
3083 * 'const'? typeArguments? '{' (mapLiteralEntry (',' mapLiteralEntry)* ','?)? '}' 3312 * 'const'? typeArguments? '{' (mapLiteralEntry (',' mapLiteralEntry)* ',' ?)? '}'
3084 * </pre> 3313 * </pre>
3314 *
3085 * @param modifier the 'const' modifier appearing before the literal, or `null ` if there is 3315 * @param modifier the 'const' modifier appearing before the literal, or `null ` if there is
3086 * no modifier 3316 * no modifier
3087 * @param typeArguments the type arguments that were declared, or `null` if th ere are no 3317 * @param typeArguments the type arguments that were declared, or `null` if th ere are no
3088 * type arguments 3318 * type arguments
3089 * @return the map literal that was parsed 3319 * @return the map literal that was parsed
3090 */ 3320 */
3091 MapLiteral parseMapLiteral(Token modifier, TypeArgumentList typeArguments) { 3321 MapLiteral parseMapLiteral(Token modifier, TypeArgumentList typeArguments) {
3092 if (typeArguments != null) { 3322 if (typeArguments != null) {
3093 int num = typeArguments.arguments.length; 3323 int num = typeArguments.arguments.length;
3094 if (num != 2) { 3324 if (num != 2) {
3095 reportError(ParserErrorCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS, typeArgumen ts, [num]); 3325 reportError(ParserErrorCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS, typeArgumen ts, [num]);
3096 } 3326 }
3097 } 3327 }
3098 Token leftBracket = expect2(TokenType.OPEN_CURLY_BRACKET); 3328 Token leftBracket = expect2(TokenType.OPEN_CURLY_BRACKET);
3099 List<MapLiteralEntry> entries = new List<MapLiteralEntry>(); 3329 List<MapLiteralEntry> entries = new List<MapLiteralEntry>();
3100 if (matches5(TokenType.CLOSE_CURLY_BRACKET)) { 3330 if (matches5(TokenType.CLOSE_CURLY_BRACKET)) {
3101 return new MapLiteral.full(modifier, typeArguments, leftBracket, entries, andAdvance); 3331 return new MapLiteral.full(modifier, typeArguments, leftBracket, entries, andAdvance);
3102 } 3332 }
3103 entries.add(parseMapLiteralEntry()); 3333 entries.add(parseMapLiteralEntry());
3104 while (optional(TokenType.COMMA)) { 3334 while (optional(TokenType.COMMA)) {
3105 if (matches5(TokenType.CLOSE_CURLY_BRACKET)) { 3335 if (matches5(TokenType.CLOSE_CURLY_BRACKET)) {
3106 return new MapLiteral.full(modifier, typeArguments, leftBracket, entries , andAdvance); 3336 return new MapLiteral.full(modifier, typeArguments, leftBracket, entries , andAdvance);
3107 } 3337 }
3108 entries.add(parseMapLiteralEntry()); 3338 entries.add(parseMapLiteralEntry());
3109 } 3339 }
3110 Token rightBracket = expect2(TokenType.CLOSE_CURLY_BRACKET); 3340 Token rightBracket = expect2(TokenType.CLOSE_CURLY_BRACKET);
3111 return new MapLiteral.full(modifier, typeArguments, leftBracket, entries, ri ghtBracket); 3341 return new MapLiteral.full(modifier, typeArguments, leftBracket, entries, ri ghtBracket);
3112 } 3342 }
3113 3343
3114 /** 3344 /**
3115 * Parse a map literal entry. 3345 * Parse a map literal entry.
3346 *
3116 * <pre> 3347 * <pre>
3117 * mapLiteralEntry ::= 3348 * mapLiteralEntry ::=
3118 * expression ':' expression 3349 * expression ':' expression
3119 * </pre> 3350 * </pre>
3351 *
3120 * @return the map literal entry that was parsed 3352 * @return the map literal entry that was parsed
3121 */ 3353 */
3122 MapLiteralEntry parseMapLiteralEntry() { 3354 MapLiteralEntry parseMapLiteralEntry() {
3123 Expression key = parseExpression2(); 3355 Expression key = parseExpression2();
3124 Token separator = expect2(TokenType.COLON); 3356 Token separator = expect2(TokenType.COLON);
3125 Expression value = parseExpression2(); 3357 Expression value = parseExpression2();
3126 return new MapLiteralEntry.full(key, separator, value); 3358 return new MapLiteralEntry.full(key, separator, value);
3127 } 3359 }
3128 3360
3129 /** 3361 /**
3130 * Parse a method declaration. 3362 * Parse a method declaration.
3363 *
3131 * <pre> 3364 * <pre>
3132 * functionDeclaration ::= 3365 * functionDeclaration ::=
3133 * 'external'? 'static'? functionSignature functionBody 3366 * 'external'? 'static'? functionSignature functionBody
3134 * | 'external'? functionSignature ';' 3367 * | 'external'? functionSignature ';'
3135 * </pre> 3368 * </pre>
3369 *
3136 * @param commentAndMetadata the documentation comment and metadata to be asso ciated with the 3370 * @param commentAndMetadata the documentation comment and metadata to be asso ciated with the
3137 * declaration 3371 * declaration
3138 * @param externalKeyword the 'external' token 3372 * @param externalKeyword the 'external' token
3139 * @param staticKeyword the static keyword, or `null` if the getter is not sta tic 3373 * @param staticKeyword the static keyword, or `null` if the getter is not sta tic
3140 * @param returnType the return type of the method 3374 * @param returnType the return type of the method
3141 * @return the method declaration that was parsed 3375 * @return the method declaration that was parsed
3142 */ 3376 */
3143 MethodDeclaration parseMethodDeclaration(CommentAndMetadata commentAndMetadata , Token externalKeyword, Token staticKeyword, TypeName returnType) { 3377 MethodDeclaration parseMethodDeclaration(CommentAndMetadata commentAndMetadata , Token externalKeyword, Token staticKeyword, TypeName returnType) {
3144 SimpleIdentifier methodName = parseSimpleIdentifier(); 3378 SimpleIdentifier methodName = parseSimpleIdentifier();
3145 FormalParameterList parameters = parseFormalParameterList(); 3379 FormalParameterList parameters = parseFormalParameterList();
3146 validateFormalParameterList(parameters); 3380 validateFormalParameterList(parameters);
3147 return parseMethodDeclaration2(commentAndMetadata, externalKeyword, staticKe yword, returnType, methodName, parameters); 3381 return parseMethodDeclaration2(commentAndMetadata, externalKeyword, staticKe yword, returnType, methodName, parameters);
3148 } 3382 }
3149 3383
3150 /** 3384 /**
3151 * Parse a method declaration. 3385 * Parse a method declaration.
3386 *
3152 * <pre> 3387 * <pre>
3153 * functionDeclaration ::= 3388 * functionDeclaration ::=
3154 * ('external' 'static'?)? functionSignature functionBody 3389 * ('external' 'static'?)? functionSignature functionBody
3155 * | 'external'? functionSignature ';' 3390 * | 'external'? functionSignature ';'
3156 * </pre> 3391 * </pre>
3392 *
3157 * @param commentAndMetadata the documentation comment and metadata to be asso ciated with the 3393 * @param commentAndMetadata the documentation comment and metadata to be asso ciated with the
3158 * declaration 3394 * declaration
3159 * @param externalKeyword the 'external' token 3395 * @param externalKeyword the 'external' token
3160 * @param staticKeyword the static keyword, or `null` if the getter is not sta tic 3396 * @param staticKeyword the static keyword, or `null` if the getter is not sta tic
3161 * @param returnType the return type of the method 3397 * @param returnType the return type of the method
3162 * @param name the name of the method 3398 * @param name the name of the method
3163 * @param parameters the parameters to the method 3399 * @param parameters the parameters to the method
3164 * @return the method declaration that was parsed 3400 * @return the method declaration that was parsed
3165 */ 3401 */
3166 MethodDeclaration parseMethodDeclaration2(CommentAndMetadata commentAndMetadat a, Token externalKeyword, Token staticKeyword, TypeName returnType, SimpleIdenti fier name, FormalParameterList parameters) { 3402 MethodDeclaration parseMethodDeclaration2(CommentAndMetadata commentAndMetadat a, Token externalKeyword, Token staticKeyword, TypeName returnType, SimpleIdenti fier name, FormalParameterList parameters) {
3167 FunctionBody body = parseFunctionBody(externalKeyword != null || staticKeywo rd == null, ParserErrorCode.MISSING_FUNCTION_BODY, false); 3403 FunctionBody body = parseFunctionBody(externalKeyword != null || staticKeywo rd == null, ParserErrorCode.MISSING_FUNCTION_BODY, false);
3168 if (externalKeyword != null) { 3404 if (externalKeyword != null) {
3169 if (body is! EmptyFunctionBody) { 3405 if (body is! EmptyFunctionBody) {
3170 reportError(ParserErrorCode.EXTERNAL_METHOD_WITH_BODY, body, []); 3406 reportError(ParserErrorCode.EXTERNAL_METHOD_WITH_BODY, body, []);
3171 } 3407 }
3172 } else if (staticKeyword != null) { 3408 } else if (staticKeyword != null) {
3173 if (body is EmptyFunctionBody) { 3409 if (body is EmptyFunctionBody) {
3174 reportError(ParserErrorCode.ABSTRACT_STATIC_METHOD, body, []); 3410 reportError(ParserErrorCode.ABSTRACT_STATIC_METHOD, body, []);
3175 } 3411 }
3176 } 3412 }
3177 return new MethodDeclaration.full(commentAndMetadata.comment, commentAndMeta data.metadata, externalKeyword, staticKeyword, returnType, null, null, name, par ameters, body); 3413 return new MethodDeclaration.full(commentAndMetadata.comment, commentAndMeta data.metadata, externalKeyword, staticKeyword, returnType, null, null, name, par ameters, body);
3178 } 3414 }
3179 3415
3180 /** 3416 /**
3181 * Parse the modifiers preceding a declaration. This method allows the modifie rs to appear in any 3417 * Parse the modifiers preceding a declaration. This method allows the modifie rs to appear in any
3182 * order but does generate errors for duplicated modifiers. Checks for other p roblems, such as 3418 * order but does generate errors for duplicated modifiers. Checks for other p roblems, such as
3183 * having the modifiers appear in the wrong order or specifying both 'const' a nd 'final', are 3419 * having the modifiers appear in the wrong order or specifying both 'const' a nd 'final', are
3184 * reported in one of the methods whose name is prefixed with `validateModifie rsFor`. 3420 * reported in one of the methods whose name is prefixed with `validateModifie rsFor`.
3421 *
3185 * <pre> 3422 * <pre>
3186 * modifiers ::= 3423 * modifiers ::=
3187 * ('abstract' | 'const' | 'external' | 'factory' | 'final' | 'static' | 'var' ) 3424 * ('abstract' | 'const' | 'external' | 'factory' | 'final' | 'static' | ' var')*
3188 * </pre> 3425 * </pre>
3426 *
3189 * @return the modifiers that were parsed 3427 * @return the modifiers that were parsed
3190 */ 3428 */
3191 Modifiers parseModifiers() { 3429 Modifiers parseModifiers() {
3192 Modifiers modifiers = new Modifiers(); 3430 Modifiers modifiers = new Modifiers();
3193 bool progress = true; 3431 bool progress = true;
3194 while (progress) { 3432 while (progress) {
3195 if (matches(Keyword.ABSTRACT) && !matches4(peek(), TokenType.PERIOD) && !m atches4(peek(), TokenType.LT)) { 3433 if (matches(Keyword.ABSTRACT) && !matches4(peek(), TokenType.PERIOD) && !m atches4(peek(), TokenType.LT)) {
3196 if (modifiers.abstractKeyword != null) { 3434 if (modifiers.abstractKeyword != null) {
3197 reportError7(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexem e]); 3435 reportError7(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexem e]);
3198 advance(); 3436 advance();
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
3243 } 3481 }
3244 } else { 3482 } else {
3245 progress = false; 3483 progress = false;
3246 } 3484 }
3247 } 3485 }
3248 return modifiers; 3486 return modifiers;
3249 } 3487 }
3250 3488
3251 /** 3489 /**
3252 * Parse a multiplicative expression. 3490 * Parse a multiplicative expression.
3491 *
3253 * <pre> 3492 * <pre>
3254 * multiplicativeExpression ::= 3493 * multiplicativeExpression ::=
3255 * unaryExpression (multiplicativeOperator unaryExpression) 3494 * unaryExpression (multiplicativeOperator unaryExpression)*
3256 * | 'super' (multiplicativeOperator unaryExpression)+ 3495 * | 'super' (multiplicativeOperator unaryExpression)+
3257 * </pre> 3496 * </pre>
3497 *
3258 * @return the multiplicative expression that was parsed 3498 * @return the multiplicative expression that was parsed
3259 */ 3499 */
3260 Expression parseMultiplicativeExpression() { 3500 Expression parseMultiplicativeExpression() {
3261 Expression expression; 3501 Expression expression;
3262 if (matches(Keyword.SUPER) && _currentToken.next.type.isMultiplicativeOperat or) { 3502 if (matches(Keyword.SUPER) && _currentToken.next.type.isMultiplicativeOperat or) {
3263 expression = new SuperExpression.full(andAdvance); 3503 expression = new SuperExpression.full(andAdvance);
3264 } else { 3504 } else {
3265 expression = parseUnaryExpression(); 3505 expression = parseUnaryExpression();
3266 } 3506 }
3267 while (_currentToken.type.isMultiplicativeOperator) { 3507 while (_currentToken.type.isMultiplicativeOperator) {
3268 Token operator = andAdvance; 3508 Token operator = andAdvance;
3269 expression = new BinaryExpression.full(expression, operator, parseUnaryExp ression()); 3509 expression = new BinaryExpression.full(expression, operator, parseUnaryExp ression());
3270 } 3510 }
3271 return expression; 3511 return expression;
3272 } 3512 }
3273 3513
3274 /** 3514 /**
3275 * Parse a new expression. 3515 * Parse a new expression.
3516 *
3276 * <pre> 3517 * <pre>
3277 * newExpression ::= 3518 * newExpression ::=
3278 * instanceCreationExpression 3519 * instanceCreationExpression
3279 * </pre> 3520 * </pre>
3521 *
3280 * @return the new expression that was parsed 3522 * @return the new expression that was parsed
3281 */ 3523 */
3282 InstanceCreationExpression parseNewExpression() => parseInstanceCreationExpres sion(expect(Keyword.NEW)); 3524 InstanceCreationExpression parseNewExpression() => parseInstanceCreationExpres sion(expect(Keyword.NEW));
3283 3525
3284 /** 3526 /**
3285 * Parse a non-labeled statement. 3527 * Parse a non-labeled statement.
3528 *
3286 * <pre> 3529 * <pre>
3287 * nonLabeledStatement ::= 3530 * nonLabeledStatement ::=
3288 * block 3531 * block
3289 * | assertStatement 3532 * | assertStatement
3290 * | breakStatement 3533 * | breakStatement
3291 * | continueStatement 3534 * | continueStatement
3292 * | doStatement 3535 * | doStatement
3293 * | forStatement 3536 * | forStatement
3294 * | ifStatement 3537 * | ifStatement
3295 * | returnStatement 3538 * | returnStatement
3296 * | switchStatement 3539 * | switchStatement
3297 * | tryStatement 3540 * | tryStatement
3298 * | whileStatement 3541 * | whileStatement
3299 * | variableDeclarationList ';' 3542 * | variableDeclarationList ';'
3300 * | expressionStatement 3543 * | expressionStatement
3301 * | functionSignature functionBody 3544 * | functionSignature functionBody
3302 * </pre> 3545 * </pre>
3546 *
3303 * @return the non-labeled statement that was parsed 3547 * @return the non-labeled statement that was parsed
3304 */ 3548 */
3305 Statement parseNonLabeledStatement() { 3549 Statement parseNonLabeledStatement() {
3306 CommentAndMetadata commentAndMetadata = parseCommentAndMetadata(); 3550 CommentAndMetadata commentAndMetadata = parseCommentAndMetadata();
3307 if (matches5(TokenType.OPEN_CURLY_BRACKET)) { 3551 if (matches5(TokenType.OPEN_CURLY_BRACKET)) {
3308 if (matches4(peek(), TokenType.STRING)) { 3552 if (matches4(peek(), TokenType.STRING)) {
3309 Token afterString = skipStringLiteral(_currentToken.next); 3553 Token afterString = skipStringLiteral(_currentToken.next);
3310 if (afterString != null && identical(afterString.type, TokenType.COLON)) { 3554 if (afterString != null && identical(afterString.type, TokenType.COLON)) {
3311 return new ExpressionStatement.full(parseExpression2(), expect2(TokenT ype.SEMICOLON)); 3555 return new ExpressionStatement.full(parseExpression2(), expect2(TokenT ype.SEMICOLON));
3312 } 3556 }
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
3383 } else if (matches5(TokenType.CLOSE_CURLY_BRACKET)) { 3627 } else if (matches5(TokenType.CLOSE_CURLY_BRACKET)) {
3384 reportError7(ParserErrorCode.MISSING_STATEMENT, []); 3628 reportError7(ParserErrorCode.MISSING_STATEMENT, []);
3385 return new EmptyStatement.full(createSyntheticToken2(TokenType.SEMICOLON)) ; 3629 return new EmptyStatement.full(createSyntheticToken2(TokenType.SEMICOLON)) ;
3386 } else { 3630 } else {
3387 return new ExpressionStatement.full(parseExpression2(), expect2(TokenType. SEMICOLON)); 3631 return new ExpressionStatement.full(parseExpression2(), expect2(TokenType. SEMICOLON));
3388 } 3632 }
3389 } 3633 }
3390 3634
3391 /** 3635 /**
3392 * Parse a normal formal parameter. 3636 * Parse a normal formal parameter.
3637 *
3393 * <pre> 3638 * <pre>
3394 * normalFormalParameter ::= 3639 * normalFormalParameter ::=
3395 * functionSignature 3640 * functionSignature
3396 * | fieldFormalParameter 3641 * | fieldFormalParameter
3397 * | simpleFormalParameter 3642 * | simpleFormalParameter
3643 *
3398 * functionSignature: 3644 * functionSignature:
3399 * metadata returnType? identifier formalParameterList 3645 * metadata returnType? identifier formalParameterList
3646 *
3400 * fieldFormalParameter ::= 3647 * fieldFormalParameter ::=
3401 * metadata finalConstVarOrType? 'this' '.' identifier 3648 * metadata finalConstVarOrType? 'this' '.' identifier
3649 *
3402 * simpleFormalParameter ::= 3650 * simpleFormalParameter ::=
3403 * declaredIdentifier 3651 * declaredIdentifier
3404 * | metadata identifier 3652 * | metadata identifier
3405 * </pre> 3653 * </pre>
3654 *
3406 * @return the normal formal parameter that was parsed 3655 * @return the normal formal parameter that was parsed
3407 */ 3656 */
3408 NormalFormalParameter parseNormalFormalParameter() { 3657 NormalFormalParameter parseNormalFormalParameter() {
3409 CommentAndMetadata commentAndMetadata = parseCommentAndMetadata(); 3658 CommentAndMetadata commentAndMetadata = parseCommentAndMetadata();
3410 FinalConstVarOrType holder = parseFinalConstVarOrType(true); 3659 FinalConstVarOrType holder = parseFinalConstVarOrType(true);
3411 Token thisKeyword = null; 3660 Token thisKeyword = null;
3412 Token period = null; 3661 Token period = null;
3413 if (matches(Keyword.THIS)) { 3662 if (matches(Keyword.THIS)) {
3414 thisKeyword = andAdvance; 3663 thisKeyword = andAdvance;
3415 period = expect2(TokenType.PERIOD); 3664 period = expect2(TokenType.PERIOD);
(...skipping 10 matching lines...) Expand all
3426 reportError8(ParserErrorCode.VOID_PARAMETER, type.name.beginToken, []); 3675 reportError8(ParserErrorCode.VOID_PARAMETER, type.name.beginToken, []);
3427 } 3676 }
3428 if (thisKeyword != null) { 3677 if (thisKeyword != null) {
3429 return new FieldFormalParameter.full(commentAndMetadata.comment, commentAn dMetadata.metadata, holder.keyword, holder.type, thisKeyword, period, identifier ); 3678 return new FieldFormalParameter.full(commentAndMetadata.comment, commentAn dMetadata.metadata, holder.keyword, holder.type, thisKeyword, period, identifier );
3430 } 3679 }
3431 return new SimpleFormalParameter.full(commentAndMetadata.comment, commentAnd Metadata.metadata, holder.keyword, holder.type, identifier); 3680 return new SimpleFormalParameter.full(commentAndMetadata.comment, commentAnd Metadata.metadata, holder.keyword, holder.type, identifier);
3432 } 3681 }
3433 3682
3434 /** 3683 /**
3435 * Parse an operator declaration. 3684 * Parse an operator declaration.
3685 *
3436 * <pre> 3686 * <pre>
3437 * operatorDeclaration ::= 3687 * operatorDeclaration ::=
3438 * operatorSignature (';' | functionBody) 3688 * operatorSignature (';' | functionBody)
3689 *
3439 * operatorSignature ::= 3690 * operatorSignature ::=
3440 * 'external'? returnType? 'operator' operator formalParameterList 3691 * 'external'? returnType? 'operator' operator formalParameterList
3441 * </pre> 3692 * </pre>
3693 *
3442 * @param commentAndMetadata the documentation comment and metadata to be asso ciated with the 3694 * @param commentAndMetadata the documentation comment and metadata to be asso ciated with the
3443 * declaration 3695 * declaration
3444 * @param externalKeyword the 'external' token 3696 * @param externalKeyword the 'external' token
3445 * @param the return type that has already been parsed, or `null` if there was no return 3697 * @param the return type that has already been parsed, or `null` if there was no return
3446 * type 3698 * type
3447 * @return the operator declaration that was parsed 3699 * @return the operator declaration that was parsed
3448 */ 3700 */
3449 MethodDeclaration parseOperator(CommentAndMetadata commentAndMetadata, Token e xternalKeyword, TypeName returnType) { 3701 MethodDeclaration parseOperator(CommentAndMetadata commentAndMetadata, Token e xternalKeyword, TypeName returnType) {
3450 Token operatorKeyword; 3702 Token operatorKeyword;
3451 if (matches(Keyword.OPERATOR)) { 3703 if (matches(Keyword.OPERATOR)) {
3452 operatorKeyword = andAdvance; 3704 operatorKeyword = andAdvance;
3453 } else { 3705 } else {
3454 reportError8(ParserErrorCode.MISSING_KEYWORD_OPERATOR, _currentToken, []); 3706 reportError8(ParserErrorCode.MISSING_KEYWORD_OPERATOR, _currentToken, []);
3455 operatorKeyword = createSyntheticToken(Keyword.OPERATOR); 3707 operatorKeyword = createSyntheticToken(Keyword.OPERATOR);
3456 } 3708 }
(...skipping 12 matching lines...) Expand all
3469 validateFormalParameterList(parameters); 3721 validateFormalParameterList(parameters);
3470 FunctionBody body = parseFunctionBody(true, ParserErrorCode.MISSING_FUNCTION _BODY, false); 3722 FunctionBody body = parseFunctionBody(true, ParserErrorCode.MISSING_FUNCTION _BODY, false);
3471 if (externalKeyword != null && body is! EmptyFunctionBody) { 3723 if (externalKeyword != null && body is! EmptyFunctionBody) {
3472 reportError7(ParserErrorCode.EXTERNAL_OPERATOR_WITH_BODY, []); 3724 reportError7(ParserErrorCode.EXTERNAL_OPERATOR_WITH_BODY, []);
3473 } 3725 }
3474 return new MethodDeclaration.full(commentAndMetadata.comment, commentAndMeta data.metadata, externalKeyword, null, returnType, null, operatorKeyword, name, p arameters, body); 3726 return new MethodDeclaration.full(commentAndMetadata.comment, commentAndMeta data.metadata, externalKeyword, null, returnType, null, operatorKeyword, name, p arameters, body);
3475 } 3727 }
3476 3728
3477 /** 3729 /**
3478 * Parse a return type if one is given, otherwise return `null` without advanc ing. 3730 * Parse a return type if one is given, otherwise return `null` without advanc ing.
3731 *
3479 * @return the return type that was parsed 3732 * @return the return type that was parsed
3480 */ 3733 */
3481 TypeName parseOptionalReturnType() { 3734 TypeName parseOptionalReturnType() {
3482 if (matches(Keyword.VOID)) { 3735 if (matches(Keyword.VOID)) {
3483 return parseReturnType(); 3736 return parseReturnType();
3484 } else if (matchesIdentifier() && !matches(Keyword.GET) && !matches(Keyword. SET) && !matches(Keyword.OPERATOR) && (matchesIdentifier2(peek()) || matches4(pe ek(), TokenType.LT))) { 3737 } else if (matchesIdentifier() && !matches(Keyword.GET) && !matches(Keyword. SET) && !matches(Keyword.OPERATOR) && (matchesIdentifier2(peek()) || matches4(pe ek(), TokenType.LT))) {
3485 return parseReturnType(); 3738 return parseReturnType();
3486 } else if (matchesIdentifier() && matches4(peek(), TokenType.PERIOD) && matc hesIdentifier2(peek2(2)) && (matchesIdentifier2(peek2(3)) || matches4(peek2(3), TokenType.LT))) { 3739 } else if (matchesIdentifier() && matches4(peek(), TokenType.PERIOD) && matc hesIdentifier2(peek2(2)) && (matchesIdentifier2(peek2(3)) || matches4(peek2(3), TokenType.LT))) {
3487 return parseReturnType(); 3740 return parseReturnType();
3488 } 3741 }
3489 return null; 3742 return null;
3490 } 3743 }
3491 3744
3492 /** 3745 /**
3493 * Parse a part or part-of directive. 3746 * Parse a part or part-of directive.
3747 *
3494 * <pre> 3748 * <pre>
3495 * partDirective ::= 3749 * partDirective ::=
3496 * metadata 'part' stringLiteral ';' 3750 * metadata 'part' stringLiteral ';'
3751 *
3497 * partOfDirective ::= 3752 * partOfDirective ::=
3498 * metadata 'part' 'of' identifier ';' 3753 * metadata 'part' 'of' identifier ';'
3499 * </pre> 3754 * </pre>
3755 *
3500 * @param commentAndMetadata the metadata to be associated with the directive 3756 * @param commentAndMetadata the metadata to be associated with the directive
3501 * @return the part or part-of directive that was parsed 3757 * @return the part or part-of directive that was parsed
3502 */ 3758 */
3503 Directive parsePartDirective(CommentAndMetadata commentAndMetadata) { 3759 Directive parsePartDirective(CommentAndMetadata commentAndMetadata) {
3504 Token partKeyword = expect(Keyword.PART); 3760 Token partKeyword = expect(Keyword.PART);
3505 if (matches2(_OF)) { 3761 if (matches2(_OF)) {
3506 Token ofKeyword = andAdvance; 3762 Token ofKeyword = andAdvance;
3507 LibraryIdentifier libraryName = parseLibraryName(ParserErrorCode.MISSING_N AME_IN_PART_OF_DIRECTIVE, ofKeyword); 3763 LibraryIdentifier libraryName = parseLibraryName(ParserErrorCode.MISSING_N AME_IN_PART_OF_DIRECTIVE, ofKeyword);
3508 Token semicolon = expect2(TokenType.SEMICOLON); 3764 Token semicolon = expect2(TokenType.SEMICOLON);
3509 return new PartOfDirective.full(commentAndMetadata.comment, commentAndMeta data.metadata, partKeyword, ofKeyword, libraryName, semicolon); 3765 return new PartOfDirective.full(commentAndMetadata.comment, commentAndMeta data.metadata, partKeyword, ofKeyword, libraryName, semicolon);
3510 } 3766 }
3511 StringLiteral partUri = parseStringLiteral(); 3767 StringLiteral partUri = parseStringLiteral();
3512 Token semicolon = expect2(TokenType.SEMICOLON); 3768 Token semicolon = expect2(TokenType.SEMICOLON);
3513 return new PartDirective.full(commentAndMetadata.comment, commentAndMetadata .metadata, partKeyword, partUri, semicolon); 3769 return new PartDirective.full(commentAndMetadata.comment, commentAndMetadata .metadata, partKeyword, partUri, semicolon);
3514 } 3770 }
3515 3771
3516 /** 3772 /**
3517 * Parse a postfix expression. 3773 * Parse a postfix expression.
3774 *
3518 * <pre> 3775 * <pre>
3519 * postfixExpression ::= 3776 * postfixExpression ::=
3520 * assignableExpression postfixOperator 3777 * assignableExpression postfixOperator
3521 * | primary selector 3778 * | primary selector*
3779 *
3522 * selector ::= 3780 * selector ::=
3523 * assignableSelector 3781 * assignableSelector
3524 * | argumentList 3782 * | argumentList
3525 * </pre> 3783 * </pre>
3784 *
3526 * @return the postfix expression that was parsed 3785 * @return the postfix expression that was parsed
3527 */ 3786 */
3528 Expression parsePostfixExpression() { 3787 Expression parsePostfixExpression() {
3529 Expression operand = parseAssignableExpression(true); 3788 Expression operand = parseAssignableExpression(true);
3530 if (matches5(TokenType.OPEN_SQUARE_BRACKET) || matches5(TokenType.PERIOD) || matches5(TokenType.OPEN_PAREN)) { 3789 if (matches5(TokenType.OPEN_SQUARE_BRACKET) || matches5(TokenType.PERIOD) || matches5(TokenType.OPEN_PAREN)) {
3531 do { 3790 do {
3532 if (matches5(TokenType.OPEN_PAREN)) { 3791 if (matches5(TokenType.OPEN_PAREN)) {
3533 ArgumentList argumentList = parseArgumentList(); 3792 ArgumentList argumentList = parseArgumentList();
3534 if (operand is PropertyAccess) { 3793 if (operand is PropertyAccess) {
3535 PropertyAccess access = operand as PropertyAccess; 3794 PropertyAccess access = operand as PropertyAccess;
3536 operand = new MethodInvocation.full(access.target, access.operator, access.propertyName, argumentList); 3795 operand = new MethodInvocation.full(access.target, access.operator, access.propertyName, argumentList);
3537 } else { 3796 } else {
3538 operand = new FunctionExpressionInvocation.full(operand, argumentLis t); 3797 operand = new FunctionExpressionInvocation.full(operand, argumentLis t);
3539 } 3798 }
3540 } else { 3799 } else {
3541 operand = parseAssignableSelector(operand, true); 3800 operand = parseAssignableSelector(operand, true);
3542 } 3801 }
3543 } while (matches5(TokenType.OPEN_SQUARE_BRACKET) || matches5(TokenType.PER IOD) || matches5(TokenType.OPEN_PAREN)); 3802 } while (matches5(TokenType.OPEN_SQUARE_BRACKET) || matches5(TokenType.PER IOD) || matches5(TokenType.OPEN_PAREN));
3544 return operand; 3803 return operand;
3545 } 3804 }
3546 if (!_currentToken.type.isIncrementOperator) { 3805 if (!_currentToken.type.isIncrementOperator) {
3547 return operand; 3806 return operand;
3548 } 3807 }
3549 if (operand is FunctionExpressionInvocation) { 3808 if (operand is Literal || operand is FunctionExpressionInvocation) {
3550 reportError7(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, []); 3809 reportError7(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, []);
3551 } 3810 }
3552 Token operator = andAdvance; 3811 Token operator = andAdvance;
3553 return new PostfixExpression.full(operand, operator); 3812 return new PostfixExpression.full(operand, operator);
3554 } 3813 }
3555 3814
3556 /** 3815 /**
3557 * Parse a prefixed identifier. 3816 * Parse a prefixed identifier.
3817 *
3558 * <pre> 3818 * <pre>
3559 * prefixedIdentifier ::= 3819 * prefixedIdentifier ::=
3560 * identifier ('.' identifier)? 3820 * identifier ('.' identifier)?
3561 * </pre> 3821 * </pre>
3822 *
3562 * @return the prefixed identifier that was parsed 3823 * @return the prefixed identifier that was parsed
3563 */ 3824 */
3564 Identifier parsePrefixedIdentifier() { 3825 Identifier parsePrefixedIdentifier() {
3565 SimpleIdentifier qualifier = parseSimpleIdentifier(); 3826 SimpleIdentifier qualifier = parseSimpleIdentifier();
3566 if (!matches5(TokenType.PERIOD)) { 3827 if (!matches5(TokenType.PERIOD)) {
3567 return qualifier; 3828 return qualifier;
3568 } 3829 }
3569 Token period = andAdvance; 3830 Token period = andAdvance;
3570 SimpleIdentifier qualified = parseSimpleIdentifier(); 3831 SimpleIdentifier qualified = parseSimpleIdentifier();
3571 return new PrefixedIdentifier.full(qualifier, period, qualified); 3832 return new PrefixedIdentifier.full(qualifier, period, qualified);
3572 } 3833 }
3573 3834
3574 /** 3835 /**
3575 * Parse a primary expression. 3836 * Parse a primary expression.
3837 *
3576 * <pre> 3838 * <pre>
3577 * primary ::= 3839 * primary ::=
3578 * thisExpression 3840 * thisExpression
3579 * | 'super' assignableSelector 3841 * | 'super' assignableSelector
3580 * | functionExpression 3842 * | functionExpression
3581 * | literal 3843 * | literal
3582 * | identifier 3844 * | identifier
3583 * | newExpression 3845 * | newExpression
3584 * | constObjectExpression 3846 * | constObjectExpression
3585 * | '(' expression ')' 3847 * | '(' expression ')'
3586 * | argumentDefinitionTest 3848 * | argumentDefinitionTest
3849 *
3587 * literal ::= 3850 * literal ::=
3588 * nullLiteral 3851 * nullLiteral
3589 * | booleanLiteral 3852 * | booleanLiteral
3590 * | numericLiteral 3853 * | numericLiteral
3591 * | stringLiteral 3854 * | stringLiteral
3592 * | mapLiteral 3855 * | mapLiteral
3593 * | listLiteral 3856 * | listLiteral
3594 * </pre> 3857 * </pre>
3858 *
3595 * @return the primary expression that was parsed 3859 * @return the primary expression that was parsed
3596 */ 3860 */
3597 Expression parsePrimaryExpression() { 3861 Expression parsePrimaryExpression() {
3598 if (matches(Keyword.THIS)) { 3862 if (matches(Keyword.THIS)) {
3599 return new ThisExpression.full(andAdvance); 3863 return new ThisExpression.full(andAdvance);
3600 } else if (matches(Keyword.SUPER)) { 3864 } else if (matches(Keyword.SUPER)) {
3601 return parseAssignableSelector(new SuperExpression.full(andAdvance), false ); 3865 return parseAssignableSelector(new SuperExpression.full(andAdvance), false );
3602 } else if (matches(Keyword.NULL)) { 3866 } else if (matches(Keyword.NULL)) {
3603 return new NullLiteral.full(andAdvance); 3867 return new NullLiteral.full(andAdvance);
3604 } else if (matches(Keyword.FALSE)) { 3868 } else if (matches(Keyword.FALSE)) {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
3658 advance(); 3922 advance();
3659 return parsePrimaryExpression(); 3923 return parsePrimaryExpression();
3660 } else { 3924 } else {
3661 reportError7(ParserErrorCode.MISSING_IDENTIFIER, []); 3925 reportError7(ParserErrorCode.MISSING_IDENTIFIER, []);
3662 return createSyntheticIdentifier(); 3926 return createSyntheticIdentifier();
3663 } 3927 }
3664 } 3928 }
3665 3929
3666 /** 3930 /**
3667 * Parse a redirecting constructor invocation. 3931 * Parse a redirecting constructor invocation.
3932 *
3668 * <pre> 3933 * <pre>
3669 * redirectingConstructorInvocation ::= 3934 * redirectingConstructorInvocation ::=
3670 * 'this' ('.' identifier)? arguments 3935 * 'this' ('.' identifier)? arguments
3671 * </pre> 3936 * </pre>
3937 *
3672 * @return the redirecting constructor invocation that was parsed 3938 * @return the redirecting constructor invocation that was parsed
3673 */ 3939 */
3674 RedirectingConstructorInvocation parseRedirectingConstructorInvocation() { 3940 RedirectingConstructorInvocation parseRedirectingConstructorInvocation() {
3675 Token keyword = expect(Keyword.THIS); 3941 Token keyword = expect(Keyword.THIS);
3676 Token period = null; 3942 Token period = null;
3677 SimpleIdentifier constructorName = null; 3943 SimpleIdentifier constructorName = null;
3678 if (matches5(TokenType.PERIOD)) { 3944 if (matches5(TokenType.PERIOD)) {
3679 period = andAdvance; 3945 period = andAdvance;
3680 constructorName = parseSimpleIdentifier(); 3946 constructorName = parseSimpleIdentifier();
3681 } 3947 }
3682 ArgumentList argumentList = parseArgumentList(); 3948 ArgumentList argumentList = parseArgumentList();
3683 return new RedirectingConstructorInvocation.full(keyword, period, constructo rName, argumentList); 3949 return new RedirectingConstructorInvocation.full(keyword, period, constructo rName, argumentList);
3684 } 3950 }
3685 3951
3686 /** 3952 /**
3687 * Parse a relational expression. 3953 * Parse a relational expression.
3954 *
3688 * <pre> 3955 * <pre>
3689 * relationalExpression ::= 3956 * relationalExpression ::=
3690 * shiftExpression ('is' '!'? type | 'as' type | relationalOperator shiftExpre ssion)? 3957 * shiftExpression ('is' '!'? type | 'as' type | relationalOperator shiftE xpression)?
3691 * | 'super' relationalOperator shiftExpression 3958 * | 'super' relationalOperator shiftExpression
3692 * </pre> 3959 * </pre>
3960 *
3693 * @return the relational expression that was parsed 3961 * @return the relational expression that was parsed
3694 */ 3962 */
3695 Expression parseRelationalExpression() { 3963 Expression parseRelationalExpression() {
3696 if (matches(Keyword.SUPER) && _currentToken.next.type.isRelationalOperator) { 3964 if (matches(Keyword.SUPER) && _currentToken.next.type.isRelationalOperator) {
3697 Expression expression = new SuperExpression.full(andAdvance); 3965 Expression expression = new SuperExpression.full(andAdvance);
3698 Token operator = andAdvance; 3966 Token operator = andAdvance;
3699 expression = new BinaryExpression.full(expression, operator, parseShiftExp ression()); 3967 expression = new BinaryExpression.full(expression, operator, parseShiftExp ression());
3700 return expression; 3968 return expression;
3701 } 3969 }
3702 Expression expression = parseShiftExpression(); 3970 Expression expression = parseShiftExpression();
3703 if (matches(Keyword.AS)) { 3971 if (matches(Keyword.AS)) {
3704 Token asOperator = andAdvance; 3972 Token asOperator = andAdvance;
3705 expression = new AsExpression.full(expression, asOperator, parseTypeName() ); 3973 expression = new AsExpression.full(expression, asOperator, parseTypeName() );
3706 } else if (matches(Keyword.IS)) { 3974 } else if (matches(Keyword.IS)) {
3707 Token isOperator = andAdvance; 3975 Token isOperator = andAdvance;
3708 Token notOperator = null; 3976 Token notOperator = null;
3709 if (matches5(TokenType.BANG)) { 3977 if (matches5(TokenType.BANG)) {
3710 notOperator = andAdvance; 3978 notOperator = andAdvance;
3711 } 3979 }
3712 expression = new IsExpression.full(expression, isOperator, notOperator, pa rseTypeName()); 3980 expression = new IsExpression.full(expression, isOperator, notOperator, pa rseTypeName());
3713 } else if (_currentToken.type.isRelationalOperator) { 3981 } else if (_currentToken.type.isRelationalOperator) {
3714 Token operator = andAdvance; 3982 Token operator = andAdvance;
3715 expression = new BinaryExpression.full(expression, operator, parseShiftExp ression()); 3983 expression = new BinaryExpression.full(expression, operator, parseShiftExp ression());
3716 } 3984 }
3717 return expression; 3985 return expression;
3718 } 3986 }
3719 3987
3720 /** 3988 /**
3721 * Parse a rethrow expression. 3989 * Parse a rethrow expression.
3990 *
3722 * <pre> 3991 * <pre>
3723 * rethrowExpression ::= 3992 * rethrowExpression ::=
3724 * 'rethrow' 3993 * 'rethrow'
3725 * </pre> 3994 * </pre>
3995 *
3726 * @return the rethrow expression that was parsed 3996 * @return the rethrow expression that was parsed
3727 */ 3997 */
3728 Expression parseRethrowExpression() => new RethrowExpression.full(expect(Keywo rd.RETHROW)); 3998 Expression parseRethrowExpression() => new RethrowExpression.full(expect(Keywo rd.RETHROW));
3729 3999
3730 /** 4000 /**
3731 * Parse a return statement. 4001 * Parse a return statement.
4002 *
3732 * <pre> 4003 * <pre>
3733 * returnStatement ::= 4004 * returnStatement ::=
3734 * 'return' expression? ';' 4005 * 'return' expression? ';'
3735 * </pre> 4006 * </pre>
4007 *
3736 * @return the return statement that was parsed 4008 * @return the return statement that was parsed
3737 */ 4009 */
3738 Statement parseReturnStatement() { 4010 Statement parseReturnStatement() {
3739 Token returnKeyword = expect(Keyword.RETURN); 4011 Token returnKeyword = expect(Keyword.RETURN);
3740 if (matches5(TokenType.SEMICOLON)) { 4012 if (matches5(TokenType.SEMICOLON)) {
3741 return new ReturnStatement.full(returnKeyword, null, andAdvance); 4013 return new ReturnStatement.full(returnKeyword, null, andAdvance);
3742 } 4014 }
3743 Expression expression = parseExpression2(); 4015 Expression expression = parseExpression2();
3744 Token semicolon = expect2(TokenType.SEMICOLON); 4016 Token semicolon = expect2(TokenType.SEMICOLON);
3745 return new ReturnStatement.full(returnKeyword, expression, semicolon); 4017 return new ReturnStatement.full(returnKeyword, expression, semicolon);
3746 } 4018 }
3747 4019
3748 /** 4020 /**
3749 * Parse a return type. 4021 * Parse a return type.
4022 *
3750 * <pre> 4023 * <pre>
3751 * returnType ::= 4024 * returnType ::=
3752 * 'void' 4025 * 'void'
3753 * | type 4026 * | type
3754 * </pre> 4027 * </pre>
4028 *
3755 * @return the return type that was parsed 4029 * @return the return type that was parsed
3756 */ 4030 */
3757 TypeName parseReturnType() { 4031 TypeName parseReturnType() {
3758 if (matches(Keyword.VOID)) { 4032 if (matches(Keyword.VOID)) {
3759 return new TypeName.full(new SimpleIdentifier.full(andAdvance), null); 4033 return new TypeName.full(new SimpleIdentifier.full(andAdvance), null);
3760 } else { 4034 } else {
3761 return parseTypeName(); 4035 return parseTypeName();
3762 } 4036 }
3763 } 4037 }
3764 4038
3765 /** 4039 /**
3766 * Parse a setter. 4040 * Parse a setter.
4041 *
3767 * <pre> 4042 * <pre>
3768 * setter ::= 4043 * setter ::=
3769 * setterSignature functionBody? 4044 * setterSignature functionBody?
4045 *
3770 * setterSignature ::= 4046 * setterSignature ::=
3771 * 'external'? 'static'? returnType? 'set' identifier formalParameterList 4047 * 'external'? 'static'? returnType? 'set' identifier formalParameterList
3772 * </pre> 4048 * </pre>
4049 *
3773 * @param commentAndMetadata the documentation comment and metadata to be asso ciated with the 4050 * @param commentAndMetadata the documentation comment and metadata to be asso ciated with the
3774 * declaration 4051 * declaration
3775 * @param externalKeyword the 'external' token 4052 * @param externalKeyword the 'external' token
3776 * @param staticKeyword the static keyword, or `null` if the setter is not sta tic 4053 * @param staticKeyword the static keyword, or `null` if the setter is not sta tic
3777 * @param the return type that has already been parsed, or `null` if there was no return 4054 * @param the return type that has already been parsed, or `null` if there was no return
3778 * type 4055 * type
3779 * @return the setter that was parsed 4056 * @return the setter that was parsed
3780 */ 4057 */
3781 MethodDeclaration parseSetter(CommentAndMetadata commentAndMetadata, Token ext ernalKeyword, Token staticKeyword, TypeName returnType) { 4058 MethodDeclaration parseSetter(CommentAndMetadata commentAndMetadata, Token ext ernalKeyword, Token staticKeyword, TypeName returnType) {
3782 Token propertyKeyword = expect(Keyword.SET); 4059 Token propertyKeyword = expect(Keyword.SET);
3783 SimpleIdentifier name = parseSimpleIdentifier(); 4060 SimpleIdentifier name = parseSimpleIdentifier();
3784 FormalParameterList parameters = parseFormalParameterList(); 4061 FormalParameterList parameters = parseFormalParameterList();
3785 validateFormalParameterList(parameters); 4062 validateFormalParameterList(parameters);
3786 FunctionBody body = parseFunctionBody(externalKeyword != null || staticKeywo rd == null, ParserErrorCode.STATIC_SETTER_WITHOUT_BODY, false); 4063 FunctionBody body = parseFunctionBody(externalKeyword != null || staticKeywo rd == null, ParserErrorCode.STATIC_SETTER_WITHOUT_BODY, false);
3787 if (externalKeyword != null && body is! EmptyFunctionBody) { 4064 if (externalKeyword != null && body is! EmptyFunctionBody) {
3788 reportError7(ParserErrorCode.EXTERNAL_SETTER_WITH_BODY, []); 4065 reportError7(ParserErrorCode.EXTERNAL_SETTER_WITH_BODY, []);
3789 } 4066 }
3790 return new MethodDeclaration.full(commentAndMetadata.comment, commentAndMeta data.metadata, externalKeyword, staticKeyword, returnType, propertyKeyword, null , name, parameters, body); 4067 return new MethodDeclaration.full(commentAndMetadata.comment, commentAndMeta data.metadata, externalKeyword, staticKeyword, returnType, propertyKeyword, null , name, parameters, body);
3791 } 4068 }
3792 4069
3793 /** 4070 /**
3794 * Parse a shift expression. 4071 * Parse a shift expression.
4072 *
3795 * <pre> 4073 * <pre>
3796 * shiftExpression ::= 4074 * shiftExpression ::=
3797 * additiveExpression (shiftOperator additiveExpression) 4075 * additiveExpression (shiftOperator additiveExpression)*
3798 * | 'super' (shiftOperator additiveExpression)+ 4076 * | 'super' (shiftOperator additiveExpression)+
3799 * </pre> 4077 * </pre>
4078 *
3800 * @return the shift expression that was parsed 4079 * @return the shift expression that was parsed
3801 */ 4080 */
3802 Expression parseShiftExpression() { 4081 Expression parseShiftExpression() {
3803 Expression expression; 4082 Expression expression;
3804 if (matches(Keyword.SUPER) && _currentToken.next.type.isShiftOperator) { 4083 if (matches(Keyword.SUPER) && _currentToken.next.type.isShiftOperator) {
3805 expression = new SuperExpression.full(andAdvance); 4084 expression = new SuperExpression.full(andAdvance);
3806 } else { 4085 } else {
3807 expression = parseAdditiveExpression(); 4086 expression = parseAdditiveExpression();
3808 } 4087 }
3809 while (_currentToken.type.isShiftOperator) { 4088 while (_currentToken.type.isShiftOperator) {
3810 Token operator = andAdvance; 4089 Token operator = andAdvance;
3811 expression = new BinaryExpression.full(expression, operator, parseAdditive Expression()); 4090 expression = new BinaryExpression.full(expression, operator, parseAdditive Expression());
3812 } 4091 }
3813 return expression; 4092 return expression;
3814 } 4093 }
3815 4094
3816 /** 4095 /**
3817 * Parse a simple identifier. 4096 * Parse a simple identifier.
4097 *
3818 * <pre> 4098 * <pre>
3819 * identifier ::= 4099 * identifier ::=
3820 * IDENTIFIER 4100 * IDENTIFIER
3821 * </pre> 4101 * </pre>
4102 *
3822 * @return the simple identifier that was parsed 4103 * @return the simple identifier that was parsed
3823 */ 4104 */
3824 SimpleIdentifier parseSimpleIdentifier() { 4105 SimpleIdentifier parseSimpleIdentifier() {
3825 if (matchesIdentifier()) { 4106 if (matchesIdentifier()) {
3826 return new SimpleIdentifier.full(andAdvance); 4107 return new SimpleIdentifier.full(andAdvance);
3827 } 4108 }
3828 reportError7(ParserErrorCode.MISSING_IDENTIFIER, []); 4109 reportError7(ParserErrorCode.MISSING_IDENTIFIER, []);
3829 return createSyntheticIdentifier(); 4110 return createSyntheticIdentifier();
3830 } 4111 }
3831 4112
3832 /** 4113 /**
3833 * Parse a statement. 4114 * Parse a statement.
4115 *
3834 * <pre> 4116 * <pre>
3835 * statement ::= 4117 * statement ::=
3836 * label* nonLabeledStatement 4118 * label* nonLabeledStatement
3837 * </pre> 4119 * </pre>
4120 *
3838 * @return the statement that was parsed 4121 * @return the statement that was parsed
3839 */ 4122 */
3840 Statement parseStatement2() { 4123 Statement parseStatement2() {
3841 List<Label> labels = new List<Label>(); 4124 List<Label> labels = new List<Label>();
3842 while (matchesIdentifier() && matches4(peek(), TokenType.COLON)) { 4125 while (matchesIdentifier() && matches4(peek(), TokenType.COLON)) {
3843 SimpleIdentifier label = parseSimpleIdentifier(); 4126 SimpleIdentifier label = parseSimpleIdentifier();
3844 Token colon = expect2(TokenType.COLON); 4127 Token colon = expect2(TokenType.COLON);
3845 labels.add(new Label.full(label, colon)); 4128 labels.add(new Label.full(label, colon));
3846 } 4129 }
3847 Statement statement = parseNonLabeledStatement(); 4130 Statement statement = parseNonLabeledStatement();
3848 if (labels.isEmpty) { 4131 if (labels.isEmpty) {
3849 return statement; 4132 return statement;
3850 } 4133 }
3851 return new LabeledStatement.full(labels, statement); 4134 return new LabeledStatement.full(labels, statement);
3852 } 4135 }
3853 4136
3854 /** 4137 /**
3855 * Parse a list of statements within a switch statement. 4138 * Parse a list of statements within a switch statement.
4139 *
3856 * <pre> 4140 * <pre>
3857 * statements ::= 4141 * statements ::=
3858 * statement 4142 * statement*
3859 * </pre> 4143 * </pre>
4144 *
3860 * @return the statements that were parsed 4145 * @return the statements that were parsed
3861 */ 4146 */
3862 List<Statement> parseStatements2() { 4147 List<Statement> parseStatements2() {
3863 List<Statement> statements = new List<Statement>(); 4148 List<Statement> statements = new List<Statement>();
3864 Token statementStart = _currentToken; 4149 Token statementStart = _currentToken;
3865 while (!matches5(TokenType.EOF) && !matches5(TokenType.CLOSE_CURLY_BRACKET) && !isSwitchMember()) { 4150 while (!matches5(TokenType.EOF) && !matches5(TokenType.CLOSE_CURLY_BRACKET) && !isSwitchMember()) {
3866 statements.add(parseStatement2()); 4151 statements.add(parseStatement2());
3867 if (identical(_currentToken, statementStart)) { 4152 if (identical(_currentToken, statementStart)) {
3868 reportError8(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentT oken.lexeme]); 4153 reportError8(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentT oken.lexeme]);
3869 advance(); 4154 advance();
3870 } 4155 }
3871 statementStart = _currentToken; 4156 statementStart = _currentToken;
3872 } 4157 }
3873 return statements; 4158 return statements;
3874 } 4159 }
3875 4160
3876 /** 4161 /**
3877 * Parse a string literal that contains interpolations. 4162 * Parse a string literal that contains interpolations.
4163 *
3878 * @return the string literal that was parsed 4164 * @return the string literal that was parsed
3879 */ 4165 */
3880 StringInterpolation parseStringInterpolation(Token string) { 4166 StringInterpolation parseStringInterpolation(Token string) {
3881 List<InterpolationElement> elements = new List<InterpolationElement>(); 4167 List<InterpolationElement> elements = new List<InterpolationElement>();
3882 elements.add(new InterpolationString.full(string, computeStringValue(string. lexeme))); 4168 elements.add(new InterpolationString.full(string, computeStringValue(string. lexeme)));
3883 while (matches5(TokenType.STRING_INTERPOLATION_EXPRESSION) || matches5(Token Type.STRING_INTERPOLATION_IDENTIFIER)) { 4169 while (matches5(TokenType.STRING_INTERPOLATION_EXPRESSION) || matches5(Token Type.STRING_INTERPOLATION_IDENTIFIER)) {
3884 if (matches5(TokenType.STRING_INTERPOLATION_EXPRESSION)) { 4170 if (matches5(TokenType.STRING_INTERPOLATION_EXPRESSION)) {
3885 Token openToken = andAdvance; 4171 Token openToken = andAdvance;
3886 Expression expression = parseExpression2(); 4172 Expression expression = parseExpression2();
3887 Token rightBracket = expect2(TokenType.CLOSE_CURLY_BRACKET); 4173 Token rightBracket = expect2(TokenType.CLOSE_CURLY_BRACKET);
(...skipping 11 matching lines...) Expand all
3899 if (matches5(TokenType.STRING)) { 4185 if (matches5(TokenType.STRING)) {
3900 string = andAdvance; 4186 string = andAdvance;
3901 elements.add(new InterpolationString.full(string, computeStringValue(str ing.lexeme))); 4187 elements.add(new InterpolationString.full(string, computeStringValue(str ing.lexeme)));
3902 } 4188 }
3903 } 4189 }
3904 return new StringInterpolation.full(elements); 4190 return new StringInterpolation.full(elements);
3905 } 4191 }
3906 4192
3907 /** 4193 /**
3908 * Parse a string literal. 4194 * Parse a string literal.
4195 *
3909 * <pre> 4196 * <pre>
3910 * stringLiteral ::= 4197 * stringLiteral ::=
3911 * MULTI_LINE_STRING+ 4198 * MULTI_LINE_STRING+
3912 * | SINGLE_LINE_STRING+ 4199 * | SINGLE_LINE_STRING+
3913 * </pre> 4200 * </pre>
4201 *
3914 * @return the string literal that was parsed 4202 * @return the string literal that was parsed
3915 */ 4203 */
3916 StringLiteral parseStringLiteral() { 4204 StringLiteral parseStringLiteral() {
3917 List<StringLiteral> strings = new List<StringLiteral>(); 4205 List<StringLiteral> strings = new List<StringLiteral>();
3918 while (matches5(TokenType.STRING)) { 4206 while (matches5(TokenType.STRING)) {
3919 Token string = andAdvance; 4207 Token string = andAdvance;
3920 if (matches5(TokenType.STRING_INTERPOLATION_EXPRESSION) || matches5(TokenT ype.STRING_INTERPOLATION_IDENTIFIER)) { 4208 if (matches5(TokenType.STRING_INTERPOLATION_EXPRESSION) || matches5(TokenT ype.STRING_INTERPOLATION_IDENTIFIER)) {
3921 strings.add(parseStringInterpolation(string)); 4209 strings.add(parseStringInterpolation(string));
3922 } else { 4210 } else {
3923 strings.add(new SimpleStringLiteral.full(string, computeStringValue(stri ng.lexeme))); 4211 strings.add(new SimpleStringLiteral.full(string, computeStringValue(stri ng.lexeme)));
3924 } 4212 }
3925 } 4213 }
3926 if (strings.length < 1) { 4214 if (strings.length < 1) {
3927 reportError7(ParserErrorCode.EXPECTED_STRING_LITERAL, []); 4215 reportError7(ParserErrorCode.EXPECTED_STRING_LITERAL, []);
3928 return createSyntheticStringLiteral(); 4216 return createSyntheticStringLiteral();
3929 } else if (strings.length == 1) { 4217 } else if (strings.length == 1) {
3930 return strings[0]; 4218 return strings[0];
3931 } else { 4219 } else {
3932 return new AdjacentStrings.full(strings); 4220 return new AdjacentStrings.full(strings);
3933 } 4221 }
3934 } 4222 }
3935 4223
3936 /** 4224 /**
3937 * Parse a super constructor invocation. 4225 * Parse a super constructor invocation.
4226 *
3938 * <pre> 4227 * <pre>
3939 * superConstructorInvocation ::= 4228 * superConstructorInvocation ::=
3940 * 'super' ('.' identifier)? arguments 4229 * 'super' ('.' identifier)? arguments
3941 * </pre> 4230 * </pre>
4231 *
3942 * @return the super constructor invocation that was parsed 4232 * @return the super constructor invocation that was parsed
3943 */ 4233 */
3944 SuperConstructorInvocation parseSuperConstructorInvocation() { 4234 SuperConstructorInvocation parseSuperConstructorInvocation() {
3945 Token keyword = expect(Keyword.SUPER); 4235 Token keyword = expect(Keyword.SUPER);
3946 Token period = null; 4236 Token period = null;
3947 SimpleIdentifier constructorName = null; 4237 SimpleIdentifier constructorName = null;
3948 if (matches5(TokenType.PERIOD)) { 4238 if (matches5(TokenType.PERIOD)) {
3949 period = andAdvance; 4239 period = andAdvance;
3950 constructorName = parseSimpleIdentifier(); 4240 constructorName = parseSimpleIdentifier();
3951 } 4241 }
3952 ArgumentList argumentList = parseArgumentList(); 4242 ArgumentList argumentList = parseArgumentList();
3953 return new SuperConstructorInvocation.full(keyword, period, constructorName, argumentList); 4243 return new SuperConstructorInvocation.full(keyword, period, constructorName, argumentList);
3954 } 4244 }
3955 4245
3956 /** 4246 /**
3957 * Parse a switch statement. 4247 * Parse a switch statement.
4248 *
3958 * <pre> 4249 * <pre>
3959 * switchStatement ::= 4250 * switchStatement ::=
3960 * 'switch' '(' expression ')' '{' switchCase* defaultCase? '}' 4251 * 'switch' '(' expression ')' '{' switchCase* defaultCase? '}'
4252 *
3961 * switchCase ::= 4253 * switchCase ::=
3962 * label* ('case' expression ':') statements 4254 * label* ('case' expression ':') statements
4255 *
3963 * defaultCase ::= 4256 * defaultCase ::=
3964 * label* 'default' ':' statements 4257 * label* 'default' ':' statements
3965 * </pre> 4258 * </pre>
4259 *
3966 * @return the switch statement that was parsed 4260 * @return the switch statement that was parsed
3967 */ 4261 */
3968 SwitchStatement parseSwitchStatement() { 4262 SwitchStatement parseSwitchStatement() {
3969 bool wasInSwitch = _inSwitch; 4263 bool wasInSwitch = _inSwitch;
3970 _inSwitch = true; 4264 _inSwitch = true;
3971 try { 4265 try {
3972 Set<String> definedLabels = new Set<String>(); 4266 Set<String> definedLabels = new Set<String>();
3973 Token keyword = expect(Keyword.SWITCH); 4267 Token keyword = expect(Keyword.SWITCH);
3974 Token leftParenthesis = expect2(TokenType.OPEN_PAREN); 4268 Token leftParenthesis = expect2(TokenType.OPEN_PAREN);
3975 Expression expression = parseExpression2(); 4269 Expression expression = parseExpression2();
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
4014 } 4308 }
4015 Token rightBracket = expect2(TokenType.CLOSE_CURLY_BRACKET); 4309 Token rightBracket = expect2(TokenType.CLOSE_CURLY_BRACKET);
4016 return new SwitchStatement.full(keyword, leftParenthesis, expression, righ tParenthesis, leftBracket, members, rightBracket); 4310 return new SwitchStatement.full(keyword, leftParenthesis, expression, righ tParenthesis, leftBracket, members, rightBracket);
4017 } finally { 4311 } finally {
4018 _inSwitch = wasInSwitch; 4312 _inSwitch = wasInSwitch;
4019 } 4313 }
4020 } 4314 }
4021 4315
4022 /** 4316 /**
4023 * Parse a throw expression. 4317 * Parse a throw expression.
4318 *
4024 * <pre> 4319 * <pre>
4025 * throwExpression ::= 4320 * throwExpression ::=
4026 * 'throw' expression 4321 * 'throw' expression
4027 * </pre> 4322 * </pre>
4323 *
4028 * @return the throw expression that was parsed 4324 * @return the throw expression that was parsed
4029 */ 4325 */
4030 Expression parseThrowExpression() { 4326 Expression parseThrowExpression() {
4031 Token keyword = expect(Keyword.THROW); 4327 Token keyword = expect(Keyword.THROW);
4032 if (matches5(TokenType.SEMICOLON) || matches5(TokenType.CLOSE_PAREN)) { 4328 if (matches5(TokenType.SEMICOLON) || matches5(TokenType.CLOSE_PAREN)) {
4033 reportError8(ParserErrorCode.MISSING_EXPRESSION_IN_THROW, _currentToken, [ ]); 4329 reportError8(ParserErrorCode.MISSING_EXPRESSION_IN_THROW, _currentToken, [ ]);
4034 return new ThrowExpression.full(keyword, createSyntheticIdentifier()); 4330 return new ThrowExpression.full(keyword, createSyntheticIdentifier());
4035 } 4331 }
4036 Expression expression = parseExpression2(); 4332 Expression expression = parseExpression2();
4037 return new ThrowExpression.full(keyword, expression); 4333 return new ThrowExpression.full(keyword, expression);
4038 } 4334 }
4039 4335
4040 /** 4336 /**
4041 * Parse a throw expression. 4337 * Parse a throw expression.
4338 *
4042 * <pre> 4339 * <pre>
4043 * throwExpressionWithoutCascade ::= 4340 * throwExpressionWithoutCascade ::=
4044 * 'throw' expressionWithoutCascade 4341 * 'throw' expressionWithoutCascade
4045 * </pre> 4342 * </pre>
4343 *
4046 * @return the throw expression that was parsed 4344 * @return the throw expression that was parsed
4047 */ 4345 */
4048 Expression parseThrowExpressionWithoutCascade() { 4346 Expression parseThrowExpressionWithoutCascade() {
4049 Token keyword = expect(Keyword.THROW); 4347 Token keyword = expect(Keyword.THROW);
4050 if (matches5(TokenType.SEMICOLON) || matches5(TokenType.CLOSE_PAREN)) { 4348 if (matches5(TokenType.SEMICOLON) || matches5(TokenType.CLOSE_PAREN)) {
4051 reportError8(ParserErrorCode.MISSING_EXPRESSION_IN_THROW, _currentToken, [ ]); 4349 reportError8(ParserErrorCode.MISSING_EXPRESSION_IN_THROW, _currentToken, [ ]);
4052 return new ThrowExpression.full(keyword, createSyntheticIdentifier()); 4350 return new ThrowExpression.full(keyword, createSyntheticIdentifier());
4053 } 4351 }
4054 Expression expression = parseExpressionWithoutCascade(); 4352 Expression expression = parseExpressionWithoutCascade();
4055 return new ThrowExpression.full(keyword, expression); 4353 return new ThrowExpression.full(keyword, expression);
4056 } 4354 }
4057 4355
4058 /** 4356 /**
4059 * Parse a try statement. 4357 * Parse a try statement.
4358 *
4060 * <pre> 4359 * <pre>
4061 * tryStatement ::= 4360 * tryStatement ::=
4062 * 'try' block (onPart+ finallyPart? | finallyPart) 4361 * 'try' block (onPart+ finallyPart? | finallyPart)
4362 *
4063 * onPart ::= 4363 * onPart ::=
4064 * catchPart block 4364 * catchPart block
4065 * | 'on' type catchPart? block 4365 * | 'on' type catchPart? block
4366 *
4066 * catchPart ::= 4367 * catchPart ::=
4067 * 'catch' '(' identifier (',' identifier)? ')' 4368 * 'catch' '(' identifier (',' identifier)? ')'
4369 *
4068 * finallyPart ::= 4370 * finallyPart ::=
4069 * 'finally' block 4371 * 'finally' block
4070 * </pre> 4372 * </pre>
4373 *
4071 * @return the try statement that was parsed 4374 * @return the try statement that was parsed
4072 */ 4375 */
4073 Statement parseTryStatement() { 4376 Statement parseTryStatement() {
4074 Token tryKeyword = expect(Keyword.TRY); 4377 Token tryKeyword = expect(Keyword.TRY);
4075 Block body = parseBlock(); 4378 Block body = parseBlock();
4076 List<CatchClause> catchClauses = new List<CatchClause>(); 4379 List<CatchClause> catchClauses = new List<CatchClause>();
4077 Block finallyClause = null; 4380 Block finallyClause = null;
4078 while (matches2(_ON) || matches(Keyword.CATCH)) { 4381 while (matches2(_ON) || matches(Keyword.CATCH)) {
4079 Token onKeyword = null; 4382 Token onKeyword = null;
4080 TypeName exceptionType = null; 4383 TypeName exceptionType = null;
(...skipping 27 matching lines...) Expand all
4108 } else { 4411 } else {
4109 if (catchClauses.isEmpty) { 4412 if (catchClauses.isEmpty) {
4110 reportError7(ParserErrorCode.MISSING_CATCH_OR_FINALLY, []); 4413 reportError7(ParserErrorCode.MISSING_CATCH_OR_FINALLY, []);
4111 } 4414 }
4112 } 4415 }
4113 return new TryStatement.full(tryKeyword, body, catchClauses, finallyKeyword, finallyClause); 4416 return new TryStatement.full(tryKeyword, body, catchClauses, finallyKeyword, finallyClause);
4114 } 4417 }
4115 4418
4116 /** 4419 /**
4117 * Parse a type alias. 4420 * Parse a type alias.
4421 *
4118 * <pre> 4422 * <pre>
4119 * typeAlias ::= 4423 * typeAlias ::=
4120 * 'typedef' typeAliasBody 4424 * 'typedef' typeAliasBody
4425 *
4121 * typeAliasBody ::= 4426 * typeAliasBody ::=
4122 * classTypeAlias 4427 * classTypeAlias
4123 * | functionTypeAlias 4428 * | functionTypeAlias
4429 *
4124 * classTypeAlias ::= 4430 * classTypeAlias ::=
4125 * identifier typeParameters? '=' 'abstract'? mixinApplication 4431 * identifier typeParameters? '=' 'abstract'? mixinApplication
4432 *
4126 * mixinApplication ::= 4433 * mixinApplication ::=
4127 * qualified withClause implementsClause? ';' 4434 * qualified withClause implementsClause? ';'
4435 *
4128 * functionTypeAlias ::= 4436 * functionTypeAlias ::=
4129 * functionPrefix typeParameterList? formalParameterList ';' 4437 * functionPrefix typeParameterList? formalParameterList ';'
4438 *
4130 * functionPrefix ::= 4439 * functionPrefix ::=
4131 * returnType? name 4440 * returnType? name
4132 * </pre> 4441 * </pre>
4442 *
4133 * @param commentAndMetadata the metadata to be associated with the member 4443 * @param commentAndMetadata the metadata to be associated with the member
4134 * @return the type alias that was parsed 4444 * @return the type alias that was parsed
4135 */ 4445 */
4136 TypeAlias parseTypeAlias(CommentAndMetadata commentAndMetadata) { 4446 TypeAlias parseTypeAlias(CommentAndMetadata commentAndMetadata) {
4137 Token keyword = expect(Keyword.TYPEDEF); 4447 Token keyword = expect(Keyword.TYPEDEF);
4138 if (matchesIdentifier()) { 4448 if (matchesIdentifier()) {
4139 Token next = peek(); 4449 Token next = peek();
4140 if (matches4(next, TokenType.LT)) { 4450 if (matches4(next, TokenType.LT)) {
4141 next = skipTypeParameterList(next); 4451 next = skipTypeParameterList(next);
4142 if (next != null && matches4(next, TokenType.EQ)) { 4452 if (next != null && matches4(next, TokenType.EQ)) {
4143 return parseClassTypeAlias(commentAndMetadata, keyword); 4453 return parseClassTypeAlias(commentAndMetadata, keyword);
4144 } 4454 }
4145 } else if (matches4(next, TokenType.EQ)) { 4455 } else if (matches4(next, TokenType.EQ)) {
4146 return parseClassTypeAlias(commentAndMetadata, keyword); 4456 return parseClassTypeAlias(commentAndMetadata, keyword);
4147 } 4457 }
4148 } 4458 }
4149 return parseFunctionTypeAlias(commentAndMetadata, keyword); 4459 return parseFunctionTypeAlias(commentAndMetadata, keyword);
4150 } 4460 }
4151 4461
4152 /** 4462 /**
4153 * Parse a list of type arguments. 4463 * Parse a list of type arguments.
4464 *
4154 * <pre> 4465 * <pre>
4155 * typeArguments ::= 4466 * typeArguments ::=
4156 * '<' typeList '>' 4467 * '<' typeList '>'
4468 *
4157 * typeList ::= 4469 * typeList ::=
4158 * type (',' type) 4470 * type (',' type)*
4159 * </pre> 4471 * </pre>
4472 *
4160 * @return the type argument list that was parsed 4473 * @return the type argument list that was parsed
4161 */ 4474 */
4162 TypeArgumentList parseTypeArgumentList() { 4475 TypeArgumentList parseTypeArgumentList() {
4163 Token leftBracket = expect2(TokenType.LT); 4476 Token leftBracket = expect2(TokenType.LT);
4164 List<TypeName> arguments = new List<TypeName>(); 4477 List<TypeName> arguments = new List<TypeName>();
4165 arguments.add(parseTypeName()); 4478 arguments.add(parseTypeName());
4166 while (optional(TokenType.COMMA)) { 4479 while (optional(TokenType.COMMA)) {
4167 arguments.add(parseTypeName()); 4480 arguments.add(parseTypeName());
4168 } 4481 }
4169 Token rightBracket = expect2(TokenType.GT); 4482 Token rightBracket = expect2(TokenType.GT);
4170 return new TypeArgumentList.full(leftBracket, arguments, rightBracket); 4483 return new TypeArgumentList.full(leftBracket, arguments, rightBracket);
4171 } 4484 }
4172 4485
4173 /** 4486 /**
4174 * Parse a type name. 4487 * Parse a type name.
4488 *
4175 * <pre> 4489 * <pre>
4176 * type ::= 4490 * type ::=
4177 * qualified typeArguments? 4491 * qualified typeArguments?
4178 * </pre> 4492 * </pre>
4493 *
4179 * @return the type name that was parsed 4494 * @return the type name that was parsed
4180 */ 4495 */
4181 TypeName parseTypeName() { 4496 TypeName parseTypeName() {
4182 Identifier typeName; 4497 Identifier typeName;
4183 if (matches(Keyword.VAR)) { 4498 if (matches(Keyword.VAR)) {
4184 reportError7(ParserErrorCode.VAR_AS_TYPE_NAME, []); 4499 reportError7(ParserErrorCode.VAR_AS_TYPE_NAME, []);
4185 typeName = new SimpleIdentifier.full(andAdvance); 4500 typeName = new SimpleIdentifier.full(andAdvance);
4186 } else if (matchesIdentifier()) { 4501 } else if (matchesIdentifier()) {
4187 typeName = parsePrefixedIdentifier(); 4502 typeName = parsePrefixedIdentifier();
4188 } else { 4503 } else {
4189 typeName = createSyntheticIdentifier(); 4504 typeName = createSyntheticIdentifier();
4190 reportError7(ParserErrorCode.EXPECTED_TYPE_NAME, []); 4505 reportError7(ParserErrorCode.EXPECTED_TYPE_NAME, []);
4191 } 4506 }
4192 TypeArgumentList typeArguments = null; 4507 TypeArgumentList typeArguments = null;
4193 if (matches5(TokenType.LT)) { 4508 if (matches5(TokenType.LT)) {
4194 typeArguments = parseTypeArgumentList(); 4509 typeArguments = parseTypeArgumentList();
4195 } 4510 }
4196 return new TypeName.full(typeName, typeArguments); 4511 return new TypeName.full(typeName, typeArguments);
4197 } 4512 }
4198 4513
4199 /** 4514 /**
4200 * Parse a type parameter. 4515 * Parse a type parameter.
4516 *
4201 * <pre> 4517 * <pre>
4202 * typeParameter ::= 4518 * typeParameter ::=
4203 * metadata name ('extends' bound)? 4519 * metadata name ('extends' bound)?
4204 * </pre> 4520 * </pre>
4521 *
4205 * @return the type parameter that was parsed 4522 * @return the type parameter that was parsed
4206 */ 4523 */
4207 TypeParameter parseTypeParameter() { 4524 TypeParameter parseTypeParameter() {
4208 CommentAndMetadata commentAndMetadata = parseCommentAndMetadata(); 4525 CommentAndMetadata commentAndMetadata = parseCommentAndMetadata();
4209 SimpleIdentifier name = parseSimpleIdentifier(); 4526 SimpleIdentifier name = parseSimpleIdentifier();
4210 if (matches(Keyword.EXTENDS)) { 4527 if (matches(Keyword.EXTENDS)) {
4211 Token keyword = andAdvance; 4528 Token keyword = andAdvance;
4212 TypeName bound = parseTypeName(); 4529 TypeName bound = parseTypeName();
4213 return new TypeParameter.full(commentAndMetadata.comment, commentAndMetada ta.metadata, name, keyword, bound); 4530 return new TypeParameter.full(commentAndMetadata.comment, commentAndMetada ta.metadata, name, keyword, bound);
4214 } 4531 }
4215 return new TypeParameter.full(commentAndMetadata.comment, commentAndMetadata .metadata, name, null, null); 4532 return new TypeParameter.full(commentAndMetadata.comment, commentAndMetadata .metadata, name, null, null);
4216 } 4533 }
4217 4534
4218 /** 4535 /**
4219 * Parse a list of type parameters. 4536 * Parse a list of type parameters.
4537 *
4220 * <pre> 4538 * <pre>
4221 * typeParameterList ::= 4539 * typeParameterList ::=
4222 * '<' typeParameter (',' typeParameter)* '>' 4540 * '<' typeParameter (',' typeParameter)* '>'
4223 * </pre> 4541 * </pre>
4542 *
4224 * @return the list of type parameters that were parsed 4543 * @return the list of type parameters that were parsed
4225 */ 4544 */
4226 TypeParameterList parseTypeParameterList() { 4545 TypeParameterList parseTypeParameterList() {
4227 Token leftBracket = expect2(TokenType.LT); 4546 Token leftBracket = expect2(TokenType.LT);
4228 List<TypeParameter> typeParameters = new List<TypeParameter>(); 4547 List<TypeParameter> typeParameters = new List<TypeParameter>();
4229 typeParameters.add(parseTypeParameter()); 4548 typeParameters.add(parseTypeParameter());
4230 while (optional(TokenType.COMMA)) { 4549 while (optional(TokenType.COMMA)) {
4231 typeParameters.add(parseTypeParameter()); 4550 typeParameters.add(parseTypeParameter());
4232 } 4551 }
4233 Token rightBracket = expect2(TokenType.GT); 4552 Token rightBracket = expect2(TokenType.GT);
4234 return new TypeParameterList.full(leftBracket, typeParameters, rightBracket) ; 4553 return new TypeParameterList.full(leftBracket, typeParameters, rightBracket) ;
4235 } 4554 }
4236 4555
4237 /** 4556 /**
4238 * Parse a unary expression. 4557 * Parse a unary expression.
4558 *
4239 * <pre> 4559 * <pre>
4240 * unaryExpression ::= 4560 * unaryExpression ::=
4241 * prefixOperator unaryExpression 4561 * prefixOperator unaryExpression
4242 * | postfixExpression 4562 * | postfixExpression
4243 * | unaryOperator 'super' 4563 * | unaryOperator 'super'
4244 * | '-' 'super' 4564 * | '-' 'super'
4245 * | incrementOperator assignableExpression 4565 * | incrementOperator assignableExpression
4246 * </pre> 4566 * </pre>
4567 *
4247 * @return the unary expression that was parsed 4568 * @return the unary expression that was parsed
4248 */ 4569 */
4249 Expression parseUnaryExpression() { 4570 Expression parseUnaryExpression() {
4250 if (matches5(TokenType.MINUS) || matches5(TokenType.BANG) || matches5(TokenT ype.TILDE)) { 4571 if (matches5(TokenType.MINUS) || matches5(TokenType.BANG) || matches5(TokenT ype.TILDE)) {
4251 Token operator = andAdvance; 4572 Token operator = andAdvance;
4252 if (matches(Keyword.SUPER)) { 4573 if (matches(Keyword.SUPER)) {
4253 if (matches4(peek(), TokenType.OPEN_SQUARE_BRACKET) || matches4(peek(), TokenType.PERIOD)) { 4574 if (matches4(peek(), TokenType.OPEN_SQUARE_BRACKET) || matches4(peek(), TokenType.PERIOD)) {
4254 return new PrefixExpression.full(operator, parseUnaryExpression()); 4575 return new PrefixExpression.full(operator, parseUnaryExpression());
4255 } 4576 }
4256 return new PrefixExpression.full(operator, new SuperExpression.full(andA dvance)); 4577 return new PrefixExpression.full(operator, new SuperExpression.full(andA dvance));
(...skipping 21 matching lines...) Expand all
4278 return new PrefixExpression.full(operator, parseAssignableExpression(false )); 4599 return new PrefixExpression.full(operator, parseAssignableExpression(false ));
4279 } else if (matches5(TokenType.PLUS)) { 4600 } else if (matches5(TokenType.PLUS)) {
4280 reportError7(ParserErrorCode.MISSING_IDENTIFIER, []); 4601 reportError7(ParserErrorCode.MISSING_IDENTIFIER, []);
4281 return createSyntheticIdentifier(); 4602 return createSyntheticIdentifier();
4282 } 4603 }
4283 return parsePostfixExpression(); 4604 return parsePostfixExpression();
4284 } 4605 }
4285 4606
4286 /** 4607 /**
4287 * Parse a variable declaration. 4608 * Parse a variable declaration.
4609 *
4288 * <pre> 4610 * <pre>
4289 * variableDeclaration ::= 4611 * variableDeclaration ::=
4290 * identifier ('=' expression)? 4612 * identifier ('=' expression)?
4291 * </pre> 4613 * </pre>
4614 *
4292 * @return the variable declaration that was parsed 4615 * @return the variable declaration that was parsed
4293 */ 4616 */
4294 VariableDeclaration parseVariableDeclaration() { 4617 VariableDeclaration parseVariableDeclaration() {
4295 CommentAndMetadata commentAndMetadata = parseCommentAndMetadata(); 4618 CommentAndMetadata commentAndMetadata = parseCommentAndMetadata();
4296 SimpleIdentifier name = parseSimpleIdentifier(); 4619 SimpleIdentifier name = parseSimpleIdentifier();
4297 Token equals = null; 4620 Token equals = null;
4298 Expression initializer = null; 4621 Expression initializer = null;
4299 if (matches5(TokenType.EQ)) { 4622 if (matches5(TokenType.EQ)) {
4300 equals = andAdvance; 4623 equals = andAdvance;
4301 initializer = parseExpression2(); 4624 initializer = parseExpression2();
4302 } 4625 }
4303 return new VariableDeclaration.full(commentAndMetadata.comment, commentAndMe tadata.metadata, name, equals, initializer); 4626 return new VariableDeclaration.full(commentAndMetadata.comment, commentAndMe tadata.metadata, name, equals, initializer);
4304 } 4627 }
4305 4628
4306 /** 4629 /**
4307 * Parse a variable declaration list. 4630 * Parse a variable declaration list.
4631 *
4308 * <pre> 4632 * <pre>
4309 * variableDeclarationList ::= 4633 * variableDeclarationList ::=
4310 * finalConstVarOrType variableDeclaration (',' variableDeclaration) 4634 * finalConstVarOrType variableDeclaration (',' variableDeclaration)*
4311 * </pre> 4635 * </pre>
4636 *
4312 * @param commentAndMetadata the metadata to be associated with the variable d eclaration list 4637 * @param commentAndMetadata the metadata to be associated with the variable d eclaration list
4313 * @return the variable declaration list that was parsed 4638 * @return the variable declaration list that was parsed
4314 */ 4639 */
4315 VariableDeclarationList parseVariableDeclarationList(CommentAndMetadata commen tAndMetadata) { 4640 VariableDeclarationList parseVariableDeclarationList(CommentAndMetadata commen tAndMetadata) {
4316 FinalConstVarOrType holder = parseFinalConstVarOrType(false); 4641 FinalConstVarOrType holder = parseFinalConstVarOrType(false);
4317 return parseVariableDeclarationList2(commentAndMetadata, holder.keyword, hol der.type); 4642 return parseVariableDeclarationList2(commentAndMetadata, holder.keyword, hol der.type);
4318 } 4643 }
4319 4644
4320 /** 4645 /**
4321 * Parse a variable declaration list. 4646 * Parse a variable declaration list.
4647 *
4322 * <pre> 4648 * <pre>
4323 * variableDeclarationList ::= 4649 * variableDeclarationList ::=
4324 * finalConstVarOrType variableDeclaration (',' variableDeclaration) 4650 * finalConstVarOrType variableDeclaration (',' variableDeclaration)*
4325 * </pre> 4651 * </pre>
4326 * @param commentAndMetadata the metadata to be associated with the variable d eclaration list, or`null` if there is no attempt at parsing the comment and meta data 4652 *
4653 * @param commentAndMetadata the metadata to be associated with the variable d eclaration list, or
4654 * `null` if there is no attempt at parsing the comment and metadata
4327 * @param keyword the token representing the 'final', 'const' or 'var' keyword , or `null` if 4655 * @param keyword the token representing the 'final', 'const' or 'var' keyword , or `null` if
4328 * there is no keyword 4656 * there is no keyword
4329 * @param type the type of the variables in the list 4657 * @param type the type of the variables in the list
4330 * @return the variable declaration list that was parsed 4658 * @return the variable declaration list that was parsed
4331 */ 4659 */
4332 VariableDeclarationList parseVariableDeclarationList2(CommentAndMetadata comme ntAndMetadata, Token keyword, TypeName type) { 4660 VariableDeclarationList parseVariableDeclarationList2(CommentAndMetadata comme ntAndMetadata, Token keyword, TypeName type) {
4333 List<VariableDeclaration> variables = new List<VariableDeclaration>(); 4661 List<VariableDeclaration> variables = new List<VariableDeclaration>();
4334 variables.add(parseVariableDeclaration()); 4662 variables.add(parseVariableDeclaration());
4335 while (matches5(TokenType.COMMA)) { 4663 while (matches5(TokenType.COMMA)) {
4336 advance(); 4664 advance();
4337 variables.add(parseVariableDeclaration()); 4665 variables.add(parseVariableDeclaration());
4338 } 4666 }
4339 return new VariableDeclarationList.full(commentAndMetadata != null ? comment AndMetadata.comment : null, commentAndMetadata != null ? commentAndMetadata.meta data : null, keyword, type, variables); 4667 return new VariableDeclarationList.full(commentAndMetadata != null ? comment AndMetadata.comment : null, commentAndMetadata != null ? commentAndMetadata.meta data : null, keyword, type, variables);
4340 } 4668 }
4341 4669
4342 /** 4670 /**
4343 * Parse a variable declaration statement. 4671 * Parse a variable declaration statement.
4672 *
4344 * <pre> 4673 * <pre>
4345 * variableDeclarationStatement ::= 4674 * variableDeclarationStatement ::=
4346 * variableDeclarationList ';' 4675 * variableDeclarationList ';'
4347 * </pre> 4676 * </pre>
4677 *
4348 * @param commentAndMetadata the metadata to be associated with the variable d eclaration 4678 * @param commentAndMetadata the metadata to be associated with the variable d eclaration
4349 * statement, or `null` if there is no attempt at parsing the comment and meta data 4679 * statement, or `null` if there is no attempt at parsing the comment and metadata
4350 * @return the variable declaration statement that was parsed 4680 * @return the variable declaration statement that was parsed
4351 */ 4681 */
4352 VariableDeclarationStatement parseVariableDeclarationStatement(CommentAndMetad ata commentAndMetadata) { 4682 VariableDeclarationStatement parseVariableDeclarationStatement(CommentAndMetad ata commentAndMetadata) {
4353 VariableDeclarationList variableList = parseVariableDeclarationList(commentA ndMetadata); 4683 VariableDeclarationList variableList = parseVariableDeclarationList(commentA ndMetadata);
4354 Token semicolon = expect2(TokenType.SEMICOLON); 4684 Token semicolon = expect2(TokenType.SEMICOLON);
4355 return new VariableDeclarationStatement.full(variableList, semicolon); 4685 return new VariableDeclarationStatement.full(variableList, semicolon);
4356 } 4686 }
4357 4687
4358 /** 4688 /**
4359 * Parse a variable declaration statement. 4689 * Parse a variable declaration statement.
4690 *
4360 * <pre> 4691 * <pre>
4361 * variableDeclarationStatement ::= 4692 * variableDeclarationStatement ::=
4362 * variableDeclarationList ';' 4693 * variableDeclarationList ';'
4363 * </pre> 4694 * </pre>
4695 *
4364 * @param commentAndMetadata the metadata to be associated with the variable d eclaration 4696 * @param commentAndMetadata the metadata to be associated with the variable d eclaration
4365 * statement, or `null` if there is no attempt at parsing the comment and meta data 4697 * statement, or `null` if there is no attempt at parsing the comment and metadata
4366 * @param keyword the token representing the 'final', 'const' or 'var' keyword , or `null` if 4698 * @param keyword the token representing the 'final', 'const' or 'var' keyword , or `null` if
4367 * there is no keyword 4699 * there is no keyword
4368 * @param type the type of the variables in the list 4700 * @param type the type of the variables in the list
4369 * @return the variable declaration statement that was parsed 4701 * @return the variable declaration statement that was parsed
4370 */ 4702 */
4371 VariableDeclarationStatement parseVariableDeclarationStatement2(CommentAndMeta data commentAndMetadata, Token keyword, TypeName type) { 4703 VariableDeclarationStatement parseVariableDeclarationStatement2(CommentAndMeta data commentAndMetadata, Token keyword, TypeName type) {
4372 VariableDeclarationList variableList = parseVariableDeclarationList2(comment AndMetadata, keyword, type); 4704 VariableDeclarationList variableList = parseVariableDeclarationList2(comment AndMetadata, keyword, type);
4373 Token semicolon = expect2(TokenType.SEMICOLON); 4705 Token semicolon = expect2(TokenType.SEMICOLON);
4374 return new VariableDeclarationStatement.full(variableList, semicolon); 4706 return new VariableDeclarationStatement.full(variableList, semicolon);
4375 } 4707 }
4376 4708
4377 /** 4709 /**
4378 * Parse a while statement. 4710 * Parse a while statement.
4711 *
4379 * <pre> 4712 * <pre>
4380 * whileStatement ::= 4713 * whileStatement ::=
4381 * 'while' '(' expression ')' statement 4714 * 'while' '(' expression ')' statement
4382 * </pre> 4715 * </pre>
4716 *
4383 * @return the while statement that was parsed 4717 * @return the while statement that was parsed
4384 */ 4718 */
4385 Statement parseWhileStatement() { 4719 Statement parseWhileStatement() {
4386 bool wasInLoop = _inLoop; 4720 bool wasInLoop = _inLoop;
4387 _inLoop = true; 4721 _inLoop = true;
4388 try { 4722 try {
4389 Token keyword = expect(Keyword.WHILE); 4723 Token keyword = expect(Keyword.WHILE);
4390 Token leftParenthesis = expect2(TokenType.OPEN_PAREN); 4724 Token leftParenthesis = expect2(TokenType.OPEN_PAREN);
4391 Expression condition = parseExpression2(); 4725 Expression condition = parseExpression2();
4392 Token rightParenthesis = expect2(TokenType.CLOSE_PAREN); 4726 Token rightParenthesis = expect2(TokenType.CLOSE_PAREN);
4393 Statement body = parseStatement2(); 4727 Statement body = parseStatement2();
4394 return new WhileStatement.full(keyword, leftParenthesis, condition, rightP arenthesis, body); 4728 return new WhileStatement.full(keyword, leftParenthesis, condition, rightP arenthesis, body);
4395 } finally { 4729 } finally {
4396 _inLoop = wasInLoop; 4730 _inLoop = wasInLoop;
4397 } 4731 }
4398 } 4732 }
4399 4733
4400 /** 4734 /**
4401 * Parse a with clause. 4735 * Parse a with clause.
4736 *
4402 * <pre> 4737 * <pre>
4403 * withClause ::= 4738 * withClause ::=
4404 * 'with' typeName (',' typeName) 4739 * 'with' typeName (',' typeName)*
4405 * </pre> 4740 * </pre>
4741 *
4406 * @return the with clause that was parsed 4742 * @return the with clause that was parsed
4407 */ 4743 */
4408 WithClause parseWithClause() { 4744 WithClause parseWithClause() {
4409 Token with2 = expect(Keyword.WITH); 4745 Token with2 = expect(Keyword.WITH);
4410 List<TypeName> types = new List<TypeName>(); 4746 List<TypeName> types = new List<TypeName>();
4411 types.add(parseTypeName()); 4747 types.add(parseTypeName());
4412 while (optional(TokenType.COMMA)) { 4748 while (optional(TokenType.COMMA)) {
4413 types.add(parseTypeName()); 4749 types.add(parseTypeName());
4414 } 4750 }
4415 return new WithClause.full(with2, types); 4751 return new WithClause.full(with2, types);
4416 } 4752 }
4417 4753
4418 /** 4754 /**
4419 * Return the token that is immediately after the current token. This is equiv alent to[peek]. 4755 * Return the token that is immediately after the current token. This is equiv alent to
4756 * [peek].
4757 *
4420 * @return the token that is immediately after the current token 4758 * @return the token that is immediately after the current token
4421 */ 4759 */
4422 Token peek() => _currentToken.next; 4760 Token peek() => _currentToken.next;
4423 4761
4424 /** 4762 /**
4425 * Return the token that is the given distance after the current token. 4763 * Return the token that is the given distance after the current token.
4426 * @param distance the number of tokens to look ahead, where `0` is the curren t token,`1` is the next token, etc. 4764 *
4765 * @param distance the number of tokens to look ahead, where `0` is the curren t token,
4766 * `1` is the next token, etc.
4427 * @return the token that is the given distance after the current token 4767 * @return the token that is the given distance after the current token
4428 */ 4768 */
4429 Token peek2(int distance) { 4769 Token peek2(int distance) {
4430 Token token = _currentToken; 4770 Token token = _currentToken;
4431 for (int i = 0; i < distance; i++) { 4771 for (int i = 0; i < distance; i++) {
4432 token = token.next; 4772 token = token.next;
4433 } 4773 }
4434 return token; 4774 return token;
4435 } 4775 }
4436 4776
4437 /** 4777 /**
4438 * Report an error with the given error code and arguments. 4778 * Report an error with the given error code and arguments.
4779 *
4439 * @param errorCode the error code of the error to be reported 4780 * @param errorCode the error code of the error to be reported
4440 * @param node the node specifying the location of the error 4781 * @param node the node specifying the location of the error
4441 * @param arguments the arguments to the error, used to compose the error mess age 4782 * @param arguments the arguments to the error, used to compose the error mess age
4442 */ 4783 */
4443 void reportError(ParserErrorCode errorCode, ASTNode node, List<Object> argumen ts) { 4784 void reportError(ParserErrorCode errorCode, ASTNode node, List<Object> argumen ts) {
4444 _errorListener.onError(new AnalysisError.con2(_source, node.offset, node.len gth, errorCode, arguments)); 4785 _errorListener.onError(new AnalysisError.con2(_source, node.offset, node.len gth, errorCode, arguments));
4445 } 4786 }
4446 4787
4447 /** 4788 /**
4448 * Report an error with the given error code and arguments. 4789 * Report an error with the given error code and arguments.
4790 *
4449 * @param errorCode the error code of the error to be reported 4791 * @param errorCode the error code of the error to be reported
4450 * @param arguments the arguments to the error, used to compose the error mess age 4792 * @param arguments the arguments to the error, used to compose the error mess age
4451 */ 4793 */
4452 void reportError7(ParserErrorCode errorCode, List<Object> arguments) { 4794 void reportError7(ParserErrorCode errorCode, List<Object> arguments) {
4453 reportError8(errorCode, _currentToken, arguments); 4795 reportError8(errorCode, _currentToken, arguments);
4454 } 4796 }
4455 4797
4456 /** 4798 /**
4457 * Report an error with the given error code and arguments. 4799 * Report an error with the given error code and arguments.
4800 *
4458 * @param errorCode the error code of the error to be reported 4801 * @param errorCode the error code of the error to be reported
4459 * @param token the token specifying the location of the error 4802 * @param token the token specifying the location of the error
4460 * @param arguments the arguments to the error, used to compose the error mess age 4803 * @param arguments the arguments to the error, used to compose the error mess age
4461 */ 4804 */
4462 void reportError8(ParserErrorCode errorCode, Token token, List<Object> argumen ts) { 4805 void reportError8(ParserErrorCode errorCode, Token token, List<Object> argumen ts) {
4463 _errorListener.onError(new AnalysisError.con2(_source, token.offset, token.l ength, errorCode, arguments)); 4806 _errorListener.onError(new AnalysisError.con2(_source, token.offset, token.l ength, errorCode, arguments));
4464 } 4807 }
4465 4808
4466 /** 4809 /**
4467 * Parse the 'final', 'const', 'var' or type preceding a variable declaration, starting at the 4810 * Parse the 'final', 'const', 'var' or type preceding a variable declaration, starting at the
4468 * given token, without actually creating a type or changing the current token . Return the token 4811 * given token, without actually creating a type or changing the current token . Return the token
4469 * following the type that was parsed, or `null` if the given token is not the first token 4812 * following the type that was parsed, or `null` if the given token is not the first token
4470 * in a valid type. 4813 * in a valid type.
4814 *
4471 * <pre> 4815 * <pre>
4472 * finalConstVarOrType ::= 4816 * finalConstVarOrType ::=
4473 * | 'final' type? 4817 * | 'final' type?
4474 * | 'const' type? 4818 * | 'const' type?
4475 * | 'var' 4819 * | 'var'
4476 * | type 4820 * | type
4477 * </pre> 4821 * </pre>
4822 *
4478 * @param startToken the token at which parsing is to begin 4823 * @param startToken the token at which parsing is to begin
4479 * @return the token following the type that was parsed 4824 * @return the token following the type that was parsed
4480 */ 4825 */
4481 Token skipFinalConstVarOrType(Token startToken) { 4826 Token skipFinalConstVarOrType(Token startToken) {
4482 if (matches3(startToken, Keyword.FINAL) || matches3(startToken, Keyword.CONS T)) { 4827 if (matches3(startToken, Keyword.FINAL) || matches3(startToken, Keyword.CONS T)) {
4483 Token next = startToken.next; 4828 Token next = startToken.next;
4484 if (matchesIdentifier2(next.next) || matches4(next.next, TokenType.LT) || matches3(next.next, Keyword.THIS)) { 4829 if (matchesIdentifier2(next.next) || matches4(next.next, TokenType.LT) || matches3(next.next, Keyword.THIS)) {
4485 return skipTypeName(next); 4830 return skipTypeName(next);
4486 } 4831 }
4487 } else if (matches3(startToken, Keyword.VAR)) { 4832 } else if (matches3(startToken, Keyword.VAR)) {
(...skipping 13 matching lines...) Expand all
4501 * parameter list that was parsed, or `null` if the given token is not the fir st token in a 4846 * parameter list that was parsed, or `null` if the given token is not the fir st token in a
4502 * valid list of formal parameter. 4847 * valid list of formal parameter.
4503 * 4848 *
4504 * Note that unlike other skip methods, this method uses a heuristic. In the w orst case, the 4849 * Note that unlike other skip methods, this method uses a heuristic. In the w orst case, the
4505 * parameters could be prefixed by metadata, which would require us to be able to skip arbitrary 4850 * parameters could be prefixed by metadata, which would require us to be able to skip arbitrary
4506 * expressions. Rather than duplicate the logic of most of the parse methods w e simply look for 4851 * expressions. Rather than duplicate the logic of most of the parse methods w e simply look for
4507 * something that is likely to be a list of parameters and then skip to return ing the token after 4852 * something that is likely to be a list of parameters and then skip to return ing the token after
4508 * the closing parenthesis. 4853 * the closing parenthesis.
4509 * 4854 *
4510 * This method must be kept in sync with [parseFormalParameterList]. 4855 * This method must be kept in sync with [parseFormalParameterList].
4856 *
4511 * <pre> 4857 * <pre>
4512 * formalParameterList ::= 4858 * formalParameterList ::=
4513 * '(' ')' 4859 * '(' ')'
4514 * | '(' normalFormalParameters (',' optionalFormalParameters)? ')' 4860 * | '(' normalFormalParameters (',' optionalFormalParameters)? ')'
4515 * | '(' optionalFormalParameters ')' 4861 * | '(' optionalFormalParameters ')'
4862 *
4516 * normalFormalParameters ::= 4863 * normalFormalParameters ::=
4517 * normalFormalParameter (',' normalFormalParameter) 4864 * normalFormalParameter (',' normalFormalParameter)*
4865 *
4518 * optionalFormalParameters ::= 4866 * optionalFormalParameters ::=
4519 * optionalPositionalFormalParameters 4867 * optionalPositionalFormalParameters
4520 * | namedFormalParameters 4868 * | namedFormalParameters
4869 *
4521 * optionalPositionalFormalParameters ::= 4870 * optionalPositionalFormalParameters ::=
4522 * '\[' defaultFormalParameter (',' defaultFormalParameter)* '\]' 4871 * '[' defaultFormalParameter (',' defaultFormalParameter)* ']'
4872 *
4523 * namedFormalParameters ::= 4873 * namedFormalParameters ::=
4524 * '{' defaultNamedParameter (',' defaultNamedParameter)* '}' 4874 * '{' defaultNamedParameter (',' defaultNamedParameter)* '}'
4525 * </pre> 4875 * </pre>
4876 *
4526 * @param startToken the token at which parsing is to begin 4877 * @param startToken the token at which parsing is to begin
4527 * @return the token following the formal parameter list that was parsed 4878 * @return the token following the formal parameter list that was parsed
4528 */ 4879 */
4529 Token skipFormalParameterList(Token startToken) { 4880 Token skipFormalParameterList(Token startToken) {
4530 if (!matches4(startToken, TokenType.OPEN_PAREN)) { 4881 if (!matches4(startToken, TokenType.OPEN_PAREN)) {
4531 return null; 4882 return null;
4532 } 4883 }
4533 Token next = startToken.next; 4884 Token next = startToken.next;
4534 if (matches4(next, TokenType.CLOSE_PAREN)) { 4885 if (matches4(next, TokenType.CLOSE_PAREN)) {
4535 return next.next; 4886 return next.next;
(...skipping 13 matching lines...) Expand all
4549 } 4900 }
4550 if (skipSimpleIdentifier(afterType) == null) { 4901 if (skipSimpleIdentifier(afterType) == null) {
4551 return null; 4902 return null;
4552 } 4903 }
4553 return skipPastMatchingToken(startToken); 4904 return skipPastMatchingToken(startToken);
4554 } 4905 }
4555 4906
4556 /** 4907 /**
4557 * If the given token is a begin token with an associated end token, then retu rn the token 4908 * If the given token is a begin token with an associated end token, then retu rn the token
4558 * following the end token. Otherwise, return `null`. 4909 * following the end token. Otherwise, return `null`.
4910 *
4559 * @param startToken the token that is assumed to be a being token 4911 * @param startToken the token that is assumed to be a being token
4560 * @return the token following the matching end token 4912 * @return the token following the matching end token
4561 */ 4913 */
4562 Token skipPastMatchingToken(Token startToken) { 4914 Token skipPastMatchingToken(Token startToken) {
4563 if (startToken is! BeginToken) { 4915 if (startToken is! BeginToken) {
4564 return null; 4916 return null;
4565 } 4917 }
4566 Token closeParen = ((startToken as BeginToken)).endToken; 4918 Token closeParen = ((startToken as BeginToken)).endToken;
4567 if (closeParen == null) { 4919 if (closeParen == null) {
4568 return null; 4920 return null;
4569 } 4921 }
4570 return closeParen.next; 4922 return closeParen.next;
4571 } 4923 }
4572 4924
4573 /** 4925 /**
4574 * Parse a prefixed identifier, starting at the given token, without actually creating a prefixed 4926 * Parse a prefixed identifier, starting at the given token, without actually creating a prefixed
4575 * identifier or changing the current token. Return the token following the pr efixed identifier 4927 * identifier or changing the current token. Return the token following the pr efixed identifier
4576 * that was parsed, or `null` if the given token is not the first token in a v alid prefixed 4928 * that was parsed, or `null` if the given token is not the first token in a v alid prefixed
4577 * identifier. 4929 * identifier.
4578 * 4930 *
4579 * This method must be kept in sync with [parsePrefixedIdentifier]. 4931 * This method must be kept in sync with [parsePrefixedIdentifier].
4932 *
4580 * <pre> 4933 * <pre>
4581 * prefixedIdentifier ::= 4934 * prefixedIdentifier ::=
4582 * identifier ('.' identifier)? 4935 * identifier ('.' identifier)?
4583 * </pre> 4936 * </pre>
4937 *
4584 * @param startToken the token at which parsing is to begin 4938 * @param startToken the token at which parsing is to begin
4585 * @return the token following the prefixed identifier that was parsed 4939 * @return the token following the prefixed identifier that was parsed
4586 */ 4940 */
4587 Token skipPrefixedIdentifier(Token startToken) { 4941 Token skipPrefixedIdentifier(Token startToken) {
4588 Token token = skipSimpleIdentifier(startToken); 4942 Token token = skipSimpleIdentifier(startToken);
4589 if (token == null) { 4943 if (token == null) {
4590 return null; 4944 return null;
4591 } else if (!matches4(token, TokenType.PERIOD)) { 4945 } else if (!matches4(token, TokenType.PERIOD)) {
4592 return token; 4946 return token;
4593 } 4947 }
4594 return skipSimpleIdentifier(token.next); 4948 return skipSimpleIdentifier(token.next);
4595 } 4949 }
4596 4950
4597 /** 4951 /**
4598 * Parse a return type, starting at the given token, without actually creating a return type or 4952 * Parse a return type, starting at the given token, without actually creating a return type or
4599 * changing the current token. Return the token following the return type that was parsed, or`null` if the given token is not the first token in a valid retur n type. 4953 * changing the current token. Return the token following the return type that was parsed, or
4954 * `null` if the given token is not the first token in a valid return type.
4600 * 4955 *
4601 * This method must be kept in sync with [parseReturnType]. 4956 * This method must be kept in sync with [parseReturnType].
4957 *
4602 * <pre> 4958 * <pre>
4603 * returnType ::= 4959 * returnType ::=
4604 * 'void' 4960 * 'void'
4605 * | type 4961 * | type
4606 * </pre> 4962 * </pre>
4963 *
4607 * @param startToken the token at which parsing is to begin 4964 * @param startToken the token at which parsing is to begin
4608 * @return the token following the return type that was parsed 4965 * @return the token following the return type that was parsed
4609 */ 4966 */
4610 Token skipReturnType(Token startToken) { 4967 Token skipReturnType(Token startToken) {
4611 if (matches3(startToken, Keyword.VOID)) { 4968 if (matches3(startToken, Keyword.VOID)) {
4612 return startToken.next; 4969 return startToken.next;
4613 } else { 4970 } else {
4614 return skipTypeName(startToken); 4971 return skipTypeName(startToken);
4615 } 4972 }
4616 } 4973 }
4617 4974
4618 /** 4975 /**
4619 * Parse a simple identifier, starting at the given token, without actually cr eating a simple 4976 * Parse a simple identifier, starting at the given token, without actually cr eating a simple
4620 * identifier or changing the current token. Return the token following the si mple identifier that 4977 * identifier or changing the current token. Return the token following the si mple identifier that
4621 * was parsed, or `null` if the given token is not the first token in a valid simple 4978 * was parsed, or `null` if the given token is not the first token in a valid simple
4622 * identifier. 4979 * identifier.
4623 * 4980 *
4624 * This method must be kept in sync with [parseSimpleIdentifier]. 4981 * This method must be kept in sync with [parseSimpleIdentifier].
4982 *
4625 * <pre> 4983 * <pre>
4626 * identifier ::= 4984 * identifier ::=
4627 * IDENTIFIER 4985 * IDENTIFIER
4628 * </pre> 4986 * </pre>
4987 *
4629 * @param startToken the token at which parsing is to begin 4988 * @param startToken the token at which parsing is to begin
4630 * @return the token following the simple identifier that was parsed 4989 * @return the token following the simple identifier that was parsed
4631 */ 4990 */
4632 Token skipSimpleIdentifier(Token startToken) { 4991 Token skipSimpleIdentifier(Token startToken) {
4633 if (matches4(startToken, TokenType.IDENTIFIER) || (matches4(startToken, Toke nType.KEYWORD) && ((startToken as KeywordToken)).keyword.isPseudoKeyword)) { 4992 if (matches4(startToken, TokenType.IDENTIFIER) || (matches4(startToken, Toke nType.KEYWORD) && ((startToken as KeywordToken)).keyword.isPseudoKeyword)) {
4634 return startToken.next; 4993 return startToken.next;
4635 } 4994 }
4636 return null; 4995 return null;
4637 } 4996 }
4638 4997
4639 /** 4998 /**
4640 * Parse a string literal that contains interpolations, starting at the given token, without 4999 * Parse a string literal that contains interpolations, starting at the given token, without
4641 * actually creating a string literal or changing the current token. Return th e token following 5000 * actually creating a string literal or changing the current token. Return th e token following
4642 * the string literal that was parsed, or `null` if the given token is not the first token 5001 * the string literal that was parsed, or `null` if the given token is not the first token
4643 * in a valid string literal. 5002 * in a valid string literal.
4644 * 5003 *
4645 * This method must be kept in sync with [parseStringInterpolation]. 5004 * This method must be kept in sync with [parseStringInterpolation].
5005 *
4646 * @param startToken the token at which parsing is to begin 5006 * @param startToken the token at which parsing is to begin
4647 * @return the string literal that was parsed 5007 * @return the string literal that was parsed
4648 */ 5008 */
4649 Token skipStringInterpolation(Token startToken) { 5009 Token skipStringInterpolation(Token startToken) {
4650 Token token = startToken; 5010 Token token = startToken;
4651 TokenType type = token.type; 5011 TokenType type = token.type;
4652 while (identical(type, TokenType.STRING_INTERPOLATION_EXPRESSION) || identic al(type, TokenType.STRING_INTERPOLATION_IDENTIFIER)) { 5012 while (identical(type, TokenType.STRING_INTERPOLATION_EXPRESSION) || identic al(type, TokenType.STRING_INTERPOLATION_IDENTIFIER)) {
4653 if (identical(type, TokenType.STRING_INTERPOLATION_EXPRESSION)) { 5013 if (identical(type, TokenType.STRING_INTERPOLATION_EXPRESSION)) {
4654 token = token.next; 5014 token = token.next;
4655 type = token.type; 5015 type = token.type;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
4688 } 5048 }
4689 return token; 5049 return token;
4690 } 5050 }
4691 5051
4692 /** 5052 /**
4693 * Parse a string literal, starting at the given token, without actually creat ing a string literal 5053 * Parse a string literal, starting at the given token, without actually creat ing a string literal
4694 * or changing the current token. Return the token following the string litera l that was parsed, 5054 * or changing the current token. Return the token following the string litera l that was parsed,
4695 * or `null` if the given token is not the first token in a valid string liter al. 5055 * or `null` if the given token is not the first token in a valid string liter al.
4696 * 5056 *
4697 * This method must be kept in sync with [parseStringLiteral]. 5057 * This method must be kept in sync with [parseStringLiteral].
5058 *
4698 * <pre> 5059 * <pre>
4699 * stringLiteral ::= 5060 * stringLiteral ::=
4700 * MULTI_LINE_STRING+ 5061 * MULTI_LINE_STRING+
4701 * | SINGLE_LINE_STRING+ 5062 * | SINGLE_LINE_STRING+
4702 * </pre> 5063 * </pre>
5064 *
4703 * @param startToken the token at which parsing is to begin 5065 * @param startToken the token at which parsing is to begin
4704 * @return the token following the string literal that was parsed 5066 * @return the token following the string literal that was parsed
4705 */ 5067 */
4706 Token skipStringLiteral(Token startToken) { 5068 Token skipStringLiteral(Token startToken) {
4707 Token token = startToken; 5069 Token token = startToken;
4708 while (token != null && matches4(token, TokenType.STRING)) { 5070 while (token != null && matches4(token, TokenType.STRING)) {
4709 token = token.next; 5071 token = token.next;
4710 TokenType type = token.type; 5072 TokenType type = token.type;
4711 if (identical(type, TokenType.STRING_INTERPOLATION_EXPRESSION) || identica l(type, TokenType.STRING_INTERPOLATION_IDENTIFIER)) { 5073 if (identical(type, TokenType.STRING_INTERPOLATION_EXPRESSION) || identica l(type, TokenType.STRING_INTERPOLATION_IDENTIFIER)) {
4712 token = skipStringInterpolation(token); 5074 token = skipStringInterpolation(token);
4713 } 5075 }
4714 } 5076 }
4715 if (identical(token, startToken)) { 5077 if (identical(token, startToken)) {
4716 return null; 5078 return null;
4717 } 5079 }
4718 return token; 5080 return token;
4719 } 5081 }
4720 5082
4721 /** 5083 /**
4722 * Parse a list of type arguments, starting at the given token, without actual ly creating a type argument list 5084 * Parse a list of type arguments, starting at the given token, without actual ly creating a type argument list
4723 * or changing the current token. Return the token following the type argument list that was parsed, 5085 * or changing the current token. Return the token following the type argument list that was parsed,
4724 * or `null` if the given token is not the first token in a valid type argumen t list. 5086 * or `null` if the given token is not the first token in a valid type argumen t list.
4725 * 5087 *
4726 * This method must be kept in sync with [parseTypeArgumentList]. 5088 * This method must be kept in sync with [parseTypeArgumentList].
5089 *
4727 * <pre> 5090 * <pre>
4728 * typeArguments ::= 5091 * typeArguments ::=
4729 * '<' typeList '>' 5092 * '<' typeList '>'
5093 *
4730 * typeList ::= 5094 * typeList ::=
4731 * type (',' type) 5095 * type (',' type)*
4732 * </pre> 5096 * </pre>
5097 *
4733 * @param startToken the token at which parsing is to begin 5098 * @param startToken the token at which parsing is to begin
4734 * @return the token following the type argument list that was parsed 5099 * @return the token following the type argument list that was parsed
4735 */ 5100 */
4736 Token skipTypeArgumentList(Token startToken) { 5101 Token skipTypeArgumentList(Token startToken) {
4737 Token token = startToken; 5102 Token token = startToken;
4738 if (!matches4(token, TokenType.LT)) { 5103 if (!matches4(token, TokenType.LT)) {
4739 return null; 5104 return null;
4740 } 5105 }
4741 token = skipTypeName(token.next); 5106 token = skipTypeName(token.next);
4742 if (token == null) { 5107 if (token == null) {
(...skipping 10 matching lines...) Expand all
4753 } else if (identical(token.type, TokenType.GT_GT)) { 5118 } else if (identical(token.type, TokenType.GT_GT)) {
4754 Token second = new Token(TokenType.GT, token.offset + 1); 5119 Token second = new Token(TokenType.GT, token.offset + 1);
4755 second.setNextWithoutSettingPrevious(token.next); 5120 second.setNextWithoutSettingPrevious(token.next);
4756 return second; 5121 return second;
4757 } 5122 }
4758 return null; 5123 return null;
4759 } 5124 }
4760 5125
4761 /** 5126 /**
4762 * Parse a type name, starting at the given token, without actually creating a type name or 5127 * Parse a type name, starting at the given token, without actually creating a type name or
4763 * changing the current token. Return the token following the type name that w as parsed, or`null` if the given token is not the first token in a valid type na me. 5128 * changing the current token. Return the token following the type name that w as parsed, or
5129 * `null` if the given token is not the first token in a valid type name.
4764 * 5130 *
4765 * This method must be kept in sync with [parseTypeName]. 5131 * This method must be kept in sync with [parseTypeName].
5132 *
4766 * <pre> 5133 * <pre>
4767 * type ::= 5134 * type ::=
4768 * qualified typeArguments? 5135 * qualified typeArguments?
4769 * </pre> 5136 * </pre>
5137 *
4770 * @param startToken the token at which parsing is to begin 5138 * @param startToken the token at which parsing is to begin
4771 * @return the token following the type name that was parsed 5139 * @return the token following the type name that was parsed
4772 */ 5140 */
4773 Token skipTypeName(Token startToken) { 5141 Token skipTypeName(Token startToken) {
4774 Token token = skipPrefixedIdentifier(startToken); 5142 Token token = skipPrefixedIdentifier(startToken);
4775 if (token == null) { 5143 if (token == null) {
4776 return null; 5144 return null;
4777 } 5145 }
4778 if (matches4(token, TokenType.LT)) { 5146 if (matches4(token, TokenType.LT)) {
4779 token = skipTypeArgumentList(token); 5147 token = skipTypeArgumentList(token);
4780 } 5148 }
4781 return token; 5149 return token;
4782 } 5150 }
4783 5151
4784 /** 5152 /**
4785 * Parse a list of type parameters, starting at the given token, without actua lly creating a type 5153 * Parse a list of type parameters, starting at the given token, without actua lly creating a type
4786 * parameter list or changing the current token. Return the token following th e type parameter 5154 * parameter list or changing the current token. Return the token following th e type parameter
4787 * list that was parsed, or `null` if the given token is not the first token i n a valid type 5155 * list that was parsed, or `null` if the given token is not the first token i n a valid type
4788 * parameter list. 5156 * parameter list.
4789 * 5157 *
4790 * This method must be kept in sync with [parseTypeParameterList]. 5158 * This method must be kept in sync with [parseTypeParameterList].
5159 *
4791 * <pre> 5160 * <pre>
4792 * typeParameterList ::= 5161 * typeParameterList ::=
4793 * '<' typeParameter (',' typeParameter)* '>' 5162 * '<' typeParameter (',' typeParameter)* '>'
4794 * </pre> 5163 * </pre>
5164 *
4795 * @param startToken the token at which parsing is to begin 5165 * @param startToken the token at which parsing is to begin
4796 * @return the token following the type parameter list that was parsed 5166 * @return the token following the type parameter list that was parsed
4797 */ 5167 */
4798 Token skipTypeParameterList(Token startToken) { 5168 Token skipTypeParameterList(Token startToken) {
4799 if (!matches4(startToken, TokenType.LT)) { 5169 if (!matches4(startToken, TokenType.LT)) {
4800 return null; 5170 return null;
4801 } 5171 }
4802 int depth = 1; 5172 int depth = 1;
4803 Token next = startToken.next; 5173 Token next = startToken.next;
4804 while (depth > 0) { 5174 while (depth > 0) {
(...skipping 23 matching lines...) Expand all
4828 depth -= 2; 5198 depth -= 2;
4829 } 5199 }
4830 next = next.next; 5200 next = next.next;
4831 } 5201 }
4832 return next; 5202 return next;
4833 } 5203 }
4834 5204
4835 /** 5205 /**
4836 * Translate the characters at the given index in the given string, appending the translated 5206 * Translate the characters at the given index in the given string, appending the translated
4837 * character to the given builder. The index is assumed to be valid. 5207 * character to the given builder. The index is assumed to be valid.
5208 *
4838 * @param builder the builder to which the translated character is to be appen ded 5209 * @param builder the builder to which the translated character is to be appen ded
4839 * @param lexeme the string containing the character(s) to be translated 5210 * @param lexeme the string containing the character(s) to be translated
4840 * @param index the index of the character to be translated 5211 * @param index the index of the character to be translated
4841 * @return the index of the next character to be translated 5212 * @return the index of the next character to be translated
4842 */ 5213 */
4843 int translateCharacter(JavaStringBuilder builder, String lexeme, int index) { 5214 int translateCharacter(JavaStringBuilder builder, String lexeme, int index) {
4844 int currentChar = lexeme.codeUnitAt(index); 5215 int currentChar = lexeme.codeUnitAt(index);
4845 if (currentChar != 0x5C) { 5216 if (currentChar != 0x5C) {
4846 builder.appendChar(currentChar); 5217 builder.appendChar(currentChar);
4847 return index + 1; 5218 return index + 1;
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
4933 return currentIndex + 4; 5304 return currentIndex + 4;
4934 } 5305 }
4935 } else { 5306 } else {
4936 builder.appendChar(currentChar); 5307 builder.appendChar(currentChar);
4937 } 5308 }
4938 return currentIndex + 1; 5309 return currentIndex + 1;
4939 } 5310 }
4940 5311
4941 /** 5312 /**
4942 * Validate that the given parameter list does not contain any field initializ ers. 5313 * Validate that the given parameter list does not contain any field initializ ers.
5314 *
4943 * @param parameterList the parameter list to be validated 5315 * @param parameterList the parameter list to be validated
4944 */ 5316 */
4945 void validateFormalParameterList(FormalParameterList parameterList) { 5317 void validateFormalParameterList(FormalParameterList parameterList) {
4946 for (FormalParameter parameter in parameterList.parameters) { 5318 for (FormalParameter parameter in parameterList.parameters) {
4947 if (parameter is FieldFormalParameter) { 5319 if (parameter is FieldFormalParameter) {
4948 reportError(ParserErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, ((par ameter as FieldFormalParameter)).identifier, []); 5320 reportError(ParserErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, ((par ameter as FieldFormalParameter)).identifier, []);
4949 } 5321 }
4950 } 5322 }
4951 } 5323 }
4952 5324
4953 /** 5325 /**
4954 * Validate that the given set of modifiers is appropriate for a class and ret urn the 'abstract' 5326 * Validate that the given set of modifiers is appropriate for a class and ret urn the 'abstract'
4955 * keyword if there is one. 5327 * keyword if there is one.
5328 *
4956 * @param modifiers the modifiers being validated 5329 * @param modifiers the modifiers being validated
4957 */ 5330 */
4958 Token validateModifiersForClass(Modifiers modifiers) { 5331 Token validateModifiersForClass(Modifiers modifiers) {
4959 validateModifiersForTopLevelDeclaration(modifiers); 5332 validateModifiersForTopLevelDeclaration(modifiers);
4960 if (modifiers.constKeyword != null) { 5333 if (modifiers.constKeyword != null) {
4961 reportError8(ParserErrorCode.CONST_CLASS, modifiers.constKeyword, []); 5334 reportError8(ParserErrorCode.CONST_CLASS, modifiers.constKeyword, []);
4962 } 5335 }
4963 if (modifiers.externalKeyword != null) { 5336 if (modifiers.externalKeyword != null) {
4964 reportError8(ParserErrorCode.EXTERNAL_CLASS, modifiers.externalKeyword, [] ); 5337 reportError8(ParserErrorCode.EXTERNAL_CLASS, modifiers.externalKeyword, [] );
4965 } 5338 }
4966 if (modifiers.finalKeyword != null) { 5339 if (modifiers.finalKeyword != null) {
4967 reportError8(ParserErrorCode.FINAL_CLASS, modifiers.finalKeyword, []); 5340 reportError8(ParserErrorCode.FINAL_CLASS, modifiers.finalKeyword, []);
4968 } 5341 }
4969 if (modifiers.varKeyword != null) { 5342 if (modifiers.varKeyword != null) {
4970 reportError8(ParserErrorCode.VAR_CLASS, modifiers.varKeyword, []); 5343 reportError8(ParserErrorCode.VAR_CLASS, modifiers.varKeyword, []);
4971 } 5344 }
4972 return modifiers.abstractKeyword; 5345 return modifiers.abstractKeyword;
4973 } 5346 }
4974 5347
4975 /** 5348 /**
4976 * Validate that the given set of modifiers is appropriate for a constructor a nd return the 5349 * Validate that the given set of modifiers is appropriate for a constructor a nd return the
4977 * 'const' keyword if there is one. 5350 * 'const' keyword if there is one.
5351 *
4978 * @param modifiers the modifiers being validated 5352 * @param modifiers the modifiers being validated
4979 * @return the 'const' or 'final' keyword associated with the constructor 5353 * @return the 'const' or 'final' keyword associated with the constructor
4980 */ 5354 */
4981 Token validateModifiersForConstructor(Modifiers modifiers) { 5355 Token validateModifiersForConstructor(Modifiers modifiers) {
4982 if (modifiers.abstractKeyword != null) { 5356 if (modifiers.abstractKeyword != null) {
4983 reportError7(ParserErrorCode.ABSTRACT_CLASS_MEMBER, []); 5357 reportError7(ParserErrorCode.ABSTRACT_CLASS_MEMBER, []);
4984 } 5358 }
4985 if (modifiers.finalKeyword != null) { 5359 if (modifiers.finalKeyword != null) {
4986 reportError8(ParserErrorCode.FINAL_CONSTRUCTOR, modifiers.finalKeyword, [] ); 5360 reportError8(ParserErrorCode.FINAL_CONSTRUCTOR, modifiers.finalKeyword, [] );
4987 } 5361 }
(...skipping 11 matching lines...) Expand all
4999 } 5373 }
5000 if (externalKeyword != null && factoryKeyword != null && factoryKeyword.offs et < externalKeyword.offset) { 5374 if (externalKeyword != null && factoryKeyword != null && factoryKeyword.offs et < externalKeyword.offset) {
5001 reportError8(ParserErrorCode.EXTERNAL_AFTER_FACTORY, externalKeyword, []); 5375 reportError8(ParserErrorCode.EXTERNAL_AFTER_FACTORY, externalKeyword, []);
5002 } 5376 }
5003 return constKeyword; 5377 return constKeyword;
5004 } 5378 }
5005 5379
5006 /** 5380 /**
5007 * Validate that the given set of modifiers is appropriate for a field and ret urn the 'final', 5381 * Validate that the given set of modifiers is appropriate for a field and ret urn the 'final',
5008 * 'const' or 'var' keyword if there is one. 5382 * 'const' or 'var' keyword if there is one.
5383 *
5009 * @param modifiers the modifiers being validated 5384 * @param modifiers the modifiers being validated
5010 * @return the 'final', 'const' or 'var' keyword associated with the field 5385 * @return the 'final', 'const' or 'var' keyword associated with the field
5011 */ 5386 */
5012 Token validateModifiersForField(Modifiers modifiers) { 5387 Token validateModifiersForField(Modifiers modifiers) {
5013 if (modifiers.abstractKeyword != null) { 5388 if (modifiers.abstractKeyword != null) {
5014 reportError7(ParserErrorCode.ABSTRACT_CLASS_MEMBER, []); 5389 reportError7(ParserErrorCode.ABSTRACT_CLASS_MEMBER, []);
5015 } 5390 }
5016 if (modifiers.externalKeyword != null) { 5391 if (modifiers.externalKeyword != null) {
5017 reportError8(ParserErrorCode.EXTERNAL_FIELD, modifiers.externalKeyword, [] ); 5392 reportError8(ParserErrorCode.EXTERNAL_FIELD, modifiers.externalKeyword, [] );
5018 } 5393 }
(...skipping 21 matching lines...) Expand all
5040 if (staticKeyword != null && finalKeyword.offset < staticKeyword.offset) { 5415 if (staticKeyword != null && finalKeyword.offset < staticKeyword.offset) {
5041 reportError8(ParserErrorCode.STATIC_AFTER_FINAL, staticKeyword, []); 5416 reportError8(ParserErrorCode.STATIC_AFTER_FINAL, staticKeyword, []);
5042 } 5417 }
5043 } else if (varKeyword != null && staticKeyword != null && varKeyword.offset < staticKeyword.offset) { 5418 } else if (varKeyword != null && staticKeyword != null && varKeyword.offset < staticKeyword.offset) {
5044 reportError8(ParserErrorCode.STATIC_AFTER_VAR, staticKeyword, []); 5419 reportError8(ParserErrorCode.STATIC_AFTER_VAR, staticKeyword, []);
5045 } 5420 }
5046 return lexicallyFirst([constKeyword, finalKeyword, varKeyword]); 5421 return lexicallyFirst([constKeyword, finalKeyword, varKeyword]);
5047 } 5422 }
5048 5423
5049 /** 5424 /**
5425 * Validate that the given set of modifiers is appropriate for a local functio n.
5426 *
5427 * @param modifiers the modifiers being validated
5428 */
5429 void validateModifiersForFunctionDeclarationStatement(Modifiers modifiers) {
5430 if (modifiers.abstractKeyword != null || modifiers.constKeyword != null || m odifiers.externalKeyword != null || modifiers.factoryKeyword != null || modifier s.finalKeyword != null || modifiers.staticKeyword != null || modifiers.varKeywor d != null) {
5431 reportError7(ParserErrorCode.LOCAL_FUNCTION_DECLARATION_MODIFIER, []);
5432 }
5433 }
5434
5435 /**
5050 * Validate that the given set of modifiers is appropriate for a getter, sette r, or method. 5436 * Validate that the given set of modifiers is appropriate for a getter, sette r, or method.
5437 *
5051 * @param modifiers the modifiers being validated 5438 * @param modifiers the modifiers being validated
5052 */ 5439 */
5053 void validateModifiersForGetterOrSetterOrMethod(Modifiers modifiers) { 5440 void validateModifiersForGetterOrSetterOrMethod(Modifiers modifiers) {
5054 if (modifiers.abstractKeyword != null) { 5441 if (modifiers.abstractKeyword != null) {
5055 reportError7(ParserErrorCode.ABSTRACT_CLASS_MEMBER, []); 5442 reportError7(ParserErrorCode.ABSTRACT_CLASS_MEMBER, []);
5056 } 5443 }
5057 if (modifiers.constKeyword != null) { 5444 if (modifiers.constKeyword != null) {
5058 reportError8(ParserErrorCode.CONST_METHOD, modifiers.constKeyword, []); 5445 reportError8(ParserErrorCode.CONST_METHOD, modifiers.constKeyword, []);
5059 } 5446 }
5060 if (modifiers.factoryKeyword != null) { 5447 if (modifiers.factoryKeyword != null) {
5061 reportError8(ParserErrorCode.NON_CONSTRUCTOR_FACTORY, modifiers.factoryKey word, []); 5448 reportError8(ParserErrorCode.NON_CONSTRUCTOR_FACTORY, modifiers.factoryKey word, []);
5062 } 5449 }
5063 if (modifiers.finalKeyword != null) { 5450 if (modifiers.finalKeyword != null) {
5064 reportError8(ParserErrorCode.FINAL_METHOD, modifiers.finalKeyword, []); 5451 reportError8(ParserErrorCode.FINAL_METHOD, modifiers.finalKeyword, []);
5065 } 5452 }
5066 if (modifiers.varKeyword != null) { 5453 if (modifiers.varKeyword != null) {
5067 reportError8(ParserErrorCode.VAR_RETURN_TYPE, modifiers.varKeyword, []); 5454 reportError8(ParserErrorCode.VAR_RETURN_TYPE, modifiers.varKeyword, []);
5068 } 5455 }
5069 Token externalKeyword = modifiers.externalKeyword; 5456 Token externalKeyword = modifiers.externalKeyword;
5070 Token staticKeyword = modifiers.staticKeyword; 5457 Token staticKeyword = modifiers.staticKeyword;
5071 if (externalKeyword != null && staticKeyword != null && staticKeyword.offset < externalKeyword.offset) { 5458 if (externalKeyword != null && staticKeyword != null && staticKeyword.offset < externalKeyword.offset) {
5072 reportError8(ParserErrorCode.EXTERNAL_AFTER_STATIC, externalKeyword, []); 5459 reportError8(ParserErrorCode.EXTERNAL_AFTER_STATIC, externalKeyword, []);
5073 } 5460 }
5074 } 5461 }
5075 5462
5076 /** 5463 /**
5077 * Validate that the given set of modifiers is appropriate for a getter, sette r, or method. 5464 * Validate that the given set of modifiers is appropriate for a getter, sette r, or method.
5465 *
5078 * @param modifiers the modifiers being validated 5466 * @param modifiers the modifiers being validated
5079 */ 5467 */
5080 void validateModifiersForOperator(Modifiers modifiers) { 5468 void validateModifiersForOperator(Modifiers modifiers) {
5081 if (modifiers.abstractKeyword != null) { 5469 if (modifiers.abstractKeyword != null) {
5082 reportError7(ParserErrorCode.ABSTRACT_CLASS_MEMBER, []); 5470 reportError7(ParserErrorCode.ABSTRACT_CLASS_MEMBER, []);
5083 } 5471 }
5084 if (modifiers.constKeyword != null) { 5472 if (modifiers.constKeyword != null) {
5085 reportError8(ParserErrorCode.CONST_METHOD, modifiers.constKeyword, []); 5473 reportError8(ParserErrorCode.CONST_METHOD, modifiers.constKeyword, []);
5086 } 5474 }
5087 if (modifiers.factoryKeyword != null) { 5475 if (modifiers.factoryKeyword != null) {
5088 reportError8(ParserErrorCode.NON_CONSTRUCTOR_FACTORY, modifiers.factoryKey word, []); 5476 reportError8(ParserErrorCode.NON_CONSTRUCTOR_FACTORY, modifiers.factoryKey word, []);
5089 } 5477 }
5090 if (modifiers.finalKeyword != null) { 5478 if (modifiers.finalKeyword != null) {
5091 reportError8(ParserErrorCode.FINAL_METHOD, modifiers.finalKeyword, []); 5479 reportError8(ParserErrorCode.FINAL_METHOD, modifiers.finalKeyword, []);
5092 } 5480 }
5093 if (modifiers.staticKeyword != null) { 5481 if (modifiers.staticKeyword != null) {
5094 reportError8(ParserErrorCode.STATIC_OPERATOR, modifiers.staticKeyword, []) ; 5482 reportError8(ParserErrorCode.STATIC_OPERATOR, modifiers.staticKeyword, []) ;
5095 } 5483 }
5096 if (modifiers.varKeyword != null) { 5484 if (modifiers.varKeyword != null) {
5097 reportError8(ParserErrorCode.VAR_RETURN_TYPE, modifiers.varKeyword, []); 5485 reportError8(ParserErrorCode.VAR_RETURN_TYPE, modifiers.varKeyword, []);
5098 } 5486 }
5099 } 5487 }
5100 5488
5101 /** 5489 /**
5102 * Validate that the given set of modifiers is appropriate for a top-level dec laration. 5490 * Validate that the given set of modifiers is appropriate for a top-level dec laration.
5491 *
5103 * @param modifiers the modifiers being validated 5492 * @param modifiers the modifiers being validated
5104 */ 5493 */
5105 void validateModifiersForTopLevelDeclaration(Modifiers modifiers) { 5494 void validateModifiersForTopLevelDeclaration(Modifiers modifiers) {
5106 if (modifiers.factoryKeyword != null) { 5495 if (modifiers.factoryKeyword != null) {
5107 reportError8(ParserErrorCode.FACTORY_TOP_LEVEL_DECLARATION, modifiers.fact oryKeyword, []); 5496 reportError8(ParserErrorCode.FACTORY_TOP_LEVEL_DECLARATION, modifiers.fact oryKeyword, []);
5108 } 5497 }
5109 if (modifiers.staticKeyword != null) { 5498 if (modifiers.staticKeyword != null) {
5110 reportError8(ParserErrorCode.STATIC_TOP_LEVEL_DECLARATION, modifiers.stati cKeyword, []); 5499 reportError8(ParserErrorCode.STATIC_TOP_LEVEL_DECLARATION, modifiers.stati cKeyword, []);
5111 } 5500 }
5112 } 5501 }
5113 5502
5114 /** 5503 /**
5115 * Validate that the given set of modifiers is appropriate for a top-level fun ction. 5504 * Validate that the given set of modifiers is appropriate for a top-level fun ction.
5505 *
5116 * @param modifiers the modifiers being validated 5506 * @param modifiers the modifiers being validated
5117 */ 5507 */
5118 void validateModifiersForTopLevelFunction(Modifiers modifiers) { 5508 void validateModifiersForTopLevelFunction(Modifiers modifiers) {
5119 validateModifiersForTopLevelDeclaration(modifiers); 5509 validateModifiersForTopLevelDeclaration(modifiers);
5120 if (modifiers.abstractKeyword != null) { 5510 if (modifiers.abstractKeyword != null) {
5121 reportError7(ParserErrorCode.ABSTRACT_TOP_LEVEL_FUNCTION, []); 5511 reportError7(ParserErrorCode.ABSTRACT_TOP_LEVEL_FUNCTION, []);
5122 } 5512 }
5123 if (modifiers.constKeyword != null) { 5513 if (modifiers.constKeyword != null) {
5124 reportError8(ParserErrorCode.CONST_CLASS, modifiers.constKeyword, []); 5514 reportError8(ParserErrorCode.CONST_CLASS, modifiers.constKeyword, []);
5125 } 5515 }
5126 if (modifiers.finalKeyword != null) { 5516 if (modifiers.finalKeyword != null) {
5127 reportError8(ParserErrorCode.FINAL_CLASS, modifiers.finalKeyword, []); 5517 reportError8(ParserErrorCode.FINAL_CLASS, modifiers.finalKeyword, []);
5128 } 5518 }
5129 if (modifiers.varKeyword != null) { 5519 if (modifiers.varKeyword != null) {
5130 reportError8(ParserErrorCode.VAR_RETURN_TYPE, modifiers.varKeyword, []); 5520 reportError8(ParserErrorCode.VAR_RETURN_TYPE, modifiers.varKeyword, []);
5131 } 5521 }
5132 } 5522 }
5133 5523
5134 /** 5524 /**
5135 * Validate that the given set of modifiers is appropriate for a field and ret urn the 'final', 5525 * Validate that the given set of modifiers is appropriate for a field and ret urn the 'final',
5136 * 'const' or 'var' keyword if there is one. 5526 * 'const' or 'var' keyword if there is one.
5527 *
5137 * @param modifiers the modifiers being validated 5528 * @param modifiers the modifiers being validated
5138 * @return the 'final', 'const' or 'var' keyword associated with the field 5529 * @return the 'final', 'const' or 'var' keyword associated with the field
5139 */ 5530 */
5140 Token validateModifiersForTopLevelVariable(Modifiers modifiers) { 5531 Token validateModifiersForTopLevelVariable(Modifiers modifiers) {
5141 validateModifiersForTopLevelDeclaration(modifiers); 5532 validateModifiersForTopLevelDeclaration(modifiers);
5142 if (modifiers.abstractKeyword != null) { 5533 if (modifiers.abstractKeyword != null) {
5143 reportError7(ParserErrorCode.ABSTRACT_TOP_LEVEL_VARIABLE, []); 5534 reportError7(ParserErrorCode.ABSTRACT_TOP_LEVEL_VARIABLE, []);
5144 } 5535 }
5145 if (modifiers.externalKeyword != null) { 5536 if (modifiers.externalKeyword != null) {
5146 reportError8(ParserErrorCode.EXTERNAL_FIELD, modifiers.externalKeyword, [] ); 5537 reportError8(ParserErrorCode.EXTERNAL_FIELD, modifiers.externalKeyword, [] );
(...skipping 12 matching lines...) Expand all
5159 if (varKeyword != null) { 5550 if (varKeyword != null) {
5160 reportError8(ParserErrorCode.FINAL_AND_VAR, varKeyword, []); 5551 reportError8(ParserErrorCode.FINAL_AND_VAR, varKeyword, []);
5161 } 5552 }
5162 } 5553 }
5163 return lexicallyFirst([constKeyword, finalKeyword, varKeyword]); 5554 return lexicallyFirst([constKeyword, finalKeyword, varKeyword]);
5164 } 5555 }
5165 5556
5166 /** 5557 /**
5167 * Validate that the given set of modifiers is appropriate for a class and ret urn the 'abstract' 5558 * Validate that the given set of modifiers is appropriate for a class and ret urn the 'abstract'
5168 * keyword if there is one. 5559 * keyword if there is one.
5560 *
5169 * @param modifiers the modifiers being validated 5561 * @param modifiers the modifiers being validated
5170 */ 5562 */
5171 void validateModifiersForTypedef(Modifiers modifiers) { 5563 void validateModifiersForTypedef(Modifiers modifiers) {
5172 validateModifiersForTopLevelDeclaration(modifiers); 5564 validateModifiersForTopLevelDeclaration(modifiers);
5173 if (modifiers.abstractKeyword != null) { 5565 if (modifiers.abstractKeyword != null) {
5174 reportError8(ParserErrorCode.ABSTRACT_TYPEDEF, modifiers.abstractKeyword, []); 5566 reportError8(ParserErrorCode.ABSTRACT_TYPEDEF, modifiers.abstractKeyword, []);
5175 } 5567 }
5176 if (modifiers.constKeyword != null) { 5568 if (modifiers.constKeyword != null) {
5177 reportError8(ParserErrorCode.CONST_TYPEDEF, modifiers.constKeyword, []); 5569 reportError8(ParserErrorCode.CONST_TYPEDEF, modifiers.constKeyword, []);
5178 } 5570 }
5179 if (modifiers.externalKeyword != null) { 5571 if (modifiers.externalKeyword != null) {
5180 reportError8(ParserErrorCode.EXTERNAL_TYPEDEF, modifiers.externalKeyword, []); 5572 reportError8(ParserErrorCode.EXTERNAL_TYPEDEF, modifiers.externalKeyword, []);
5181 } 5573 }
5182 if (modifiers.finalKeyword != null) { 5574 if (modifiers.finalKeyword != null) {
5183 reportError8(ParserErrorCode.FINAL_TYPEDEF, modifiers.finalKeyword, []); 5575 reportError8(ParserErrorCode.FINAL_TYPEDEF, modifiers.finalKeyword, []);
5184 } 5576 }
5185 if (modifiers.varKeyword != null) { 5577 if (modifiers.varKeyword != null) {
5186 reportError8(ParserErrorCode.VAR_TYPEDEF, modifiers.varKeyword, []); 5578 reportError8(ParserErrorCode.VAR_TYPEDEF, modifiers.varKeyword, []);
5187 } 5579 }
5188 } 5580 }
5189 } 5581 }
5190 class KeywordToken_10 extends KeywordToken { 5582 class KeywordToken_11 extends KeywordToken {
5191 KeywordToken_10(Keyword arg0, int arg1) : super(arg0, arg1); 5583 KeywordToken_11(Keyword arg0, int arg1) : super(arg0, arg1);
5192 int get length => 0; 5584 int get length => 0;
5193 } 5585 }
5194 class AnalysisErrorListener_11 implements AnalysisErrorListener { 5586 class AnalysisErrorListener_12 implements AnalysisErrorListener {
5195 List<bool> errorFound; 5587 List<bool> errorFound;
5196 AnalysisErrorListener_11(this.errorFound); 5588 AnalysisErrorListener_12(this.errorFound);
5197 void onError(AnalysisError error) { 5589 void onError(AnalysisError error) {
5198 errorFound[0] = true; 5590 errorFound[0] = true;
5199 } 5591 }
5200 } 5592 }
5201 /** 5593 /**
5202 * The enumeration `ParserErrorCode` defines the error codes used for errors det ected by the 5594 * The enumeration `ParserErrorCode` defines the error codes used for errors det ected by the
5203 * parser. The convention for this class is for the name of the error code to in dicate the problem 5595 * parser. The convention for this class is for the name of the error code to in dicate the problem
5204 * that caused the error to be generated and for the error message to explain wh at is wrong and, 5596 * that caused the error to be generated and for the error message to explain wh at is wrong and,
5205 * when appropriate, how the problem can be corrected. 5597 * when appropriate, how the problem can be corrected.
5598 *
5206 * @coverage dart.engine.parser 5599 * @coverage dart.engine.parser
5207 */ 5600 */
5208 class ParserErrorCode implements Comparable<ParserErrorCode>, ErrorCode { 5601 class ParserErrorCode implements Comparable<ParserErrorCode>, ErrorCode {
5209 static final ParserErrorCode ABSTRACT_CLASS_MEMBER = new ParserErrorCode.con2( 'ABSTRACT_CLASS_MEMBER', 0, "Members of classes cannot be declared to be 'abstra ct'"); 5602 static final ParserErrorCode ABSTRACT_CLASS_MEMBER = new ParserErrorCode.con2( 'ABSTRACT_CLASS_MEMBER', 0, "Members of classes cannot be declared to be 'abstra ct'");
5210 static final ParserErrorCode ABSTRACT_STATIC_METHOD = new ParserErrorCode.con2 ('ABSTRACT_STATIC_METHOD', 1, "Static methods cannot be declared to be 'abstract '"); 5603 static final ParserErrorCode ABSTRACT_STATIC_METHOD = new ParserErrorCode.con2 ('ABSTRACT_STATIC_METHOD', 1, "Static methods cannot be declared to be 'abstract '");
5211 static final ParserErrorCode ABSTRACT_TOP_LEVEL_FUNCTION = new ParserErrorCode .con2('ABSTRACT_TOP_LEVEL_FUNCTION', 2, "Top-level functions cannot be declared to be 'abstract'"); 5604 static final ParserErrorCode ABSTRACT_TOP_LEVEL_FUNCTION = new ParserErrorCode .con2('ABSTRACT_TOP_LEVEL_FUNCTION', 2, "Top-level functions cannot be declared to be 'abstract'");
5212 static final ParserErrorCode ABSTRACT_TOP_LEVEL_VARIABLE = new ParserErrorCode .con2('ABSTRACT_TOP_LEVEL_VARIABLE', 3, "Top-level variables cannot be declared to be 'abstract'"); 5605 static final ParserErrorCode ABSTRACT_TOP_LEVEL_VARIABLE = new ParserErrorCode .con2('ABSTRACT_TOP_LEVEL_VARIABLE', 3, "Top-level variables cannot be declared to be 'abstract'");
5213 static final ParserErrorCode ABSTRACT_TYPEDEF = new ParserErrorCode.con2('ABST RACT_TYPEDEF', 4, "Type aliases cannot be declared to be 'abstract'"); 5606 static final ParserErrorCode ABSTRACT_TYPEDEF = new ParserErrorCode.con2('ABST RACT_TYPEDEF', 4, "Type aliases cannot be declared to be 'abstract'");
5214 static final ParserErrorCode BREAK_OUTSIDE_OF_LOOP = new ParserErrorCode.con2( 'BREAK_OUTSIDE_OF_LOOP', 5, "A break statement cannot be used outside of a loop or switch statement"); 5607 static final ParserErrorCode BREAK_OUTSIDE_OF_LOOP = new ParserErrorCode.con2( 'BREAK_OUTSIDE_OF_LOOP', 5, "A break statement cannot be used outside of a loop or switch statement");
5215 static final ParserErrorCode CONST_AND_FINAL = new ParserErrorCode.con2('CONST _AND_FINAL', 6, "Members cannot be declared to be both 'const' and 'final'"); 5608 static final ParserErrorCode CONST_AND_FINAL = new ParserErrorCode.con2('CONST _AND_FINAL', 6, "Members cannot be declared to be both 'const' and 'final'");
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
5260 static final ParserErrorCode IMPLEMENTS_BEFORE_WITH = new ParserErrorCode.con2 ('IMPLEMENTS_BEFORE_WITH', 51, "The with clause must be before the implements cl ause"); 5653 static final ParserErrorCode IMPLEMENTS_BEFORE_WITH = new ParserErrorCode.con2 ('IMPLEMENTS_BEFORE_WITH', 51, "The with clause must be before the implements cl ause");
5261 static final ParserErrorCode IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE = new Parse rErrorCode.con2('IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE', 52, "Import directives must preceed part directives"); 5654 static final ParserErrorCode IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE = new Parse rErrorCode.con2('IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE', 52, "Import directives must preceed part directives");
5262 static final ParserErrorCode INITIALIZED_VARIABLE_IN_FOR_EACH = new ParserErro rCode.con2('INITIALIZED_VARIABLE_IN_FOR_EACH', 53, "The loop variable in a for-e ach loop cannot be initialized"); 5655 static final ParserErrorCode INITIALIZED_VARIABLE_IN_FOR_EACH = new ParserErro rCode.con2('INITIALIZED_VARIABLE_IN_FOR_EACH', 53, "The loop variable in a for-e ach loop cannot be initialized");
5263 static final ParserErrorCode INVALID_CODE_POINT = new ParserErrorCode.con2('IN VALID_CODE_POINT', 54, "The escape sequence '%s' is not a valid code point"); 5656 static final ParserErrorCode INVALID_CODE_POINT = new ParserErrorCode.con2('IN VALID_CODE_POINT', 54, "The escape sequence '%s' is not a valid code point");
5264 static final ParserErrorCode INVALID_COMMENT_REFERENCE = new ParserErrorCode.c on2('INVALID_COMMENT_REFERENCE', 55, "Comment references should contain a possib ly prefixed identifier and can start with 'new', but should not contain anything else"); 5657 static final ParserErrorCode INVALID_COMMENT_REFERENCE = new ParserErrorCode.c on2('INVALID_COMMENT_REFERENCE', 55, "Comment references should contain a possib ly prefixed identifier and can start with 'new', but should not contain anything else");
5265 static final ParserErrorCode INVALID_HEX_ESCAPE = new ParserErrorCode.con2('IN VALID_HEX_ESCAPE', 56, "An escape sequence starting with '\\x' must be followed by 2 hexidecimal digits"); 5658 static final ParserErrorCode INVALID_HEX_ESCAPE = new ParserErrorCode.con2('IN VALID_HEX_ESCAPE', 56, "An escape sequence starting with '\\x' must be followed by 2 hexidecimal digits");
5266 static final ParserErrorCode INVALID_OPERATOR = new ParserErrorCode.con2('INVA LID_OPERATOR', 57, "The string '%s' is not a valid operator"); 5659 static final ParserErrorCode INVALID_OPERATOR = new ParserErrorCode.con2('INVA LID_OPERATOR', 57, "The string '%s' is not a valid operator");
5267 static final ParserErrorCode INVALID_OPERATOR_FOR_SUPER = new ParserErrorCode. con2('INVALID_OPERATOR_FOR_SUPER', 58, "The operator '%s' cannot be used with 's uper'"); 5660 static final ParserErrorCode INVALID_OPERATOR_FOR_SUPER = new ParserErrorCode. con2('INVALID_OPERATOR_FOR_SUPER', 58, "The operator '%s' cannot be used with 's uper'");
5268 static final ParserErrorCode INVALID_UNICODE_ESCAPE = new ParserErrorCode.con2 ('INVALID_UNICODE_ESCAPE', 59, "An escape sequence starting with '\\u' must be f ollowed by 4 hexidecimal digits or from 1 to 6 digits between '{' and '}'"); 5661 static final ParserErrorCode INVALID_UNICODE_ESCAPE = new ParserErrorCode.con2 ('INVALID_UNICODE_ESCAPE', 59, "An escape sequence starting with '\\u' must be f ollowed by 4 hexidecimal digits or from 1 to 6 digits between '{' and '}'");
5269 static final ParserErrorCode LIBRARY_DIRECTIVE_NOT_FIRST = new ParserErrorCode .con2('LIBRARY_DIRECTIVE_NOT_FIRST', 60, "The library directive must appear befo re all other directives"); 5662 static final ParserErrorCode LIBRARY_DIRECTIVE_NOT_FIRST = new ParserErrorCode .con2('LIBRARY_DIRECTIVE_NOT_FIRST', 60, "The library directive must appear befo re all other directives");
5270 static final ParserErrorCode MISSING_ASSIGNABLE_SELECTOR = new ParserErrorCode .con2('MISSING_ASSIGNABLE_SELECTOR', 61, "Missing selector such as \".<identifie r>\" or \"[0]\""); 5663 static final ParserErrorCode LOCAL_FUNCTION_DECLARATION_MODIFIER = new ParserE rrorCode.con2('LOCAL_FUNCTION_DECLARATION_MODIFIER', 61, "Local function declara tions cannot specify any modifier");
5271 static final ParserErrorCode MISSING_CATCH_OR_FINALLY = new ParserErrorCode.co n2('MISSING_CATCH_OR_FINALLY', 62, "A try statement must have either a catch or finally clause"); 5664 static final ParserErrorCode MISSING_ASSIGNABLE_SELECTOR = new ParserErrorCode .con2('MISSING_ASSIGNABLE_SELECTOR', 62, "Missing selector such as \".<identifie r>\" or \"[0]\"");
5272 static final ParserErrorCode MISSING_CLASS_BODY = new ParserErrorCode.con2('MI SSING_CLASS_BODY', 63, "A class definition must have a body, even if it is empty "); 5665 static final ParserErrorCode MISSING_CATCH_OR_FINALLY = new ParserErrorCode.co n2('MISSING_CATCH_OR_FINALLY', 63, "A try statement must have either a catch or finally clause");
5273 static final ParserErrorCode MISSING_CLOSING_PARENTHESIS = new ParserErrorCode .con2('MISSING_CLOSING_PARENTHESIS', 64, "The closing parenthesis is missing"); 5666 static final ParserErrorCode MISSING_CLASS_BODY = new ParserErrorCode.con2('MI SSING_CLASS_BODY', 64, "A class definition must have a body, even if it is empty ");
5274 static final ParserErrorCode MISSING_CONST_FINAL_VAR_OR_TYPE = new ParserError Code.con2('MISSING_CONST_FINAL_VAR_OR_TYPE', 65, "Variables must be declared usi ng the keywords 'const', 'final', 'var' or a type name"); 5667 static final ParserErrorCode MISSING_CLOSING_PARENTHESIS = new ParserErrorCode .con2('MISSING_CLOSING_PARENTHESIS', 65, "The closing parenthesis is missing");
5275 static final ParserErrorCode MISSING_EXPRESSION_IN_THROW = new ParserErrorCode .con2('MISSING_EXPRESSION_IN_THROW', 66, "Throw expressions must compute the obj ect to be thrown"); 5668 static final ParserErrorCode MISSING_CONST_FINAL_VAR_OR_TYPE = new ParserError Code.con2('MISSING_CONST_FINAL_VAR_OR_TYPE', 66, "Variables must be declared usi ng the keywords 'const', 'final', 'var' or a type name");
5276 static final ParserErrorCode MISSING_FUNCTION_BODY = new ParserErrorCode.con2( 'MISSING_FUNCTION_BODY', 67, "A function body must be provided"); 5669 static final ParserErrorCode MISSING_EXPRESSION_IN_THROW = new ParserErrorCode .con2('MISSING_EXPRESSION_IN_THROW', 67, "Throw expressions must compute the obj ect to be thrown");
5277 static final ParserErrorCode MISSING_FUNCTION_PARAMETERS = new ParserErrorCode .con2('MISSING_FUNCTION_PARAMETERS', 68, "Functions must have an explicit list o f parameters"); 5670 static final ParserErrorCode MISSING_FUNCTION_BODY = new ParserErrorCode.con2( 'MISSING_FUNCTION_BODY', 68, "A function body must be provided");
5278 static final ParserErrorCode MISSING_IDENTIFIER = new ParserErrorCode.con2('MI SSING_IDENTIFIER', 69, "Expected an identifier"); 5671 static final ParserErrorCode MISSING_FUNCTION_PARAMETERS = new ParserErrorCode .con2('MISSING_FUNCTION_PARAMETERS', 69, "Functions must have an explicit list o f parameters");
5279 static final ParserErrorCode MISSING_KEYWORD_OPERATOR = new ParserErrorCode.co n2('MISSING_KEYWORD_OPERATOR', 70, "Operator declarations must be preceeded by t he keyword 'operator'"); 5672 static final ParserErrorCode MISSING_IDENTIFIER = new ParserErrorCode.con2('MI SSING_IDENTIFIER', 70, "Expected an identifier");
5280 static final ParserErrorCode MISSING_NAME_IN_LIBRARY_DIRECTIVE = new ParserErr orCode.con2('MISSING_NAME_IN_LIBRARY_DIRECTIVE', 71, "Library directives must in clude a library name"); 5673 static final ParserErrorCode MISSING_KEYWORD_OPERATOR = new ParserErrorCode.co n2('MISSING_KEYWORD_OPERATOR', 71, "Operator declarations must be preceeded by t he keyword 'operator'");
5281 static final ParserErrorCode MISSING_NAME_IN_PART_OF_DIRECTIVE = new ParserErr orCode.con2('MISSING_NAME_IN_PART_OF_DIRECTIVE', 72, "Library directives must in clude a library name"); 5674 static final ParserErrorCode MISSING_NAME_IN_LIBRARY_DIRECTIVE = new ParserErr orCode.con2('MISSING_NAME_IN_LIBRARY_DIRECTIVE', 72, "Library directives must in clude a library name");
5282 static final ParserErrorCode MISSING_STATEMENT = new ParserErrorCode.con2('MIS SING_STATEMENT', 73, "Expected a statement"); 5675 static final ParserErrorCode MISSING_NAME_IN_PART_OF_DIRECTIVE = new ParserErr orCode.con2('MISSING_NAME_IN_PART_OF_DIRECTIVE', 73, "Library directives must in clude a library name");
5283 static final ParserErrorCode MISSING_TERMINATOR_FOR_PARAMETER_GROUP = new Pars erErrorCode.con2('MISSING_TERMINATOR_FOR_PARAMETER_GROUP', 74, "There is no '%s' to close the parameter group"); 5676 static final ParserErrorCode MISSING_STATEMENT = new ParserErrorCode.con2('MIS SING_STATEMENT', 74, "Expected a statement");
5284 static final ParserErrorCode MISSING_TYPEDEF_PARAMETERS = new ParserErrorCode. con2('MISSING_TYPEDEF_PARAMETERS', 75, "Type aliases for functions must have an explicit list of parameters"); 5677 static final ParserErrorCode MISSING_TERMINATOR_FOR_PARAMETER_GROUP = new Pars erErrorCode.con2('MISSING_TERMINATOR_FOR_PARAMETER_GROUP', 75, "There is no '%s' to close the parameter group");
5285 static final ParserErrorCode MISSING_VARIABLE_IN_FOR_EACH = new ParserErrorCod e.con2('MISSING_VARIABLE_IN_FOR_EACH', 76, "A loop variable must be declared in a for-each loop before the 'in', but none were found"); 5678 static final ParserErrorCode MISSING_TYPEDEF_PARAMETERS = new ParserErrorCode. con2('MISSING_TYPEDEF_PARAMETERS', 76, "Type aliases for functions must have an explicit list of parameters");
5286 static final ParserErrorCode MIXED_PARAMETER_GROUPS = new ParserErrorCode.con2 ('MIXED_PARAMETER_GROUPS', 77, "Cannot have both positional and named parameters in a single parameter list"); 5679 static final ParserErrorCode MISSING_VARIABLE_IN_FOR_EACH = new ParserErrorCod e.con2('MISSING_VARIABLE_IN_FOR_EACH', 77, "A loop variable must be declared in a for-each loop before the 'in', but none were found");
5287 static final ParserErrorCode MULTIPLE_EXTENDS_CLAUSES = new ParserErrorCode.co n2('MULTIPLE_EXTENDS_CLAUSES', 78, "Each class definition can have at most one e xtends clause"); 5680 static final ParserErrorCode MIXED_PARAMETER_GROUPS = new ParserErrorCode.con2 ('MIXED_PARAMETER_GROUPS', 78, "Cannot have both positional and named parameters in a single parameter list");
5288 static final ParserErrorCode MULTIPLE_IMPLEMENTS_CLAUSES = new ParserErrorCode .con2('MULTIPLE_IMPLEMENTS_CLAUSES', 79, "Each class definition can have at most one implements clause"); 5681 static final ParserErrorCode MULTIPLE_EXTENDS_CLAUSES = new ParserErrorCode.co n2('MULTIPLE_EXTENDS_CLAUSES', 79, "Each class definition can have at most one e xtends clause");
5289 static final ParserErrorCode MULTIPLE_LIBRARY_DIRECTIVES = new ParserErrorCode .con2('MULTIPLE_LIBRARY_DIRECTIVES', 80, "Only one library directive may be decl ared in a file"); 5682 static final ParserErrorCode MULTIPLE_IMPLEMENTS_CLAUSES = new ParserErrorCode .con2('MULTIPLE_IMPLEMENTS_CLAUSES', 80, "Each class definition can have at most one implements clause");
5290 static final ParserErrorCode MULTIPLE_NAMED_PARAMETER_GROUPS = new ParserError Code.con2('MULTIPLE_NAMED_PARAMETER_GROUPS', 81, "Cannot have multiple groups of named parameters in a single parameter list"); 5683 static final ParserErrorCode MULTIPLE_LIBRARY_DIRECTIVES = new ParserErrorCode .con2('MULTIPLE_LIBRARY_DIRECTIVES', 81, "Only one library directive may be decl ared in a file");
5291 static final ParserErrorCode MULTIPLE_PART_OF_DIRECTIVES = new ParserErrorCode .con2('MULTIPLE_PART_OF_DIRECTIVES', 82, "Only one part-of directive may be decl ared in a file"); 5684 static final ParserErrorCode MULTIPLE_NAMED_PARAMETER_GROUPS = new ParserError Code.con2('MULTIPLE_NAMED_PARAMETER_GROUPS', 82, "Cannot have multiple groups of named parameters in a single parameter list");
5292 static final ParserErrorCode MULTIPLE_POSITIONAL_PARAMETER_GROUPS = new Parser ErrorCode.con2('MULTIPLE_POSITIONAL_PARAMETER_GROUPS', 83, "Cannot have multiple groups of positional parameters in a single parameter list"); 5685 static final ParserErrorCode MULTIPLE_PART_OF_DIRECTIVES = new ParserErrorCode .con2('MULTIPLE_PART_OF_DIRECTIVES', 83, "Only one part-of directive may be decl ared in a file");
5293 static final ParserErrorCode MULTIPLE_VARIABLES_IN_FOR_EACH = new ParserErrorC ode.con2('MULTIPLE_VARIABLES_IN_FOR_EACH', 84, "A single loop variable must be d eclared in a for-each loop before the 'in', but %s were found"); 5686 static final ParserErrorCode MULTIPLE_POSITIONAL_PARAMETER_GROUPS = new Parser ErrorCode.con2('MULTIPLE_POSITIONAL_PARAMETER_GROUPS', 84, "Cannot have multiple groups of positional parameters in a single parameter list");
5294 static final ParserErrorCode MULTIPLE_WITH_CLAUSES = new ParserErrorCode.con2( 'MULTIPLE_WITH_CLAUSES', 85, "Each class definition can have at most one with cl ause"); 5687 static final ParserErrorCode MULTIPLE_VARIABLES_IN_FOR_EACH = new ParserErrorC ode.con2('MULTIPLE_VARIABLES_IN_FOR_EACH', 85, "A single loop variable must be d eclared in a for-each loop before the 'in', but %s were found");
5295 static final ParserErrorCode NAMED_FUNCTION_EXPRESSION = new ParserErrorCode.c on2('NAMED_FUNCTION_EXPRESSION', 86, "Function expressions cannot be named"); 5688 static final ParserErrorCode MULTIPLE_WITH_CLAUSES = new ParserErrorCode.con2( 'MULTIPLE_WITH_CLAUSES', 86, "Each class definition can have at most one with cl ause");
5296 static final ParserErrorCode NAMED_PARAMETER_OUTSIDE_GROUP = new ParserErrorCo de.con2('NAMED_PARAMETER_OUTSIDE_GROUP', 87, "Named parameters must be enclosed in curly braces ('{' and '}')"); 5689 static final ParserErrorCode NAMED_FUNCTION_EXPRESSION = new ParserErrorCode.c on2('NAMED_FUNCTION_EXPRESSION', 87, "Function expressions cannot be named");
5297 static final ParserErrorCode NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE = new Parser ErrorCode.con2('NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE', 88, "Native functions can only be declared in the SDK and code that is loaded through native extensions") ; 5690 static final ParserErrorCode NAMED_PARAMETER_OUTSIDE_GROUP = new ParserErrorCo de.con2('NAMED_PARAMETER_OUTSIDE_GROUP', 88, "Named parameters must be enclosed in curly braces ('{' and '}')");
5298 static final ParserErrorCode NON_CONSTRUCTOR_FACTORY = new ParserErrorCode.con 2('NON_CONSTRUCTOR_FACTORY', 89, "Only constructors can be declared to be a 'fac tory'"); 5691 static final ParserErrorCode NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE = new Parser ErrorCode.con2('NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE', 89, "Native functions can only be declared in the SDK and code that is loaded through native extensions") ;
5299 static final ParserErrorCode NON_IDENTIFIER_LIBRARY_NAME = new ParserErrorCode .con2('NON_IDENTIFIER_LIBRARY_NAME', 90, "The name of a library must be an ident ifier"); 5692 static final ParserErrorCode NON_CONSTRUCTOR_FACTORY = new ParserErrorCode.con 2('NON_CONSTRUCTOR_FACTORY', 90, "Only constructors can be declared to be a 'fac tory'");
5300 static final ParserErrorCode NON_PART_OF_DIRECTIVE_IN_PART = new ParserErrorCo de.con2('NON_PART_OF_DIRECTIVE_IN_PART', 91, "The part-of directive must be the only directive in a part"); 5693 static final ParserErrorCode NON_IDENTIFIER_LIBRARY_NAME = new ParserErrorCode .con2('NON_IDENTIFIER_LIBRARY_NAME', 91, "The name of a library must be an ident ifier");
5301 static final ParserErrorCode NON_USER_DEFINABLE_OPERATOR = new ParserErrorCode .con2('NON_USER_DEFINABLE_OPERATOR', 92, "The operator '%s' is not user definabl e"); 5694 static final ParserErrorCode NON_PART_OF_DIRECTIVE_IN_PART = new ParserErrorCo de.con2('NON_PART_OF_DIRECTIVE_IN_PART', 92, "The part-of directive must be the only directive in a part");
5302 static final ParserErrorCode POSITIONAL_AFTER_NAMED_ARGUMENT = new ParserError Code.con2('POSITIONAL_AFTER_NAMED_ARGUMENT', 93, "Positional arguments must occu r before named arguments"); 5695 static final ParserErrorCode NON_USER_DEFINABLE_OPERATOR = new ParserErrorCode .con2('NON_USER_DEFINABLE_OPERATOR', 93, "The operator '%s' is not user definabl e");
5303 static final ParserErrorCode POSITIONAL_PARAMETER_OUTSIDE_GROUP = new ParserEr rorCode.con2('POSITIONAL_PARAMETER_OUTSIDE_GROUP', 94, "Positional parameters mu st be enclosed in square brackets ('[' and ']')"); 5696 static final ParserErrorCode NORMAL_BEFORE_OPTIONAL_PARAMETERS = new ParserErr orCode.con2('NORMAL_BEFORE_OPTIONAL_PARAMETERS', 94, "Normal parameters must occ ur before optional parameters");
5304 static final ParserErrorCode STATIC_AFTER_CONST = new ParserErrorCode.con2('ST ATIC_AFTER_CONST', 95, "The modifier 'static' should be before the modifier 'con st'"); 5697 static final ParserErrorCode POSITIONAL_AFTER_NAMED_ARGUMENT = new ParserError Code.con2('POSITIONAL_AFTER_NAMED_ARGUMENT', 95, "Positional arguments must occu r before named arguments");
5305 static final ParserErrorCode STATIC_AFTER_FINAL = new ParserErrorCode.con2('ST ATIC_AFTER_FINAL', 96, "The modifier 'static' should be before the modifier 'fin al'"); 5698 static final ParserErrorCode POSITIONAL_PARAMETER_OUTSIDE_GROUP = new ParserEr rorCode.con2('POSITIONAL_PARAMETER_OUTSIDE_GROUP', 96, "Positional parameters mu st be enclosed in square brackets ('[' and ']')");
5306 static final ParserErrorCode STATIC_AFTER_VAR = new ParserErrorCode.con2('STAT IC_AFTER_VAR', 97, "The modifier 'static' should be before the modifier 'var'"); 5699 static final ParserErrorCode STATIC_AFTER_CONST = new ParserErrorCode.con2('ST ATIC_AFTER_CONST', 97, "The modifier 'static' should be before the modifier 'con st'");
5307 static final ParserErrorCode STATIC_CONSTRUCTOR = new ParserErrorCode.con2('ST ATIC_CONSTRUCTOR', 98, "Constructors cannot be static"); 5700 static final ParserErrorCode STATIC_AFTER_FINAL = new ParserErrorCode.con2('ST ATIC_AFTER_FINAL', 98, "The modifier 'static' should be before the modifier 'fin al'");
5308 static final ParserErrorCode STATIC_GETTER_WITHOUT_BODY = new ParserErrorCode. con2('STATIC_GETTER_WITHOUT_BODY', 99, "A 'static' getter must have a body"); 5701 static final ParserErrorCode STATIC_AFTER_VAR = new ParserErrorCode.con2('STAT IC_AFTER_VAR', 99, "The modifier 'static' should be before the modifier 'var'");
5309 static final ParserErrorCode STATIC_OPERATOR = new ParserErrorCode.con2('STATI C_OPERATOR', 100, "Operators cannot be static"); 5702 static final ParserErrorCode STATIC_CONSTRUCTOR = new ParserErrorCode.con2('ST ATIC_CONSTRUCTOR', 100, "Constructors cannot be static");
5310 static final ParserErrorCode STATIC_SETTER_WITHOUT_BODY = new ParserErrorCode. con2('STATIC_SETTER_WITHOUT_BODY', 101, "A 'static' setter must have a body"); 5703 static final ParserErrorCode STATIC_GETTER_WITHOUT_BODY = new ParserErrorCode. con2('STATIC_GETTER_WITHOUT_BODY', 101, "A 'static' getter must have a body");
5311 static final ParserErrorCode STATIC_TOP_LEVEL_DECLARATION = new ParserErrorCod e.con2('STATIC_TOP_LEVEL_DECLARATION', 102, "Top-level declarations cannot be de clared to be 'static'"); 5704 static final ParserErrorCode STATIC_OPERATOR = new ParserErrorCode.con2('STATI C_OPERATOR', 102, "Operators cannot be static");
5312 static final ParserErrorCode SWITCH_HAS_CASE_AFTER_DEFAULT_CASE = new ParserEr rorCode.con2('SWITCH_HAS_CASE_AFTER_DEFAULT_CASE', 103, "The 'default' case shou ld be the last case in a switch statement"); 5705 static final ParserErrorCode STATIC_SETTER_WITHOUT_BODY = new ParserErrorCode. con2('STATIC_SETTER_WITHOUT_BODY', 103, "A 'static' setter must have a body");
5313 static final ParserErrorCode SWITCH_HAS_MULTIPLE_DEFAULT_CASES = new ParserErr orCode.con2('SWITCH_HAS_MULTIPLE_DEFAULT_CASES', 104, "The 'default' case can on ly be declared once"); 5706 static final ParserErrorCode STATIC_TOP_LEVEL_DECLARATION = new ParserErrorCod e.con2('STATIC_TOP_LEVEL_DECLARATION', 104, "Top-level declarations cannot be de clared to be 'static'");
5314 static final ParserErrorCode TOP_LEVEL_OPERATOR = new ParserErrorCode.con2('TO P_LEVEL_OPERATOR', 105, "Operators must be declared within a class"); 5707 static final ParserErrorCode SWITCH_HAS_CASE_AFTER_DEFAULT_CASE = new ParserEr rorCode.con2('SWITCH_HAS_CASE_AFTER_DEFAULT_CASE', 105, "The 'default' case shou ld be the last case in a switch statement");
5315 static final ParserErrorCode UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP = new P arserErrorCode.con2('UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP', 106, "There is no '%s' to open a parameter group"); 5708 static final ParserErrorCode SWITCH_HAS_MULTIPLE_DEFAULT_CASES = new ParserErr orCode.con2('SWITCH_HAS_MULTIPLE_DEFAULT_CASES', 106, "The 'default' case can on ly be declared once");
5316 static final ParserErrorCode UNEXPECTED_TOKEN = new ParserErrorCode.con2('UNEX PECTED_TOKEN', 107, "Unexpected token '%s'"); 5709 static final ParserErrorCode TOP_LEVEL_OPERATOR = new ParserErrorCode.con2('TO P_LEVEL_OPERATOR', 107, "Operators must be declared within a class");
5317 static final ParserErrorCode WITH_BEFORE_EXTENDS = new ParserErrorCode.con2('W ITH_BEFORE_EXTENDS', 108, "The extends clause must be before the with clause"); 5710 static final ParserErrorCode UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP = new P arserErrorCode.con2('UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP', 108, "There is no '%s' to open a parameter group");
5318 static final ParserErrorCode WITH_WITHOUT_EXTENDS = new ParserErrorCode.con2(' WITH_WITHOUT_EXTENDS', 109, "The with clause cannot be used without an extends c lause"); 5711 static final ParserErrorCode UNEXPECTED_TOKEN = new ParserErrorCode.con2('UNEX PECTED_TOKEN', 109, "Unexpected token '%s'");
5319 static final ParserErrorCode WRONG_SEPARATOR_FOR_NAMED_PARAMETER = new ParserE rrorCode.con2('WRONG_SEPARATOR_FOR_NAMED_PARAMETER', 110, "The default value of a named parameter should be preceeded by ':'"); 5712 static final ParserErrorCode WITH_BEFORE_EXTENDS = new ParserErrorCode.con2('W ITH_BEFORE_EXTENDS', 110, "The extends clause must be before the with clause");
5320 static final ParserErrorCode WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER = new Pa rserErrorCode.con2('WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER', 111, "The default value of a positional parameter should be preceeded by '='"); 5713 static final ParserErrorCode WITH_WITHOUT_EXTENDS = new ParserErrorCode.con2(' WITH_WITHOUT_EXTENDS', 111, "The with clause cannot be used without an extends c lause");
5321 static final ParserErrorCode WRONG_TERMINATOR_FOR_PARAMETER_GROUP = new Parser ErrorCode.con2('WRONG_TERMINATOR_FOR_PARAMETER_GROUP', 112, "Expected '%s' to cl ose parameter group"); 5714 static final ParserErrorCode WRONG_SEPARATOR_FOR_NAMED_PARAMETER = new ParserE rrorCode.con2('WRONG_SEPARATOR_FOR_NAMED_PARAMETER', 112, "The default value of a named parameter should be preceeded by ':'");
5322 static final ParserErrorCode VAR_AS_TYPE_NAME = new ParserErrorCode.con2('VAR_ AS_TYPE_NAME', 113, "The keyword 'var' cannot be used as a type name"); 5715 static final ParserErrorCode WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER = new Pa rserErrorCode.con2('WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER', 113, "The default value of a positional parameter should be preceeded by '='");
5323 static final ParserErrorCode VAR_CLASS = new ParserErrorCode.con2('VAR_CLASS', 114, "Classes cannot be declared to be 'var'"); 5716 static final ParserErrorCode WRONG_TERMINATOR_FOR_PARAMETER_GROUP = new Parser ErrorCode.con2('WRONG_TERMINATOR_FOR_PARAMETER_GROUP', 114, "Expected '%s' to cl ose parameter group");
5324 static final ParserErrorCode VAR_RETURN_TYPE = new ParserErrorCode.con2('VAR_R ETURN_TYPE', 115, "The return type cannot be 'var'"); 5717 static final ParserErrorCode VAR_AS_TYPE_NAME = new ParserErrorCode.con2('VAR_ AS_TYPE_NAME', 115, "The keyword 'var' cannot be used as a type name");
5325 static final ParserErrorCode VAR_TYPEDEF = new ParserErrorCode.con2('VAR_TYPED EF', 116, "Type aliases cannot be declared to be 'var'"); 5718 static final ParserErrorCode VAR_CLASS = new ParserErrorCode.con2('VAR_CLASS', 116, "Classes cannot be declared to be 'var'");
5326 static final ParserErrorCode VOID_PARAMETER = new ParserErrorCode.con2('VOID_P ARAMETER', 117, "Parameters cannot have a type of 'void'"); 5719 static final ParserErrorCode VAR_RETURN_TYPE = new ParserErrorCode.con2('VAR_R ETURN_TYPE', 117, "The return type cannot be 'var'");
5327 static final ParserErrorCode VOID_VARIABLE = new ParserErrorCode.con2('VOID_VA RIABLE', 118, "Variables cannot have a type of 'void'"); 5720 static final ParserErrorCode VAR_TYPEDEF = new ParserErrorCode.con2('VAR_TYPED EF', 118, "Type aliases cannot be declared to be 'var'");
5328 static final List<ParserErrorCode> values = [ABSTRACT_CLASS_MEMBER, ABSTRACT_S TATIC_METHOD, ABSTRACT_TOP_LEVEL_FUNCTION, ABSTRACT_TOP_LEVEL_VARIABLE, ABSTRACT _TYPEDEF, BREAK_OUTSIDE_OF_LOOP, CONST_AND_FINAL, CONST_AND_VAR, CONST_CLASS, CO NST_CONSTRUCTOR_WITH_BODY, CONST_FACTORY, CONST_METHOD, CONST_TYPEDEF, CONSTRUCT OR_WITH_RETURN_TYPE, CONTINUE_OUTSIDE_OF_LOOP, CONTINUE_WITHOUT_LABEL_IN_CASE, D EPRECATED_ARGUMENT_DEFINITION_TEST, DIRECTIVE_AFTER_DECLARATION, DUPLICATE_LABEL _IN_SWITCH_STATEMENT, DUPLICATED_MODIFIER, EXPECTED_CASE_OR_DEFAULT, EXPECTED_CL ASS_MEMBER, EXPECTED_EXECUTABLE, EXPECTED_LIST_OR_MAP_LITERAL, EXPECTED_STRING_L ITERAL, EXPECTED_TOKEN, EXPECTED_TWO_MAP_TYPE_ARGUMENTS, EXPECTED_TYPE_NAME, EXP ORT_DIRECTIVE_AFTER_PART_DIRECTIVE, EXTERNAL_AFTER_CONST, EXTERNAL_AFTER_FACTORY , EXTERNAL_AFTER_STATIC, EXTERNAL_CLASS, EXTERNAL_CONSTRUCTOR_WITH_BODY, EXTERNA L_FIELD, EXTERNAL_GETTER_WITH_BODY, EXTERNAL_METHOD_WITH_BODY, EXTERNAL_OPERATOR _WITH_BODY, EXTERNAL_SETTER_WITH_BODY, EXTERNAL_TYPEDEF, FACTORY_TOP_LEVEL_DECLA RATION, FACTORY_WITHOUT_BODY, FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, FINAL_AND_V AR, FINAL_CLASS, FINAL_CONSTRUCTOR, FINAL_METHOD, FINAL_TYPEDEF, GETTER_WITH_PAR AMETERS, ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, IMPLEMENTS_BEFORE_EXTENDS, IMPLEM ENTS_BEFORE_WITH, IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE, INITIALIZED_VARIABLE_IN _FOR_EACH, INVALID_CODE_POINT, INVALID_COMMENT_REFERENCE, INVALID_HEX_ESCAPE, IN VALID_OPERATOR, INVALID_OPERATOR_FOR_SUPER, INVALID_UNICODE_ESCAPE, LIBRARY_DIRE CTIVE_NOT_FIRST, MISSING_ASSIGNABLE_SELECTOR, MISSING_CATCH_OR_FINALLY, MISSING_ CLASS_BODY, MISSING_CLOSING_PARENTHESIS, MISSING_CONST_FINAL_VAR_OR_TYPE, MISSIN G_EXPRESSION_IN_THROW, MISSING_FUNCTION_BODY, MISSING_FUNCTION_PARAMETERS, MISSI NG_IDENTIFIER, MISSING_KEYWORD_OPERATOR, MISSING_NAME_IN_LIBRARY_DIRECTIVE, MISS ING_NAME_IN_PART_OF_DIRECTIVE, MISSING_STATEMENT, MISSING_TERMINATOR_FOR_PARAMET ER_GROUP, MISSING_TYPEDEF_PARAMETERS, MISSING_VARIABLE_IN_FOR_EACH, MIXED_PARAME TER_GROUPS, MULTIPLE_EXTENDS_CLAUSES, MULTIPLE_IMPLEMENTS_CLAUSES, MULTIPLE_LIBR ARY_DIRECTIVES, MULTIPLE_NAMED_PARAMETER_GROUPS, MULTIPLE_PART_OF_DIRECTIVES, MU LTIPLE_POSITIONAL_PARAMETER_GROUPS, MULTIPLE_VARIABLES_IN_FOR_EACH, MULTIPLE_WIT H_CLAUSES, NAMED_FUNCTION_EXPRESSION, NAMED_PARAMETER_OUTSIDE_GROUP, NATIVE_FUNC TION_BODY_IN_NON_SDK_CODE, NON_CONSTRUCTOR_FACTORY, NON_IDENTIFIER_LIBRARY_NAME, NON_PART_OF_DIRECTIVE_IN_PART, NON_USER_DEFINABLE_OPERATOR, POSITIONAL_AFTER_NA MED_ARGUMENT, POSITIONAL_PARAMETER_OUTSIDE_GROUP, STATIC_AFTER_CONST, STATIC_AFT ER_FINAL, STATIC_AFTER_VAR, STATIC_CONSTRUCTOR, STATIC_GETTER_WITHOUT_BODY, STAT IC_OPERATOR, STATIC_SETTER_WITHOUT_BODY, STATIC_TOP_LEVEL_DECLARATION, SWITCH_HA S_CASE_AFTER_DEFAULT_CASE, SWITCH_HAS_MULTIPLE_DEFAULT_CASES, TOP_LEVEL_OPERATOR , UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP, UNEXPECTED_TOKEN, WITH_BEFORE_EXTEN DS, WITH_WITHOUT_EXTENDS, WRONG_SEPARATOR_FOR_NAMED_PARAMETER, WRONG_SEPARATOR_F OR_POSITIONAL_PARAMETER, WRONG_TERMINATOR_FOR_PARAMETER_GROUP, VAR_AS_TYPE_NAME, VAR_CLASS, VAR_RETURN_TYPE, VAR_TYPEDEF, VOID_PARAMETER, VOID_VARIABLE]; 5721 static final ParserErrorCode VOID_PARAMETER = new ParserErrorCode.con2('VOID_P ARAMETER', 119, "Parameters cannot have a type of 'void'");
5722 static final ParserErrorCode VOID_VARIABLE = new ParserErrorCode.con2('VOID_VA RIABLE', 120, "Variables cannot have a type of 'void'");
5723 static final List<ParserErrorCode> values = [ABSTRACT_CLASS_MEMBER, ABSTRACT_S TATIC_METHOD, ABSTRACT_TOP_LEVEL_FUNCTION, ABSTRACT_TOP_LEVEL_VARIABLE, ABSTRACT _TYPEDEF, BREAK_OUTSIDE_OF_LOOP, CONST_AND_FINAL, CONST_AND_VAR, CONST_CLASS, CO NST_CONSTRUCTOR_WITH_BODY, CONST_FACTORY, CONST_METHOD, CONST_TYPEDEF, CONSTRUCT OR_WITH_RETURN_TYPE, CONTINUE_OUTSIDE_OF_LOOP, CONTINUE_WITHOUT_LABEL_IN_CASE, D EPRECATED_ARGUMENT_DEFINITION_TEST, DIRECTIVE_AFTER_DECLARATION, DUPLICATE_LABEL _IN_SWITCH_STATEMENT, DUPLICATED_MODIFIER, EXPECTED_CASE_OR_DEFAULT, EXPECTED_CL ASS_MEMBER, EXPECTED_EXECUTABLE, EXPECTED_LIST_OR_MAP_LITERAL, EXPECTED_STRING_L ITERAL, EXPECTED_TOKEN, EXPECTED_TWO_MAP_TYPE_ARGUMENTS, EXPECTED_TYPE_NAME, EXP ORT_DIRECTIVE_AFTER_PART_DIRECTIVE, EXTERNAL_AFTER_CONST, EXTERNAL_AFTER_FACTORY , EXTERNAL_AFTER_STATIC, EXTERNAL_CLASS, EXTERNAL_CONSTRUCTOR_WITH_BODY, EXTERNA L_FIELD, EXTERNAL_GETTER_WITH_BODY, EXTERNAL_METHOD_WITH_BODY, EXTERNAL_OPERATOR _WITH_BODY, EXTERNAL_SETTER_WITH_BODY, EXTERNAL_TYPEDEF, FACTORY_TOP_LEVEL_DECLA RATION, FACTORY_WITHOUT_BODY, FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, FINAL_AND_V AR, FINAL_CLASS, FINAL_CONSTRUCTOR, FINAL_METHOD, FINAL_TYPEDEF, GETTER_WITH_PAR AMETERS, ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, IMPLEMENTS_BEFORE_EXTENDS, IMPLEM ENTS_BEFORE_WITH, IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE, INITIALIZED_VARIABLE_IN _FOR_EACH, INVALID_CODE_POINT, INVALID_COMMENT_REFERENCE, INVALID_HEX_ESCAPE, IN VALID_OPERATOR, INVALID_OPERATOR_FOR_SUPER, INVALID_UNICODE_ESCAPE, LIBRARY_DIRE CTIVE_NOT_FIRST, LOCAL_FUNCTION_DECLARATION_MODIFIER, MISSING_ASSIGNABLE_SELECTO R, MISSING_CATCH_OR_FINALLY, MISSING_CLASS_BODY, MISSING_CLOSING_PARENTHESIS, MI SSING_CONST_FINAL_VAR_OR_TYPE, MISSING_EXPRESSION_IN_THROW, MISSING_FUNCTION_BOD Y, MISSING_FUNCTION_PARAMETERS, MISSING_IDENTIFIER, MISSING_KEYWORD_OPERATOR, MI SSING_NAME_IN_LIBRARY_DIRECTIVE, MISSING_NAME_IN_PART_OF_DIRECTIVE, MISSING_STAT EMENT, MISSING_TERMINATOR_FOR_PARAMETER_GROUP, MISSING_TYPEDEF_PARAMETERS, MISSI NG_VARIABLE_IN_FOR_EACH, MIXED_PARAMETER_GROUPS, MULTIPLE_EXTENDS_CLAUSES, MULTI PLE_IMPLEMENTS_CLAUSES, MULTIPLE_LIBRARY_DIRECTIVES, MULTIPLE_NAMED_PARAMETER_GR OUPS, MULTIPLE_PART_OF_DIRECTIVES, MULTIPLE_POSITIONAL_PARAMETER_GROUPS, MULTIPL E_VARIABLES_IN_FOR_EACH, MULTIPLE_WITH_CLAUSES, NAMED_FUNCTION_EXPRESSION, NAMED _PARAMETER_OUTSIDE_GROUP, NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE, NON_CONSTRUCTOR_ FACTORY, NON_IDENTIFIER_LIBRARY_NAME, NON_PART_OF_DIRECTIVE_IN_PART, NON_USER_DE FINABLE_OPERATOR, NORMAL_BEFORE_OPTIONAL_PARAMETERS, POSITIONAL_AFTER_NAMED_ARGU MENT, POSITIONAL_PARAMETER_OUTSIDE_GROUP, STATIC_AFTER_CONST, STATIC_AFTER_FINAL , STATIC_AFTER_VAR, STATIC_CONSTRUCTOR, STATIC_GETTER_WITHOUT_BODY, STATIC_OPERA TOR, STATIC_SETTER_WITHOUT_BODY, STATIC_TOP_LEVEL_DECLARATION, SWITCH_HAS_CASE_A FTER_DEFAULT_CASE, SWITCH_HAS_MULTIPLE_DEFAULT_CASES, TOP_LEVEL_OPERATOR, UNEXPE CTED_TERMINATOR_FOR_PARAMETER_GROUP, UNEXPECTED_TOKEN, WITH_BEFORE_EXTENDS, WITH _WITHOUT_EXTENDS, WRONG_SEPARATOR_FOR_NAMED_PARAMETER, WRONG_SEPARATOR_FOR_POSIT IONAL_PARAMETER, WRONG_TERMINATOR_FOR_PARAMETER_GROUP, VAR_AS_TYPE_NAME, VAR_CLA SS, VAR_RETURN_TYPE, VAR_TYPEDEF, VOID_PARAMETER, VOID_VARIABLE];
5329 5724
5330 /// The name of this enum constant, as declared in the enum declaration. 5725 /// The name of this enum constant, as declared in the enum declaration.
5331 final String name; 5726 final String name;
5332 5727
5333 /// The position in the enum declaration. 5728 /// The position in the enum declaration.
5334 final int ordinal; 5729 final int ordinal;
5335 5730
5336 /** 5731 /**
5337 * The severity of this error. 5732 * The severity of this error.
5338 */ 5733 */
5339 ErrorSeverity _severity; 5734 ErrorSeverity _severity;
5340 5735
5341 /** 5736 /**
5342 * The message template used to create the message to be displayed for this er ror. 5737 * The message template used to create the message to be displayed for this er ror.
5343 */ 5738 */
5344 String _message; 5739 String _message;
5345 5740
5346 /** 5741 /**
5347 * Initialize a newly created error code to have the given severity and messag e. 5742 * Initialize a newly created error code to have the given severity and messag e.
5743 *
5348 * @param severity the severity of the error 5744 * @param severity the severity of the error
5349 * @param message the message template used to create the message to be displa yed for the error 5745 * @param message the message template used to create the message to be displa yed for the error
5350 */ 5746 */
5351 ParserErrorCode.con1(this.name, this.ordinal, ErrorSeverity severity2, String message2) { 5747 ParserErrorCode.con1(this.name, this.ordinal, ErrorSeverity severity2, String message2) {
5352 _jtd_constructor_311_impl(severity2, message2); 5748 _jtd_constructor_311_impl(severity2, message2);
5353 } 5749 }
5354 _jtd_constructor_311_impl(ErrorSeverity severity2, String message2) { 5750 _jtd_constructor_311_impl(ErrorSeverity severity2, String message2) {
5355 this._severity = severity2; 5751 this._severity = severity2;
5356 this._message = message2; 5752 this._message = message2;
5357 } 5753 }
5358 5754
5359 /** 5755 /**
5360 * Initialize a newly created error code to have the given message and a sever ity of ERROR. 5756 * Initialize a newly created error code to have the given message and a sever ity of ERROR.
5757 *
5361 * @param message the message template used to create the message to be displa yed for the error 5758 * @param message the message template used to create the message to be displa yed for the error
5362 */ 5759 */
5363 ParserErrorCode.con2(this.name, this.ordinal, String message) { 5760 ParserErrorCode.con2(this.name, this.ordinal, String message) {
5364 _jtd_constructor_312_impl(message); 5761 _jtd_constructor_312_impl(message);
5365 } 5762 }
5366 _jtd_constructor_312_impl(String message) { 5763 _jtd_constructor_312_impl(String message) {
5367 _jtd_constructor_311_impl(ErrorSeverity.ERROR, message); 5764 _jtd_constructor_311_impl(ErrorSeverity.ERROR, message);
5368 } 5765 }
5369 ErrorSeverity get errorSeverity => _severity; 5766 ErrorSeverity get errorSeverity => _severity;
5370 String get message => _message; 5767 String get message => _message;
(...skipping 11 matching lines...) Expand all
5382 /** 5779 /**
5383 * The writer to which the source is to be written. 5780 * The writer to which the source is to be written.
5384 */ 5781 */
5385 PrintWriter _writer; 5782 PrintWriter _writer;
5386 int _indentLevel = 0; 5783 int _indentLevel = 0;
5387 String _indentString = ""; 5784 String _indentString = "";
5388 5785
5389 /** 5786 /**
5390 * Initialize a newly created visitor to write source code representing the vi sited nodes to the 5787 * Initialize a newly created visitor to write source code representing the vi sited nodes to the
5391 * given writer. 5788 * given writer.
5789 *
5392 * @param writer the writer to which the source is to be written 5790 * @param writer the writer to which the source is to be written
5393 */ 5791 */
5394 ToFormattedSourceVisitor(PrintWriter writer) { 5792 ToFormattedSourceVisitor(PrintWriter writer) {
5395 this._writer = writer; 5793 this._writer = writer;
5396 } 5794 }
5397 Object visitAdjacentStrings(AdjacentStrings node) { 5795 Object visitAdjacentStrings(AdjacentStrings node) {
5398 visitList5(node.strings, " "); 5796 visitList5(node.strings, " ");
5399 return null; 5797 return null;
5400 } 5798 }
5401 Object visitAnnotation(Annotation node) { 5799 Object visitAnnotation(Annotation node) {
(...skipping 744 matching lines...) Expand 10 before | Expand all | Expand 10 after
6146 void nl() { 6544 void nl() {
6147 _writer.print("\n"); 6545 _writer.print("\n");
6148 } 6546 }
6149 void nl2() { 6547 void nl2() {
6150 nl(); 6548 nl();
6151 indent(); 6549 indent();
6152 } 6550 }
6153 6551
6154 /** 6552 /**
6155 * Safely visit the given node. 6553 * Safely visit the given node.
6554 *
6156 * @param node the node to be visited 6555 * @param node the node to be visited
6157 */ 6556 */
6158 void visit(ASTNode node) { 6557 void visit(ASTNode node) {
6159 if (node != null) { 6558 if (node != null) {
6160 node.accept(this); 6559 node.accept(this);
6161 } 6560 }
6162 } 6561 }
6163 6562
6164 /** 6563 /**
6165 * Safely visit the given node, printing the suffix after the node if it is no n-<code>null</code>. 6564 * Safely visit the given node, printing the suffix after the node if it is no n-<code>null</code>.
6565 *
6166 * @param suffix the suffix to be printed if there is a node to visit 6566 * @param suffix the suffix to be printed if there is a node to visit
6167 * @param node the node to be visited 6567 * @param node the node to be visited
6168 */ 6568 */
6169 void visit6(ASTNode node, String suffix) { 6569 void visit6(ASTNode node, String suffix) {
6170 if (node != null) { 6570 if (node != null) {
6171 node.accept(this); 6571 node.accept(this);
6172 _writer.print(suffix); 6572 _writer.print(suffix);
6173 } 6573 }
6174 } 6574 }
6175 6575
6176 /** 6576 /**
6177 * Safely visit the given node, printing the prefix before the node if it is n on-<code>null</code> 6577 * Safely visit the given node, printing the prefix before the node if it is n on-<code>null</code>
6178 * . 6578 * .
6579 *
6179 * @param prefix the prefix to be printed if there is a node to visit 6580 * @param prefix the prefix to be printed if there is a node to visit
6180 * @param node the node to be visited 6581 * @param node the node to be visited
6181 */ 6582 */
6182 void visit7(String prefix, ASTNode node) { 6583 void visit7(String prefix, ASTNode node) {
6183 if (node != null) { 6584 if (node != null) {
6184 _writer.print(prefix); 6585 _writer.print(prefix);
6185 node.accept(this); 6586 node.accept(this);
6186 } 6587 }
6187 } 6588 }
6188 6589
6189 /** 6590 /**
6190 * Safely visit the given node, printing the suffix after the node if it is no n-<code>null</code>. 6591 * Safely visit the given node, printing the suffix after the node if it is no n-<code>null</code>.
6592 *
6191 * @param suffix the suffix to be printed if there is a node to visit 6593 * @param suffix the suffix to be printed if there is a node to visit
6192 * @param node the node to be visited 6594 * @param node the node to be visited
6193 */ 6595 */
6194 void visit8(Token token, String suffix) { 6596 void visit8(Token token, String suffix) {
6195 if (token != null) { 6597 if (token != null) {
6196 _writer.print(token.lexeme); 6598 _writer.print(token.lexeme);
6197 _writer.print(suffix); 6599 _writer.print(suffix);
6198 } 6600 }
6199 } 6601 }
6200 6602
6201 /** 6603 /**
6202 * Print a list of nodes without any separation. 6604 * Print a list of nodes without any separation.
6605 *
6203 * @param nodes the nodes to be printed 6606 * @param nodes the nodes to be printed
6204 * @param separator the separator to be printed between adjacent nodes 6607 * @param separator the separator to be printed between adjacent nodes
6205 */ 6608 */
6206 void visitList(NodeList<ASTNode> nodes) { 6609 void visitList(NodeList<ASTNode> nodes) {
6207 visitList5(nodes, ""); 6610 visitList5(nodes, "");
6208 } 6611 }
6209 6612
6210 /** 6613 /**
6211 * Print a list of nodes, separated by the given separator. 6614 * Print a list of nodes, separated by the given separator.
6615 *
6212 * @param nodes the nodes to be printed 6616 * @param nodes the nodes to be printed
6213 * @param separator the separator to be printed between adjacent nodes 6617 * @param separator the separator to be printed between adjacent nodes
6214 */ 6618 */
6215 void visitList5(NodeList<ASTNode> nodes, String separator) { 6619 void visitList5(NodeList<ASTNode> nodes, String separator) {
6216 if (nodes != null) { 6620 if (nodes != null) {
6217 int size = nodes.length; 6621 int size = nodes.length;
6218 for (int i = 0; i < size; i++) { 6622 for (int i = 0; i < size; i++) {
6219 if ("\n" == separator) { 6623 if ("\n" == separator) {
6220 _writer.print("\n"); 6624 _writer.print("\n");
6221 indent(); 6625 indent();
6222 } else if (i > 0) { 6626 } else if (i > 0) {
6223 _writer.print(separator); 6627 _writer.print(separator);
6224 } 6628 }
6225 nodes[i].accept(this); 6629 nodes[i].accept(this);
6226 } 6630 }
6227 } 6631 }
6228 } 6632 }
6229 6633
6230 /** 6634 /**
6231 * Print a list of nodes, separated by the given separator. 6635 * Print a list of nodes, separated by the given separator.
6636 *
6232 * @param nodes the nodes to be printed 6637 * @param nodes the nodes to be printed
6233 * @param separator the separator to be printed between adjacent nodes 6638 * @param separator the separator to be printed between adjacent nodes
6234 * @param suffix the suffix to be printed if the list is not empty 6639 * @param suffix the suffix to be printed if the list is not empty
6235 */ 6640 */
6236 void visitList6(NodeList<ASTNode> nodes, String separator, String suffix) { 6641 void visitList6(NodeList<ASTNode> nodes, String separator, String suffix) {
6237 if (nodes != null) { 6642 if (nodes != null) {
6238 int size = nodes.length; 6643 int size = nodes.length;
6239 if (size > 0) { 6644 if (size > 0) {
6240 for (int i = 0; i < size; i++) { 6645 for (int i = 0; i < size; i++) {
6241 if (i > 0) { 6646 if (i > 0) {
6242 _writer.print(separator); 6647 _writer.print(separator);
6243 } 6648 }
6244 nodes[i].accept(this); 6649 nodes[i].accept(this);
6245 } 6650 }
6246 _writer.print(suffix); 6651 _writer.print(suffix);
6247 } 6652 }
6248 } 6653 }
6249 } 6654 }
6250 6655
6251 /** 6656 /**
6252 * Print a list of nodes, separated by the given separator. 6657 * Print a list of nodes, separated by the given separator.
6658 *
6253 * @param prefix the prefix to be printed if the list is not empty 6659 * @param prefix the prefix to be printed if the list is not empty
6254 * @param nodes the nodes to be printed 6660 * @param nodes the nodes to be printed
6255 * @param separator the separator to be printed between adjacent nodes 6661 * @param separator the separator to be printed between adjacent nodes
6256 */ 6662 */
6257 void visitList7(String prefix, NodeList<ASTNode> nodes, String separator) { 6663 void visitList7(String prefix, NodeList<ASTNode> nodes, String separator) {
6258 if (nodes != null) { 6664 if (nodes != null) {
6259 int size = nodes.length; 6665 int size = nodes.length;
6260 if (size > 0) { 6666 if (size > 0) {
6261 _writer.print(prefix); 6667 _writer.print(prefix);
6262 for (int i = 0; i < size; i++) { 6668 for (int i = 0; i < size; i++) {
6263 if (i > 0) { 6669 if (i > 0) {
6264 _writer.print(separator); 6670 _writer.print(separator);
6265 } 6671 }
6266 nodes[i].accept(this); 6672 nodes[i].accept(this);
6267 } 6673 }
6268 } 6674 }
6269 } 6675 }
6270 } 6676 }
6271 } 6677 }
OLDNEW
« no previous file with comments | « pkg/analyzer_experimental/lib/src/generated/java_io.dart ('k') | pkg/analyzer_experimental/lib/src/generated/resolver.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698