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

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

Issue 16256021: Remove trailing spaces in analyzer_experimental (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: 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
4 library engine.parser; 3 library engine.parser;
5
6 import 'dart:collection'; 4 import 'dart:collection';
7 import 'java_core.dart'; 5 import 'java_core.dart';
8 import 'java_engine.dart'; 6 import 'java_engine.dart';
9 import 'instrumentation.dart'; 7 import 'instrumentation.dart';
10 import 'error.dart'; 8 import 'error.dart';
11 import 'source.dart'; 9 import 'source.dart';
12 import 'scanner.dart'; 10 import 'scanner.dart';
13 import 'ast.dart'; 11 import 'ast.dart';
14 import 'utilities_dart.dart'; 12 import 'utilities_dart.dart';
15
16
17 /** 13 /**
18 * Instances of the class {@code CommentAndMetadata} implement a simple data-hol der for a method 14 * Instances of the class {@code CommentAndMetadata} implement a simple data-hol der for a method
19 * that needs to return multiple values. 15 * that needs to return multiple values.
20 * @coverage dart.engine.parser 16 * @coverage dart.engine.parser
21 */ 17 */
22 class CommentAndMetadata { 18 class CommentAndMetadata {
23 19
24 /** 20 /**
25 * The documentation comment that was parsed, or {@code null} if none was give n. 21 * The documentation comment that was parsed, or {@code null} if none was give n.
26 */ 22 */
27 Comment _comment; 23 Comment _comment;
28 24
29 /** 25 /**
30 * The metadata that was parsed. 26 * The metadata that was parsed.
31 */ 27 */
32 List<Annotation> _metadata; 28 List<Annotation> _metadata;
33 29
34 /** 30 /**
35 * Initialize a newly created holder with the given data. 31 * Initialize a newly created holder with the given data.
36 * @param comment the documentation comment that was parsed 32 * @param comment the documentation comment that was parsed
37 * @param metadata the metadata that was parsed 33 * @param metadata the metadata that was parsed
38 */ 34 */
39 CommentAndMetadata(Comment comment, List<Annotation> metadata) { 35 CommentAndMetadata(Comment comment, List<Annotation> metadata) {
40 this._comment = comment; 36 this._comment = comment;
41 this._metadata = metadata; 37 this._metadata = metadata;
42 } 38 }
43 39
44 /** 40 /**
45 * Return the documentation comment that was parsed, or {@code null} if none w as given. 41 * Return the documentation comment that was parsed, or {@code null} if none w as given.
46 * @return the documentation comment that was parsed 42 * @return the documentation comment that was parsed
47 */ 43 */
48 Comment get comment => _comment; 44 Comment get comment => _comment;
49 45
50 /** 46 /**
51 * Return the metadata that was parsed. If there was no metadata, then the lis t will be empty. 47 * Return the metadata that was parsed. If there was no metadata, then the lis t will be empty.
52 * @return the metadata that was parsed 48 * @return the metadata that was parsed
53 */ 49 */
54 List<Annotation> get metadata => _metadata; 50 List<Annotation> get metadata => _metadata;
55 } 51 }
56
57 /** 52 /**
58 * Instances of the class {@code FinalConstVarOrType} implement a simple data-ho lder for a method 53 * Instances of the class {@code FinalConstVarOrType} implement a simple data-ho lder for a method
59 * that needs to return multiple values. 54 * that needs to return multiple values.
60 * @coverage dart.engine.parser 55 * @coverage dart.engine.parser
61 */ 56 */
62 class FinalConstVarOrType { 57 class FinalConstVarOrType {
63 58
64 /** 59 /**
65 * The 'final', 'const' or 'var' keyword, or {@code null} if none was given. 60 * The 'final', 'const' or 'var' keyword, or {@code null} if none was given.
66 */ 61 */
67 Token _keyword; 62 Token _keyword;
68 63
69 /** 64 /**
70 * The type, of {@code null} if no type was specified. 65 * The type, of {@code null} if no type was specified.
71 */ 66 */
72 TypeName _type; 67 TypeName _type;
73 68
74 /** 69 /**
75 * Initialize a newly created holder with the given data. 70 * Initialize a newly created holder with the given data.
76 * @param keyword the 'final', 'const' or 'var' keyword 71 * @param keyword the 'final', 'const' or 'var' keyword
77 * @param type the type 72 * @param type the type
78 */ 73 */
79 FinalConstVarOrType(Token keyword, TypeName type) { 74 FinalConstVarOrType(Token keyword, TypeName type) {
80 this._keyword = keyword; 75 this._keyword = keyword;
81 this._type = type; 76 this._type = type;
82 } 77 }
83 78
84 /** 79 /**
85 * Return the 'final', 'const' or 'var' keyword, or {@code null} if none was g iven. 80 * Return the 'final', 'const' or 'var' keyword, or {@code null} if none was g iven.
86 * @return the 'final', 'const' or 'var' keyword 81 * @return the 'final', 'const' or 'var' keyword
87 */ 82 */
88 Token get keyword => _keyword; 83 Token get keyword => _keyword;
89 84
90 /** 85 /**
91 * Return the type, of {@code null} if no type was specified. 86 * Return the type, of {@code null} if no type was specified.
92 * @return the type 87 * @return the type
93 */ 88 */
94 TypeName get type => _type; 89 TypeName get type => _type;
95 } 90 }
96
97 /** 91 /**
98 * Instances of the class {@code Modifiers} implement a simple data-holder for a method that needs 92 * Instances of the class {@code Modifiers} implement a simple data-holder for a method that needs
99 * to return multiple values. 93 * to return multiple values.
100 * @coverage dart.engine.parser 94 * @coverage dart.engine.parser
101 */ 95 */
102 class Modifiers { 96 class Modifiers {
103 97
104 /** 98 /**
105 * The token representing the keyword 'abstract', or {@code null} if the keywo rd was not found. 99 * The token representing the keyword 'abstract', or {@code null} if the keywo rd was not found.
106 */ 100 */
107 Token _abstractKeyword; 101 Token _abstractKeyword;
108 102
109 /** 103 /**
110 * The token representing the keyword 'const', or {@code null} if the keyword was not found. 104 * The token representing the keyword 'const', or {@code null} if the keyword was not found.
111 */ 105 */
112 Token _constKeyword; 106 Token _constKeyword;
113 107
114 /** 108 /**
115 * The token representing the keyword 'external', or {@code null} if the keywo rd was not found. 109 * The token representing the keyword 'external', or {@code null} if the keywo rd was not found.
116 */ 110 */
117 Token _externalKeyword; 111 Token _externalKeyword;
118 112
119 /** 113 /**
120 * The token representing the keyword 'factory', or {@code null} if the keywor d was not found. 114 * The token representing the keyword 'factory', or {@code null} if the keywor d was not found.
121 */ 115 */
122 Token _factoryKeyword; 116 Token _factoryKeyword;
123 117
124 /** 118 /**
125 * The token representing the keyword 'final', or {@code null} if the keyword was not found. 119 * The token representing the keyword 'final', or {@code null} if the keyword was not found.
126 */ 120 */
127 Token _finalKeyword; 121 Token _finalKeyword;
128 122
129 /** 123 /**
130 * The token representing the keyword 'static', or {@code null} if the keyword was not found. 124 * The token representing the keyword 'static', or {@code null} if the keyword was not found.
131 */ 125 */
132 Token _staticKeyword; 126 Token _staticKeyword;
133 127
134 /** 128 /**
135 * The token representing the keyword 'var', or {@code null} if the keyword wa s not found. 129 * The token representing the keyword 'var', or {@code null} if the keyword wa s not found.
136 */ 130 */
137 Token _varKeyword; 131 Token _varKeyword;
138 132
139 /** 133 /**
140 * Return the token representing the keyword 'abstract', or {@code null} if th e keyword was not 134 * Return the token representing the keyword 'abstract', or {@code null} if th e keyword was not
141 * found. 135 * found.
142 * @return the token representing the keyword 'abstract' 136 * @return the token representing the keyword 'abstract'
143 */ 137 */
144 Token get abstractKeyword => _abstractKeyword; 138 Token get abstractKeyword => _abstractKeyword;
145 139
146 /** 140 /**
147 * Return the token representing the keyword 'const', or {@code null} if the k eyword was not 141 * Return the token representing the keyword 'const', or {@code null} if the k eyword was not
148 * found. 142 * found.
149 * @return the token representing the keyword 'const' 143 * @return the token representing the keyword 'const'
150 */ 144 */
151 Token get constKeyword => _constKeyword; 145 Token get constKeyword => _constKeyword;
152 146
153 /** 147 /**
154 * Return the token representing the keyword 'external', or {@code null} if th e keyword was not 148 * Return the token representing the keyword 'external', or {@code null} if th e keyword was not
155 * found. 149 * found.
156 * @return the token representing the keyword 'external' 150 * @return the token representing the keyword 'external'
157 */ 151 */
158 Token get externalKeyword => _externalKeyword; 152 Token get externalKeyword => _externalKeyword;
159 153
160 /** 154 /**
161 * Return the token representing the keyword 'factory', or {@code null} if the keyword was not 155 * Return the token representing the keyword 'factory', or {@code null} if the keyword was not
162 * found. 156 * found.
163 * @return the token representing the keyword 'factory' 157 * @return the token representing the keyword 'factory'
164 */ 158 */
165 Token get factoryKeyword => _factoryKeyword; 159 Token get factoryKeyword => _factoryKeyword;
166 160
167 /** 161 /**
168 * Return the token representing the keyword 'final', or {@code null} if the k eyword was not 162 * Return the token representing the keyword 'final', or {@code null} if the k eyword was not
169 * found. 163 * found.
170 * @return the token representing the keyword 'final' 164 * @return the token representing the keyword 'final'
171 */ 165 */
172 Token get finalKeyword => _finalKeyword; 166 Token get finalKeyword => _finalKeyword;
173 167
174 /** 168 /**
175 * Return the token representing the keyword 'static', or {@code null} if the keyword was not 169 * Return the token representing the keyword 'static', or {@code null} if the keyword was not
176 * found. 170 * found.
177 * @return the token representing the keyword 'static' 171 * @return the token representing the keyword 'static'
178 */ 172 */
179 Token get staticKeyword => _staticKeyword; 173 Token get staticKeyword => _staticKeyword;
180 174
181 /** 175 /**
182 * Return the token representing the keyword 'var', or {@code null} if the key word was not found. 176 * Return the token representing the keyword 'var', or {@code null} if the key word was not found.
183 * @return the token representing the keyword 'var' 177 * @return the token representing the keyword 'var'
184 */ 178 */
185 Token get varKeyword => _varKeyword; 179 Token get varKeyword => _varKeyword;
186 180
187 /** 181 /**
188 * Set the token representing the keyword 'abstract' to the given token. 182 * Set the token representing the keyword 'abstract' to the given token.
189 * @param abstractKeyword the token representing the keyword 'abstract' 183 * @param abstractKeyword the token representing the keyword 'abstract'
190 */ 184 */
191 void set abstractKeyword(Token abstractKeyword2) { 185 void set abstractKeyword(Token abstractKeyword2) {
192 this._abstractKeyword = abstractKeyword2; 186 this._abstractKeyword = abstractKeyword2;
193 } 187 }
194 188
195 /** 189 /**
196 * Set the token representing the keyword 'const' to the given token. 190 * Set the token representing the keyword 'const' to the given token.
197 * @param constKeyword the token representing the keyword 'const' 191 * @param constKeyword the token representing the keyword 'const'
198 */ 192 */
199 void set constKeyword(Token constKeyword2) { 193 void set constKeyword(Token constKeyword2) {
200 this._constKeyword = constKeyword2; 194 this._constKeyword = constKeyword2;
201 } 195 }
202 196
203 /** 197 /**
204 * Set the token representing the keyword 'external' to the given token. 198 * Set the token representing the keyword 'external' to the given token.
205 * @param externalKeyword the token representing the keyword 'external' 199 * @param externalKeyword the token representing the keyword 'external'
206 */ 200 */
207 void set externalKeyword(Token externalKeyword2) { 201 void set externalKeyword(Token externalKeyword2) {
208 this._externalKeyword = externalKeyword2; 202 this._externalKeyword = externalKeyword2;
209 } 203 }
210 204
211 /** 205 /**
212 * Set the token representing the keyword 'factory' to the given token. 206 * Set the token representing the keyword 'factory' to the given token.
213 * @param factoryKeyword the token representing the keyword 'factory' 207 * @param factoryKeyword the token representing the keyword 'factory'
214 */ 208 */
215 void set factoryKeyword(Token factoryKeyword2) { 209 void set factoryKeyword(Token factoryKeyword2) {
216 this._factoryKeyword = factoryKeyword2; 210 this._factoryKeyword = factoryKeyword2;
217 } 211 }
218 212
219 /** 213 /**
220 * Set the token representing the keyword 'final' to the given token. 214 * Set the token representing the keyword 'final' to the given token.
221 * @param finalKeyword the token representing the keyword 'final' 215 * @param finalKeyword the token representing the keyword 'final'
222 */ 216 */
223 void set finalKeyword(Token finalKeyword2) { 217 void set finalKeyword(Token finalKeyword2) {
224 this._finalKeyword = finalKeyword2; 218 this._finalKeyword = finalKeyword2;
225 } 219 }
226 220
227 /** 221 /**
228 * Set the token representing the keyword 'static' to the given token. 222 * Set the token representing the keyword 'static' to the given token.
229 * @param staticKeyword the token representing the keyword 'static' 223 * @param staticKeyword the token representing the keyword 'static'
230 */ 224 */
231 void set staticKeyword(Token staticKeyword2) { 225 void set staticKeyword(Token staticKeyword2) {
232 this._staticKeyword = staticKeyword2; 226 this._staticKeyword = staticKeyword2;
233 } 227 }
234 228
235 /** 229 /**
236 * Set the token representing the keyword 'var' to the given token. 230 * Set the token representing the keyword 'var' to the given token.
237 * @param varKeyword the token representing the keyword 'var' 231 * @param varKeyword the token representing the keyword 'var'
238 */ 232 */
239 void set varKeyword(Token varKeyword2) { 233 void set varKeyword(Token varKeyword2) {
240 this._varKeyword = varKeyword2; 234 this._varKeyword = varKeyword2;
241 } 235 }
242 String toString() { 236 String toString() {
243 JavaStringBuilder builder = new JavaStringBuilder(); 237 JavaStringBuilder builder = new JavaStringBuilder();
244 bool needsSpace = appendKeyword(builder, false, _abstractKeyword); 238 bool needsSpace = appendKeyword(builder, false, _abstractKeyword);
245 needsSpace = appendKeyword(builder, needsSpace, _constKeyword); 239 needsSpace = appendKeyword(builder, needsSpace, _constKeyword);
246 needsSpace = appendKeyword(builder, needsSpace, _externalKeyword); 240 needsSpace = appendKeyword(builder, needsSpace, _externalKeyword);
247 needsSpace = appendKeyword(builder, needsSpace, _factoryKeyword); 241 needsSpace = appendKeyword(builder, needsSpace, _factoryKeyword);
248 needsSpace = appendKeyword(builder, needsSpace, _finalKeyword); 242 needsSpace = appendKeyword(builder, needsSpace, _finalKeyword);
249 needsSpace = appendKeyword(builder, needsSpace, _staticKeyword); 243 needsSpace = appendKeyword(builder, needsSpace, _staticKeyword);
250 appendKeyword(builder, needsSpace, _varKeyword); 244 appendKeyword(builder, needsSpace, _varKeyword);
251 return builder.toString(); 245 return builder.toString();
252 } 246 }
253 247
254 /** 248 /**
255 * If the given keyword is not {@code null}, append it to the given builder, p refixing it with a 249 * If the given keyword is not {@code null}, append it to the given builder, p refixing it with a
256 * space if needed. 250 * space if needed.
257 * @param builder the builder to which the keyword will be appended 251 * @param builder the builder to which the keyword will be appended
258 * @param needsSpace {@code true} if the keyword needs to be prefixed with a s pace 252 * @param needsSpace {@code true} if the keyword needs to be prefixed with a s pace
259 * @param keyword the keyword to be appended 253 * @param keyword the keyword to be appended
260 * @return {@code true} if subsequent keywords need to be prefixed with a spac e 254 * @return {@code true} if subsequent keywords need to be prefixed with a spac e
261 */ 255 */
262 bool appendKeyword(JavaStringBuilder builder, bool needsSpace, Token keyword) { 256 bool appendKeyword(JavaStringBuilder builder, bool needsSpace, Token keyword) {
263 if (keyword != null) { 257 if (keyword != null) {
264 if (needsSpace) { 258 if (needsSpace) {
265 builder.appendChar(0x20); 259 builder.appendChar(0x20);
266 } 260 }
267 builder.append(keyword.lexeme); 261 builder.append(keyword.lexeme);
268 return true; 262 return true;
269 } 263 }
270 return needsSpace; 264 return needsSpace;
271 } 265 }
272 } 266 }
273
274 /** 267 /**
275 * Instances of the class {@code Parser} are used to parse tokens into an AST st ructure. 268 * Instances of the class {@code Parser} are used to parse tokens into an AST st ructure.
276 * @coverage dart.engine.parser 269 * @coverage dart.engine.parser
277 */ 270 */
278 class Parser { 271 class Parser {
279 272
280 /** 273 /**
281 * The source being parsed. 274 * The source being parsed.
282 */ 275 */
283 Source _source; 276 Source _source;
284 277
285 /** 278 /**
286 * The error listener that will be informed of any errors that are found durin g the parse. 279 * The error listener that will be informed of any errors that are found durin g the parse.
287 */ 280 */
288 AnalysisErrorListener _errorListener; 281 AnalysisErrorListener _errorListener;
289 282
290 /** 283 /**
291 * The next token to be parsed. 284 * The next token to be parsed.
292 */ 285 */
293 Token _currentToken; 286 Token _currentToken;
294 287
295 /** 288 /**
296 * A flag indicating whether the parser is currently in the body of a loop. 289 * A flag indicating whether the parser is currently in the body of a loop.
297 */ 290 */
298 bool _inLoop = false; 291 bool _inLoop = false;
299 292
300 /** 293 /**
301 * A flag indicating whether the parser is currently in a switch statement. 294 * A flag indicating whether the parser is currently in a switch statement.
302 */ 295 */
303 bool _inSwitch = false; 296 bool _inSwitch = false;
304 static String _HIDE = "hide"; 297 static String _HIDE = "hide";
305 static String _OF = "of"; 298 static String _OF = "of";
306 static String _ON = "on"; 299 static String _ON = "on";
307 static String _SHOW = "show"; 300 static String _SHOW = "show";
308 static String _NATIVE = "native"; 301 static String _NATIVE = "native";
309 302
310 /** 303 /**
311 * Initialize a newly created parser. 304 * Initialize a newly created parser.
312 * @param source the source being parsed 305 * @param source the source being parsed
313 * @param errorListener the error listener that will be informed of any errors that are found 306 * @param errorListener the error listener that will be informed of any errors that are found
314 * during the parse 307 * during the parse
315 */ 308 */
316 Parser(Source source, AnalysisErrorListener errorListener) { 309 Parser(Source source, AnalysisErrorListener errorListener) {
317 this._source = source; 310 this._source = source;
318 this._errorListener = errorListener; 311 this._errorListener = errorListener;
319 } 312 }
320 313
321 /** 314 /**
322 * Parse a compilation unit, starting with the given token. 315 * Parse a compilation unit, starting with the given token.
323 * @param token the first token of the compilation unit 316 * @param token the first token of the compilation unit
324 * @return the compilation unit that was parsed 317 * @return the compilation unit that was parsed
325 */ 318 */
326 CompilationUnit parseCompilationUnit(Token token) { 319 CompilationUnit parseCompilationUnit(Token token) {
327 InstrumentationBuilder instrumentation = Instrumentation.builder2("dart.engi ne.Parser.parseCompilationUnit"); 320 InstrumentationBuilder instrumentation = Instrumentation.builder2("dart.engi ne.Parser.parseCompilationUnit");
328 try { 321 try {
329 _currentToken = token; 322 _currentToken = token;
330 return parseCompilationUnit2(); 323 return parseCompilationUnit2();
331 } finally { 324 } finally {
332 instrumentation.log(); 325 instrumentation.log();
333 } 326 }
334 } 327 }
335 328
336 /** 329 /**
337 * Parse an expression, starting with the given token. 330 * Parse an expression, starting with the given token.
338 * @param token the first token of the expression 331 * @param token the first token of the expression
339 * @return the expression that was parsed, or {@code null} if the tokens do no t represent a 332 * @return the expression that was parsed, or {@code null} if the tokens do no t represent a
340 * recognizable expression 333 * recognizable expression
341 */ 334 */
342 Expression parseExpression(Token token) { 335 Expression parseExpression(Token token) {
343 InstrumentationBuilder instrumentation = Instrumentation.builder2("dart.engi ne.Parser.parseExpression"); 336 InstrumentationBuilder instrumentation = Instrumentation.builder2("dart.engi ne.Parser.parseExpression");
344 try { 337 try {
345 _currentToken = token; 338 _currentToken = token;
346 return parseExpression2(); 339 return parseExpression2();
347 } finally { 340 } finally {
348 instrumentation.log(); 341 instrumentation.log();
349 } 342 }
350 } 343 }
351 344
352 /** 345 /**
353 * Parse a statement, starting with the given token. 346 * Parse a statement, starting with the given token.
354 * @param token the first token of the statement 347 * @param token the first token of the statement
355 * @return the statement that was parsed, or {@code null} if the tokens do not represent a 348 * @return the statement that was parsed, or {@code null} if the tokens do not represent a
356 * recognizable statement 349 * recognizable statement
357 */ 350 */
358 Statement parseStatement(Token token) { 351 Statement parseStatement(Token token) {
359 InstrumentationBuilder instrumentation = Instrumentation.builder2("dart.engi ne.Parser.parseStatement"); 352 InstrumentationBuilder instrumentation = Instrumentation.builder2("dart.engi ne.Parser.parseStatement");
360 try { 353 try {
361 _currentToken = token; 354 _currentToken = token;
362 return parseStatement2(); 355 return parseStatement2();
363 } finally { 356 } finally {
364 instrumentation.log(); 357 instrumentation.log();
365 } 358 }
366 } 359 }
367 360
368 /** 361 /**
369 * Parse a sequence of statements, starting with the given token. 362 * Parse a sequence of statements, starting with the given token.
370 * @param token the first token of the sequence of statement 363 * @param token the first token of the sequence of statement
371 * @return the statements that were parsed, or {@code null} if the tokens do n ot represent a 364 * @return the statements that were parsed, or {@code null} if the tokens do n ot represent a
372 * recognizable sequence of statements 365 * recognizable sequence of statements
373 */ 366 */
374 List<Statement> parseStatements(Token token) { 367 List<Statement> parseStatements(Token token) {
375 InstrumentationBuilder instrumentation = Instrumentation.builder2("dart.engi ne.Parser.parseStatements"); 368 InstrumentationBuilder instrumentation = Instrumentation.builder2("dart.engi ne.Parser.parseStatements");
376 try { 369 try {
377 _currentToken = token; 370 _currentToken = token;
378 return parseStatements2(); 371 return parseStatements2();
379 } finally { 372 } finally {
380 instrumentation.log(); 373 instrumentation.log();
381 } 374 }
382 } 375 }
383 void set currentToken(Token currentToken2) { 376 void set currentToken(Token currentToken2) {
384 this._currentToken = currentToken2; 377 this._currentToken = currentToken2;
385 } 378 }
386 379
387 /** 380 /**
388 * Advance to the next token in the token stream. 381 * Advance to the next token in the token stream.
389 */ 382 */
390 void advance() { 383 void advance() {
391 _currentToken = _currentToken.next; 384 _currentToken = _currentToken.next;
392 } 385 }
393 386
394 /** 387 /**
395 * Append the character equivalent of the given scalar value to the given buil der. Use the start 388 * Append the character equivalent of the given scalar value to the given buil der. Use the start
396 * and end indices to report an error, and don't append anything to the builde r, if the scalar 389 * and end indices to report an error, and don't append anything to the builde r, if the scalar
397 * value is invalid. 390 * value is invalid.
398 * @param builder the builder to which the scalar value is to be appended 391 * @param builder the builder to which the scalar value is to be appended
399 * @param escapeSequence the escape sequence that was parsed to produce the sc alar value 392 * @param escapeSequence the escape sequence that was parsed to produce the sc alar value
400 * @param scalarValue the value to be appended 393 * @param scalarValue the value to be appended
401 * @param startIndex the index of the first character representing the scalar value 394 * @param startIndex the index of the first character representing the scalar value
402 * @param endIndex the index of the last character representing the scalar val ue 395 * @param endIndex the index of the last character representing the scalar val ue
403 */ 396 */
404 void appendScalarValue(JavaStringBuilder builder, String escapeSequence, int s calarValue, int startIndex, int endIndex) { 397 void appendScalarValue(JavaStringBuilder builder, String escapeSequence, int s calarValue, int startIndex, int endIndex) {
405 if (scalarValue < 0 || scalarValue > Character.MAX_CODE_POINT || (scalarValu e >= 0xD800 && scalarValue <= 0xDFFF)) { 398 if (scalarValue < 0 || scalarValue > Character.MAX_CODE_POINT || (scalarValu e >= 0xD800 && scalarValue <= 0xDFFF)) {
406 reportError7(ParserErrorCode.INVALID_CODE_POINT, [escapeSequence]); 399 reportError7(ParserErrorCode.INVALID_CODE_POINT, [escapeSequence]);
407 return; 400 return;
408 } 401 }
409 if (scalarValue < Character.MAX_VALUE) { 402 if (scalarValue < Character.MAX_VALUE) {
410 builder.appendChar((scalarValue as int)); 403 builder.appendChar((scalarValue as int));
411 } else { 404 } else {
412 builder.append(Character.toChars(scalarValue)); 405 builder.append(Character.toChars(scalarValue));
413 } 406 }
414 } 407 }
415 408
416 /** 409 /**
417 * Compute the content of a string with the given literal representation. 410 * Compute the content of a string with the given literal representation.
418 * @param lexeme the literal representation of the string 411 * @param lexeme the literal representation of the string
419 * @return the actual value of the string 412 * @return the actual value of the string
420 */ 413 */
421 String computeStringValue(String lexeme) { 414 String computeStringValue(String lexeme) {
422 if (lexeme.startsWith("r\"\"\"") || lexeme.startsWith("r'''")) { 415 if (lexeme.startsWith("r\"\"\"") || lexeme.startsWith("r'''")) {
423 if (lexeme.length > 4) { 416 if (lexeme.length > 4) {
424 return lexeme.substring(4, lexeme.length - 3); 417 return lexeme.substring(4, lexeme.length - 3);
425 } 418 }
(...skipping 14 matching lines...) Expand all
440 } else if (end > 1 && (lexeme.endsWith("\"") || lexeme.endsWith("'"))) { 433 } else if (end > 1 && (lexeme.endsWith("\"") || lexeme.endsWith("'"))) {
441 end -= 1; 434 end -= 1;
442 } 435 }
443 JavaStringBuilder builder = new JavaStringBuilder(); 436 JavaStringBuilder builder = new JavaStringBuilder();
444 int index = start; 437 int index = start;
445 while (index < end) { 438 while (index < end) {
446 index = translateCharacter(builder, lexeme, index); 439 index = translateCharacter(builder, lexeme, index);
447 } 440 }
448 return builder.toString(); 441 return builder.toString();
449 } 442 }
450 443
451 /** 444 /**
452 * Convert the given method declaration into the nearest valid top-level funct ion declaration. 445 * Convert the given method declaration into the nearest valid top-level funct ion declaration.
453 * @param method the method to be converted 446 * @param method the method to be converted
454 * @return the function declaration that most closely captures the components of the given method 447 * @return the function declaration that most closely captures the components of the given method
455 * declaration 448 * declaration
456 */ 449 */
457 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)); 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));
458 451
459 /** 452 /**
460 * Return {@code true} if the current token could be the start of a compilatio n unit member. This 453 * Return {@code true} if the current token could be the start of a compilatio n unit member. This
461 * method is used for recovery purposes to decide when to stop skipping tokens after finding an 454 * method is used for recovery purposes to decide when to stop skipping tokens after finding an
462 * error while parsing a compilation unit member. 455 * error while parsing a compilation unit member.
463 * @return {@code true} if the current token could be the start of a compilati on unit member 456 * @return {@code true} if the current token could be the start of a compilati on unit member
464 */ 457 */
465 bool couldBeStartOfCompilationUnitMember() { 458 bool couldBeStartOfCompilationUnitMember() {
466 if ((matches(Keyword.IMPORT) || matches(Keyword.EXPORT) || matches(Keyword.L IBRARY) || matches(Keyword.PART)) && !matches4(peek(), TokenType.PERIOD) && !mat ches4(peek(), TokenType.LT)) { 459 if ((matches(Keyword.IMPORT) || matches(Keyword.EXPORT) || matches(Keyword.L IBRARY) || matches(Keyword.PART)) && !matches4(peek(), TokenType.PERIOD) && !mat ches4(peek(), TokenType.LT)) {
467 return true; 460 return true;
468 } else if (matches(Keyword.CLASS)) { 461 } else if (matches(Keyword.CLASS)) {
469 return true; 462 return true;
470 } else if (matches(Keyword.TYPEDEF) && !matches4(peek(), TokenType.PERIOD) & & !matches4(peek(), TokenType.LT)) { 463 } else if (matches(Keyword.TYPEDEF) && !matches4(peek(), TokenType.PERIOD) & & !matches4(peek(), TokenType.LT)) {
471 return true; 464 return true;
472 } else if (matches(Keyword.VOID) || ((matches(Keyword.GET) || matches(Keywor d.SET)) && matchesIdentifier2(peek())) || (matches(Keyword.OPERATOR) && isOperat or(peek()))) { 465 } else if (matches(Keyword.VOID) || ((matches(Keyword.GET) || matches(Keywor d.SET)) && matchesIdentifier2(peek())) || (matches(Keyword.OPERATOR) && isOperat or(peek()))) {
473 return true; 466 return true;
474 } else if (matchesIdentifier()) { 467 } else if (matchesIdentifier()) {
475 if (matches4(peek(), TokenType.OPEN_PAREN)) { 468 if (matches4(peek(), TokenType.OPEN_PAREN)) {
476 return true; 469 return true;
477 } 470 }
478 Token token = skipReturnType(_currentToken); 471 Token token = skipReturnType(_currentToken);
479 if (token == null) { 472 if (token == null) {
480 return false; 473 return false;
481 } 474 }
482 if (matches(Keyword.GET) || matches(Keyword.SET) || (matches(Keyword.OPERA TOR) && isOperator(peek())) || matchesIdentifier()) { 475 if (matches(Keyword.GET) || matches(Keyword.SET) || (matches(Keyword.OPERA TOR) && isOperator(peek())) || matchesIdentifier()) {
483 return true; 476 return true;
484 } 477 }
485 } 478 }
486 return false; 479 return false;
487 } 480 }
488 481
489 /** 482 /**
490 * Create a synthetic identifier. 483 * Create a synthetic identifier.
491 * @return the synthetic identifier that was created 484 * @return the synthetic identifier that was created
492 */ 485 */
493 SimpleIdentifier createSyntheticIdentifier() => new SimpleIdentifier.full(crea teSyntheticToken2(TokenType.IDENTIFIER)); 486 SimpleIdentifier createSyntheticIdentifier() => new SimpleIdentifier.full(crea teSyntheticToken2(TokenType.IDENTIFIER));
494 487
495 /** 488 /**
496 * Create a synthetic string literal. 489 * Create a synthetic string literal.
497 * @return the synthetic string literal that was created 490 * @return the synthetic string literal that was created
498 */ 491 */
499 SimpleStringLiteral createSyntheticStringLiteral() => new SimpleStringLiteral. full(createSyntheticToken2(TokenType.STRING), ""); 492 SimpleStringLiteral createSyntheticStringLiteral() => new SimpleStringLiteral. full(createSyntheticToken2(TokenType.STRING), "");
500 493
501 /** 494 /**
502 * Create a synthetic token representing the given keyword. 495 * Create a synthetic token representing the given keyword.
503 * @return the synthetic token that was created 496 * @return the synthetic token that was created
504 */ 497 */
505 Token createSyntheticToken(Keyword keyword) => new KeywordToken_11(keyword, _c urrentToken.offset); 498 Token createSyntheticToken(Keyword keyword) => new KeywordToken_11(keyword, _c urrentToken.offset);
506 499
507 /** 500 /**
508 * Create a synthetic token with the given type. 501 * Create a synthetic token with the given type.
509 * @return the synthetic token that was created 502 * @return the synthetic token that was created
510 */ 503 */
511 Token createSyntheticToken2(TokenType type) => new StringToken(type, "", _curr entToken.offset); 504 Token createSyntheticToken2(TokenType type) => new StringToken(type, "", _curr entToken.offset);
512 505
513 /** 506 /**
514 * Check that the given expression is assignable and report an error if it isn 't. 507 * Check that the given expression is assignable and report an error if it isn 't.
515 * <pre> 508 * <pre>
516 * assignableExpression ::= 509 * assignableExpression ::=
517 * primary (arguments* assignableSelector)+ 510 * primary (arguments* assignableSelector)+
518 * | 'super' assignableSelector 511 * | 'super' assignableSelector
519 * | identifier 512 * | identifier
520 * assignableSelector ::= 513 * assignableSelector ::=
521 * '\[' expression '\]' 514 * '\[' expression '\]'
522 * | '.' identifier 515 * | '.' identifier
523 * </pre> 516 * </pre>
524 * @param expression the expression being checked 517 * @param expression the expression being checked
525 */ 518 */
526 void ensureAssignable(Expression expression) { 519 void ensureAssignable(Expression expression) {
527 if (expression != null && !expression.isAssignable()) { 520 if (expression != null && !expression.isAssignable()) {
528 reportError7(ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, []); 521 reportError7(ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, []);
529 } 522 }
530 } 523 }
531 524
532 /** 525 /**
533 * If the current token is a keyword matching the given string, return it afte r advancing to the 526 * If the current token is a keyword matching the given string, return it afte r advancing to the
534 * next token. Otherwise report an error and return the current token without advancing. 527 * next token. Otherwise report an error and return the current token without advancing.
535 * @param keyword the keyword that is expected 528 * @param keyword the keyword that is expected
536 * @return the token that matched the given type 529 * @return the token that matched the given type
537 */ 530 */
538 Token expect(Keyword keyword) { 531 Token expect(Keyword keyword) {
539 if (matches(keyword)) { 532 if (matches(keyword)) {
540 return andAdvance; 533 return andAdvance;
541 } 534 }
542 reportError7(ParserErrorCode.EXPECTED_TOKEN, [keyword.syntax]); 535 reportError7(ParserErrorCode.EXPECTED_TOKEN, [keyword.syntax]);
543 return _currentToken; 536 return _currentToken;
544 } 537 }
545 538
546 /** 539 /**
547 * If the current token has the expected type, return it after advancing to th e next token. 540 * If the current token has the expected type, return it after advancing to th e next token.
548 * Otherwise report an error and return the current token without advancing. 541 * Otherwise report an error and return the current token without advancing.
549 * @param type the type of token that is expected 542 * @param type the type of token that is expected
550 * @return the token that matched the given type 543 * @return the token that matched the given type
551 */ 544 */
552 Token expect2(TokenType type) { 545 Token expect2(TokenType type) {
553 if (matches5(type)) { 546 if (matches5(type)) {
554 return andAdvance; 547 return andAdvance;
555 } 548 }
556 if (identical(type, TokenType.SEMICOLON)) { 549 if (identical(type, TokenType.SEMICOLON)) {
557 reportError8(ParserErrorCode.EXPECTED_TOKEN, _currentToken.previous, [type .lexeme]); 550 reportError8(ParserErrorCode.EXPECTED_TOKEN, _currentToken.previous, [type .lexeme]);
558 } else { 551 } else {
559 reportError7(ParserErrorCode.EXPECTED_TOKEN, [type.lexeme]); 552 reportError7(ParserErrorCode.EXPECTED_TOKEN, [type.lexeme]);
560 } 553 }
561 return _currentToken; 554 return _currentToken;
562 } 555 }
563 556
564 /** 557 /**
565 * Search the given list of ranges for a range that contains the given index. Return the range 558 * Search the given list of ranges for a range that contains the given index. Return the range
566 * that was found, or {@code null} if none of the ranges contain the index. 559 * that was found, or {@code null} if none of the ranges contain the index.
567 * @param ranges the ranges to be searched 560 * @param ranges the ranges to be searched
568 * @param index the index contained in the returned range 561 * @param index the index contained in the returned range
569 * @return the range that was found 562 * @return the range that was found
570 */ 563 */
571 List<int> findRange(List<List<int>> ranges, int index) { 564 List<int> findRange(List<List<int>> ranges, int index) {
572 for (List<int> range in ranges) { 565 for (List<int> range in ranges) {
573 if (range[0] <= index && index <= range[1]) { 566 if (range[0] <= index && index <= range[1]) {
574 return range; 567 return range;
575 } else if (index < range[0]) { 568 } else if (index < range[0]) {
576 return null; 569 return null;
577 } 570 }
578 } 571 }
579 return null; 572 return null;
580 } 573 }
581 574
582 /** 575 /**
583 * Advance to the next token in the token stream, making it the new current to ken. 576 * Advance to the next token in the token stream, making it the new current to ken.
584 * @return the token that was current before this method was invoked 577 * @return the token that was current before this method was invoked
585 */ 578 */
586 Token get andAdvance { 579 Token get andAdvance {
587 Token token = _currentToken; 580 Token token = _currentToken;
588 advance(); 581 advance();
589 return token; 582 return token;
590 } 583 }
591 584
592 /** 585 /**
593 * Return a list of the ranges of characters in the given comment string that should be treated as 586 * Return a list of the ranges of characters in the given comment string that should be treated as
594 * code blocks. 587 * code blocks.
595 * @param comment the comment being processed 588 * @param comment the comment being processed
596 * @return the ranges of characters that should be treated as code blocks 589 * @return the ranges of characters that should be treated as code blocks
597 */ 590 */
598 List<List<int>> getCodeBlockRanges(String comment) { 591 List<List<int>> getCodeBlockRanges(String comment) {
599 List<List<int>> ranges = new List<List<int>>(); 592 List<List<int>> ranges = new List<List<int>>();
600 int length2 = comment.length; 593 int length2 = comment.length;
601 int index = 0; 594 int index = 0;
(...skipping 21 matching lines...) Expand all
623 end = length2; 616 end = length2;
624 } 617 }
625 ranges.add(<int> [index, end]); 618 ranges.add(<int> [index, end]);
626 index = end + 1; 619 index = end + 1;
627 } else { 620 } else {
628 index = index + 1; 621 index = index + 1;
629 } 622 }
630 } 623 }
631 return ranges; 624 return ranges;
632 } 625 }
633 626
634 /** 627 /**
635 * Return the end token associated with the given begin token, or {@code null} if either the given 628 * Return the end token associated with the given begin token, or {@code null} if either the given
636 * token is not a begin token or it does not have an end token associated with it. 629 * token is not a begin token or it does not have an end token associated with it.
637 * @param beginToken the token that is expected to have an end token associate d with it 630 * @param beginToken the token that is expected to have an end token associate d with it
638 * @return the end token associated with the begin token 631 * @return the end token associated with the begin token
639 */ 632 */
640 Token getEndToken(Token beginToken) { 633 Token getEndToken(Token beginToken) {
641 if (beginToken is BeginToken) { 634 if (beginToken is BeginToken) {
642 return ((beginToken as BeginToken)).endToken; 635 return ((beginToken as BeginToken)).endToken;
643 } 636 }
644 return null; 637 return null;
645 } 638 }
646 639
647 /** 640 /**
648 * Return {@code true} if the current token is the first token of a return typ e that is followed 641 * Return {@code true} if the current token is the first token of a return typ e that is followed
649 * by an identifier, possibly followed by a list of type parameters, followed by a 642 * by an identifier, possibly followed by a list of type parameters, followed by a
650 * left-parenthesis. This is used by parseTypeAlias to determine whether or no t to parse a return 643 * left-parenthesis. This is used by parseTypeAlias to determine whether or no t to parse a return
651 * type. 644 * type.
652 * @return {@code true} if we can successfully parse the rest of a type alias if we first parse a 645 * @return {@code true} if we can successfully parse the rest of a type alias if we first parse a
653 * return type. 646 * return type.
654 */ 647 */
655 bool hasReturnTypeInTypeAlias() { 648 bool hasReturnTypeInTypeAlias() {
656 Token next = skipReturnType(_currentToken); 649 Token next = skipReturnType(_currentToken);
657 if (next == null) { 650 if (next == null) {
658 return false; 651 return false;
659 } 652 }
660 return matchesIdentifier2(next); 653 return matchesIdentifier2(next);
661 } 654 }
662 655
663 /** 656 /**
664 * Return {@code true} if the current token appears to be the beginning of a f unction declaration. 657 * Return {@code true} if the current token appears to be the beginning of a f unction declaration.
665 * @return {@code true} if the current token appears to be the beginning of a function declaration 658 * @return {@code true} if the current token appears to be the beginning of a function declaration
666 */ 659 */
667 bool isFunctionDeclaration() { 660 bool isFunctionDeclaration() {
668 if (matches(Keyword.VOID)) { 661 if (matches(Keyword.VOID)) {
669 return true; 662 return true;
670 } 663 }
671 Token afterReturnType = skipTypeName(_currentToken); 664 Token afterReturnType = skipTypeName(_currentToken);
672 if (afterReturnType == null) { 665 if (afterReturnType == null) {
673 afterReturnType = _currentToken; 666 afterReturnType = _currentToken;
674 } 667 }
675 Token afterIdentifier = skipSimpleIdentifier(afterReturnType); 668 Token afterIdentifier = skipSimpleIdentifier(afterReturnType);
676 if (afterIdentifier == null) { 669 if (afterIdentifier == null) {
677 afterIdentifier = skipSimpleIdentifier(_currentToken); 670 afterIdentifier = skipSimpleIdentifier(_currentToken);
678 } 671 }
679 if (afterIdentifier == null) { 672 if (afterIdentifier == null) {
680 return false; 673 return false;
681 } 674 }
682 return isFunctionExpression(afterIdentifier); 675 return isFunctionExpression(afterIdentifier);
683 } 676 }
684 677
685 /** 678 /**
686 * Return {@code true} if the given token appears to be the beginning of a fun ction expression. 679 * Return {@code true} if the given token appears to be the beginning of a fun ction expression.
687 * @param startToken the token that might be the start of a function expressio n 680 * @param startToken the token that might be the start of a function expressio n
688 * @return {@code true} if the given token appears to be the beginning of a fu nction expression 681 * @return {@code true} if the given token appears to be the beginning of a fu nction expression
689 */ 682 */
690 bool isFunctionExpression(Token startToken) { 683 bool isFunctionExpression(Token startToken) {
691 Token afterParameters = skipFormalParameterList(startToken); 684 Token afterParameters = skipFormalParameterList(startToken);
692 if (afterParameters == null) { 685 if (afterParameters == null) {
693 return false; 686 return false;
694 } 687 }
695 return matchesAny(afterParameters, [TokenType.OPEN_CURLY_BRACKET, TokenType. FUNCTION]); 688 return matchesAny(afterParameters, [TokenType.OPEN_CURLY_BRACKET, TokenType. FUNCTION]);
696 } 689 }
697 690
698 /** 691 /**
699 * Return {@code true} if the given character is a valid hexadecimal digit. 692 * Return {@code true} if the given character is a valid hexadecimal digit.
700 * @param character the character being tested 693 * @param character the character being tested
701 * @return {@code true} if the character is a valid hexadecimal digit 694 * @return {@code true} if the character is a valid hexadecimal digit
702 */ 695 */
703 bool isHexDigit(int character) => (0x30 <= character && character <= 0x39) || (0x41 <= character && character <= 0x46) || (0x61 <= character && character <= 0 x66); 696 bool isHexDigit(int character) => (0x30 <= character && character <= 0x39) || (0x41 <= character && character <= 0x46) || (0x61 <= character && character <= 0 x66);
704 697
705 /** 698 /**
706 * Return {@code true} if the current token is the first token in an initializ ed variable 699 * Return {@code true} if the current token is the first token in an initializ ed variable
707 * declaration rather than an expression. This method assumes that we have alr eady skipped past 700 * declaration rather than an expression. This method assumes that we have alr eady skipped past
708 * any metadata that might be associated with the declaration. 701 * any metadata that might be associated with the declaration.
709 * <pre> 702 * <pre>
710 * initializedVariableDeclaration ::= 703 * initializedVariableDeclaration ::=
711 * declaredIdentifier ('=' expression)? (',' initializedIdentifier) 704 * declaredIdentifier ('=' expression)? (',' initializedIdentifier)
712 * declaredIdentifier ::= 705 * declaredIdentifier ::=
713 * metadata finalConstVarOrType identifier 706 * metadata finalConstVarOrType identifier
714 * finalConstVarOrType ::= 707 * finalConstVarOrType ::=
(...skipping 20 matching lines...) Expand all
735 if (token == null) { 728 if (token == null) {
736 return false; 729 return false;
737 } 730 }
738 token = skipSimpleIdentifier(token); 731 token = skipSimpleIdentifier(token);
739 if (token == null) { 732 if (token == null) {
740 return false; 733 return false;
741 } 734 }
742 TokenType type2 = token.type; 735 TokenType type2 = token.type;
743 return identical(type2, TokenType.EQ) || identical(type2, TokenType.COMMA) | | identical(type2, TokenType.SEMICOLON) || matches3(token, Keyword.IN); 736 return identical(type2, TokenType.EQ) || identical(type2, TokenType.COMMA) | | identical(type2, TokenType.SEMICOLON) || matches3(token, Keyword.IN);
744 } 737 }
745 738
746 /** 739 /**
747 * Given that we have just found bracketed text within a comment, look to see whether that text is 740 * Given that we have just found bracketed text within a comment, look to see whether that text is
748 * (a) followed by a parenthesized link address, (b) followed by a colon, or ( c) followed by 741 * (a) followed by a parenthesized link address, (b) followed by a colon, or ( c) followed by
749 * optional whitespace and another square bracket. 742 * optional whitespace and another square bracket.
750 * <p> 743 * <p>
751 * This method uses the syntax described by the <a 744 * This method uses the syntax described by the <a
752 * href="http://daringfireball.net/projects/markdown/syntax">markdown</a> proj ect. 745 * href="http://daringfireball.net/projects/markdown/syntax">markdown</a> proj ect.
753 * @param comment the comment text in which the bracketed text was found 746 * @param comment the comment text in which the bracketed text was found
754 * @param rightIndex the index of the right bracket 747 * @param rightIndex the index of the right bracket
755 * @return {@code true} if the bracketed text is followed by a link address 748 * @return {@code true} if the bracketed text is followed by a link address
(...skipping 10 matching lines...) Expand all
766 } 759 }
767 while (Character.isWhitespace(nextChar)) { 760 while (Character.isWhitespace(nextChar)) {
768 index = index + 1; 761 index = index + 1;
769 if (index >= length2) { 762 if (index >= length2) {
770 return false; 763 return false;
771 } 764 }
772 nextChar = comment.codeUnitAt(index); 765 nextChar = comment.codeUnitAt(index);
773 } 766 }
774 return nextChar == 0x5B; 767 return nextChar == 0x5B;
775 } 768 }
776 769
777 /** 770 /**
778 * Return {@code true} if the given token appears to be the beginning of an op erator declaration. 771 * Return {@code true} if the given token appears to be the beginning of an op erator declaration.
779 * @param startToken the token that might be the start of an operator declarat ion 772 * @param startToken the token that might be the start of an operator declarat ion
780 * @return {@code true} if the given token appears to be the beginning of an o perator declaration 773 * @return {@code true} if the given token appears to be the beginning of an o perator declaration
781 */ 774 */
782 bool isOperator(Token startToken) { 775 bool isOperator(Token startToken) {
783 if (startToken.isOperator()) { 776 if (startToken.isOperator()) {
784 Token token = startToken.next; 777 Token token = startToken.next;
785 while (token.isOperator()) { 778 while (token.isOperator()) {
786 token = token.next; 779 token = token.next;
787 } 780 }
788 return matches4(token, TokenType.OPEN_PAREN); 781 return matches4(token, TokenType.OPEN_PAREN);
789 } 782 }
790 return false; 783 return false;
791 } 784 }
792 785
793 /** 786 /**
794 * Return {@code true} if the current token appears to be the beginning of a s witch member. 787 * Return {@code true} if the current token appears to be the beginning of a s witch member.
795 * @return {@code true} if the current token appears to be the beginning of a switch member 788 * @return {@code true} if the current token appears to be the beginning of a switch member
796 */ 789 */
797 bool isSwitchMember() { 790 bool isSwitchMember() {
798 Token token = _currentToken; 791 Token token = _currentToken;
799 while (matches4(token, TokenType.IDENTIFIER) && matches4(token.next, TokenTy pe.COLON)) { 792 while (matches4(token, TokenType.IDENTIFIER) && matches4(token.next, TokenTy pe.COLON)) {
800 token = token.next.next; 793 token = token.next.next;
801 } 794 }
802 if (identical(token.type, TokenType.KEYWORD)) { 795 if (identical(token.type, TokenType.KEYWORD)) {
803 Keyword keyword2 = ((token as KeywordToken)).keyword; 796 Keyword keyword2 = ((token as KeywordToken)).keyword;
804 return identical(keyword2, Keyword.CASE) || identical(keyword2, Keyword.DE FAULT); 797 return identical(keyword2, Keyword.CASE) || identical(keyword2, Keyword.DE FAULT);
805 } 798 }
806 return false; 799 return false;
807 } 800 }
808 801
809 /** 802 /**
810 * Compare the given tokens to find the token that appears first in the source being parsed. That 803 * Compare the given tokens to find the token that appears first in the source being parsed. That
811 * is, return the left-most of all of the tokens. The arguments are allowed to be {@code null}. 804 * is, return the left-most of all of the tokens. The arguments are allowed to be {@code null}.
812 * Return the token with the smallest offset, or {@code null} if there are no arguments or if all 805 * Return the token with the smallest offset, or {@code null} if there are no arguments or if all
813 * of the arguments are {@code null}. 806 * of the arguments are {@code null}.
814 * @param tokens the tokens being compared 807 * @param tokens the tokens being compared
815 * @return the token with the smallest offset 808 * @return the token with the smallest offset
816 */ 809 */
817 Token lexicallyFirst(List<Token> tokens) { 810 Token lexicallyFirst(List<Token> tokens) {
818 Token first = null; 811 Token first = null;
819 int firstOffset = 2147483647; 812 int firstOffset = 2147483647;
820 for (Token token in tokens) { 813 for (Token token in tokens) {
821 if (token != null) { 814 if (token != null) {
822 int offset2 = token.offset; 815 int offset2 = token.offset;
823 if (offset2 < firstOffset) { 816 if (offset2 < firstOffset) {
824 first = token; 817 first = token;
825 firstOffset = offset2; 818 firstOffset = offset2;
826 } 819 }
827 } 820 }
828 } 821 }
829 return first; 822 return first;
830 } 823 }
831 824
832 /** 825 /**
833 * Return {@code true} if the current token matches the given keyword. 826 * Return {@code true} if the current token matches the given keyword.
834 * @param keyword the keyword that can optionally appear in the current locati on 827 * @param keyword the keyword that can optionally appear in the current locati on
835 * @return {@code true} if the current token matches the given keyword 828 * @return {@code true} if the current token matches the given keyword
836 */ 829 */
837 bool matches(Keyword keyword) => matches3(_currentToken, keyword); 830 bool matches(Keyword keyword) => matches3(_currentToken, keyword);
838 831
839 /** 832 /**
840 * Return {@code true} if the current token matches the given identifier. 833 * Return {@code true} if the current token matches the given identifier.
841 * @param identifier the identifier that can optionally appear in the current location 834 * @param identifier the identifier that can optionally appear in the current location
842 * @return {@code true} if the current token matches the given identifier 835 * @return {@code true} if the current token matches the given identifier
843 */ 836 */
844 bool matches2(String identifier) => identical(_currentToken.type, TokenType.ID ENTIFIER) && _currentToken.lexeme == identifier; 837 bool matches2(String identifier) => identical(_currentToken.type, TokenType.ID ENTIFIER) && _currentToken.lexeme == identifier;
845 838
846 /** 839 /**
847 * Return {@code true} if the given token matches the given keyword. 840 * Return {@code true} if the given token matches the given keyword.
848 * @param token the token being tested 841 * @param token the token being tested
849 * @param keyword the keyword that is being tested for 842 * @param keyword the keyword that is being tested for
850 * @return {@code true} if the given token matches the given keyword 843 * @return {@code true} if the given token matches the given keyword
851 */ 844 */
852 bool matches3(Token token, Keyword keyword2) => identical(token.type, TokenTyp e.KEYWORD) && identical(((token as KeywordToken)).keyword, keyword2); 845 bool matches3(Token token, Keyword keyword2) => identical(token.type, TokenTyp e.KEYWORD) && identical(((token as KeywordToken)).keyword, keyword2);
853 846
854 /** 847 /**
855 * Return {@code true} if the given token has the given type. 848 * Return {@code true} if the given token has the given type.
856 * @param token the token being tested 849 * @param token the token being tested
857 * @param type the type of token that is being tested for 850 * @param type the type of token that is being tested for
858 * @return {@code true} if the given token has the given type 851 * @return {@code true} if the given token has the given type
859 */ 852 */
860 bool matches4(Token token, TokenType type2) => identical(token.type, type2); 853 bool matches4(Token token, TokenType type2) => identical(token.type, type2);
861 854
862 /** 855 /**
863 * Return {@code true} if the current token has the given type. Note that this method, unlike 856 * Return {@code true} if the current token has the given type. Note that this method, unlike
864 * other variants, will modify the token stream if possible to match a wider r ange of tokens. In 857 * other variants, will modify the token stream if possible to match a wider r ange of tokens. In
865 * particular, if we are attempting to match a '>' and the next token is eithe r a '>>' or '>>>', 858 * particular, if we are attempting to match a '>' and the next token is eithe r a '>>' or '>>>',
866 * the token stream will be re-written and {@code true} will be returned. 859 * the token stream will be re-written and {@code true} will be returned.
867 * @param type the type of token that can optionally appear in the current loc ation 860 * @param type the type of token that can optionally appear in the current loc ation
868 * @return {@code true} if the current token has the given type 861 * @return {@code true} if the current token has the given type
869 */ 862 */
870 bool matches5(TokenType type2) { 863 bool matches5(TokenType type2) {
871 TokenType currentType = _currentToken.type; 864 TokenType currentType = _currentToken.type;
(...skipping 27 matching lines...) Expand all
899 first.setNext(second); 892 first.setNext(second);
900 _currentToken.previous.setNext(first); 893 _currentToken.previous.setNext(first);
901 _currentToken = first; 894 _currentToken = first;
902 return true; 895 return true;
903 } 896 }
904 } 897 }
905 return false; 898 return false;
906 } 899 }
907 return true; 900 return true;
908 } 901 }
909 902
910 /** 903 /**
911 * Return {@code true} if the given token has any one of the given types. 904 * Return {@code true} if the given token has any one of the given types.
912 * @param token the token being tested 905 * @param token the token being tested
913 * @param types the types of token that are being tested for 906 * @param types the types of token that are being tested for
914 * @return {@code true} if the given token has any of the given types 907 * @return {@code true} if the given token has any of the given types
915 */ 908 */
916 bool matchesAny(Token token, List<TokenType> types) { 909 bool matchesAny(Token token, List<TokenType> types) {
917 TokenType actualType = token.type; 910 TokenType actualType = token.type;
918 for (TokenType type in types) { 911 for (TokenType type in types) {
919 if (identical(actualType, type)) { 912 if (identical(actualType, type)) {
920 return true; 913 return true;
921 } 914 }
922 } 915 }
923 return false; 916 return false;
924 } 917 }
925 918
926 /** 919 /**
927 * Return {@code true} if the current token is a valid identifier. Valid ident ifiers include 920 * Return {@code true} if the current token is a valid identifier. Valid ident ifiers include
928 * built-in identifiers (pseudo-keywords). 921 * built-in identifiers (pseudo-keywords).
929 * @return {@code true} if the current token is a valid identifier 922 * @return {@code true} if the current token is a valid identifier
930 */ 923 */
931 bool matchesIdentifier() => matchesIdentifier2(_currentToken); 924 bool matchesIdentifier() => matchesIdentifier2(_currentToken);
932 925
933 /** 926 /**
934 * Return {@code true} if the given token is a valid identifier. Valid identif iers include 927 * Return {@code true} if the given token is a valid identifier. Valid identif iers include
935 * built-in identifiers (pseudo-keywords). 928 * built-in identifiers (pseudo-keywords).
936 * @return {@code true} if the given token is a valid identifier 929 * @return {@code true} if the given token is a valid identifier
937 */ 930 */
938 bool matchesIdentifier2(Token token) => matches4(token, TokenType.IDENTIFIER) || (matches4(token, TokenType.KEYWORD) && ((token as KeywordToken)).keyword.isPs eudoKeyword()); 931 bool matchesIdentifier2(Token token) => matches4(token, TokenType.IDENTIFIER) || (matches4(token, TokenType.KEYWORD) && ((token as KeywordToken)).keyword.isPs eudoKeyword());
939 932
940 /** 933 /**
941 * If the current token has the given type, then advance to the next token and return {@code true}. Otherwise, return {@code false} without advancing. 934 * If the current token has the given type, then advance to the next token and return {@code true}. Otherwise, return {@code false} without advancing.
942 * @param type the type of token that can optionally appear in the current loc ation 935 * @param type the type of token that can optionally appear in the current loc ation
943 * @return {@code true} if the current token has the given type 936 * @return {@code true} if the current token has the given type
944 */ 937 */
945 bool optional(TokenType type) { 938 bool optional(TokenType type) {
946 if (matches5(type)) { 939 if (matches5(type)) {
947 advance(); 940 advance();
948 return true; 941 return true;
949 } 942 }
950 return false; 943 return false;
951 } 944 }
952 945
953 /** 946 /**
954 * Parse an additive expression. 947 * Parse an additive expression.
955 * <pre> 948 * <pre>
956 * additiveExpression ::= 949 * additiveExpression ::=
957 * multiplicativeExpression (additiveOperator multiplicativeExpression) 950 * multiplicativeExpression (additiveOperator multiplicativeExpression)
958 * | 'super' (additiveOperator multiplicativeExpression)+ 951 * | 'super' (additiveOperator multiplicativeExpression)+
959 * </pre> 952 * </pre>
960 * @return the additive expression that was parsed 953 * @return the additive expression that was parsed
961 */ 954 */
962 Expression parseAdditiveExpression() { 955 Expression parseAdditiveExpression() {
963 Expression expression; 956 Expression expression;
964 if (matches(Keyword.SUPER) && _currentToken.next.type.isAdditiveOperator()) { 957 if (matches(Keyword.SUPER) && _currentToken.next.type.isAdditiveOperator()) {
965 expression = new SuperExpression.full(andAdvance); 958 expression = new SuperExpression.full(andAdvance);
966 } else { 959 } else {
967 expression = parseMultiplicativeExpression(); 960 expression = parseMultiplicativeExpression();
968 } 961 }
969 while (_currentToken.type.isAdditiveOperator()) { 962 while (_currentToken.type.isAdditiveOperator()) {
970 Token operator = andAdvance; 963 Token operator = andAdvance;
971 expression = new BinaryExpression.full(expression, operator, parseMultipli cativeExpression()); 964 expression = new BinaryExpression.full(expression, operator, parseMultipli cativeExpression());
972 } 965 }
973 return expression; 966 return expression;
974 } 967 }
975 968
976 /** 969 /**
977 * Parse an annotation. 970 * Parse an annotation.
978 * <pre> 971 * <pre>
979 * annotation ::= 972 * annotation ::=
980 * '@' qualified ('.' identifier)? arguments? 973 * '@' qualified ('.' identifier)? arguments?
981 * </pre> 974 * </pre>
982 * @return the annotation that was parsed 975 * @return the annotation that was parsed
983 */ 976 */
984 Annotation parseAnnotation() { 977 Annotation parseAnnotation() {
985 Token atSign = expect2(TokenType.AT); 978 Token atSign = expect2(TokenType.AT);
986 Identifier name = parsePrefixedIdentifier(); 979 Identifier name = parsePrefixedIdentifier();
987 Token period = null; 980 Token period = null;
988 SimpleIdentifier constructorName = null; 981 SimpleIdentifier constructorName = null;
989 if (matches5(TokenType.PERIOD)) { 982 if (matches5(TokenType.PERIOD)) {
990 period = andAdvance; 983 period = andAdvance;
991 constructorName = parseSimpleIdentifier(); 984 constructorName = parseSimpleIdentifier();
992 } 985 }
993 ArgumentList arguments = null; 986 ArgumentList arguments = null;
994 if (matches5(TokenType.OPEN_PAREN)) { 987 if (matches5(TokenType.OPEN_PAREN)) {
995 arguments = parseArgumentList(); 988 arguments = parseArgumentList();
996 } 989 }
997 return new Annotation.full(atSign, name, period, constructorName, arguments) ; 990 return new Annotation.full(atSign, name, period, constructorName, arguments) ;
998 } 991 }
999 992
1000 /** 993 /**
1001 * Parse an argument. 994 * Parse an argument.
1002 * <pre> 995 * <pre>
1003 * argument ::= 996 * argument ::=
1004 * namedArgument 997 * namedArgument
1005 * | expression 998 * | expression
1006 * namedArgument ::= 999 * namedArgument ::=
1007 * label expression 1000 * label expression
1008 * </pre> 1001 * </pre>
1009 * @return the argument that was parsed 1002 * @return the argument that was parsed
1010 */ 1003 */
1011 Expression parseArgument() { 1004 Expression parseArgument() {
1012 if (matchesIdentifier() && matches4(peek(), TokenType.COLON)) { 1005 if (matchesIdentifier() && matches4(peek(), TokenType.COLON)) {
1013 SimpleIdentifier label = new SimpleIdentifier.full(andAdvance); 1006 SimpleIdentifier label = new SimpleIdentifier.full(andAdvance);
1014 Label name = new Label.full(label, andAdvance); 1007 Label name = new Label.full(label, andAdvance);
1015 return new NamedExpression.full(name, parseExpression2()); 1008 return new NamedExpression.full(name, parseExpression2());
1016 } else { 1009 } else {
1017 return parseExpression2(); 1010 return parseExpression2();
1018 } 1011 }
1019 } 1012 }
1020 1013
1021 /** 1014 /**
1022 * Parse an argument definition test. 1015 * Parse an argument definition test.
1023 * <pre> 1016 * <pre>
1024 * argumentDefinitionTest ::= 1017 * argumentDefinitionTest ::=
1025 * '?' identifier 1018 * '?' identifier
1026 * </pre> 1019 * </pre>
1027 * @return the argument definition test that was parsed 1020 * @return the argument definition test that was parsed
1028 */ 1021 */
1029 ArgumentDefinitionTest parseArgumentDefinitionTest() { 1022 ArgumentDefinitionTest parseArgumentDefinitionTest() {
1030 Token question = expect2(TokenType.QUESTION); 1023 Token question = expect2(TokenType.QUESTION);
1031 SimpleIdentifier identifier = parseSimpleIdentifier(); 1024 SimpleIdentifier identifier = parseSimpleIdentifier();
1032 return new ArgumentDefinitionTest.full(question, identifier); 1025 return new ArgumentDefinitionTest.full(question, identifier);
1033 } 1026 }
1034 1027
1035 /** 1028 /**
1036 * Parse a list of arguments. 1029 * Parse a list of arguments.
1037 * <pre> 1030 * <pre>
1038 * arguments ::= 1031 * arguments ::=
1039 * '(' argumentList? ')' 1032 * '(' argumentList? ')'
1040 * argumentList ::= 1033 * argumentList ::=
1041 * namedArgument (',' namedArgument) 1034 * namedArgument (',' namedArgument)
1042 * | expressionList (',' namedArgument) 1035 * | expressionList (',' namedArgument)
1043 * </pre> 1036 * </pre>
1044 * @return the argument list that was parsed 1037 * @return the argument list that was parsed
(...skipping 16 matching lines...) Expand all
1061 reportError7(ParserErrorCode.POSITIONAL_AFTER_NAMED_ARGUMENT, []); 1054 reportError7(ParserErrorCode.POSITIONAL_AFTER_NAMED_ARGUMENT, []);
1062 generatedError = true; 1055 generatedError = true;
1063 } 1056 }
1064 } else if (argument is NamedExpression) { 1057 } else if (argument is NamedExpression) {
1065 foundNamedArgument = true; 1058 foundNamedArgument = true;
1066 } 1059 }
1067 } 1060 }
1068 Token rightParenthesis = expect2(TokenType.CLOSE_PAREN); 1061 Token rightParenthesis = expect2(TokenType.CLOSE_PAREN);
1069 return new ArgumentList.full(leftParenthesis, arguments, rightParenthesis); 1062 return new ArgumentList.full(leftParenthesis, arguments, rightParenthesis);
1070 } 1063 }
1071 1064
1072 /** 1065 /**
1073 * Parse an assert statement. 1066 * Parse an assert statement.
1074 * <pre> 1067 * <pre>
1075 * assertStatement ::= 1068 * assertStatement ::=
1076 * 'assert' '(' conditionalExpression ')' ';' 1069 * 'assert' '(' conditionalExpression ')' ';'
1077 * </pre> 1070 * </pre>
1078 * @return the assert statement 1071 * @return the assert statement
1079 */ 1072 */
1080 AssertStatement parseAssertStatement() { 1073 AssertStatement parseAssertStatement() {
1081 Token keyword = expect(Keyword.ASSERT); 1074 Token keyword = expect(Keyword.ASSERT);
1082 Token leftParen = expect2(TokenType.OPEN_PAREN); 1075 Token leftParen = expect2(TokenType.OPEN_PAREN);
1083 Expression expression = parseConditionalExpression(); 1076 Expression expression = parseConditionalExpression();
1084 Token rightParen = expect2(TokenType.CLOSE_PAREN); 1077 Token rightParen = expect2(TokenType.CLOSE_PAREN);
1085 Token semicolon = expect2(TokenType.SEMICOLON); 1078 Token semicolon = expect2(TokenType.SEMICOLON);
1086 return new AssertStatement.full(keyword, leftParen, expression, rightParen, semicolon); 1079 return new AssertStatement.full(keyword, leftParen, expression, rightParen, semicolon);
1087 } 1080 }
1088 1081
1089 /** 1082 /**
1090 * Parse an assignable expression. 1083 * Parse an assignable expression.
1091 * <pre> 1084 * <pre>
1092 * assignableExpression ::= 1085 * assignableExpression ::=
1093 * primary (arguments* assignableSelector)+ 1086 * primary (arguments* assignableSelector)+
1094 * | 'super' assignableSelector 1087 * | 'super' assignableSelector
1095 * | identifier 1088 * | identifier
1096 * </pre> 1089 * </pre>
1097 * @param primaryAllowed {@code true} if the expression is allowed to be a pri mary without any 1090 * @param primaryAllowed {@code true} if the expression is allowed to be a pri mary without any
1098 * assignable selector 1091 * assignable selector
(...skipping 28 matching lines...) Expand all
1127 if (!isOptional && (expression is PrefixedIdentifier)) { 1120 if (!isOptional && (expression is PrefixedIdentifier)) {
1128 PrefixedIdentifier identifier = expression as PrefixedIdentifier; 1121 PrefixedIdentifier identifier = expression as PrefixedIdentifier;
1129 expression = new PropertyAccess.full(identifier.prefix, identifier.per iod, identifier.identifier); 1122 expression = new PropertyAccess.full(identifier.prefix, identifier.per iod, identifier.identifier);
1130 } 1123 }
1131 return expression; 1124 return expression;
1132 } 1125 }
1133 expression = selectorExpression; 1126 expression = selectorExpression;
1134 isOptional = true; 1127 isOptional = true;
1135 } 1128 }
1136 } 1129 }
1137 1130
1138 /** 1131 /**
1139 * Parse an assignable selector. 1132 * Parse an assignable selector.
1140 * <pre> 1133 * <pre>
1141 * assignableSelector ::= 1134 * assignableSelector ::=
1142 * '\[' expression '\]' 1135 * '\[' expression '\]'
1143 * | '.' identifier 1136 * | '.' identifier
1144 * </pre> 1137 * </pre>
1145 * @param prefix the expression preceding the selector 1138 * @param prefix the expression preceding the selector
1146 * @param optional {@code true} if the selector is optional 1139 * @param optional {@code true} if the selector is optional
1147 * @return the assignable selector that was parsed 1140 * @return the assignable selector that was parsed
1148 */ 1141 */
1149 Expression parseAssignableSelector(Expression prefix, bool optional) { 1142 Expression parseAssignableSelector(Expression prefix, bool optional) {
1150 if (matches5(TokenType.OPEN_SQUARE_BRACKET)) { 1143 if (matches5(TokenType.OPEN_SQUARE_BRACKET)) {
1151 Token leftBracket = andAdvance; 1144 Token leftBracket = andAdvance;
1152 Expression index = parseExpression2(); 1145 Expression index = parseExpression2();
1153 Token rightBracket = expect2(TokenType.CLOSE_SQUARE_BRACKET); 1146 Token rightBracket = expect2(TokenType.CLOSE_SQUARE_BRACKET);
1154 return new IndexExpression.forTarget_full(prefix, leftBracket, index, righ tBracket); 1147 return new IndexExpression.forTarget_full(prefix, leftBracket, index, righ tBracket);
1155 } else if (matches5(TokenType.PERIOD)) { 1148 } else if (matches5(TokenType.PERIOD)) {
1156 Token period = andAdvance; 1149 Token period = andAdvance;
1157 return new PropertyAccess.full(prefix, period, parseSimpleIdentifier()); 1150 return new PropertyAccess.full(prefix, period, parseSimpleIdentifier());
1158 } else { 1151 } else {
1159 if (!optional) { 1152 if (!optional) {
1160 reportError7(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, []); 1153 reportError7(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, []);
1161 } 1154 }
1162 return prefix; 1155 return prefix;
1163 } 1156 }
1164 } 1157 }
1165 1158
1166 /** 1159 /**
1167 * Parse a bitwise and expression. 1160 * Parse a bitwise and expression.
1168 * <pre> 1161 * <pre>
1169 * bitwiseAndExpression ::= 1162 * bitwiseAndExpression ::=
1170 * equalityExpression ('&' equalityExpression) 1163 * equalityExpression ('&' equalityExpression)
1171 * | 'super' ('&' equalityExpression)+ 1164 * | 'super' ('&' equalityExpression)+
1172 * </pre> 1165 * </pre>
1173 * @return the bitwise and expression that was parsed 1166 * @return the bitwise and expression that was parsed
1174 */ 1167 */
1175 Expression parseBitwiseAndExpression() { 1168 Expression parseBitwiseAndExpression() {
1176 Expression expression; 1169 Expression expression;
1177 if (matches(Keyword.SUPER) && matches4(peek(), TokenType.AMPERSAND)) { 1170 if (matches(Keyword.SUPER) && matches4(peek(), TokenType.AMPERSAND)) {
1178 expression = new SuperExpression.full(andAdvance); 1171 expression = new SuperExpression.full(andAdvance);
1179 } else { 1172 } else {
1180 expression = parseEqualityExpression(); 1173 expression = parseEqualityExpression();
1181 } 1174 }
1182 while (matches5(TokenType.AMPERSAND)) { 1175 while (matches5(TokenType.AMPERSAND)) {
1183 Token operator = andAdvance; 1176 Token operator = andAdvance;
1184 expression = new BinaryExpression.full(expression, operator, parseEquality Expression()); 1177 expression = new BinaryExpression.full(expression, operator, parseEquality Expression());
1185 } 1178 }
1186 return expression; 1179 return expression;
1187 } 1180 }
1188 1181
1189 /** 1182 /**
1190 * Parse a bitwise or expression. 1183 * Parse a bitwise or expression.
1191 * <pre> 1184 * <pre>
1192 * bitwiseOrExpression ::= 1185 * bitwiseOrExpression ::=
1193 * bitwiseXorExpression ('|' bitwiseXorExpression) 1186 * bitwiseXorExpression ('|' bitwiseXorExpression)
1194 * | 'super' ('|' bitwiseXorExpression)+ 1187 * | 'super' ('|' bitwiseXorExpression)+
1195 * </pre> 1188 * </pre>
1196 * @return the bitwise or expression that was parsed 1189 * @return the bitwise or expression that was parsed
1197 */ 1190 */
1198 Expression parseBitwiseOrExpression() { 1191 Expression parseBitwiseOrExpression() {
1199 Expression expression; 1192 Expression expression;
1200 if (matches(Keyword.SUPER) && matches4(peek(), TokenType.BAR)) { 1193 if (matches(Keyword.SUPER) && matches4(peek(), TokenType.BAR)) {
1201 expression = new SuperExpression.full(andAdvance); 1194 expression = new SuperExpression.full(andAdvance);
1202 } else { 1195 } else {
1203 expression = parseBitwiseXorExpression(); 1196 expression = parseBitwiseXorExpression();
1204 } 1197 }
1205 while (matches5(TokenType.BAR)) { 1198 while (matches5(TokenType.BAR)) {
1206 Token operator = andAdvance; 1199 Token operator = andAdvance;
1207 expression = new BinaryExpression.full(expression, operator, parseBitwiseX orExpression()); 1200 expression = new BinaryExpression.full(expression, operator, parseBitwiseX orExpression());
1208 } 1201 }
1209 return expression; 1202 return expression;
1210 } 1203 }
1211 1204
1212 /** 1205 /**
1213 * Parse a bitwise exclusive-or expression. 1206 * Parse a bitwise exclusive-or expression.
1214 * <pre> 1207 * <pre>
1215 * bitwiseXorExpression ::= 1208 * bitwiseXorExpression ::=
1216 * bitwiseAndExpression ('^' bitwiseAndExpression) 1209 * bitwiseAndExpression ('^' bitwiseAndExpression)
1217 * | 'super' ('^' bitwiseAndExpression)+ 1210 * | 'super' ('^' bitwiseAndExpression)+
1218 * </pre> 1211 * </pre>
1219 * @return the bitwise exclusive-or expression that was parsed 1212 * @return the bitwise exclusive-or expression that was parsed
1220 */ 1213 */
1221 Expression parseBitwiseXorExpression() { 1214 Expression parseBitwiseXorExpression() {
1222 Expression expression; 1215 Expression expression;
1223 if (matches(Keyword.SUPER) && matches4(peek(), TokenType.CARET)) { 1216 if (matches(Keyword.SUPER) && matches4(peek(), TokenType.CARET)) {
1224 expression = new SuperExpression.full(andAdvance); 1217 expression = new SuperExpression.full(andAdvance);
1225 } else { 1218 } else {
1226 expression = parseBitwiseAndExpression(); 1219 expression = parseBitwiseAndExpression();
1227 } 1220 }
1228 while (matches5(TokenType.CARET)) { 1221 while (matches5(TokenType.CARET)) {
1229 Token operator = andAdvance; 1222 Token operator = andAdvance;
1230 expression = new BinaryExpression.full(expression, operator, parseBitwiseA ndExpression()); 1223 expression = new BinaryExpression.full(expression, operator, parseBitwiseA ndExpression());
1231 } 1224 }
1232 return expression; 1225 return expression;
1233 } 1226 }
1234 1227
1235 /** 1228 /**
1236 * Parse a block. 1229 * Parse a block.
1237 * <pre> 1230 * <pre>
1238 * block ::= 1231 * block ::=
1239 * '{' statements '}' 1232 * '{' statements '}'
1240 * </pre> 1233 * </pre>
1241 * @return the block that was parsed 1234 * @return the block that was parsed
1242 */ 1235 */
1243 Block parseBlock() { 1236 Block parseBlock() {
1244 Token leftBracket = expect2(TokenType.OPEN_CURLY_BRACKET); 1237 Token leftBracket = expect2(TokenType.OPEN_CURLY_BRACKET);
1245 List<Statement> statements = new List<Statement>(); 1238 List<Statement> statements = new List<Statement>();
1246 Token statementStart = _currentToken; 1239 Token statementStart = _currentToken;
1247 while (!matches5(TokenType.EOF) && !matches5(TokenType.CLOSE_CURLY_BRACKET)) { 1240 while (!matches5(TokenType.EOF) && !matches5(TokenType.CLOSE_CURLY_BRACKET)) {
1248 Statement statement = parseStatement2(); 1241 Statement statement = parseStatement2();
1249 if (statement != null) { 1242 if (statement != null) {
1250 statements.add(statement); 1243 statements.add(statement);
1251 } 1244 }
1252 if (identical(_currentToken, statementStart)) { 1245 if (identical(_currentToken, statementStart)) {
1253 reportError8(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentT oken.lexeme]); 1246 reportError8(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentT oken.lexeme]);
1254 advance(); 1247 advance();
1255 } 1248 }
1256 statementStart = _currentToken; 1249 statementStart = _currentToken;
1257 } 1250 }
1258 Token rightBracket = expect2(TokenType.CLOSE_CURLY_BRACKET); 1251 Token rightBracket = expect2(TokenType.CLOSE_CURLY_BRACKET);
1259 return new Block.full(leftBracket, statements, rightBracket); 1252 return new Block.full(leftBracket, statements, rightBracket);
1260 } 1253 }
1261 1254
1262 /** 1255 /**
1263 * Parse a break statement. 1256 * Parse a break statement.
1264 * <pre> 1257 * <pre>
1265 * breakStatement ::= 1258 * breakStatement ::=
1266 * 'break' identifier? ';' 1259 * 'break' identifier? ';'
1267 * </pre> 1260 * </pre>
1268 * @return the break statement that was parsed 1261 * @return the break statement that was parsed
1269 */ 1262 */
1270 Statement parseBreakStatement() { 1263 Statement parseBreakStatement() {
1271 Token breakKeyword = expect(Keyword.BREAK); 1264 Token breakKeyword = expect(Keyword.BREAK);
1272 SimpleIdentifier label = null; 1265 SimpleIdentifier label = null;
1273 if (matchesIdentifier()) { 1266 if (matchesIdentifier()) {
1274 label = parseSimpleIdentifier(); 1267 label = parseSimpleIdentifier();
1275 } 1268 }
1276 if (!_inLoop && !_inSwitch && label == null) { 1269 if (!_inLoop && !_inSwitch && label == null) {
1277 reportError8(ParserErrorCode.BREAK_OUTSIDE_OF_LOOP, breakKeyword, []); 1270 reportError8(ParserErrorCode.BREAK_OUTSIDE_OF_LOOP, breakKeyword, []);
1278 } 1271 }
1279 Token semicolon = expect2(TokenType.SEMICOLON); 1272 Token semicolon = expect2(TokenType.SEMICOLON);
1280 return new BreakStatement.full(breakKeyword, label, semicolon); 1273 return new BreakStatement.full(breakKeyword, label, semicolon);
1281 } 1274 }
1282 1275
1283 /** 1276 /**
1284 * Parse a cascade section. 1277 * Parse a cascade section.
1285 * <pre> 1278 * <pre>
1286 * cascadeSection ::= 1279 * cascadeSection ::=
1287 * '..' (cascadeSelector arguments*) (assignableSelector arguments*)* cascadeA ssignment? 1280 * '..' (cascadeSelector arguments*) (assignableSelector arguments*)* cascadeA ssignment?
1288 * cascadeSelector ::= 1281 * cascadeSelector ::=
1289 * '\[' expression '\]' 1282 * '\[' expression '\]'
1290 * | identifier 1283 * | identifier
1291 * cascadeAssignment ::= 1284 * cascadeAssignment ::=
1292 * assignmentOperator expressionWithoutCascade 1285 * assignmentOperator expressionWithoutCascade
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1337 } 1330 }
1338 } 1331 }
1339 } 1332 }
1340 if (_currentToken.type.isAssignmentOperator()) { 1333 if (_currentToken.type.isAssignmentOperator()) {
1341 Token operator = andAdvance; 1334 Token operator = andAdvance;
1342 ensureAssignable(expression); 1335 ensureAssignable(expression);
1343 expression = new AssignmentExpression.full(expression, operator, parseExpr essionWithoutCascade()); 1336 expression = new AssignmentExpression.full(expression, operator, parseExpr essionWithoutCascade());
1344 } 1337 }
1345 return expression; 1338 return expression;
1346 } 1339 }
1347 1340
1348 /** 1341 /**
1349 * Parse a class declaration. 1342 * Parse a class declaration.
1350 * <pre> 1343 * <pre>
1351 * classDeclaration ::= 1344 * classDeclaration ::=
1352 * metadata 'abstract'? 'class' name typeParameterList? (extendsClause withCla use?)? implementsClause? '{' classMembers '}' 1345 * metadata 'abstract'? 'class' name typeParameterList? (extendsClause withCla use?)? implementsClause? '{' classMembers '}'
1353 * </pre> 1346 * </pre>
1354 * @param commentAndMetadata the metadata to be associated with the member 1347 * @param commentAndMetadata the metadata to be associated with the member
1355 * @param abstractKeyword the token for the keyword 'abstract', or {@code null } if the keyword was 1348 * @param abstractKeyword the token for the keyword 'abstract', or {@code null } if the keyword was
1356 * not given 1349 * not given
1357 * @return the class declaration that was parsed 1350 * @return the class declaration that was parsed
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1416 leftBracket = expect2(TokenType.OPEN_CURLY_BRACKET); 1409 leftBracket = expect2(TokenType.OPEN_CURLY_BRACKET);
1417 members = parseClassMembers(className, getEndToken(leftBracket)); 1410 members = parseClassMembers(className, getEndToken(leftBracket));
1418 rightBracket = expect2(TokenType.CLOSE_CURLY_BRACKET); 1411 rightBracket = expect2(TokenType.CLOSE_CURLY_BRACKET);
1419 } else { 1412 } else {
1420 leftBracket = createSyntheticToken2(TokenType.OPEN_CURLY_BRACKET); 1413 leftBracket = createSyntheticToken2(TokenType.OPEN_CURLY_BRACKET);
1421 rightBracket = createSyntheticToken2(TokenType.CLOSE_CURLY_BRACKET); 1414 rightBracket = createSyntheticToken2(TokenType.CLOSE_CURLY_BRACKET);
1422 reportError7(ParserErrorCode.MISSING_CLASS_BODY, []); 1415 reportError7(ParserErrorCode.MISSING_CLASS_BODY, []);
1423 } 1416 }
1424 return new ClassDeclaration.full(commentAndMetadata.comment, commentAndMetad ata.metadata, abstractKeyword, keyword, name, typeParameters, extendsClause, wit hClause, implementsClause, leftBracket, members, rightBracket); 1417 return new ClassDeclaration.full(commentAndMetadata.comment, commentAndMetad ata.metadata, abstractKeyword, keyword, name, typeParameters, extendsClause, wit hClause, implementsClause, leftBracket, members, rightBracket);
1425 } 1418 }
1426 1419
1427 /** 1420 /**
1428 * Parse a class member. 1421 * Parse a class member.
1429 * <pre> 1422 * <pre>
1430 * classMemberDefinition ::= 1423 * classMemberDefinition ::=
1431 * declaration ';' 1424 * declaration ';'
1432 * | methodSignature functionBody 1425 * | methodSignature functionBody
1433 * </pre> 1426 * </pre>
1434 * @param className the name of the class containing the member being parsed 1427 * @param className the name of the class containing the member being parsed
1435 * @return the class member that was parsed, or {@code null} if what was found was not a valid 1428 * @return the class member that was parsed, or {@code null} if what was found was not a valid
1436 * class member 1429 * class member
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1525 if (methodName.name == className) { 1518 if (methodName.name == className) {
1526 reportError(ParserErrorCode.CONSTRUCTOR_WITH_RETURN_TYPE, type, []); 1519 reportError(ParserErrorCode.CONSTRUCTOR_WITH_RETURN_TYPE, type, []);
1527 return parseConstructor(commentAndMetadata, modifiers.externalKeyword, v alidateModifiersForConstructor(modifiers), modifiers.factoryKeyword, methodName, null, null, parameters); 1520 return parseConstructor(commentAndMetadata, modifiers.externalKeyword, v alidateModifiersForConstructor(modifiers), modifiers.factoryKeyword, methodName, null, null, parameters);
1528 } 1521 }
1529 validateModifiersForGetterOrSetterOrMethod(modifiers); 1522 validateModifiersForGetterOrSetterOrMethod(modifiers);
1530 validateFormalParameterList(parameters); 1523 validateFormalParameterList(parameters);
1531 return parseMethodDeclaration2(commentAndMetadata, modifiers.externalKeywo rd, modifiers.staticKeyword, type, methodName, parameters); 1524 return parseMethodDeclaration2(commentAndMetadata, modifiers.externalKeywo rd, modifiers.staticKeyword, type, methodName, parameters);
1532 } 1525 }
1533 return parseInitializedIdentifierList(commentAndMetadata, modifiers.staticKe yword, validateModifiersForField(modifiers), type); 1526 return parseInitializedIdentifierList(commentAndMetadata, modifiers.staticKe yword, validateModifiersForField(modifiers), type);
1534 } 1527 }
1535 1528
1536 /** 1529 /**
1537 * Parse a list of class members. 1530 * Parse a list of class members.
1538 * <pre> 1531 * <pre>
1539 * classMembers ::= 1532 * classMembers ::=
1540 * (metadata memberDefinition) 1533 * (metadata memberDefinition)
1541 * </pre> 1534 * </pre>
1542 * @param className the name of the class whose members are being parsed 1535 * @param className the name of the class whose members are being parsed
1543 * @param closingBracket the closing bracket for the class, or {@code null} if the closing bracket 1536 * @param closingBracket the closing bracket for the class, or {@code null} if the closing bracket
1544 * is missing 1537 * is missing
1545 * @return the list of class members that were parsed 1538 * @return the list of class members that were parsed
(...skipping 12 matching lines...) Expand all
1558 } 1551 }
1559 } 1552 }
1560 if (identical(_currentToken, memberStart)) { 1553 if (identical(_currentToken, memberStart)) {
1561 reportError8(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentT oken.lexeme]); 1554 reportError8(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentT oken.lexeme]);
1562 advance(); 1555 advance();
1563 } 1556 }
1564 memberStart = _currentToken; 1557 memberStart = _currentToken;
1565 } 1558 }
1566 return members; 1559 return members;
1567 } 1560 }
1568 1561
1569 /** 1562 /**
1570 * Parse a class type alias. 1563 * Parse a class type alias.
1571 * <pre> 1564 * <pre>
1572 * classTypeAlias ::= 1565 * classTypeAlias ::=
1573 * identifier typeParameters? '=' 'abstract'? mixinApplication 1566 * identifier typeParameters? '=' 'abstract'? mixinApplication
1574 * mixinApplication ::= 1567 * mixinApplication ::=
1575 * type withClause implementsClause? ';' 1568 * type withClause implementsClause? ';'
1576 * </pre> 1569 * </pre>
1577 * @param commentAndMetadata the metadata to be associated with the member 1570 * @param commentAndMetadata the metadata to be associated with the member
1578 * @param keyword the token representing the 'typedef' keyword 1571 * @param keyword the token representing the 'typedef' keyword
(...skipping 28 matching lines...) Expand all
1607 Token leftBracket = andAdvance; 1600 Token leftBracket = andAdvance;
1608 parseClassMembers(className.name, getEndToken(leftBracket)); 1601 parseClassMembers(className.name, getEndToken(leftBracket));
1609 expect2(TokenType.CLOSE_CURLY_BRACKET); 1602 expect2(TokenType.CLOSE_CURLY_BRACKET);
1610 } else { 1603 } else {
1611 reportError8(ParserErrorCode.EXPECTED_TOKEN, _currentToken.previous, [To kenType.SEMICOLON.lexeme]); 1604 reportError8(ParserErrorCode.EXPECTED_TOKEN, _currentToken.previous, [To kenType.SEMICOLON.lexeme]);
1612 } 1605 }
1613 semicolon = createSyntheticToken2(TokenType.SEMICOLON); 1606 semicolon = createSyntheticToken2(TokenType.SEMICOLON);
1614 } 1607 }
1615 return new ClassTypeAlias.full(commentAndMetadata.comment, commentAndMetadat a.metadata, keyword, className, typeParameters, equals, abstractKeyword, supercl ass, withClause, implementsClause, semicolon); 1608 return new ClassTypeAlias.full(commentAndMetadata.comment, commentAndMetadat a.metadata, keyword, className, typeParameters, equals, abstractKeyword, supercl ass, withClause, implementsClause, semicolon);
1616 } 1609 }
1617 1610
1618 /** 1611 /**
1619 * Parse a list of combinators in a directive. 1612 * Parse a list of combinators in a directive.
1620 * <pre> 1613 * <pre>
1621 * combinator ::= 1614 * combinator ::=
1622 * 'show' identifier (',' identifier) 1615 * 'show' identifier (',' identifier)
1623 * | 'hide' identifier (',' identifier) 1616 * | 'hide' identifier (',' identifier)
1624 * </pre> 1617 * </pre>
1625 * @return the combinators that were parsed 1618 * @return the combinators that were parsed
1626 */ 1619 */
1627 List<Combinator> parseCombinators() { 1620 List<Combinator> parseCombinators() {
1628 List<Combinator> combinators = new List<Combinator>(); 1621 List<Combinator> combinators = new List<Combinator>();
1629 while (matches2(_SHOW) || matches2(_HIDE)) { 1622 while (matches2(_SHOW) || matches2(_HIDE)) {
1630 Token keyword = expect2(TokenType.IDENTIFIER); 1623 Token keyword = expect2(TokenType.IDENTIFIER);
1631 if (keyword.lexeme == _SHOW) { 1624 if (keyword.lexeme == _SHOW) {
1632 List<SimpleIdentifier> shownNames = parseIdentifierList(); 1625 List<SimpleIdentifier> shownNames = parseIdentifierList();
1633 combinators.add(new ShowCombinator.full(keyword, shownNames)); 1626 combinators.add(new ShowCombinator.full(keyword, shownNames));
1634 } else { 1627 } else {
1635 List<SimpleIdentifier> hiddenNames = parseIdentifierList(); 1628 List<SimpleIdentifier> hiddenNames = parseIdentifierList();
1636 combinators.add(new HideCombinator.full(keyword, hiddenNames)); 1629 combinators.add(new HideCombinator.full(keyword, hiddenNames));
1637 } 1630 }
1638 } 1631 }
1639 return combinators; 1632 return combinators;
1640 } 1633 }
1641 1634
1642 /** 1635 /**
1643 * Parse the documentation comment and metadata preceeding a declaration. This method allows any 1636 * Parse the documentation comment and metadata preceeding a declaration. This method allows any
1644 * number of documentation comments to occur before, after or between the meta data, but only 1637 * number of documentation comments to occur before, after or between the meta data, but only
1645 * returns the last (right-most) documentation comment that is found. 1638 * returns the last (right-most) documentation comment that is found.
1646 * <pre> 1639 * <pre>
1647 * metadata ::= 1640 * metadata ::=
1648 * annotation 1641 * annotation
1649 * </pre> 1642 * </pre>
1650 * @return the documentation comment and metadata that were parsed 1643 * @return the documentation comment and metadata that were parsed
1651 */ 1644 */
1652 CommentAndMetadata parseCommentAndMetadata() { 1645 CommentAndMetadata parseCommentAndMetadata() {
1653 Comment comment = parseDocumentationComment(); 1646 Comment comment = parseDocumentationComment();
1654 List<Annotation> metadata = new List<Annotation>(); 1647 List<Annotation> metadata = new List<Annotation>();
1655 while (matches5(TokenType.AT)) { 1648 while (matches5(TokenType.AT)) {
1656 metadata.add(parseAnnotation()); 1649 metadata.add(parseAnnotation());
1657 Comment optionalComment = parseDocumentationComment(); 1650 Comment optionalComment = parseDocumentationComment();
1658 if (optionalComment != null) { 1651 if (optionalComment != null) {
1659 comment = optionalComment; 1652 comment = optionalComment;
1660 } 1653 }
1661 } 1654 }
1662 return new CommentAndMetadata(comment, metadata); 1655 return new CommentAndMetadata(comment, metadata);
1663 } 1656 }
1664 1657
1665 /** 1658 /**
1666 * Parse a comment reference from the source between square brackets. 1659 * Parse a comment reference from the source between square brackets.
1667 * <pre> 1660 * <pre>
1668 * commentReference ::= 1661 * commentReference ::=
1669 * 'new'? prefixedIdentifier 1662 * 'new'? prefixedIdentifier
1670 * </pre> 1663 * </pre>
1671 * @param referenceSource the source occurring between the square brackets wit hin a documentation 1664 * @param referenceSource the source occurring between the square brackets wit hin a documentation
1672 * comment 1665 * comment
1673 * @param sourceOffset the offset of the first character of the reference sour ce 1666 * @param sourceOffset the offset of the first character of the reference sour ce
1674 * @return the comment reference that was parsed, or {@code null} if no refere nce could be found 1667 * @return the comment reference that was parsed, or {@code null} if no refere nce could be found
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1707 return null; 1700 return null;
1708 } 1701 }
1709 return new CommentReference.full(newKeyword, identifier); 1702 return new CommentReference.full(newKeyword, identifier);
1710 } else if (matches3(firstToken, Keyword.THIS) || matches3(firstToken, Keyw ord.NULL) || matches3(firstToken, Keyword.TRUE) || matches3(firstToken, Keyword. FALSE)) { 1703 } else if (matches3(firstToken, Keyword.THIS) || matches3(firstToken, Keyw ord.NULL) || matches3(firstToken, Keyword.TRUE) || matches3(firstToken, Keyword. FALSE)) {
1711 return null; 1704 return null;
1712 } 1705 }
1713 } catch (exception) { 1706 } catch (exception) {
1714 } 1707 }
1715 return null; 1708 return null;
1716 } 1709 }
1717 1710
1718 /** 1711 /**
1719 * Parse all of the comment references occurring in the given array of documen tation comments. 1712 * Parse all of the comment references occurring in the given array of documen tation comments.
1720 * <pre> 1713 * <pre>
1721 * commentReference ::= 1714 * commentReference ::=
1722 * '\[' 'new'? qualified '\]' libraryReference? 1715 * '\[' 'new'? qualified '\]' libraryReference?
1723 * libraryReference ::= 1716 * libraryReference ::=
1724 * '(' stringLiteral ')' 1717 * '(' stringLiteral ')'
1725 * </pre> 1718 * </pre>
1726 * @param tokens the comment tokens representing the documentation comments to be parsed 1719 * @param tokens the comment tokens representing the documentation comments to be parsed
1727 * @return the comment references that were parsed 1720 * @return the comment references that were parsed
(...skipping 24 matching lines...) Expand all
1752 rightIndex = leftIndex + 1; 1745 rightIndex = leftIndex + 1;
1753 } 1746 }
1754 leftIndex = comment.indexOf('[', rightIndex); 1747 leftIndex = comment.indexOf('[', rightIndex);
1755 } else { 1748 } else {
1756 leftIndex = comment.indexOf('[', range[1] + 1); 1749 leftIndex = comment.indexOf('[', range[1] + 1);
1757 } 1750 }
1758 } 1751 }
1759 } 1752 }
1760 return references; 1753 return references;
1761 } 1754 }
1762 1755
1763 /** 1756 /**
1764 * Parse a compilation unit. 1757 * Parse a compilation unit.
1765 * <p> 1758 * <p>
1766 * Specified: 1759 * Specified:
1767 * <pre> 1760 * <pre>
1768 * compilationUnit ::= 1761 * compilationUnit ::=
1769 * scriptTag? directive* topLevelDeclaration 1762 * scriptTag? directive* topLevelDeclaration
1770 * </pre> 1763 * </pre>
1771 * Actual: 1764 * Actual:
1772 * <pre> 1765 * <pre>
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1845 reportError8(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentT oken.lexeme]); 1838 reportError8(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentT oken.lexeme]);
1846 advance(); 1839 advance();
1847 while (!matches5(TokenType.EOF) && !couldBeStartOfCompilationUnitMember( )) { 1840 while (!matches5(TokenType.EOF) && !couldBeStartOfCompilationUnitMember( )) {
1848 advance(); 1841 advance();
1849 } 1842 }
1850 } 1843 }
1851 memberStart = _currentToken; 1844 memberStart = _currentToken;
1852 } 1845 }
1853 return new CompilationUnit.full(firstToken, scriptTag, directives, declarati ons, _currentToken); 1846 return new CompilationUnit.full(firstToken, scriptTag, directives, declarati ons, _currentToken);
1854 } 1847 }
1855 1848
1856 /** 1849 /**
1857 * Parse a compilation unit member. 1850 * Parse a compilation unit member.
1858 * <pre> 1851 * <pre>
1859 * compilationUnitMember ::= 1852 * compilationUnitMember ::=
1860 * classDefinition 1853 * classDefinition
1861 * | functionTypeAlias 1854 * | functionTypeAlias
1862 * | external functionSignature 1855 * | external functionSignature
1863 * | external getterSignature 1856 * | external getterSignature
1864 * | external setterSignature 1857 * | external setterSignature
1865 * | functionSignature functionBody 1858 * | functionSignature functionBody
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1928 } else if (!matchesIdentifier()) { 1921 } else if (!matchesIdentifier()) {
1929 reportError8(ParserErrorCode.EXPECTED_EXECUTABLE, _currentToken, []); 1922 reportError8(ParserErrorCode.EXPECTED_EXECUTABLE, _currentToken, []);
1930 return null; 1923 return null;
1931 } 1924 }
1932 if (matchesAny(peek(), [TokenType.OPEN_PAREN, TokenType.FUNCTION, TokenType. OPEN_CURLY_BRACKET])) { 1925 if (matchesAny(peek(), [TokenType.OPEN_PAREN, TokenType.FUNCTION, TokenType. OPEN_CURLY_BRACKET])) {
1933 validateModifiersForTopLevelFunction(modifiers); 1926 validateModifiersForTopLevelFunction(modifiers);
1934 return parseFunctionDeclaration(commentAndMetadata, modifiers.externalKeyw ord, returnType); 1927 return parseFunctionDeclaration(commentAndMetadata, modifiers.externalKeyw ord, returnType);
1935 } 1928 }
1936 return new TopLevelVariableDeclaration.full(commentAndMetadata.comment, comm entAndMetadata.metadata, parseVariableDeclarationList2(null, validateModifiersFo rTopLevelVariable(modifiers), returnType), expect2(TokenType.SEMICOLON)); 1929 return new TopLevelVariableDeclaration.full(commentAndMetadata.comment, comm entAndMetadata.metadata, parseVariableDeclarationList2(null, validateModifiersFo rTopLevelVariable(modifiers), returnType), expect2(TokenType.SEMICOLON));
1937 } 1930 }
1938 1931
1939 /** 1932 /**
1940 * Parse a conditional expression. 1933 * Parse a conditional expression.
1941 * <pre> 1934 * <pre>
1942 * conditionalExpression ::= 1935 * conditionalExpression ::=
1943 * logicalOrExpression ('?' expressionWithoutCascade ':' expressionWithoutCasc ade)? 1936 * logicalOrExpression ('?' expressionWithoutCascade ':' expressionWithoutCasc ade)?
1944 * </pre> 1937 * </pre>
1945 * @return the conditional expression that was parsed 1938 * @return the conditional expression that was parsed
1946 */ 1939 */
1947 Expression parseConditionalExpression() { 1940 Expression parseConditionalExpression() {
1948 Expression condition = parseLogicalOrExpression(); 1941 Expression condition = parseLogicalOrExpression();
1949 if (!matches5(TokenType.QUESTION)) { 1942 if (!matches5(TokenType.QUESTION)) {
1950 return condition; 1943 return condition;
1951 } 1944 }
1952 Token question = andAdvance; 1945 Token question = andAdvance;
1953 Expression thenExpression = parseExpressionWithoutCascade(); 1946 Expression thenExpression = parseExpressionWithoutCascade();
1954 Token colon = expect2(TokenType.COLON); 1947 Token colon = expect2(TokenType.COLON);
1955 Expression elseExpression = parseExpressionWithoutCascade(); 1948 Expression elseExpression = parseExpressionWithoutCascade();
1956 return new ConditionalExpression.full(condition, question, thenExpression, c olon, elseExpression); 1949 return new ConditionalExpression.full(condition, question, thenExpression, c olon, elseExpression);
1957 } 1950 }
1958 1951
1959 /** 1952 /**
1960 * Parse a const expression. 1953 * Parse a const expression.
1961 * <pre> 1954 * <pre>
1962 * constExpression ::= 1955 * constExpression ::=
1963 * instanceCreationExpression 1956 * instanceCreationExpression
1964 * | listLiteral 1957 * | listLiteral
1965 * | mapLiteral 1958 * | mapLiteral
1966 * </pre> 1959 * </pre>
1967 * @return the const expression that was parsed 1960 * @return the const expression that was parsed
1968 */ 1961 */
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2019 } else { 2012 } else {
2020 if (constKeyword != null) { 2013 if (constKeyword != null) {
2021 reportError(ParserErrorCode.CONST_CONSTRUCTOR_WITH_BODY, body, []); 2014 reportError(ParserErrorCode.CONST_CONSTRUCTOR_WITH_BODY, body, []);
2022 } else if (!bodyAllowed) { 2015 } else if (!bodyAllowed) {
2023 reportError(ParserErrorCode.EXTERNAL_CONSTRUCTOR_WITH_BODY, body, []); 2016 reportError(ParserErrorCode.EXTERNAL_CONSTRUCTOR_WITH_BODY, body, []);
2024 } 2017 }
2025 } 2018 }
2026 } 2019 }
2027 return new ConstructorDeclaration.full(commentAndMetadata.comment, commentAn dMetadata.metadata, externalKeyword, constKeyword, factoryKeyword, returnType, p eriod, name, parameters, separator, initializers, redirectedConstructor, body); 2020 return new ConstructorDeclaration.full(commentAndMetadata.comment, commentAn dMetadata.metadata, externalKeyword, constKeyword, factoryKeyword, returnType, p eriod, name, parameters, separator, initializers, redirectedConstructor, body);
2028 } 2021 }
2029 2022
2030 /** 2023 /**
2031 * Parse a field initializer within a constructor. 2024 * Parse a field initializer within a constructor.
2032 * <pre> 2025 * <pre>
2033 * fieldInitializer: 2026 * fieldInitializer:
2034 * ('this' '.')? identifier '=' conditionalExpression cascadeSection 2027 * ('this' '.')? identifier '=' conditionalExpression cascadeSection
2035 * </pre> 2028 * </pre>
2036 * @return the field initializer that was parsed 2029 * @return the field initializer that was parsed
2037 */ 2030 */
2038 ConstructorFieldInitializer parseConstructorFieldInitializer() { 2031 ConstructorFieldInitializer parseConstructorFieldInitializer() {
2039 Token keyword = null; 2032 Token keyword = null;
(...skipping 12 matching lines...) Expand all
2052 Expression section = parseCascadeSection(); 2045 Expression section = parseCascadeSection();
2053 if (section != null) { 2046 if (section != null) {
2054 cascadeSections.add(section); 2047 cascadeSections.add(section);
2055 } 2048 }
2056 tokenType = _currentToken.type; 2049 tokenType = _currentToken.type;
2057 } 2050 }
2058 expression = new CascadeExpression.full(expression, cascadeSections); 2051 expression = new CascadeExpression.full(expression, cascadeSections);
2059 } 2052 }
2060 return new ConstructorFieldInitializer.full(keyword, period, fieldName, equa ls, expression); 2053 return new ConstructorFieldInitializer.full(keyword, period, fieldName, equa ls, expression);
2061 } 2054 }
2062 2055
2063 /** 2056 /**
2064 * Parse the name of a constructor. 2057 * Parse the name of a constructor.
2065 * <pre> 2058 * <pre>
2066 * constructorName: 2059 * constructorName:
2067 * type ('.' identifier)? 2060 * type ('.' identifier)?
2068 * </pre> 2061 * </pre>
2069 * @return the constructor name that was parsed 2062 * @return the constructor name that was parsed
2070 */ 2063 */
2071 ConstructorName parseConstructorName() { 2064 ConstructorName parseConstructorName() {
2072 TypeName type = parseTypeName(); 2065 TypeName type = parseTypeName();
2073 Token period = null; 2066 Token period = null;
2074 SimpleIdentifier name = null; 2067 SimpleIdentifier name = null;
2075 if (matches5(TokenType.PERIOD)) { 2068 if (matches5(TokenType.PERIOD)) {
2076 period = andAdvance; 2069 period = andAdvance;
2077 name = parseSimpleIdentifier(); 2070 name = parseSimpleIdentifier();
2078 } 2071 }
2079 return new ConstructorName.full(type, period, name); 2072 return new ConstructorName.full(type, period, name);
2080 } 2073 }
2081 2074
2082 /** 2075 /**
2083 * Parse a continue statement. 2076 * Parse a continue statement.
2084 * <pre> 2077 * <pre>
2085 * continueStatement ::= 2078 * continueStatement ::=
2086 * 'continue' identifier? ';' 2079 * 'continue' identifier? ';'
2087 * </pre> 2080 * </pre>
2088 * @return the continue statement that was parsed 2081 * @return the continue statement that was parsed
2089 */ 2082 */
2090 Statement parseContinueStatement() { 2083 Statement parseContinueStatement() {
2091 Token continueKeyword = expect(Keyword.CONTINUE); 2084 Token continueKeyword = expect(Keyword.CONTINUE);
2092 if (!_inLoop && !_inSwitch) { 2085 if (!_inLoop && !_inSwitch) {
2093 reportError8(ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP, continueKeyword, [] ); 2086 reportError8(ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP, continueKeyword, [] );
2094 } 2087 }
2095 SimpleIdentifier label = null; 2088 SimpleIdentifier label = null;
2096 if (matchesIdentifier()) { 2089 if (matchesIdentifier()) {
2097 label = parseSimpleIdentifier(); 2090 label = parseSimpleIdentifier();
2098 } 2091 }
2099 if (_inSwitch && !_inLoop && label == null) { 2092 if (_inSwitch && !_inLoop && label == null) {
2100 reportError8(ParserErrorCode.CONTINUE_WITHOUT_LABEL_IN_CASE, continueKeywo rd, []); 2093 reportError8(ParserErrorCode.CONTINUE_WITHOUT_LABEL_IN_CASE, continueKeywo rd, []);
2101 } 2094 }
2102 Token semicolon = expect2(TokenType.SEMICOLON); 2095 Token semicolon = expect2(TokenType.SEMICOLON);
2103 return new ContinueStatement.full(continueKeyword, label, semicolon); 2096 return new ContinueStatement.full(continueKeyword, label, semicolon);
2104 } 2097 }
2105 2098
2106 /** 2099 /**
2107 * Parse a directive. 2100 * Parse a directive.
2108 * <pre> 2101 * <pre>
2109 * directive ::= 2102 * directive ::=
2110 * exportDirective 2103 * exportDirective
2111 * | libraryDirective 2104 * | libraryDirective
2112 * | importDirective 2105 * | importDirective
2113 * | partDirective 2106 * | partDirective
2114 * </pre> 2107 * </pre>
2115 * @param commentAndMetadata the metadata to be associated with the directive 2108 * @param commentAndMetadata the metadata to be associated with the directive
2116 * @return the directive that was parsed 2109 * @return the directive that was parsed
2117 */ 2110 */
2118 Directive parseDirective(CommentAndMetadata commentAndMetadata) { 2111 Directive parseDirective(CommentAndMetadata commentAndMetadata) {
2119 if (matches(Keyword.IMPORT)) { 2112 if (matches(Keyword.IMPORT)) {
2120 return parseImportDirective(commentAndMetadata); 2113 return parseImportDirective(commentAndMetadata);
2121 } else if (matches(Keyword.EXPORT)) { 2114 } else if (matches(Keyword.EXPORT)) {
2122 return parseExportDirective(commentAndMetadata); 2115 return parseExportDirective(commentAndMetadata);
2123 } else if (matches(Keyword.LIBRARY)) { 2116 } else if (matches(Keyword.LIBRARY)) {
2124 return parseLibraryDirective(commentAndMetadata); 2117 return parseLibraryDirective(commentAndMetadata);
2125 } else if (matches(Keyword.PART)) { 2118 } else if (matches(Keyword.PART)) {
2126 return parsePartDirective(commentAndMetadata); 2119 return parsePartDirective(commentAndMetadata);
2127 } else { 2120 } else {
2128 throw new IllegalStateException("parseDirective invoked in an invalid stat e; currentToken = ${_currentToken}"); 2121 throw new IllegalStateException("parseDirective invoked in an invalid stat e; currentToken = ${_currentToken}");
2129 } 2122 }
2130 } 2123 }
2131 2124
2132 /** 2125 /**
2133 * Parse a documentation comment. 2126 * Parse a documentation comment.
2134 * <pre> 2127 * <pre>
2135 * documentationComment ::= 2128 * documentationComment ::=
2136 * multiLineComment? 2129 * multiLineComment?
2137 * | singleLineComment 2130 * | singleLineComment
2138 * </pre> 2131 * </pre>
2139 * @return the documentation comment that was parsed, or {@code null} if there was no comment 2132 * @return the documentation comment that was parsed, or {@code null} if there was no comment
2140 */ 2133 */
2141 Comment parseDocumentationComment() { 2134 Comment parseDocumentationComment() {
(...skipping 15 matching lines...) Expand all
2157 } 2150 }
2158 commentToken = commentToken.next; 2151 commentToken = commentToken.next;
2159 } 2152 }
2160 if (commentTokens.isEmpty) { 2153 if (commentTokens.isEmpty) {
2161 return null; 2154 return null;
2162 } 2155 }
2163 List<Token> tokens = new List.from(commentTokens); 2156 List<Token> tokens = new List.from(commentTokens);
2164 List<CommentReference> references = parseCommentReferences(tokens); 2157 List<CommentReference> references = parseCommentReferences(tokens);
2165 return Comment.createDocumentationComment2(tokens, references); 2158 return Comment.createDocumentationComment2(tokens, references);
2166 } 2159 }
2167 2160
2168 /** 2161 /**
2169 * Parse a do statement. 2162 * Parse a do statement.
2170 * <pre> 2163 * <pre>
2171 * doStatement ::= 2164 * doStatement ::=
2172 * 'do' statement 'while' '(' expression ')' ';' 2165 * 'do' statement 'while' '(' expression ')' ';'
2173 * </pre> 2166 * </pre>
2174 * @return the do statement that was parsed 2167 * @return the do statement that was parsed
2175 */ 2168 */
2176 Statement parseDoStatement() { 2169 Statement parseDoStatement() {
2177 bool wasInLoop = _inLoop; 2170 bool wasInLoop = _inLoop;
2178 _inLoop = true; 2171 _inLoop = true;
2179 try { 2172 try {
2180 Token doKeyword = expect(Keyword.DO); 2173 Token doKeyword = expect(Keyword.DO);
2181 Statement body = parseStatement2(); 2174 Statement body = parseStatement2();
2182 Token whileKeyword = expect(Keyword.WHILE); 2175 Token whileKeyword = expect(Keyword.WHILE);
2183 Token leftParenthesis = expect2(TokenType.OPEN_PAREN); 2176 Token leftParenthesis = expect2(TokenType.OPEN_PAREN);
2184 Expression condition = parseExpression2(); 2177 Expression condition = parseExpression2();
2185 Token rightParenthesis = expect2(TokenType.CLOSE_PAREN); 2178 Token rightParenthesis = expect2(TokenType.CLOSE_PAREN);
2186 Token semicolon = expect2(TokenType.SEMICOLON); 2179 Token semicolon = expect2(TokenType.SEMICOLON);
2187 return new DoStatement.full(doKeyword, body, whileKeyword, leftParenthesis , condition, rightParenthesis, semicolon); 2180 return new DoStatement.full(doKeyword, body, whileKeyword, leftParenthesis , condition, rightParenthesis, semicolon);
2188 } finally { 2181 } finally {
2189 _inLoop = wasInLoop; 2182 _inLoop = wasInLoop;
2190 } 2183 }
2191 } 2184 }
2192 2185
2193 /** 2186 /**
2194 * Parse an empty statement. 2187 * Parse an empty statement.
2195 * <pre> 2188 * <pre>
2196 * emptyStatement ::= 2189 * emptyStatement ::=
2197 * ';' 2190 * ';'
2198 * </pre> 2191 * </pre>
2199 * @return the empty statement that was parsed 2192 * @return the empty statement that was parsed
2200 */ 2193 */
2201 Statement parseEmptyStatement() => new EmptyStatement.full(andAdvance); 2194 Statement parseEmptyStatement() => new EmptyStatement.full(andAdvance);
2202 2195
2203 /** 2196 /**
2204 * Parse an equality expression. 2197 * Parse an equality expression.
2205 * <pre> 2198 * <pre>
2206 * equalityExpression ::= 2199 * equalityExpression ::=
2207 * relationalExpression (equalityOperator relationalExpression)? 2200 * relationalExpression (equalityOperator relationalExpression)?
2208 * | 'super' equalityOperator relationalExpression 2201 * | 'super' equalityOperator relationalExpression
2209 * </pre> 2202 * </pre>
2210 * @return the equality expression that was parsed 2203 * @return the equality expression that was parsed
2211 */ 2204 */
2212 Expression parseEqualityExpression() { 2205 Expression parseEqualityExpression() {
2213 Expression expression; 2206 Expression expression;
2214 if (matches(Keyword.SUPER) && _currentToken.next.type.isEqualityOperator()) { 2207 if (matches(Keyword.SUPER) && _currentToken.next.type.isEqualityOperator()) {
2215 expression = new SuperExpression.full(andAdvance); 2208 expression = new SuperExpression.full(andAdvance);
2216 } else { 2209 } else {
2217 expression = parseRelationalExpression(); 2210 expression = parseRelationalExpression();
2218 } 2211 }
2219 while (_currentToken.type.isEqualityOperator()) { 2212 while (_currentToken.type.isEqualityOperator()) {
2220 Token operator = andAdvance; 2213 Token operator = andAdvance;
2221 expression = new BinaryExpression.full(expression, operator, parseRelation alExpression()); 2214 expression = new BinaryExpression.full(expression, operator, parseRelation alExpression());
2222 } 2215 }
2223 return expression; 2216 return expression;
2224 } 2217 }
2225 2218
2226 /** 2219 /**
2227 * Parse an export directive. 2220 * Parse an export directive.
2228 * <pre> 2221 * <pre>
2229 * exportDirective ::= 2222 * exportDirective ::=
2230 * metadata 'export' stringLiteral combinator*';' 2223 * metadata 'export' stringLiteral combinator*';'
2231 * </pre> 2224 * </pre>
2232 * @param commentAndMetadata the metadata to be associated with the directive 2225 * @param commentAndMetadata the metadata to be associated with the directive
2233 * @return the export directive that was parsed 2226 * @return the export directive that was parsed
2234 */ 2227 */
2235 ExportDirective parseExportDirective(CommentAndMetadata commentAndMetadata) { 2228 ExportDirective parseExportDirective(CommentAndMetadata commentAndMetadata) {
2236 Token exportKeyword = expect(Keyword.EXPORT); 2229 Token exportKeyword = expect(Keyword.EXPORT);
2237 StringLiteral libraryUri = parseStringLiteral(); 2230 StringLiteral libraryUri = parseStringLiteral();
2238 List<Combinator> combinators = parseCombinators(); 2231 List<Combinator> combinators = parseCombinators();
2239 Token semicolon = expect2(TokenType.SEMICOLON); 2232 Token semicolon = expect2(TokenType.SEMICOLON);
2240 return new ExportDirective.full(commentAndMetadata.comment, commentAndMetada ta.metadata, exportKeyword, libraryUri, combinators, semicolon); 2233 return new ExportDirective.full(commentAndMetadata.comment, commentAndMetada ta.metadata, exportKeyword, libraryUri, combinators, semicolon);
2241 } 2234 }
2242 2235
2243 /** 2236 /**
2244 * Parse an expression that does not contain any cascades. 2237 * Parse an expression that does not contain any cascades.
2245 * <pre> 2238 * <pre>
2246 * expression ::= 2239 * expression ::=
2247 * assignableExpression assignmentOperator expression 2240 * assignableExpression assignmentOperator expression
2248 * | conditionalExpression cascadeSection 2241 * | conditionalExpression cascadeSection
2249 * | throwExpression 2242 * | throwExpression
2250 * </pre> 2243 * </pre>
2251 * @return the expression that was parsed 2244 * @return the expression that was parsed
2252 */ 2245 */
(...skipping 15 matching lines...) Expand all
2268 tokenType = _currentToken.type; 2261 tokenType = _currentToken.type;
2269 } 2262 }
2270 return new CascadeExpression.full(expression, cascadeSections); 2263 return new CascadeExpression.full(expression, cascadeSections);
2271 } else if (tokenType.isAssignmentOperator()) { 2264 } else if (tokenType.isAssignmentOperator()) {
2272 Token operator = andAdvance; 2265 Token operator = andAdvance;
2273 ensureAssignable(expression); 2266 ensureAssignable(expression);
2274 return new AssignmentExpression.full(expression, operator, parseExpression 2()); 2267 return new AssignmentExpression.full(expression, operator, parseExpression 2());
2275 } 2268 }
2276 return expression; 2269 return expression;
2277 } 2270 }
2278 2271
2279 /** 2272 /**
2280 * Parse a list of expressions. 2273 * Parse a list of expressions.
2281 * <pre> 2274 * <pre>
2282 * expressionList ::= 2275 * expressionList ::=
2283 * expression (',' expression) 2276 * expression (',' expression)
2284 * </pre> 2277 * </pre>
2285 * @return the expression that was parsed 2278 * @return the expression that was parsed
2286 */ 2279 */
2287 List<Expression> parseExpressionList() { 2280 List<Expression> parseExpressionList() {
2288 List<Expression> expressions = new List<Expression>(); 2281 List<Expression> expressions = new List<Expression>();
2289 expressions.add(parseExpression2()); 2282 expressions.add(parseExpression2());
2290 while (optional(TokenType.COMMA)) { 2283 while (optional(TokenType.COMMA)) {
2291 expressions.add(parseExpression2()); 2284 expressions.add(parseExpression2());
2292 } 2285 }
2293 return expressions; 2286 return expressions;
2294 } 2287 }
2295 2288
2296 /** 2289 /**
2297 * Parse an expression that does not contain any cascades. 2290 * Parse an expression that does not contain any cascades.
2298 * <pre> 2291 * <pre>
2299 * expressionWithoutCascade ::= 2292 * expressionWithoutCascade ::=
2300 * assignableExpression assignmentOperator expressionWithoutCascade 2293 * assignableExpression assignmentOperator expressionWithoutCascade
2301 * | conditionalExpression 2294 * | conditionalExpression
2302 * | throwExpressionWithoutCascade 2295 * | throwExpressionWithoutCascade
2303 * </pre> 2296 * </pre>
2304 * @return the expression that was parsed 2297 * @return the expression that was parsed
2305 */ 2298 */
2306 Expression parseExpressionWithoutCascade() { 2299 Expression parseExpressionWithoutCascade() {
2307 if (matches(Keyword.THROW)) { 2300 if (matches(Keyword.THROW)) {
2308 return parseThrowExpressionWithoutCascade(); 2301 return parseThrowExpressionWithoutCascade();
2309 } else if (matches(Keyword.RETHROW)) { 2302 } else if (matches(Keyword.RETHROW)) {
2310 return parseRethrowExpression(); 2303 return parseRethrowExpression();
2311 } 2304 }
2312 Expression expression = parseConditionalExpression(); 2305 Expression expression = parseConditionalExpression();
2313 if (_currentToken.type.isAssignmentOperator()) { 2306 if (_currentToken.type.isAssignmentOperator()) {
2314 Token operator = andAdvance; 2307 Token operator = andAdvance;
2315 ensureAssignable(expression); 2308 ensureAssignable(expression);
2316 expression = new AssignmentExpression.full(expression, operator, parseExpr essionWithoutCascade()); 2309 expression = new AssignmentExpression.full(expression, operator, parseExpr essionWithoutCascade());
2317 } 2310 }
2318 return expression; 2311 return expression;
2319 } 2312 }
2320 2313
2321 /** 2314 /**
2322 * Parse a class extends clause. 2315 * Parse a class extends clause.
2323 * <pre> 2316 * <pre>
2324 * classExtendsClause ::= 2317 * classExtendsClause ::=
2325 * 'extends' type 2318 * 'extends' type
2326 * </pre> 2319 * </pre>
2327 * @return the class extends clause that was parsed 2320 * @return the class extends clause that was parsed
2328 */ 2321 */
2329 ExtendsClause parseExtendsClause() { 2322 ExtendsClause parseExtendsClause() {
2330 Token keyword = expect(Keyword.EXTENDS); 2323 Token keyword = expect(Keyword.EXTENDS);
2331 TypeName superclass = parseTypeName(); 2324 TypeName superclass = parseTypeName();
2332 return new ExtendsClause.full(keyword, superclass); 2325 return new ExtendsClause.full(keyword, superclass);
2333 } 2326 }
2334 2327
2335 /** 2328 /**
2336 * Parse the 'final', 'const', 'var' or type preceding a variable declaration. 2329 * Parse the 'final', 'const', 'var' or type preceding a variable declaration.
2337 * <pre> 2330 * <pre>
2338 * finalConstVarOrType ::= 2331 * finalConstVarOrType ::=
2339 * | 'final' type? 2332 * | 'final' type?
2340 * | 'const' type? 2333 * | 'const' type?
2341 * | 'var' 2334 * | 'var'
2342 * | type 2335 * | type
2343 * </pre> 2336 * </pre>
2344 * @param optional {@code true} if the keyword and type are optional 2337 * @param optional {@code true} if the keyword and type are optional
(...skipping 11 matching lines...) Expand all
2356 keyword = andAdvance; 2349 keyword = andAdvance;
2357 } else { 2350 } else {
2358 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)))) { 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)))) {
2359 type = parseReturnType(); 2352 type = parseReturnType();
2360 } else if (!optional) { 2353 } else if (!optional) {
2361 reportError7(ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, []); 2354 reportError7(ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, []);
2362 } 2355 }
2363 } 2356 }
2364 return new FinalConstVarOrType(keyword, type); 2357 return new FinalConstVarOrType(keyword, type);
2365 } 2358 }
2366 2359
2367 /** 2360 /**
2368 * Parse a formal parameter. At most one of {@code isOptional} and {@code isNa med} can be{@code true}. 2361 * Parse a formal parameter. At most one of {@code isOptional} and {@code isNa med} can be{@code true}.
2369 * <pre> 2362 * <pre>
2370 * defaultFormalParameter ::= 2363 * defaultFormalParameter ::=
2371 * normalFormalParameter ('=' expression)? 2364 * normalFormalParameter ('=' expression)?
2372 * defaultNamedParameter ::= 2365 * defaultNamedParameter ::=
2373 * normalFormalParameter (':' expression)? 2366 * normalFormalParameter (':' expression)?
2374 * </pre> 2367 * </pre>
2375 * @param kind the kind of parameter being expected based on the presence or a bsence of group 2368 * @param kind the kind of parameter being expected based on the presence or a bsence of group
2376 * delimiters 2369 * delimiters
(...skipping 17 matching lines...) Expand all
2394 reportError8(ParserErrorCode.WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER, s eperator, []); 2387 reportError8(ParserErrorCode.WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER, s eperator, []);
2395 } else if (identical(kind, ParameterKind.REQUIRED)) { 2388 } else if (identical(kind, ParameterKind.REQUIRED)) {
2396 reportError(ParserErrorCode.NAMED_PARAMETER_OUTSIDE_GROUP, parameter, [] ); 2389 reportError(ParserErrorCode.NAMED_PARAMETER_OUTSIDE_GROUP, parameter, [] );
2397 } 2390 }
2398 return new DefaultFormalParameter.full(parameter, kind, seperator, default Value); 2391 return new DefaultFormalParameter.full(parameter, kind, seperator, default Value);
2399 } else if (kind != ParameterKind.REQUIRED) { 2392 } else if (kind != ParameterKind.REQUIRED) {
2400 return new DefaultFormalParameter.full(parameter, kind, null, null); 2393 return new DefaultFormalParameter.full(parameter, kind, null, null);
2401 } 2394 }
2402 return parameter; 2395 return parameter;
2403 } 2396 }
2404 2397
2405 /** 2398 /**
2406 * Parse a list of formal parameters. 2399 * Parse a list of formal parameters.
2407 * <pre> 2400 * <pre>
2408 * formalParameterList ::= 2401 * formalParameterList ::=
2409 * '(' ')' 2402 * '(' ')'
2410 * | '(' normalFormalParameters (',' optionalFormalParameters)? ')' 2403 * | '(' normalFormalParameters (',' optionalFormalParameters)? ')'
2411 * | '(' optionalFormalParameters ')' 2404 * | '(' optionalFormalParameters ')'
2412 * normalFormalParameters ::= 2405 * normalFormalParameters ::=
2413 * normalFormalParameter (',' normalFormalParameter) 2406 * normalFormalParameter (',' normalFormalParameter)
2414 * optionalFormalParameters ::= 2407 * optionalFormalParameters ::=
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
2517 reportError7(ParserErrorCode.MISSING_TERMINATOR_FOR_PARAMETER_GROUP, ["}"] ); 2510 reportError7(ParserErrorCode.MISSING_TERMINATOR_FOR_PARAMETER_GROUP, ["}"] );
2518 } 2511 }
2519 if (leftSquareBracket == null) { 2512 if (leftSquareBracket == null) {
2520 leftSquareBracket = leftCurlyBracket; 2513 leftSquareBracket = leftCurlyBracket;
2521 } 2514 }
2522 if (rightSquareBracket == null) { 2515 if (rightSquareBracket == null) {
2523 rightSquareBracket = rightCurlyBracket; 2516 rightSquareBracket = rightCurlyBracket;
2524 } 2517 }
2525 return new FormalParameterList.full(leftParenthesis, parameters, leftSquareB racket, rightSquareBracket, rightParenthesis); 2518 return new FormalParameterList.full(leftParenthesis, parameters, leftSquareB racket, rightSquareBracket, rightParenthesis);
2526 } 2519 }
2527 2520
2528 /** 2521 /**
2529 * Parse a for statement. 2522 * Parse a for statement.
2530 * <pre> 2523 * <pre>
2531 * forStatement ::= 2524 * forStatement ::=
2532 * 'for' '(' forLoopParts ')' statement 2525 * 'for' '(' forLoopParts ')' statement
2533 * forLoopParts ::= 2526 * forLoopParts ::=
2534 * forInitializerStatement expression? ';' expressionList? 2527 * forInitializerStatement expression? ';' expressionList?
2535 * | declaredIdentifier 'in' expression 2528 * | declaredIdentifier 'in' expression
2536 * | identifier 'in' expression 2529 * | identifier 'in' expression
2537 * forInitializerStatement ::= 2530 * forInitializerStatement ::=
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
2592 if (!matches5(TokenType.CLOSE_PAREN)) { 2585 if (!matches5(TokenType.CLOSE_PAREN)) {
2593 updaters = parseExpressionList(); 2586 updaters = parseExpressionList();
2594 } 2587 }
2595 Token rightParenthesis = expect2(TokenType.CLOSE_PAREN); 2588 Token rightParenthesis = expect2(TokenType.CLOSE_PAREN);
2596 Statement body = parseStatement2(); 2589 Statement body = parseStatement2();
2597 return new ForStatement.full(forKeyword, leftParenthesis, variableList, in itialization, leftSeparator, condition, rightSeparator, updaters, rightParenthes is, body); 2590 return new ForStatement.full(forKeyword, leftParenthesis, variableList, in itialization, leftSeparator, condition, rightSeparator, updaters, rightParenthes is, body);
2598 } finally { 2591 } finally {
2599 _inLoop = wasInLoop; 2592 _inLoop = wasInLoop;
2600 } 2593 }
2601 } 2594 }
2602 2595
2603 /** 2596 /**
2604 * Parse a function body. 2597 * Parse a function body.
2605 * <pre> 2598 * <pre>
2606 * functionBody ::= 2599 * functionBody ::=
2607 * '=>' expression ';' 2600 * '=>' expression ';'
2608 * | block 2601 * | block
2609 * functionExpressionBody ::= 2602 * functionExpressionBody ::=
2610 * '=>' expression 2603 * '=>' expression
2611 * | block 2604 * | block
2612 * </pre> 2605 * </pre>
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2646 return new NativeFunctionBody.full(nativeToken, stringLiteral, expect2(T okenType.SEMICOLON)); 2639 return new NativeFunctionBody.full(nativeToken, stringLiteral, expect2(T okenType.SEMICOLON));
2647 } else { 2640 } else {
2648 reportError7(emptyErrorCode, []); 2641 reportError7(emptyErrorCode, []);
2649 return new EmptyFunctionBody.full(createSyntheticToken2(TokenType.SEMICO LON)); 2642 return new EmptyFunctionBody.full(createSyntheticToken2(TokenType.SEMICO LON));
2650 } 2643 }
2651 } finally { 2644 } finally {
2652 _inLoop = wasInLoop; 2645 _inLoop = wasInLoop;
2653 _inSwitch = wasInSwitch; 2646 _inSwitch = wasInSwitch;
2654 } 2647 }
2655 } 2648 }
2656 2649
2657 /** 2650 /**
2658 * Parse a function declaration. 2651 * Parse a function declaration.
2659 * <pre> 2652 * <pre>
2660 * functionDeclaration ::= 2653 * functionDeclaration ::=
2661 * functionSignature functionBody 2654 * functionSignature functionBody
2662 * | returnType? getOrSet identifier formalParameterList functionBody 2655 * | returnType? getOrSet identifier formalParameterList functionBody
2663 * </pre> 2656 * </pre>
2664 * @param commentAndMetadata the documentation comment and metadata to be asso ciated with the 2657 * @param commentAndMetadata the documentation comment and metadata to be asso ciated with the
2665 * declaration 2658 * declaration
2666 * @param externalKeyword the 'external' keyword, or {@code null} if the funct ion is not external 2659 * @param externalKeyword the 'external' keyword, or {@code null} if the funct ion is not external
(...skipping 24 matching lines...) Expand all
2691 parseFormalParameterList(); 2684 parseFormalParameterList();
2692 } 2685 }
2693 FunctionBody body; 2686 FunctionBody body;
2694 if (externalKeyword == null) { 2687 if (externalKeyword == null) {
2695 body = parseFunctionBody(false, ParserErrorCode.MISSING_FUNCTION_BODY, fal se); 2688 body = parseFunctionBody(false, ParserErrorCode.MISSING_FUNCTION_BODY, fal se);
2696 } else { 2689 } else {
2697 body = new EmptyFunctionBody.full(expect2(TokenType.SEMICOLON)); 2690 body = new EmptyFunctionBody.full(expect2(TokenType.SEMICOLON));
2698 } 2691 }
2699 return new FunctionDeclaration.full(commentAndMetadata.comment, commentAndMe tadata.metadata, externalKeyword, returnType, keyword, name, new FunctionExpress ion.full(parameters, body)); 2692 return new FunctionDeclaration.full(commentAndMetadata.comment, commentAndMe tadata.metadata, externalKeyword, returnType, keyword, name, new FunctionExpress ion.full(parameters, body));
2700 } 2693 }
2701 2694
2702 /** 2695 /**
2703 * Parse a function declaration statement. 2696 * Parse a function declaration statement.
2704 * <pre> 2697 * <pre>
2705 * functionDeclarationStatement ::= 2698 * functionDeclarationStatement ::=
2706 * functionSignature functionBody 2699 * functionSignature functionBody
2707 * </pre> 2700 * </pre>
2708 * @return the function declaration statement that was parsed 2701 * @return the function declaration statement that was parsed
2709 */ 2702 */
2710 Statement parseFunctionDeclarationStatement() => parseFunctionDeclarationState ment2(parseCommentAndMetadata(), parseOptionalReturnType()); 2703 Statement parseFunctionDeclarationStatement() => parseFunctionDeclarationState ment2(parseCommentAndMetadata(), parseOptionalReturnType());
2711 2704
2712 /** 2705 /**
2713 * Parse a function declaration statement. 2706 * Parse a function declaration statement.
2714 * <pre> 2707 * <pre>
2715 * functionDeclarationStatement ::= 2708 * functionDeclarationStatement ::=
2716 * functionSignature functionBody 2709 * functionSignature functionBody
2717 * </pre> 2710 * </pre>
2718 * @param commentAndMetadata the documentation comment and metadata to be asso ciated with the 2711 * @param commentAndMetadata the documentation comment and metadata to be asso ciated with the
2719 * declaration 2712 * declaration
2720 * @param returnType the return type, or {@code null} if there is no return ty pe 2713 * @param returnType the return type, or {@code null} if there is no return ty pe
2721 * @return the function declaration statement that was parsed 2714 * @return the function declaration statement that was parsed
2722 */ 2715 */
2723 Statement parseFunctionDeclarationStatement2(CommentAndMetadata commentAndMeta data, TypeName returnType) => new FunctionDeclarationStatement.full(parseFunctio nDeclaration(commentAndMetadata, null, returnType)); 2716 Statement parseFunctionDeclarationStatement2(CommentAndMetadata commentAndMeta data, TypeName returnType) => new FunctionDeclarationStatement.full(parseFunctio nDeclaration(commentAndMetadata, null, returnType));
2724 2717
2725 /** 2718 /**
2726 * Parse a function expression. 2719 * Parse a function expression.
2727 * <pre> 2720 * <pre>
2728 * functionExpression ::= 2721 * functionExpression ::=
2729 * formalParameterList functionExpressionBody 2722 * formalParameterList functionExpressionBody
2730 * </pre> 2723 * </pre>
2731 * @return the function expression that was parsed 2724 * @return the function expression that was parsed
2732 */ 2725 */
2733 FunctionExpression parseFunctionExpression() { 2726 FunctionExpression parseFunctionExpression() {
2734 FormalParameterList parameters = parseFormalParameterList(); 2727 FormalParameterList parameters = parseFormalParameterList();
2735 validateFormalParameterList(parameters); 2728 validateFormalParameterList(parameters);
2736 FunctionBody body = parseFunctionBody(false, ParserErrorCode.MISSING_FUNCTIO N_BODY, true); 2729 FunctionBody body = parseFunctionBody(false, ParserErrorCode.MISSING_FUNCTIO N_BODY, true);
2737 return new FunctionExpression.full(parameters, body); 2730 return new FunctionExpression.full(parameters, body);
2738 } 2731 }
2739 2732
2740 /** 2733 /**
2741 * Parse a function type alias. 2734 * Parse a function type alias.
2742 * <pre> 2735 * <pre>
2743 * functionTypeAlias ::= 2736 * functionTypeAlias ::=
2744 * functionPrefix typeParameterList? formalParameterList ';' 2737 * functionPrefix typeParameterList? formalParameterList ';'
2745 * functionPrefix ::= 2738 * functionPrefix ::=
2746 * returnType? name 2739 * returnType? name
2747 * </pre> 2740 * </pre>
2748 * @param commentAndMetadata the metadata to be associated with the member 2741 * @param commentAndMetadata the metadata to be associated with the member
2749 * @param keyword the token representing the 'typedef' keyword 2742 * @param keyword the token representing the 'typedef' keyword
(...skipping 16 matching lines...) Expand all
2766 return new FunctionTypeAlias.full(commentAndMetadata.comment, commentAndMe tadata.metadata, keyword, returnType, name, typeParameters, parameters, semicolo n); 2759 return new FunctionTypeAlias.full(commentAndMetadata.comment, commentAndMe tadata.metadata, keyword, returnType, name, typeParameters, parameters, semicolo n);
2767 } else if (!matches5(TokenType.OPEN_PAREN)) { 2760 } else if (!matches5(TokenType.OPEN_PAREN)) {
2768 reportError7(ParserErrorCode.MISSING_TYPEDEF_PARAMETERS, []); 2761 reportError7(ParserErrorCode.MISSING_TYPEDEF_PARAMETERS, []);
2769 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 )); 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 ));
2770 } 2763 }
2771 FormalParameterList parameters = parseFormalParameterList(); 2764 FormalParameterList parameters = parseFormalParameterList();
2772 validateFormalParameterList(parameters); 2765 validateFormalParameterList(parameters);
2773 Token semicolon = expect2(TokenType.SEMICOLON); 2766 Token semicolon = expect2(TokenType.SEMICOLON);
2774 return new FunctionTypeAlias.full(commentAndMetadata.comment, commentAndMeta data.metadata, keyword, returnType, name, typeParameters, parameters, semicolon) ; 2767 return new FunctionTypeAlias.full(commentAndMetadata.comment, commentAndMeta data.metadata, keyword, returnType, name, typeParameters, parameters, semicolon) ;
2775 } 2768 }
2776 2769
2777 /** 2770 /**
2778 * Parse a getter. 2771 * Parse a getter.
2779 * <pre> 2772 * <pre>
2780 * getter ::= 2773 * getter ::=
2781 * getterSignature functionBody? 2774 * getterSignature functionBody?
2782 * getterSignature ::= 2775 * getterSignature ::=
2783 * 'external'? 'static'? returnType? 'get' identifier 2776 * 'external'? 'static'? returnType? 'get' identifier
2784 * </pre> 2777 * </pre>
2785 * @param commentAndMetadata the documentation comment and metadata to be asso ciated with the 2778 * @param commentAndMetadata the documentation comment and metadata to be asso ciated with the
2786 * declaration 2779 * declaration
(...skipping 10 matching lines...) Expand all
2797 reportError7(ParserErrorCode.GETTER_WITH_PARAMETERS, []); 2790 reportError7(ParserErrorCode.GETTER_WITH_PARAMETERS, []);
2798 advance(); 2791 advance();
2799 advance(); 2792 advance();
2800 } 2793 }
2801 FunctionBody body = parseFunctionBody(externalKeyword != null || staticKeywo rd == null, ParserErrorCode.STATIC_GETTER_WITHOUT_BODY, false); 2794 FunctionBody body = parseFunctionBody(externalKeyword != null || staticKeywo rd == null, ParserErrorCode.STATIC_GETTER_WITHOUT_BODY, false);
2802 if (externalKeyword != null && body is! EmptyFunctionBody) { 2795 if (externalKeyword != null && body is! EmptyFunctionBody) {
2803 reportError7(ParserErrorCode.EXTERNAL_GETTER_WITH_BODY, []); 2796 reportError7(ParserErrorCode.EXTERNAL_GETTER_WITH_BODY, []);
2804 } 2797 }
2805 return new MethodDeclaration.full(commentAndMetadata.comment, commentAndMeta data.metadata, externalKeyword, staticKeyword, returnType, propertyKeyword, null , name, null, body); 2798 return new MethodDeclaration.full(commentAndMetadata.comment, commentAndMeta data.metadata, externalKeyword, staticKeyword, returnType, propertyKeyword, null , name, null, body);
2806 } 2799 }
2807 2800
2808 /** 2801 /**
2809 * Parse a list of identifiers. 2802 * Parse a list of identifiers.
2810 * <pre> 2803 * <pre>
2811 * identifierList ::= 2804 * identifierList ::=
2812 * identifier (',' identifier) 2805 * identifier (',' identifier)
2813 * </pre> 2806 * </pre>
2814 * @return the list of identifiers that were parsed 2807 * @return the list of identifiers that were parsed
2815 */ 2808 */
2816 List<SimpleIdentifier> parseIdentifierList() { 2809 List<SimpleIdentifier> parseIdentifierList() {
2817 List<SimpleIdentifier> identifiers = new List<SimpleIdentifier>(); 2810 List<SimpleIdentifier> identifiers = new List<SimpleIdentifier>();
2818 identifiers.add(parseSimpleIdentifier()); 2811 identifiers.add(parseSimpleIdentifier());
2819 while (matches5(TokenType.COMMA)) { 2812 while (matches5(TokenType.COMMA)) {
2820 advance(); 2813 advance();
2821 identifiers.add(parseSimpleIdentifier()); 2814 identifiers.add(parseSimpleIdentifier());
2822 } 2815 }
2823 return identifiers; 2816 return identifiers;
2824 } 2817 }
2825 2818
2826 /** 2819 /**
2827 * Parse an if statement. 2820 * Parse an if statement.
2828 * <pre> 2821 * <pre>
2829 * ifStatement ::= 2822 * ifStatement ::=
2830 * 'if' '(' expression ')' statement ('else' statement)? 2823 * 'if' '(' expression ')' statement ('else' statement)?
2831 * </pre> 2824 * </pre>
2832 * @return the if statement that was parsed 2825 * @return the if statement that was parsed
2833 */ 2826 */
2834 Statement parseIfStatement() { 2827 Statement parseIfStatement() {
2835 Token ifKeyword = expect(Keyword.IF); 2828 Token ifKeyword = expect(Keyword.IF);
2836 Token leftParenthesis = expect2(TokenType.OPEN_PAREN); 2829 Token leftParenthesis = expect2(TokenType.OPEN_PAREN);
2837 Expression condition = parseExpression2(); 2830 Expression condition = parseExpression2();
2838 Token rightParenthesis = expect2(TokenType.CLOSE_PAREN); 2831 Token rightParenthesis = expect2(TokenType.CLOSE_PAREN);
2839 Statement thenStatement = parseStatement2(); 2832 Statement thenStatement = parseStatement2();
2840 Token elseKeyword = null; 2833 Token elseKeyword = null;
2841 Statement elseStatement = null; 2834 Statement elseStatement = null;
2842 if (matches(Keyword.ELSE)) { 2835 if (matches(Keyword.ELSE)) {
2843 elseKeyword = andAdvance; 2836 elseKeyword = andAdvance;
2844 elseStatement = parseStatement2(); 2837 elseStatement = parseStatement2();
2845 } 2838 }
2846 return new IfStatement.full(ifKeyword, leftParenthesis, condition, rightPare nthesis, thenStatement, elseKeyword, elseStatement); 2839 return new IfStatement.full(ifKeyword, leftParenthesis, condition, rightPare nthesis, thenStatement, elseKeyword, elseStatement);
2847 } 2840 }
2848 2841
2849 /** 2842 /**
2850 * Parse an implements clause. 2843 * Parse an implements clause.
2851 * <pre> 2844 * <pre>
2852 * implementsClause ::= 2845 * implementsClause ::=
2853 * 'implements' type (',' type) 2846 * 'implements' type (',' type)
2854 * </pre> 2847 * </pre>
2855 * @return the implements clause that was parsed 2848 * @return the implements clause that was parsed
2856 */ 2849 */
2857 ImplementsClause parseImplementsClause() { 2850 ImplementsClause parseImplementsClause() {
2858 Token keyword = expect(Keyword.IMPLEMENTS); 2851 Token keyword = expect(Keyword.IMPLEMENTS);
2859 List<TypeName> interfaces = new List<TypeName>(); 2852 List<TypeName> interfaces = new List<TypeName>();
2860 interfaces.add(parseTypeName()); 2853 interfaces.add(parseTypeName());
2861 while (optional(TokenType.COMMA)) { 2854 while (optional(TokenType.COMMA)) {
2862 interfaces.add(parseTypeName()); 2855 interfaces.add(parseTypeName());
2863 } 2856 }
2864 return new ImplementsClause.full(keyword, interfaces); 2857 return new ImplementsClause.full(keyword, interfaces);
2865 } 2858 }
2866 2859
2867 /** 2860 /**
2868 * Parse an import directive. 2861 * Parse an import directive.
2869 * <pre> 2862 * <pre>
2870 * importDirective ::= 2863 * importDirective ::=
2871 * metadata 'import' stringLiteral ('as' identifier)? combinator*';' 2864 * metadata 'import' stringLiteral ('as' identifier)? combinator*';'
2872 * </pre> 2865 * </pre>
2873 * @param commentAndMetadata the metadata to be associated with the directive 2866 * @param commentAndMetadata the metadata to be associated with the directive
2874 * @return the import directive that was parsed 2867 * @return the import directive that was parsed
2875 */ 2868 */
2876 ImportDirective parseImportDirective(CommentAndMetadata commentAndMetadata) { 2869 ImportDirective parseImportDirective(CommentAndMetadata commentAndMetadata) {
2877 Token importKeyword = expect(Keyword.IMPORT); 2870 Token importKeyword = expect(Keyword.IMPORT);
2878 StringLiteral libraryUri = parseStringLiteral(); 2871 StringLiteral libraryUri = parseStringLiteral();
2879 Token asToken = null; 2872 Token asToken = null;
2880 SimpleIdentifier prefix = null; 2873 SimpleIdentifier prefix = null;
2881 if (matches(Keyword.AS)) { 2874 if (matches(Keyword.AS)) {
2882 asToken = andAdvance; 2875 asToken = andAdvance;
2883 prefix = parseSimpleIdentifier(); 2876 prefix = parseSimpleIdentifier();
2884 } 2877 }
2885 List<Combinator> combinators = parseCombinators(); 2878 List<Combinator> combinators = parseCombinators();
2886 Token semicolon = expect2(TokenType.SEMICOLON); 2879 Token semicolon = expect2(TokenType.SEMICOLON);
2887 return new ImportDirective.full(commentAndMetadata.comment, commentAndMetada ta.metadata, importKeyword, libraryUri, asToken, prefix, combinators, semicolon) ; 2880 return new ImportDirective.full(commentAndMetadata.comment, commentAndMetada ta.metadata, importKeyword, libraryUri, asToken, prefix, combinators, semicolon) ;
2888 } 2881 }
2889 2882
2890 /** 2883 /**
2891 * Parse a list of initialized identifiers. 2884 * Parse a list of initialized identifiers.
2892 * <pre> 2885 * <pre>
2893 * ?? ::= 2886 * ?? ::=
2894 * 'static'? ('var' | type) initializedIdentifierList ';' 2887 * 'static'? ('var' | type) initializedIdentifierList ';'
2895 * | 'final' type? initializedIdentifierList ';' 2888 * | 'final' type? initializedIdentifierList ';'
2896 * initializedIdentifierList ::= 2889 * initializedIdentifierList ::=
2897 * initializedIdentifier (',' initializedIdentifier) 2890 * initializedIdentifier (',' initializedIdentifier)
2898 * initializedIdentifier ::= 2891 * initializedIdentifier ::=
2899 * identifier ('=' expression)? 2892 * identifier ('=' expression)?
2900 * </pre> 2893 * </pre>
2901 * @param commentAndMetadata the documentation comment and metadata to be asso ciated with the 2894 * @param commentAndMetadata the documentation comment and metadata to be asso ciated with the
2902 * declaration 2895 * declaration
2903 * @param staticKeyword the static keyword, or {@code null} if the getter is n ot static 2896 * @param staticKeyword the static keyword, or {@code null} if the getter is n ot static
2904 * @param keyword the token representing the 'final', 'const' or 'var' keyword , or {@code null} if 2897 * @param keyword the token representing the 'final', 'const' or 'var' keyword , or {@code null} if
2905 * there is no keyword 2898 * there is no keyword
2906 * @param type the type that has already been parsed, or {@code null} if 'var' was provided 2899 * @param type the type that has already been parsed, or {@code null} if 'var' was provided
2907 * @return the getter that was parsed 2900 * @return the getter that was parsed
2908 */ 2901 */
2909 FieldDeclaration parseInitializedIdentifierList(CommentAndMetadata commentAndM etadata, Token staticKeyword, Token keyword, TypeName type) { 2902 FieldDeclaration parseInitializedIdentifierList(CommentAndMetadata commentAndM etadata, Token staticKeyword, Token keyword, TypeName type) {
2910 VariableDeclarationList fieldList = parseVariableDeclarationList2(null, keyw ord, type); 2903 VariableDeclarationList fieldList = parseVariableDeclarationList2(null, keyw ord, type);
2911 return new FieldDeclaration.full(commentAndMetadata.comment, commentAndMetad ata.metadata, staticKeyword, fieldList, expect2(TokenType.SEMICOLON)); 2904 return new FieldDeclaration.full(commentAndMetadata.comment, commentAndMetad ata.metadata, staticKeyword, fieldList, expect2(TokenType.SEMICOLON));
2912 } 2905 }
2913 2906
2914 /** 2907 /**
2915 * Parse an instance creation expression. 2908 * Parse an instance creation expression.
2916 * <pre> 2909 * <pre>
2917 * instanceCreationExpression ::= 2910 * instanceCreationExpression ::=
2918 * ('new' | 'const') type ('.' identifier)? argumentList 2911 * ('new' | 'const') type ('.' identifier)? argumentList
2919 * </pre> 2912 * </pre>
2920 * @param keyword the 'new' or 'const' keyword that introduces the expression 2913 * @param keyword the 'new' or 'const' keyword that introduces the expression
2921 * @return the instance creation expression that was parsed 2914 * @return the instance creation expression that was parsed
2922 */ 2915 */
2923 InstanceCreationExpression parseInstanceCreationExpression(Token keyword) { 2916 InstanceCreationExpression parseInstanceCreationExpression(Token keyword) {
2924 ConstructorName constructorName = parseConstructorName(); 2917 ConstructorName constructorName = parseConstructorName();
2925 ArgumentList argumentList = parseArgumentList(); 2918 ArgumentList argumentList = parseArgumentList();
2926 return new InstanceCreationExpression.full(keyword, constructorName, argumen tList); 2919 return new InstanceCreationExpression.full(keyword, constructorName, argumen tList);
2927 } 2920 }
2928 2921
2929 /** 2922 /**
2930 * Parse a library directive. 2923 * Parse a library directive.
2931 * <pre> 2924 * <pre>
2932 * libraryDirective ::= 2925 * libraryDirective ::=
2933 * metadata 'library' identifier ';' 2926 * metadata 'library' identifier ';'
2934 * </pre> 2927 * </pre>
2935 * @param commentAndMetadata the metadata to be associated with the directive 2928 * @param commentAndMetadata the metadata to be associated with the directive
2936 * @return the library directive that was parsed 2929 * @return the library directive that was parsed
2937 */ 2930 */
2938 LibraryDirective parseLibraryDirective(CommentAndMetadata commentAndMetadata) { 2931 LibraryDirective parseLibraryDirective(CommentAndMetadata commentAndMetadata) {
2939 Token keyword = expect(Keyword.LIBRARY); 2932 Token keyword = expect(Keyword.LIBRARY);
2940 LibraryIdentifier libraryName = parseLibraryName(ParserErrorCode.MISSING_NAM E_IN_LIBRARY_DIRECTIVE, keyword); 2933 LibraryIdentifier libraryName = parseLibraryName(ParserErrorCode.MISSING_NAM E_IN_LIBRARY_DIRECTIVE, keyword);
2941 Token semicolon = expect2(TokenType.SEMICOLON); 2934 Token semicolon = expect2(TokenType.SEMICOLON);
2942 return new LibraryDirective.full(commentAndMetadata.comment, commentAndMetad ata.metadata, keyword, libraryName, semicolon); 2935 return new LibraryDirective.full(commentAndMetadata.comment, commentAndMetad ata.metadata, keyword, libraryName, semicolon);
2943 } 2936 }
2944 2937
2945 /** 2938 /**
2946 * Parse a library identifier. 2939 * Parse a library identifier.
2947 * <pre> 2940 * <pre>
2948 * libraryIdentifier ::= 2941 * libraryIdentifier ::=
2949 * identifier ('.' identifier) 2942 * identifier ('.' identifier)
2950 * </pre> 2943 * </pre>
2951 * @return the library identifier that was parsed 2944 * @return the library identifier that was parsed
2952 */ 2945 */
2953 LibraryIdentifier parseLibraryIdentifier() { 2946 LibraryIdentifier parseLibraryIdentifier() {
2954 List<SimpleIdentifier> components = new List<SimpleIdentifier>(); 2947 List<SimpleIdentifier> components = new List<SimpleIdentifier>();
2955 components.add(parseSimpleIdentifier()); 2948 components.add(parseSimpleIdentifier());
2956 while (matches5(TokenType.PERIOD)) { 2949 while (matches5(TokenType.PERIOD)) {
2957 advance(); 2950 advance();
2958 components.add(parseSimpleIdentifier()); 2951 components.add(parseSimpleIdentifier());
2959 } 2952 }
2960 return new LibraryIdentifier.full(components); 2953 return new LibraryIdentifier.full(components);
2961 } 2954 }
2962 2955
2963 /** 2956 /**
2964 * Parse a library name. 2957 * Parse a library name.
2965 * <pre> 2958 * <pre>
2966 * libraryName ::= 2959 * libraryName ::=
2967 * libraryIdentifier 2960 * libraryIdentifier
2968 * </pre> 2961 * </pre>
2969 * @param missingNameError the error code to be used if the library name is mi ssing 2962 * @param missingNameError the error code to be used if the library name is mi ssing
2970 * @param missingNameToken the token associated with the error produced if the library name is 2963 * @param missingNameToken the token associated with the error produced if the library name is
2971 * missing 2964 * missing
2972 * @return the library name that was parsed 2965 * @return the library name that was parsed
2973 */ 2966 */
2974 LibraryIdentifier parseLibraryName(ParserErrorCode missingNameError, Token mis singNameToken) { 2967 LibraryIdentifier parseLibraryName(ParserErrorCode missingNameError, Token mis singNameToken) {
2975 if (matchesIdentifier()) { 2968 if (matchesIdentifier()) {
2976 return parseLibraryIdentifier(); 2969 return parseLibraryIdentifier();
2977 } else if (matches5(TokenType.STRING)) { 2970 } else if (matches5(TokenType.STRING)) {
2978 StringLiteral string = parseStringLiteral(); 2971 StringLiteral string = parseStringLiteral();
2979 reportError(ParserErrorCode.NON_IDENTIFIER_LIBRARY_NAME, string, []); 2972 reportError(ParserErrorCode.NON_IDENTIFIER_LIBRARY_NAME, string, []);
2980 } else { 2973 } else {
2981 reportError8(missingNameError, missingNameToken, []); 2974 reportError8(missingNameError, missingNameToken, []);
2982 } 2975 }
2983 List<SimpleIdentifier> components = new List<SimpleIdentifier>(); 2976 List<SimpleIdentifier> components = new List<SimpleIdentifier>();
2984 components.add(createSyntheticIdentifier()); 2977 components.add(createSyntheticIdentifier());
2985 return new LibraryIdentifier.full(components); 2978 return new LibraryIdentifier.full(components);
2986 } 2979 }
2987 2980
2988 /** 2981 /**
2989 * Parse a list literal. 2982 * Parse a list literal.
2990 * <pre> 2983 * <pre>
2991 * listLiteral ::= 2984 * listLiteral ::=
2992 * 'const'? typeArguments? '\[' (expressionList ','?)? '\]' 2985 * 'const'? typeArguments? '\[' (expressionList ','?)? '\]'
2993 * </pre> 2986 * </pre>
2994 * @param modifier the 'const' modifier appearing before the literal, or {@cod e null} if there is 2987 * @param modifier the 'const' modifier appearing before the literal, or {@cod e null} if there is
2995 * no modifier 2988 * no modifier
2996 * @param typeArguments the type arguments appearing before the literal, or {@ code null} if there 2989 * @param typeArguments the type arguments appearing before the literal, or {@ code null} if there
2997 * are no type arguments 2990 * are no type arguments
(...skipping 18 matching lines...) Expand all
3016 elements.add(parseExpression2()); 3009 elements.add(parseExpression2());
3017 while (optional(TokenType.COMMA)) { 3010 while (optional(TokenType.COMMA)) {
3018 if (matches5(TokenType.CLOSE_SQUARE_BRACKET)) { 3011 if (matches5(TokenType.CLOSE_SQUARE_BRACKET)) {
3019 return new ListLiteral.full(modifier, typeArguments, leftBracket, elemen ts, andAdvance); 3012 return new ListLiteral.full(modifier, typeArguments, leftBracket, elemen ts, andAdvance);
3020 } 3013 }
3021 elements.add(parseExpression2()); 3014 elements.add(parseExpression2());
3022 } 3015 }
3023 Token rightBracket = expect2(TokenType.CLOSE_SQUARE_BRACKET); 3016 Token rightBracket = expect2(TokenType.CLOSE_SQUARE_BRACKET);
3024 return new ListLiteral.full(modifier, typeArguments, leftBracket, elements, rightBracket); 3017 return new ListLiteral.full(modifier, typeArguments, leftBracket, elements, rightBracket);
3025 } 3018 }
3026 3019
3027 /** 3020 /**
3028 * Parse a list or map literal. 3021 * Parse a list or map literal.
3029 * <pre> 3022 * <pre>
3030 * listOrMapLiteral ::= 3023 * listOrMapLiteral ::=
3031 * listLiteral 3024 * listLiteral
3032 * | mapLiteral 3025 * | mapLiteral
3033 * </pre> 3026 * </pre>
3034 * @param modifier the 'const' modifier appearing before the literal, or {@cod e null} if there is 3027 * @param modifier the 'const' modifier appearing before the literal, or {@cod e null} if there is
3035 * no modifier 3028 * no modifier
3036 * @return the list or map literal that was parsed 3029 * @return the list or map literal that was parsed
3037 */ 3030 */
3038 TypedLiteral parseListOrMapLiteral(Token modifier) { 3031 TypedLiteral parseListOrMapLiteral(Token modifier) {
3039 TypeArgumentList typeArguments = null; 3032 TypeArgumentList typeArguments = null;
3040 if (matches5(TokenType.LT)) { 3033 if (matches5(TokenType.LT)) {
3041 typeArguments = parseTypeArgumentList(); 3034 typeArguments = parseTypeArgumentList();
3042 } 3035 }
3043 if (matches5(TokenType.OPEN_CURLY_BRACKET)) { 3036 if (matches5(TokenType.OPEN_CURLY_BRACKET)) {
3044 return parseMapLiteral(modifier, typeArguments); 3037 return parseMapLiteral(modifier, typeArguments);
3045 } else if (matches5(TokenType.OPEN_SQUARE_BRACKET) || matches5(TokenType.IND EX)) { 3038 } else if (matches5(TokenType.OPEN_SQUARE_BRACKET) || matches5(TokenType.IND EX)) {
3046 return parseListLiteral(modifier, typeArguments); 3039 return parseListLiteral(modifier, typeArguments);
3047 } 3040 }
3048 reportError7(ParserErrorCode.EXPECTED_LIST_OR_MAP_LITERAL, []); 3041 reportError7(ParserErrorCode.EXPECTED_LIST_OR_MAP_LITERAL, []);
3049 return new ListLiteral.full(modifier, typeArguments, createSyntheticToken2(T okenType.OPEN_SQUARE_BRACKET), null, createSyntheticToken2(TokenType.CLOSE_SQUAR E_BRACKET)); 3042 return new ListLiteral.full(modifier, typeArguments, createSyntheticToken2(T okenType.OPEN_SQUARE_BRACKET), null, createSyntheticToken2(TokenType.CLOSE_SQUAR E_BRACKET));
3050 } 3043 }
3051 3044
3052 /** 3045 /**
3053 * Parse a logical and expression. 3046 * Parse a logical and expression.
3054 * <pre> 3047 * <pre>
3055 * logicalAndExpression ::= 3048 * logicalAndExpression ::=
3056 * bitwiseOrExpression ('&&' bitwiseOrExpression) 3049 * bitwiseOrExpression ('&&' bitwiseOrExpression)
3057 * </pre> 3050 * </pre>
3058 * @return the logical and expression that was parsed 3051 * @return the logical and expression that was parsed
3059 */ 3052 */
3060 Expression parseLogicalAndExpression() { 3053 Expression parseLogicalAndExpression() {
3061 Expression expression = parseBitwiseOrExpression(); 3054 Expression expression = parseBitwiseOrExpression();
3062 while (matches5(TokenType.AMPERSAND_AMPERSAND)) { 3055 while (matches5(TokenType.AMPERSAND_AMPERSAND)) {
3063 Token operator = andAdvance; 3056 Token operator = andAdvance;
3064 expression = new BinaryExpression.full(expression, operator, parseBitwiseO rExpression()); 3057 expression = new BinaryExpression.full(expression, operator, parseBitwiseO rExpression());
3065 } 3058 }
3066 return expression; 3059 return expression;
3067 } 3060 }
3068 3061
3069 /** 3062 /**
3070 * Parse a logical or expression. 3063 * Parse a logical or expression.
3071 * <pre> 3064 * <pre>
3072 * logicalOrExpression ::= 3065 * logicalOrExpression ::=
3073 * logicalAndExpression ('||' logicalAndExpression) 3066 * logicalAndExpression ('||' logicalAndExpression)
3074 * </pre> 3067 * </pre>
3075 * @return the logical or expression that was parsed 3068 * @return the logical or expression that was parsed
3076 */ 3069 */
3077 Expression parseLogicalOrExpression() { 3070 Expression parseLogicalOrExpression() {
3078 Expression expression = parseLogicalAndExpression(); 3071 Expression expression = parseLogicalAndExpression();
3079 while (matches5(TokenType.BAR_BAR)) { 3072 while (matches5(TokenType.BAR_BAR)) {
3080 Token operator = andAdvance; 3073 Token operator = andAdvance;
3081 expression = new BinaryExpression.full(expression, operator, parseLogicalA ndExpression()); 3074 expression = new BinaryExpression.full(expression, operator, parseLogicalA ndExpression());
3082 } 3075 }
3083 return expression; 3076 return expression;
3084 } 3077 }
3085 3078
3086 /** 3079 /**
3087 * Parse a map literal. 3080 * Parse a map literal.
3088 * <pre> 3081 * <pre>
3089 * mapLiteral ::= 3082 * mapLiteral ::=
3090 * 'const'? typeArguments? '{' (mapLiteralEntry (',' mapLiteralEntry)* ','?)? '}' 3083 * 'const'? typeArguments? '{' (mapLiteralEntry (',' mapLiteralEntry)* ','?)? '}'
3091 * </pre> 3084 * </pre>
3092 * @param modifier the 'const' modifier appearing before the literal, or {@cod e null} if there is 3085 * @param modifier the 'const' modifier appearing before the literal, or {@cod e null} if there is
3093 * no modifier 3086 * no modifier
3094 * @param typeArguments the type arguments that were declared, or {@code null} if there are no 3087 * @param typeArguments the type arguments that were declared, or {@code null} if there are no
3095 * type arguments 3088 * type arguments
(...skipping 14 matching lines...) Expand all
3110 entries.add(parseMapLiteralEntry()); 3103 entries.add(parseMapLiteralEntry());
3111 while (optional(TokenType.COMMA)) { 3104 while (optional(TokenType.COMMA)) {
3112 if (matches5(TokenType.CLOSE_CURLY_BRACKET)) { 3105 if (matches5(TokenType.CLOSE_CURLY_BRACKET)) {
3113 return new MapLiteral.full(modifier, typeArguments, leftBracket, entries , andAdvance); 3106 return new MapLiteral.full(modifier, typeArguments, leftBracket, entries , andAdvance);
3114 } 3107 }
3115 entries.add(parseMapLiteralEntry()); 3108 entries.add(parseMapLiteralEntry());
3116 } 3109 }
3117 Token rightBracket = expect2(TokenType.CLOSE_CURLY_BRACKET); 3110 Token rightBracket = expect2(TokenType.CLOSE_CURLY_BRACKET);
3118 return new MapLiteral.full(modifier, typeArguments, leftBracket, entries, ri ghtBracket); 3111 return new MapLiteral.full(modifier, typeArguments, leftBracket, entries, ri ghtBracket);
3119 } 3112 }
3120 3113
3121 /** 3114 /**
3122 * Parse a map literal entry. 3115 * Parse a map literal entry.
3123 * <pre> 3116 * <pre>
3124 * mapLiteralEntry ::= 3117 * mapLiteralEntry ::=
3125 * expression ':' expression 3118 * expression ':' expression
3126 * </pre> 3119 * </pre>
3127 * @return the map literal entry that was parsed 3120 * @return the map literal entry that was parsed
3128 */ 3121 */
3129 MapLiteralEntry parseMapLiteralEntry() { 3122 MapLiteralEntry parseMapLiteralEntry() {
3130 Expression key = parseExpression2(); 3123 Expression key = parseExpression2();
3131 Token separator = expect2(TokenType.COLON); 3124 Token separator = expect2(TokenType.COLON);
3132 Expression value = parseExpression2(); 3125 Expression value = parseExpression2();
3133 return new MapLiteralEntry.full(key, separator, value); 3126 return new MapLiteralEntry.full(key, separator, value);
3134 } 3127 }
3135 3128
3136 /** 3129 /**
3137 * Parse a method declaration. 3130 * Parse a method declaration.
3138 * <pre> 3131 * <pre>
3139 * functionDeclaration ::= 3132 * functionDeclaration ::=
3140 * 'external'? 'static'? functionSignature functionBody 3133 * 'external'? 'static'? functionSignature functionBody
3141 * | 'external'? functionSignature ';' 3134 * | 'external'? functionSignature ';'
3142 * </pre> 3135 * </pre>
3143 * @param commentAndMetadata the documentation comment and metadata to be asso ciated with the 3136 * @param commentAndMetadata the documentation comment and metadata to be asso ciated with the
3144 * declaration 3137 * declaration
3145 * @param externalKeyword the 'external' token 3138 * @param externalKeyword the 'external' token
3146 * @param staticKeyword the static keyword, or {@code null} if the getter is n ot static 3139 * @param staticKeyword the static keyword, or {@code null} if the getter is n ot static
3147 * @param returnType the return type of the method 3140 * @param returnType the return type of the method
3148 * @return the method declaration that was parsed 3141 * @return the method declaration that was parsed
3149 */ 3142 */
3150 MethodDeclaration parseMethodDeclaration(CommentAndMetadata commentAndMetadata , Token externalKeyword, Token staticKeyword, TypeName returnType) { 3143 MethodDeclaration parseMethodDeclaration(CommentAndMetadata commentAndMetadata , Token externalKeyword, Token staticKeyword, TypeName returnType) {
3151 SimpleIdentifier methodName = parseSimpleIdentifier(); 3144 SimpleIdentifier methodName = parseSimpleIdentifier();
3152 FormalParameterList parameters = parseFormalParameterList(); 3145 FormalParameterList parameters = parseFormalParameterList();
3153 validateFormalParameterList(parameters); 3146 validateFormalParameterList(parameters);
3154 return parseMethodDeclaration2(commentAndMetadata, externalKeyword, staticKe yword, returnType, methodName, parameters); 3147 return parseMethodDeclaration2(commentAndMetadata, externalKeyword, staticKe yword, returnType, methodName, parameters);
3155 } 3148 }
3156 3149
3157 /** 3150 /**
3158 * Parse a method declaration. 3151 * Parse a method declaration.
3159 * <pre> 3152 * <pre>
3160 * functionDeclaration ::= 3153 * functionDeclaration ::=
3161 * ('external' 'static'?)? functionSignature functionBody 3154 * ('external' 'static'?)? functionSignature functionBody
3162 * | 'external'? functionSignature ';' 3155 * | 'external'? functionSignature ';'
3163 * </pre> 3156 * </pre>
3164 * @param commentAndMetadata the documentation comment and metadata to be asso ciated with the 3157 * @param commentAndMetadata the documentation comment and metadata to be asso ciated with the
3165 * declaration 3158 * declaration
3166 * @param externalKeyword the 'external' token 3159 * @param externalKeyword the 'external' token
3167 * @param staticKeyword the static keyword, or {@code null} if the getter is n ot static 3160 * @param staticKeyword the static keyword, or {@code null} if the getter is n ot static
3168 * @param returnType the return type of the method 3161 * @param returnType the return type of the method
3169 * @param name the name of the method 3162 * @param name the name of the method
3170 * @param parameters the parameters to the method 3163 * @param parameters the parameters to the method
3171 * @return the method declaration that was parsed 3164 * @return the method declaration that was parsed
3172 */ 3165 */
3173 MethodDeclaration parseMethodDeclaration2(CommentAndMetadata commentAndMetadat a, Token externalKeyword, Token staticKeyword, TypeName returnType, SimpleIdenti fier name, FormalParameterList parameters) { 3166 MethodDeclaration parseMethodDeclaration2(CommentAndMetadata commentAndMetadat a, Token externalKeyword, Token staticKeyword, TypeName returnType, SimpleIdenti fier name, FormalParameterList parameters) {
3174 FunctionBody body = parseFunctionBody(externalKeyword != null || staticKeywo rd == null, ParserErrorCode.MISSING_FUNCTION_BODY, false); 3167 FunctionBody body = parseFunctionBody(externalKeyword != null || staticKeywo rd == null, ParserErrorCode.MISSING_FUNCTION_BODY, false);
3175 if (externalKeyword != null) { 3168 if (externalKeyword != null) {
3176 if (body is! EmptyFunctionBody) { 3169 if (body is! EmptyFunctionBody) {
3177 reportError(ParserErrorCode.EXTERNAL_METHOD_WITH_BODY, body, []); 3170 reportError(ParserErrorCode.EXTERNAL_METHOD_WITH_BODY, body, []);
3178 } 3171 }
3179 } else if (staticKeyword != null) { 3172 } else if (staticKeyword != null) {
3180 if (body is EmptyFunctionBody) { 3173 if (body is EmptyFunctionBody) {
3181 reportError(ParserErrorCode.ABSTRACT_STATIC_METHOD, body, []); 3174 reportError(ParserErrorCode.ABSTRACT_STATIC_METHOD, body, []);
3182 } 3175 }
3183 } 3176 }
3184 return new MethodDeclaration.full(commentAndMetadata.comment, commentAndMeta data.metadata, externalKeyword, staticKeyword, returnType, null, null, name, par ameters, body); 3177 return new MethodDeclaration.full(commentAndMetadata.comment, commentAndMeta data.metadata, externalKeyword, staticKeyword, returnType, null, null, name, par ameters, body);
3185 } 3178 }
3186 3179
3187 /** 3180 /**
3188 * Parse the modifiers preceding a declaration. This method allows the modifie rs to appear in any 3181 * Parse the modifiers preceding a declaration. This method allows the modifie rs to appear in any
3189 * order but does generate errors for duplicated modifiers. Checks for other p roblems, such as 3182 * order but does generate errors for duplicated modifiers. Checks for other p roblems, such as
3190 * having the modifiers appear in the wrong order or specifying both 'const' a nd 'final', are 3183 * having the modifiers appear in the wrong order or specifying both 'const' a nd 'final', are
3191 * reported in one of the methods whose name is prefixed with {@code validateM odifiersFor}. 3184 * reported in one of the methods whose name is prefixed with {@code validateM odifiersFor}.
3192 * <pre> 3185 * <pre>
3193 * modifiers ::= 3186 * modifiers ::=
3194 * ('abstract' | 'const' | 'external' | 'factory' | 'final' | 'static' | 'var' ) 3187 * ('abstract' | 'const' | 'external' | 'factory' | 'final' | 'static' | 'var' )
3195 * </pre> 3188 * </pre>
3196 * @return the modifiers that were parsed 3189 * @return the modifiers that were parsed
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
3247 advance(); 3240 advance();
3248 } else { 3241 } else {
3249 modifiers.varKeyword = andAdvance; 3242 modifiers.varKeyword = andAdvance;
3250 } 3243 }
3251 } else { 3244 } else {
3252 progress = false; 3245 progress = false;
3253 } 3246 }
3254 } 3247 }
3255 return modifiers; 3248 return modifiers;
3256 } 3249 }
3257 3250
3258 /** 3251 /**
3259 * Parse a multiplicative expression. 3252 * Parse a multiplicative expression.
3260 * <pre> 3253 * <pre>
3261 * multiplicativeExpression ::= 3254 * multiplicativeExpression ::=
3262 * unaryExpression (multiplicativeOperator unaryExpression) 3255 * unaryExpression (multiplicativeOperator unaryExpression)
3263 * | 'super' (multiplicativeOperator unaryExpression)+ 3256 * | 'super' (multiplicativeOperator unaryExpression)+
3264 * </pre> 3257 * </pre>
3265 * @return the multiplicative expression that was parsed 3258 * @return the multiplicative expression that was parsed
3266 */ 3259 */
3267 Expression parseMultiplicativeExpression() { 3260 Expression parseMultiplicativeExpression() {
3268 Expression expression; 3261 Expression expression;
3269 if (matches(Keyword.SUPER) && _currentToken.next.type.isMultiplicativeOperat or()) { 3262 if (matches(Keyword.SUPER) && _currentToken.next.type.isMultiplicativeOperat or()) {
3270 expression = new SuperExpression.full(andAdvance); 3263 expression = new SuperExpression.full(andAdvance);
3271 } else { 3264 } else {
3272 expression = parseUnaryExpression(); 3265 expression = parseUnaryExpression();
3273 } 3266 }
3274 while (_currentToken.type.isMultiplicativeOperator()) { 3267 while (_currentToken.type.isMultiplicativeOperator()) {
3275 Token operator = andAdvance; 3268 Token operator = andAdvance;
3276 expression = new BinaryExpression.full(expression, operator, parseUnaryExp ression()); 3269 expression = new BinaryExpression.full(expression, operator, parseUnaryExp ression());
3277 } 3270 }
3278 return expression; 3271 return expression;
3279 } 3272 }
3280 3273
3281 /** 3274 /**
3282 * Parse a new expression. 3275 * Parse a new expression.
3283 * <pre> 3276 * <pre>
3284 * newExpression ::= 3277 * newExpression ::=
3285 * instanceCreationExpression 3278 * instanceCreationExpression
3286 * </pre> 3279 * </pre>
3287 * @return the new expression that was parsed 3280 * @return the new expression that was parsed
3288 */ 3281 */
3289 InstanceCreationExpression parseNewExpression() => parseInstanceCreationExpres sion(expect(Keyword.NEW)); 3282 InstanceCreationExpression parseNewExpression() => parseInstanceCreationExpres sion(expect(Keyword.NEW));
3290 3283
3291 /** 3284 /**
3292 * Parse a non-labeled statement. 3285 * Parse a non-labeled statement.
3293 * <pre> 3286 * <pre>
3294 * nonLabeledStatement ::= 3287 * nonLabeledStatement ::=
3295 * block 3288 * block
3296 * | assertStatement 3289 * | assertStatement
3297 * | breakStatement 3290 * | breakStatement
3298 * | continueStatement 3291 * | continueStatement
3299 * | doStatement 3292 * | doStatement
3300 * | forStatement 3293 * | forStatement
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
3387 return parseVariableDeclarationStatement(commentAndMetadata); 3380 return parseVariableDeclarationStatement(commentAndMetadata);
3388 } else if (isFunctionDeclaration()) { 3381 } else if (isFunctionDeclaration()) {
3389 return parseFunctionDeclarationStatement(); 3382 return parseFunctionDeclarationStatement();
3390 } else if (matches5(TokenType.CLOSE_CURLY_BRACKET)) { 3383 } else if (matches5(TokenType.CLOSE_CURLY_BRACKET)) {
3391 reportError7(ParserErrorCode.MISSING_STATEMENT, []); 3384 reportError7(ParserErrorCode.MISSING_STATEMENT, []);
3392 return new EmptyStatement.full(createSyntheticToken2(TokenType.SEMICOLON)) ; 3385 return new EmptyStatement.full(createSyntheticToken2(TokenType.SEMICOLON)) ;
3393 } else { 3386 } else {
3394 return new ExpressionStatement.full(parseExpression2(), expect2(TokenType. SEMICOLON)); 3387 return new ExpressionStatement.full(parseExpression2(), expect2(TokenType. SEMICOLON));
3395 } 3388 }
3396 } 3389 }
3397 3390
3398 /** 3391 /**
3399 * Parse a normal formal parameter. 3392 * Parse a normal formal parameter.
3400 * <pre> 3393 * <pre>
3401 * normalFormalParameter ::= 3394 * normalFormalParameter ::=
3402 * functionSignature 3395 * functionSignature
3403 * | fieldFormalParameter 3396 * | fieldFormalParameter
3404 * | simpleFormalParameter 3397 * | simpleFormalParameter
3405 * functionSignature: 3398 * functionSignature:
3406 * metadata returnType? identifier formalParameterList 3399 * metadata returnType? identifier formalParameterList
3407 * fieldFormalParameter ::= 3400 * fieldFormalParameter ::=
(...skipping 22 matching lines...) Expand all
3430 } 3423 }
3431 TypeName type2 = holder.type; 3424 TypeName type2 = holder.type;
3432 if (type2 != null && matches3(type2.name.beginToken, Keyword.VOID)) { 3425 if (type2 != null && matches3(type2.name.beginToken, Keyword.VOID)) {
3433 reportError8(ParserErrorCode.VOID_PARAMETER, type2.name.beginToken, []); 3426 reportError8(ParserErrorCode.VOID_PARAMETER, type2.name.beginToken, []);
3434 } 3427 }
3435 if (thisKeyword != null) { 3428 if (thisKeyword != null) {
3436 return new FieldFormalParameter.full(commentAndMetadata.comment, commentAn dMetadata.metadata, holder.keyword, holder.type, thisKeyword, period, identifier ); 3429 return new FieldFormalParameter.full(commentAndMetadata.comment, commentAn dMetadata.metadata, holder.keyword, holder.type, thisKeyword, period, identifier );
3437 } 3430 }
3438 return new SimpleFormalParameter.full(commentAndMetadata.comment, commentAnd Metadata.metadata, holder.keyword, holder.type, identifier); 3431 return new SimpleFormalParameter.full(commentAndMetadata.comment, commentAnd Metadata.metadata, holder.keyword, holder.type, identifier);
3439 } 3432 }
3440 3433
3441 /** 3434 /**
3442 * Parse an operator declaration. 3435 * Parse an operator declaration.
3443 * <pre> 3436 * <pre>
3444 * operatorDeclaration ::= 3437 * operatorDeclaration ::=
3445 * operatorSignature (';' | functionBody) 3438 * operatorSignature (';' | functionBody)
3446 * operatorSignature ::= 3439 * operatorSignature ::=
3447 * 'external'? returnType? 'operator' operator formalParameterList 3440 * 'external'? returnType? 'operator' operator formalParameterList
3448 * </pre> 3441 * </pre>
3449 * @param commentAndMetadata the documentation comment and metadata to be asso ciated with the 3442 * @param commentAndMetadata the documentation comment and metadata to be asso ciated with the
3450 * declaration 3443 * declaration
(...skipping 22 matching lines...) Expand all
3473 } 3466 }
3474 } 3467 }
3475 FormalParameterList parameters = parseFormalParameterList(); 3468 FormalParameterList parameters = parseFormalParameterList();
3476 validateFormalParameterList(parameters); 3469 validateFormalParameterList(parameters);
3477 FunctionBody body = parseFunctionBody(true, ParserErrorCode.MISSING_FUNCTION _BODY, false); 3470 FunctionBody body = parseFunctionBody(true, ParserErrorCode.MISSING_FUNCTION _BODY, false);
3478 if (externalKeyword != null && body is! EmptyFunctionBody) { 3471 if (externalKeyword != null && body is! EmptyFunctionBody) {
3479 reportError7(ParserErrorCode.EXTERNAL_OPERATOR_WITH_BODY, []); 3472 reportError7(ParserErrorCode.EXTERNAL_OPERATOR_WITH_BODY, []);
3480 } 3473 }
3481 return new MethodDeclaration.full(commentAndMetadata.comment, commentAndMeta data.metadata, externalKeyword, null, returnType, null, operatorKeyword, name, p arameters, body); 3474 return new MethodDeclaration.full(commentAndMetadata.comment, commentAndMeta data.metadata, externalKeyword, null, returnType, null, operatorKeyword, name, p arameters, body);
3482 } 3475 }
3483 3476
3484 /** 3477 /**
3485 * Parse a return type if one is given, otherwise return {@code null} without advancing. 3478 * Parse a return type if one is given, otherwise return {@code null} without advancing.
3486 * @return the return type that was parsed 3479 * @return the return type that was parsed
3487 */ 3480 */
3488 TypeName parseOptionalReturnType() { 3481 TypeName parseOptionalReturnType() {
3489 if (matches(Keyword.VOID)) { 3482 if (matches(Keyword.VOID)) {
3490 return parseReturnType(); 3483 return parseReturnType();
3491 } else if (matchesIdentifier() && !matches(Keyword.GET) && !matches(Keyword. SET) && !matches(Keyword.OPERATOR) && (matchesIdentifier2(peek()) || matches4(pe ek(), TokenType.LT))) { 3484 } else if (matchesIdentifier() && !matches(Keyword.GET) && !matches(Keyword. SET) && !matches(Keyword.OPERATOR) && (matchesIdentifier2(peek()) || matches4(pe ek(), TokenType.LT))) {
3492 return parseReturnType(); 3485 return parseReturnType();
3493 } else if (matchesIdentifier() && matches4(peek(), TokenType.PERIOD) && matc hesIdentifier2(peek2(2)) && (matchesIdentifier2(peek2(3)) || matches4(peek2(3), TokenType.LT))) { 3486 } else if (matchesIdentifier() && matches4(peek(), TokenType.PERIOD) && matc hesIdentifier2(peek2(2)) && (matchesIdentifier2(peek2(3)) || matches4(peek2(3), TokenType.LT))) {
3494 return parseReturnType(); 3487 return parseReturnType();
3495 } 3488 }
3496 return null; 3489 return null;
3497 } 3490 }
3498 3491
3499 /** 3492 /**
3500 * Parse a part or part-of directive. 3493 * Parse a part or part-of directive.
3501 * <pre> 3494 * <pre>
3502 * partDirective ::= 3495 * partDirective ::=
3503 * metadata 'part' stringLiteral ';' 3496 * metadata 'part' stringLiteral ';'
3504 * partOfDirective ::= 3497 * partOfDirective ::=
3505 * metadata 'part' 'of' identifier ';' 3498 * metadata 'part' 'of' identifier ';'
3506 * </pre> 3499 * </pre>
3507 * @param commentAndMetadata the metadata to be associated with the directive 3500 * @param commentAndMetadata the metadata to be associated with the directive
3508 * @return the part or part-of directive that was parsed 3501 * @return the part or part-of directive that was parsed
3509 */ 3502 */
3510 Directive parsePartDirective(CommentAndMetadata commentAndMetadata) { 3503 Directive parsePartDirective(CommentAndMetadata commentAndMetadata) {
3511 Token partKeyword = expect(Keyword.PART); 3504 Token partKeyword = expect(Keyword.PART);
3512 if (matches2(_OF)) { 3505 if (matches2(_OF)) {
3513 Token ofKeyword = andAdvance; 3506 Token ofKeyword = andAdvance;
3514 LibraryIdentifier libraryName = parseLibraryName(ParserErrorCode.MISSING_N AME_IN_PART_OF_DIRECTIVE, ofKeyword); 3507 LibraryIdentifier libraryName = parseLibraryName(ParserErrorCode.MISSING_N AME_IN_PART_OF_DIRECTIVE, ofKeyword);
3515 Token semicolon = expect2(TokenType.SEMICOLON); 3508 Token semicolon = expect2(TokenType.SEMICOLON);
3516 return new PartOfDirective.full(commentAndMetadata.comment, commentAndMeta data.metadata, partKeyword, ofKeyword, libraryName, semicolon); 3509 return new PartOfDirective.full(commentAndMetadata.comment, commentAndMeta data.metadata, partKeyword, ofKeyword, libraryName, semicolon);
3517 } 3510 }
3518 StringLiteral partUri = parseStringLiteral(); 3511 StringLiteral partUri = parseStringLiteral();
3519 Token semicolon = expect2(TokenType.SEMICOLON); 3512 Token semicolon = expect2(TokenType.SEMICOLON);
3520 return new PartDirective.full(commentAndMetadata.comment, commentAndMetadata .metadata, partKeyword, partUri, semicolon); 3513 return new PartDirective.full(commentAndMetadata.comment, commentAndMetadata .metadata, partKeyword, partUri, semicolon);
3521 } 3514 }
3522 3515
3523 /** 3516 /**
3524 * Parse a postfix expression. 3517 * Parse a postfix expression.
3525 * <pre> 3518 * <pre>
3526 * postfixExpression ::= 3519 * postfixExpression ::=
3527 * assignableExpression postfixOperator 3520 * assignableExpression postfixOperator
3528 * | primary selector 3521 * | primary selector
3529 * selector ::= 3522 * selector ::=
3530 * assignableSelector 3523 * assignableSelector
3531 * | argumentList 3524 * | argumentList
3532 * </pre> 3525 * </pre>
(...skipping 19 matching lines...) Expand all
3552 } 3545 }
3553 if (!_currentToken.type.isIncrementOperator()) { 3546 if (!_currentToken.type.isIncrementOperator()) {
3554 return operand; 3547 return operand;
3555 } 3548 }
3556 if (operand is FunctionExpressionInvocation) { 3549 if (operand is FunctionExpressionInvocation) {
3557 reportError7(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, []); 3550 reportError7(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, []);
3558 } 3551 }
3559 Token operator = andAdvance; 3552 Token operator = andAdvance;
3560 return new PostfixExpression.full(operand, operator); 3553 return new PostfixExpression.full(operand, operator);
3561 } 3554 }
3562 3555
3563 /** 3556 /**
3564 * Parse a prefixed identifier. 3557 * Parse a prefixed identifier.
3565 * <pre> 3558 * <pre>
3566 * prefixedIdentifier ::= 3559 * prefixedIdentifier ::=
3567 * identifier ('.' identifier)? 3560 * identifier ('.' identifier)?
3568 * </pre> 3561 * </pre>
3569 * @return the prefixed identifier that was parsed 3562 * @return the prefixed identifier that was parsed
3570 */ 3563 */
3571 Identifier parsePrefixedIdentifier() { 3564 Identifier parsePrefixedIdentifier() {
3572 SimpleIdentifier qualifier = parseSimpleIdentifier(); 3565 SimpleIdentifier qualifier = parseSimpleIdentifier();
3573 if (!matches5(TokenType.PERIOD)) { 3566 if (!matches5(TokenType.PERIOD)) {
3574 return qualifier; 3567 return qualifier;
3575 } 3568 }
3576 Token period = andAdvance; 3569 Token period = andAdvance;
3577 SimpleIdentifier qualified = parseSimpleIdentifier(); 3570 SimpleIdentifier qualified = parseSimpleIdentifier();
3578 return new PrefixedIdentifier.full(qualifier, period, qualified); 3571 return new PrefixedIdentifier.full(qualifier, period, qualified);
3579 } 3572 }
3580 3573
3581 /** 3574 /**
3582 * Parse a primary expression. 3575 * Parse a primary expression.
3583 * <pre> 3576 * <pre>
3584 * primary ::= 3577 * primary ::=
3585 * thisExpression 3578 * thisExpression
3586 * | 'super' assignableSelector 3579 * | 'super' assignableSelector
3587 * | functionExpression 3580 * | functionExpression
3588 * | literal 3581 * | literal
3589 * | identifier 3582 * | identifier
3590 * | newExpression 3583 * | newExpression
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
3662 return parseArgumentDefinitionTest(); 3655 return parseArgumentDefinitionTest();
3663 } else if (matches(Keyword.VOID)) { 3656 } else if (matches(Keyword.VOID)) {
3664 reportError7(ParserErrorCode.UNEXPECTED_TOKEN, [_currentToken.lexeme]); 3657 reportError7(ParserErrorCode.UNEXPECTED_TOKEN, [_currentToken.lexeme]);
3665 advance(); 3658 advance();
3666 return parsePrimaryExpression(); 3659 return parsePrimaryExpression();
3667 } else { 3660 } else {
3668 reportError7(ParserErrorCode.MISSING_IDENTIFIER, []); 3661 reportError7(ParserErrorCode.MISSING_IDENTIFIER, []);
3669 return createSyntheticIdentifier(); 3662 return createSyntheticIdentifier();
3670 } 3663 }
3671 } 3664 }
3672 3665
3673 /** 3666 /**
3674 * Parse a redirecting constructor invocation. 3667 * Parse a redirecting constructor invocation.
3675 * <pre> 3668 * <pre>
3676 * redirectingConstructorInvocation ::= 3669 * redirectingConstructorInvocation ::=
3677 * 'this' ('.' identifier)? arguments 3670 * 'this' ('.' identifier)? arguments
3678 * </pre> 3671 * </pre>
3679 * @return the redirecting constructor invocation that was parsed 3672 * @return the redirecting constructor invocation that was parsed
3680 */ 3673 */
3681 RedirectingConstructorInvocation parseRedirectingConstructorInvocation() { 3674 RedirectingConstructorInvocation parseRedirectingConstructorInvocation() {
3682 Token keyword = expect(Keyword.THIS); 3675 Token keyword = expect(Keyword.THIS);
3683 Token period = null; 3676 Token period = null;
3684 SimpleIdentifier constructorName = null; 3677 SimpleIdentifier constructorName = null;
3685 if (matches5(TokenType.PERIOD)) { 3678 if (matches5(TokenType.PERIOD)) {
3686 period = andAdvance; 3679 period = andAdvance;
3687 constructorName = parseSimpleIdentifier(); 3680 constructorName = parseSimpleIdentifier();
3688 } 3681 }
3689 ArgumentList argumentList = parseArgumentList(); 3682 ArgumentList argumentList = parseArgumentList();
3690 return new RedirectingConstructorInvocation.full(keyword, period, constructo rName, argumentList); 3683 return new RedirectingConstructorInvocation.full(keyword, period, constructo rName, argumentList);
3691 } 3684 }
3692 3685
3693 /** 3686 /**
3694 * Parse a relational expression. 3687 * Parse a relational expression.
3695 * <pre> 3688 * <pre>
3696 * relationalExpression ::= 3689 * relationalExpression ::=
3697 * shiftExpression ('is' '!'? type | 'as' type | relationalOperator shiftExpre ssion)? 3690 * shiftExpression ('is' '!'? type | 'as' type | relationalOperator shiftExpre ssion)?
3698 * | 'super' relationalOperator shiftExpression 3691 * | 'super' relationalOperator shiftExpression
3699 * </pre> 3692 * </pre>
3700 * @return the relational expression that was parsed 3693 * @return the relational expression that was parsed
3701 */ 3694 */
3702 Expression parseRelationalExpression() { 3695 Expression parseRelationalExpression() {
(...skipping 13 matching lines...) Expand all
3716 if (matches5(TokenType.BANG)) { 3709 if (matches5(TokenType.BANG)) {
3717 notOperator = andAdvance; 3710 notOperator = andAdvance;
3718 } 3711 }
3719 expression = new IsExpression.full(expression, isOperator, notOperator, pa rseTypeName()); 3712 expression = new IsExpression.full(expression, isOperator, notOperator, pa rseTypeName());
3720 } else if (_currentToken.type.isRelationalOperator()) { 3713 } else if (_currentToken.type.isRelationalOperator()) {
3721 Token operator = andAdvance; 3714 Token operator = andAdvance;
3722 expression = new BinaryExpression.full(expression, operator, parseShiftExp ression()); 3715 expression = new BinaryExpression.full(expression, operator, parseShiftExp ression());
3723 } 3716 }
3724 return expression; 3717 return expression;
3725 } 3718 }
3726 3719
3727 /** 3720 /**
3728 * Parse a rethrow expression. 3721 * Parse a rethrow expression.
3729 * <pre> 3722 * <pre>
3730 * rethrowExpression ::= 3723 * rethrowExpression ::=
3731 * 'rethrow' 3724 * 'rethrow'
3732 * </pre> 3725 * </pre>
3733 * @return the rethrow expression that was parsed 3726 * @return the rethrow expression that was parsed
3734 */ 3727 */
3735 Expression parseRethrowExpression() => new RethrowExpression.full(expect(Keywo rd.RETHROW)); 3728 Expression parseRethrowExpression() => new RethrowExpression.full(expect(Keywo rd.RETHROW));
3736 3729
3737 /** 3730 /**
3738 * Parse a return statement. 3731 * Parse a return statement.
3739 * <pre> 3732 * <pre>
3740 * returnStatement ::= 3733 * returnStatement ::=
3741 * 'return' expression? ';' 3734 * 'return' expression? ';'
3742 * </pre> 3735 * </pre>
3743 * @return the return statement that was parsed 3736 * @return the return statement that was parsed
3744 */ 3737 */
3745 Statement parseReturnStatement() { 3738 Statement parseReturnStatement() {
3746 Token returnKeyword = expect(Keyword.RETURN); 3739 Token returnKeyword = expect(Keyword.RETURN);
3747 if (matches5(TokenType.SEMICOLON)) { 3740 if (matches5(TokenType.SEMICOLON)) {
3748 return new ReturnStatement.full(returnKeyword, null, andAdvance); 3741 return new ReturnStatement.full(returnKeyword, null, andAdvance);
3749 } 3742 }
3750 Expression expression = parseExpression2(); 3743 Expression expression = parseExpression2();
3751 Token semicolon = expect2(TokenType.SEMICOLON); 3744 Token semicolon = expect2(TokenType.SEMICOLON);
3752 return new ReturnStatement.full(returnKeyword, expression, semicolon); 3745 return new ReturnStatement.full(returnKeyword, expression, semicolon);
3753 } 3746 }
3754 3747
3755 /** 3748 /**
3756 * Parse a return type. 3749 * Parse a return type.
3757 * <pre> 3750 * <pre>
3758 * returnType ::= 3751 * returnType ::=
3759 * 'void' 3752 * 'void'
3760 * | type 3753 * | type
3761 * </pre> 3754 * </pre>
3762 * @return the return type that was parsed 3755 * @return the return type that was parsed
3763 */ 3756 */
3764 TypeName parseReturnType() { 3757 TypeName parseReturnType() {
3765 if (matches(Keyword.VOID)) { 3758 if (matches(Keyword.VOID)) {
3766 return new TypeName.full(new SimpleIdentifier.full(andAdvance), null); 3759 return new TypeName.full(new SimpleIdentifier.full(andAdvance), null);
3767 } else { 3760 } else {
3768 return parseTypeName(); 3761 return parseTypeName();
3769 } 3762 }
3770 } 3763 }
3771 3764
3772 /** 3765 /**
3773 * Parse a setter. 3766 * Parse a setter.
3774 * <pre> 3767 * <pre>
3775 * setter ::= 3768 * setter ::=
3776 * setterSignature functionBody? 3769 * setterSignature functionBody?
3777 * setterSignature ::= 3770 * setterSignature ::=
3778 * 'external'? 'static'? returnType? 'set' identifier formalParameterList 3771 * 'external'? 'static'? returnType? 'set' identifier formalParameterList
3779 * </pre> 3772 * </pre>
3780 * @param commentAndMetadata the documentation comment and metadata to be asso ciated with the 3773 * @param commentAndMetadata the documentation comment and metadata to be asso ciated with the
3781 * declaration 3774 * declaration
3782 * @param externalKeyword the 'external' token 3775 * @param externalKeyword the 'external' token
3783 * @param staticKeyword the static keyword, or {@code null} if the setter is n ot static 3776 * @param staticKeyword the static keyword, or {@code null} if the setter is n ot static
3784 * @param the return type that has already been parsed, or {@code null} if the re was no return 3777 * @param the return type that has already been parsed, or {@code null} if the re was no return
3785 * type 3778 * type
3786 * @return the setter that was parsed 3779 * @return the setter that was parsed
3787 */ 3780 */
3788 MethodDeclaration parseSetter(CommentAndMetadata commentAndMetadata, Token ext ernalKeyword, Token staticKeyword, TypeName returnType) { 3781 MethodDeclaration parseSetter(CommentAndMetadata commentAndMetadata, Token ext ernalKeyword, Token staticKeyword, TypeName returnType) {
3789 Token propertyKeyword = expect(Keyword.SET); 3782 Token propertyKeyword = expect(Keyword.SET);
3790 SimpleIdentifier name = parseSimpleIdentifier(); 3783 SimpleIdentifier name = parseSimpleIdentifier();
3791 FormalParameterList parameters = parseFormalParameterList(); 3784 FormalParameterList parameters = parseFormalParameterList();
3792 validateFormalParameterList(parameters); 3785 validateFormalParameterList(parameters);
3793 FunctionBody body = parseFunctionBody(externalKeyword != null || staticKeywo rd == null, ParserErrorCode.STATIC_SETTER_WITHOUT_BODY, false); 3786 FunctionBody body = parseFunctionBody(externalKeyword != null || staticKeywo rd == null, ParserErrorCode.STATIC_SETTER_WITHOUT_BODY, false);
3794 if (externalKeyword != null && body is! EmptyFunctionBody) { 3787 if (externalKeyword != null && body is! EmptyFunctionBody) {
3795 reportError7(ParserErrorCode.EXTERNAL_SETTER_WITH_BODY, []); 3788 reportError7(ParserErrorCode.EXTERNAL_SETTER_WITH_BODY, []);
3796 } 3789 }
3797 return new MethodDeclaration.full(commentAndMetadata.comment, commentAndMeta data.metadata, externalKeyword, staticKeyword, returnType, propertyKeyword, null , name, parameters, body); 3790 return new MethodDeclaration.full(commentAndMetadata.comment, commentAndMeta data.metadata, externalKeyword, staticKeyword, returnType, propertyKeyword, null , name, parameters, body);
3798 } 3791 }
3799 3792
3800 /** 3793 /**
3801 * Parse a shift expression. 3794 * Parse a shift expression.
3802 * <pre> 3795 * <pre>
3803 * shiftExpression ::= 3796 * shiftExpression ::=
3804 * additiveExpression (shiftOperator additiveExpression) 3797 * additiveExpression (shiftOperator additiveExpression)
3805 * | 'super' (shiftOperator additiveExpression)+ 3798 * | 'super' (shiftOperator additiveExpression)+
3806 * </pre> 3799 * </pre>
3807 * @return the shift expression that was parsed 3800 * @return the shift expression that was parsed
3808 */ 3801 */
3809 Expression parseShiftExpression() { 3802 Expression parseShiftExpression() {
3810 Expression expression; 3803 Expression expression;
3811 if (matches(Keyword.SUPER) && _currentToken.next.type.isShiftOperator()) { 3804 if (matches(Keyword.SUPER) && _currentToken.next.type.isShiftOperator()) {
3812 expression = new SuperExpression.full(andAdvance); 3805 expression = new SuperExpression.full(andAdvance);
3813 } else { 3806 } else {
3814 expression = parseAdditiveExpression(); 3807 expression = parseAdditiveExpression();
3815 } 3808 }
3816 while (_currentToken.type.isShiftOperator()) { 3809 while (_currentToken.type.isShiftOperator()) {
3817 Token operator = andAdvance; 3810 Token operator = andAdvance;
3818 expression = new BinaryExpression.full(expression, operator, parseAdditive Expression()); 3811 expression = new BinaryExpression.full(expression, operator, parseAdditive Expression());
3819 } 3812 }
3820 return expression; 3813 return expression;
3821 } 3814 }
3822 3815
3823 /** 3816 /**
3824 * Parse a simple identifier. 3817 * Parse a simple identifier.
3825 * <pre> 3818 * <pre>
3826 * identifier ::= 3819 * identifier ::=
3827 * IDENTIFIER 3820 * IDENTIFIER
3828 * </pre> 3821 * </pre>
3829 * @return the simple identifier that was parsed 3822 * @return the simple identifier that was parsed
3830 */ 3823 */
3831 SimpleIdentifier parseSimpleIdentifier() { 3824 SimpleIdentifier parseSimpleIdentifier() {
3832 if (matchesIdentifier()) { 3825 if (matchesIdentifier()) {
3833 return new SimpleIdentifier.full(andAdvance); 3826 return new SimpleIdentifier.full(andAdvance);
3834 } 3827 }
3835 reportError7(ParserErrorCode.MISSING_IDENTIFIER, []); 3828 reportError7(ParserErrorCode.MISSING_IDENTIFIER, []);
3836 return createSyntheticIdentifier(); 3829 return createSyntheticIdentifier();
3837 } 3830 }
3838 3831
3839 /** 3832 /**
3840 * Parse a statement. 3833 * Parse a statement.
3841 * <pre> 3834 * <pre>
3842 * statement ::= 3835 * statement ::=
3843 * label* nonLabeledStatement 3836 * label* nonLabeledStatement
3844 * </pre> 3837 * </pre>
3845 * @return the statement that was parsed 3838 * @return the statement that was parsed
3846 */ 3839 */
3847 Statement parseStatement2() { 3840 Statement parseStatement2() {
3848 List<Label> labels = new List<Label>(); 3841 List<Label> labels = new List<Label>();
3849 while (matchesIdentifier() && matches4(peek(), TokenType.COLON)) { 3842 while (matchesIdentifier() && matches4(peek(), TokenType.COLON)) {
3850 SimpleIdentifier label = parseSimpleIdentifier(); 3843 SimpleIdentifier label = parseSimpleIdentifier();
3851 Token colon = expect2(TokenType.COLON); 3844 Token colon = expect2(TokenType.COLON);
3852 labels.add(new Label.full(label, colon)); 3845 labels.add(new Label.full(label, colon));
3853 } 3846 }
3854 Statement statement = parseNonLabeledStatement(); 3847 Statement statement = parseNonLabeledStatement();
3855 if (labels.isEmpty) { 3848 if (labels.isEmpty) {
3856 return statement; 3849 return statement;
3857 } 3850 }
3858 return new LabeledStatement.full(labels, statement); 3851 return new LabeledStatement.full(labels, statement);
3859 } 3852 }
3860 3853
3861 /** 3854 /**
3862 * Parse a list of statements within a switch statement. 3855 * Parse a list of statements within a switch statement.
3863 * <pre> 3856 * <pre>
3864 * statements ::= 3857 * statements ::=
3865 * statement 3858 * statement
3866 * </pre> 3859 * </pre>
3867 * @return the statements that were parsed 3860 * @return the statements that were parsed
3868 */ 3861 */
3869 List<Statement> parseStatements2() { 3862 List<Statement> parseStatements2() {
3870 List<Statement> statements = new List<Statement>(); 3863 List<Statement> statements = new List<Statement>();
3871 Token statementStart = _currentToken; 3864 Token statementStart = _currentToken;
3872 while (!matches5(TokenType.EOF) && !matches5(TokenType.CLOSE_CURLY_BRACKET) && !isSwitchMember()) { 3865 while (!matches5(TokenType.EOF) && !matches5(TokenType.CLOSE_CURLY_BRACKET) && !isSwitchMember()) {
3873 statements.add(parseStatement2()); 3866 statements.add(parseStatement2());
3874 if (identical(_currentToken, statementStart)) { 3867 if (identical(_currentToken, statementStart)) {
3875 reportError8(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentT oken.lexeme]); 3868 reportError8(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentT oken.lexeme]);
3876 advance(); 3869 advance();
3877 } 3870 }
3878 statementStart = _currentToken; 3871 statementStart = _currentToken;
3879 } 3872 }
3880 return statements; 3873 return statements;
3881 } 3874 }
3882 3875
3883 /** 3876 /**
3884 * Parse a string literal that contains interpolations. 3877 * Parse a string literal that contains interpolations.
3885 * @return the string literal that was parsed 3878 * @return the string literal that was parsed
3886 */ 3879 */
3887 StringInterpolation parseStringInterpolation(Token string) { 3880 StringInterpolation parseStringInterpolation(Token string) {
3888 List<InterpolationElement> elements = new List<InterpolationElement>(); 3881 List<InterpolationElement> elements = new List<InterpolationElement>();
3889 elements.add(new InterpolationString.full(string, computeStringValue(string. lexeme))); 3882 elements.add(new InterpolationString.full(string, computeStringValue(string. lexeme)));
3890 while (matches5(TokenType.STRING_INTERPOLATION_EXPRESSION) || matches5(Token Type.STRING_INTERPOLATION_IDENTIFIER)) { 3883 while (matches5(TokenType.STRING_INTERPOLATION_EXPRESSION) || matches5(Token Type.STRING_INTERPOLATION_IDENTIFIER)) {
3891 if (matches5(TokenType.STRING_INTERPOLATION_EXPRESSION)) { 3884 if (matches5(TokenType.STRING_INTERPOLATION_EXPRESSION)) {
3892 Token openToken = andAdvance; 3885 Token openToken = andAdvance;
(...skipping 10 matching lines...) Expand all
3903 } 3896 }
3904 elements.add(new InterpolationExpression.full(openToken, expression, nul l)); 3897 elements.add(new InterpolationExpression.full(openToken, expression, nul l));
3905 } 3898 }
3906 if (matches5(TokenType.STRING)) { 3899 if (matches5(TokenType.STRING)) {
3907 string = andAdvance; 3900 string = andAdvance;
3908 elements.add(new InterpolationString.full(string, computeStringValue(str ing.lexeme))); 3901 elements.add(new InterpolationString.full(string, computeStringValue(str ing.lexeme)));
3909 } 3902 }
3910 } 3903 }
3911 return new StringInterpolation.full(elements); 3904 return new StringInterpolation.full(elements);
3912 } 3905 }
3913 3906
3914 /** 3907 /**
3915 * Parse a string literal. 3908 * Parse a string literal.
3916 * <pre> 3909 * <pre>
3917 * stringLiteral ::= 3910 * stringLiteral ::=
3918 * MULTI_LINE_STRING+ 3911 * MULTI_LINE_STRING+
3919 * | SINGLE_LINE_STRING+ 3912 * | SINGLE_LINE_STRING+
3920 * </pre> 3913 * </pre>
3921 * @return the string literal that was parsed 3914 * @return the string literal that was parsed
3922 */ 3915 */
3923 StringLiteral parseStringLiteral() { 3916 StringLiteral parseStringLiteral() {
3924 List<StringLiteral> strings = new List<StringLiteral>(); 3917 List<StringLiteral> strings = new List<StringLiteral>();
3925 while (matches5(TokenType.STRING)) { 3918 while (matches5(TokenType.STRING)) {
3926 Token string = andAdvance; 3919 Token string = andAdvance;
3927 if (matches5(TokenType.STRING_INTERPOLATION_EXPRESSION) || matches5(TokenT ype.STRING_INTERPOLATION_IDENTIFIER)) { 3920 if (matches5(TokenType.STRING_INTERPOLATION_EXPRESSION) || matches5(TokenT ype.STRING_INTERPOLATION_IDENTIFIER)) {
3928 strings.add(parseStringInterpolation(string)); 3921 strings.add(parseStringInterpolation(string));
3929 } else { 3922 } else {
3930 strings.add(new SimpleStringLiteral.full(string, computeStringValue(stri ng.lexeme))); 3923 strings.add(new SimpleStringLiteral.full(string, computeStringValue(stri ng.lexeme)));
3931 } 3924 }
3932 } 3925 }
3933 if (strings.length < 1) { 3926 if (strings.length < 1) {
3934 reportError7(ParserErrorCode.EXPECTED_STRING_LITERAL, []); 3927 reportError7(ParserErrorCode.EXPECTED_STRING_LITERAL, []);
3935 return createSyntheticStringLiteral(); 3928 return createSyntheticStringLiteral();
3936 } else if (strings.length == 1) { 3929 } else if (strings.length == 1) {
3937 return strings[0]; 3930 return strings[0];
3938 } else { 3931 } else {
3939 return new AdjacentStrings.full(strings); 3932 return new AdjacentStrings.full(strings);
3940 } 3933 }
3941 } 3934 }
3942 3935
3943 /** 3936 /**
3944 * Parse a super constructor invocation. 3937 * Parse a super constructor invocation.
3945 * <pre> 3938 * <pre>
3946 * superConstructorInvocation ::= 3939 * superConstructorInvocation ::=
3947 * 'super' ('.' identifier)? arguments 3940 * 'super' ('.' identifier)? arguments
3948 * </pre> 3941 * </pre>
3949 * @return the super constructor invocation that was parsed 3942 * @return the super constructor invocation that was parsed
3950 */ 3943 */
3951 SuperConstructorInvocation parseSuperConstructorInvocation() { 3944 SuperConstructorInvocation parseSuperConstructorInvocation() {
3952 Token keyword = expect(Keyword.SUPER); 3945 Token keyword = expect(Keyword.SUPER);
3953 Token period = null; 3946 Token period = null;
3954 SimpleIdentifier constructorName = null; 3947 SimpleIdentifier constructorName = null;
3955 if (matches5(TokenType.PERIOD)) { 3948 if (matches5(TokenType.PERIOD)) {
3956 period = andAdvance; 3949 period = andAdvance;
3957 constructorName = parseSimpleIdentifier(); 3950 constructorName = parseSimpleIdentifier();
3958 } 3951 }
3959 ArgumentList argumentList = parseArgumentList(); 3952 ArgumentList argumentList = parseArgumentList();
3960 return new SuperConstructorInvocation.full(keyword, period, constructorName, argumentList); 3953 return new SuperConstructorInvocation.full(keyword, period, constructorName, argumentList);
3961 } 3954 }
3962 3955
3963 /** 3956 /**
3964 * Parse a switch statement. 3957 * Parse a switch statement.
3965 * <pre> 3958 * <pre>
3966 * switchStatement ::= 3959 * switchStatement ::=
3967 * 'switch' '(' expression ')' '{' switchCase* defaultCase? '}' 3960 * 'switch' '(' expression ')' '{' switchCase* defaultCase? '}'
3968 * switchCase ::= 3961 * switchCase ::=
3969 * label* ('case' expression ':') statements 3962 * label* ('case' expression ':') statements
3970 * defaultCase ::= 3963 * defaultCase ::=
3971 * label* 'default' ':' statements 3964 * label* 'default' ':' statements
3972 * </pre> 3965 * </pre>
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
4018 advance(); 4011 advance();
4019 } 4012 }
4020 } 4013 }
4021 } 4014 }
4022 Token rightBracket = expect2(TokenType.CLOSE_CURLY_BRACKET); 4015 Token rightBracket = expect2(TokenType.CLOSE_CURLY_BRACKET);
4023 return new SwitchStatement.full(keyword, leftParenthesis, expression, righ tParenthesis, leftBracket, members, rightBracket); 4016 return new SwitchStatement.full(keyword, leftParenthesis, expression, righ tParenthesis, leftBracket, members, rightBracket);
4024 } finally { 4017 } finally {
4025 _inSwitch = wasInSwitch; 4018 _inSwitch = wasInSwitch;
4026 } 4019 }
4027 } 4020 }
4028 4021
4029 /** 4022 /**
4030 * Parse a throw expression. 4023 * Parse a throw expression.
4031 * <pre> 4024 * <pre>
4032 * throwExpression ::= 4025 * throwExpression ::=
4033 * 'throw' expression 4026 * 'throw' expression
4034 * </pre> 4027 * </pre>
4035 * @return the throw expression that was parsed 4028 * @return the throw expression that was parsed
4036 */ 4029 */
4037 Expression parseThrowExpression() { 4030 Expression parseThrowExpression() {
4038 Token keyword = expect(Keyword.THROW); 4031 Token keyword = expect(Keyword.THROW);
4039 if (matches5(TokenType.SEMICOLON) || matches5(TokenType.CLOSE_PAREN)) { 4032 if (matches5(TokenType.SEMICOLON) || matches5(TokenType.CLOSE_PAREN)) {
4040 reportError8(ParserErrorCode.MISSING_EXPRESSION_IN_THROW, _currentToken, [ ]); 4033 reportError8(ParserErrorCode.MISSING_EXPRESSION_IN_THROW, _currentToken, [ ]);
4041 return new ThrowExpression.full(keyword, createSyntheticIdentifier()); 4034 return new ThrowExpression.full(keyword, createSyntheticIdentifier());
4042 } 4035 }
4043 Expression expression = parseExpression2(); 4036 Expression expression = parseExpression2();
4044 return new ThrowExpression.full(keyword, expression); 4037 return new ThrowExpression.full(keyword, expression);
4045 } 4038 }
4046 4039
4047 /** 4040 /**
4048 * Parse a throw expression. 4041 * Parse a throw expression.
4049 * <pre> 4042 * <pre>
4050 * throwExpressionWithoutCascade ::= 4043 * throwExpressionWithoutCascade ::=
4051 * 'throw' expressionWithoutCascade 4044 * 'throw' expressionWithoutCascade
4052 * </pre> 4045 * </pre>
4053 * @return the throw expression that was parsed 4046 * @return the throw expression that was parsed
4054 */ 4047 */
4055 Expression parseThrowExpressionWithoutCascade() { 4048 Expression parseThrowExpressionWithoutCascade() {
4056 Token keyword = expect(Keyword.THROW); 4049 Token keyword = expect(Keyword.THROW);
4057 if (matches5(TokenType.SEMICOLON) || matches5(TokenType.CLOSE_PAREN)) { 4050 if (matches5(TokenType.SEMICOLON) || matches5(TokenType.CLOSE_PAREN)) {
4058 reportError8(ParserErrorCode.MISSING_EXPRESSION_IN_THROW, _currentToken, [ ]); 4051 reportError8(ParserErrorCode.MISSING_EXPRESSION_IN_THROW, _currentToken, [ ]);
4059 return new ThrowExpression.full(keyword, createSyntheticIdentifier()); 4052 return new ThrowExpression.full(keyword, createSyntheticIdentifier());
4060 } 4053 }
4061 Expression expression = parseExpressionWithoutCascade(); 4054 Expression expression = parseExpressionWithoutCascade();
4062 return new ThrowExpression.full(keyword, expression); 4055 return new ThrowExpression.full(keyword, expression);
4063 } 4056 }
4064 4057
4065 /** 4058 /**
4066 * Parse a try statement. 4059 * Parse a try statement.
4067 * <pre> 4060 * <pre>
4068 * tryStatement ::= 4061 * tryStatement ::=
4069 * 'try' block (onPart+ finallyPart? | finallyPart) 4062 * 'try' block (onPart+ finallyPart? | finallyPart)
4070 * onPart ::= 4063 * onPart ::=
4071 * catchPart block 4064 * catchPart block
4072 * | 'on' type catchPart? block 4065 * | 'on' type catchPart? block
4073 * catchPart ::= 4066 * catchPart ::=
4074 * 'catch' '(' identifier (',' identifier)? ')' 4067 * 'catch' '(' identifier (',' identifier)? ')'
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
4112 if (matches(Keyword.FINALLY)) { 4105 if (matches(Keyword.FINALLY)) {
4113 finallyKeyword = andAdvance; 4106 finallyKeyword = andAdvance;
4114 finallyClause = parseBlock(); 4107 finallyClause = parseBlock();
4115 } else { 4108 } else {
4116 if (catchClauses.isEmpty) { 4109 if (catchClauses.isEmpty) {
4117 reportError7(ParserErrorCode.MISSING_CATCH_OR_FINALLY, []); 4110 reportError7(ParserErrorCode.MISSING_CATCH_OR_FINALLY, []);
4118 } 4111 }
4119 } 4112 }
4120 return new TryStatement.full(tryKeyword, body, catchClauses, finallyKeyword, finallyClause); 4113 return new TryStatement.full(tryKeyword, body, catchClauses, finallyKeyword, finallyClause);
4121 } 4114 }
4122 4115
4123 /** 4116 /**
4124 * Parse a type alias. 4117 * Parse a type alias.
4125 * <pre> 4118 * <pre>
4126 * typeAlias ::= 4119 * typeAlias ::=
4127 * 'typedef' typeAliasBody 4120 * 'typedef' typeAliasBody
4128 * typeAliasBody ::= 4121 * typeAliasBody ::=
4129 * classTypeAlias 4122 * classTypeAlias
4130 * | functionTypeAlias 4123 * | functionTypeAlias
4131 * classTypeAlias ::= 4124 * classTypeAlias ::=
4132 * identifier typeParameters? '=' 'abstract'? mixinApplication 4125 * identifier typeParameters? '=' 'abstract'? mixinApplication
(...skipping 15 matching lines...) Expand all
4148 next = skipTypeParameterList(next); 4141 next = skipTypeParameterList(next);
4149 if (next != null && matches4(next, TokenType.EQ)) { 4142 if (next != null && matches4(next, TokenType.EQ)) {
4150 return parseClassTypeAlias(commentAndMetadata, keyword); 4143 return parseClassTypeAlias(commentAndMetadata, keyword);
4151 } 4144 }
4152 } else if (matches4(next, TokenType.EQ)) { 4145 } else if (matches4(next, TokenType.EQ)) {
4153 return parseClassTypeAlias(commentAndMetadata, keyword); 4146 return parseClassTypeAlias(commentAndMetadata, keyword);
4154 } 4147 }
4155 } 4148 }
4156 return parseFunctionTypeAlias(commentAndMetadata, keyword); 4149 return parseFunctionTypeAlias(commentAndMetadata, keyword);
4157 } 4150 }
4158 4151
4159 /** 4152 /**
4160 * Parse a list of type arguments. 4153 * Parse a list of type arguments.
4161 * <pre> 4154 * <pre>
4162 * typeArguments ::= 4155 * typeArguments ::=
4163 * '<' typeList '>' 4156 * '<' typeList '>'
4164 * typeList ::= 4157 * typeList ::=
4165 * type (',' type) 4158 * type (',' type)
4166 * </pre> 4159 * </pre>
4167 * @return the type argument list that was parsed 4160 * @return the type argument list that was parsed
4168 */ 4161 */
4169 TypeArgumentList parseTypeArgumentList() { 4162 TypeArgumentList parseTypeArgumentList() {
4170 Token leftBracket = expect2(TokenType.LT); 4163 Token leftBracket = expect2(TokenType.LT);
4171 List<TypeName> arguments = new List<TypeName>(); 4164 List<TypeName> arguments = new List<TypeName>();
4172 arguments.add(parseTypeName()); 4165 arguments.add(parseTypeName());
4173 while (optional(TokenType.COMMA)) { 4166 while (optional(TokenType.COMMA)) {
4174 arguments.add(parseTypeName()); 4167 arguments.add(parseTypeName());
4175 } 4168 }
4176 Token rightBracket = expect2(TokenType.GT); 4169 Token rightBracket = expect2(TokenType.GT);
4177 return new TypeArgumentList.full(leftBracket, arguments, rightBracket); 4170 return new TypeArgumentList.full(leftBracket, arguments, rightBracket);
4178 } 4171 }
4179 4172
4180 /** 4173 /**
4181 * Parse a type name. 4174 * Parse a type name.
4182 * <pre> 4175 * <pre>
4183 * type ::= 4176 * type ::=
4184 * qualified typeArguments? 4177 * qualified typeArguments?
4185 * </pre> 4178 * </pre>
4186 * @return the type name that was parsed 4179 * @return the type name that was parsed
4187 */ 4180 */
4188 TypeName parseTypeName() { 4181 TypeName parseTypeName() {
4189 Identifier typeName; 4182 Identifier typeName;
4190 if (matches(Keyword.VAR)) { 4183 if (matches(Keyword.VAR)) {
4191 reportError7(ParserErrorCode.VAR_AS_TYPE_NAME, []); 4184 reportError7(ParserErrorCode.VAR_AS_TYPE_NAME, []);
4192 typeName = new SimpleIdentifier.full(andAdvance); 4185 typeName = new SimpleIdentifier.full(andAdvance);
4193 } else if (matchesIdentifier()) { 4186 } else if (matchesIdentifier()) {
4194 typeName = parsePrefixedIdentifier(); 4187 typeName = parsePrefixedIdentifier();
4195 } else { 4188 } else {
4196 typeName = createSyntheticIdentifier(); 4189 typeName = createSyntheticIdentifier();
4197 reportError7(ParserErrorCode.EXPECTED_TYPE_NAME, []); 4190 reportError7(ParserErrorCode.EXPECTED_TYPE_NAME, []);
4198 } 4191 }
4199 TypeArgumentList typeArguments = null; 4192 TypeArgumentList typeArguments = null;
4200 if (matches5(TokenType.LT)) { 4193 if (matches5(TokenType.LT)) {
4201 typeArguments = parseTypeArgumentList(); 4194 typeArguments = parseTypeArgumentList();
4202 } 4195 }
4203 return new TypeName.full(typeName, typeArguments); 4196 return new TypeName.full(typeName, typeArguments);
4204 } 4197 }
4205 4198
4206 /** 4199 /**
4207 * Parse a type parameter. 4200 * Parse a type parameter.
4208 * <pre> 4201 * <pre>
4209 * typeParameter ::= 4202 * typeParameter ::=
4210 * metadata name ('extends' bound)? 4203 * metadata name ('extends' bound)?
4211 * </pre> 4204 * </pre>
4212 * @return the type parameter that was parsed 4205 * @return the type parameter that was parsed
4213 */ 4206 */
4214 TypeParameter parseTypeParameter() { 4207 TypeParameter parseTypeParameter() {
4215 CommentAndMetadata commentAndMetadata = parseCommentAndMetadata(); 4208 CommentAndMetadata commentAndMetadata = parseCommentAndMetadata();
4216 SimpleIdentifier name = parseSimpleIdentifier(); 4209 SimpleIdentifier name = parseSimpleIdentifier();
4217 if (matches(Keyword.EXTENDS)) { 4210 if (matches(Keyword.EXTENDS)) {
4218 Token keyword = andAdvance; 4211 Token keyword = andAdvance;
4219 TypeName bound = parseTypeName(); 4212 TypeName bound = parseTypeName();
4220 return new TypeParameter.full(commentAndMetadata.comment, commentAndMetada ta.metadata, name, keyword, bound); 4213 return new TypeParameter.full(commentAndMetadata.comment, commentAndMetada ta.metadata, name, keyword, bound);
4221 } 4214 }
4222 return new TypeParameter.full(commentAndMetadata.comment, commentAndMetadata .metadata, name, null, null); 4215 return new TypeParameter.full(commentAndMetadata.comment, commentAndMetadata .metadata, name, null, null);
4223 } 4216 }
4224 4217
4225 /** 4218 /**
4226 * Parse a list of type parameters. 4219 * Parse a list of type parameters.
4227 * <pre> 4220 * <pre>
4228 * typeParameterList ::= 4221 * typeParameterList ::=
4229 * '<' typeParameter (',' typeParameter)* '>' 4222 * '<' typeParameter (',' typeParameter)* '>'
4230 * </pre> 4223 * </pre>
4231 * @return the list of type parameters that were parsed 4224 * @return the list of type parameters that were parsed
4232 */ 4225 */
4233 TypeParameterList parseTypeParameterList() { 4226 TypeParameterList parseTypeParameterList() {
4234 Token leftBracket = expect2(TokenType.LT); 4227 Token leftBracket = expect2(TokenType.LT);
4235 List<TypeParameter> typeParameters = new List<TypeParameter>(); 4228 List<TypeParameter> typeParameters = new List<TypeParameter>();
4236 typeParameters.add(parseTypeParameter()); 4229 typeParameters.add(parseTypeParameter());
4237 while (optional(TokenType.COMMA)) { 4230 while (optional(TokenType.COMMA)) {
4238 typeParameters.add(parseTypeParameter()); 4231 typeParameters.add(parseTypeParameter());
4239 } 4232 }
4240 Token rightBracket = expect2(TokenType.GT); 4233 Token rightBracket = expect2(TokenType.GT);
4241 return new TypeParameterList.full(leftBracket, typeParameters, rightBracket) ; 4234 return new TypeParameterList.full(leftBracket, typeParameters, rightBracket) ;
4242 } 4235 }
4243 4236
4244 /** 4237 /**
4245 * Parse a unary expression. 4238 * Parse a unary expression.
4246 * <pre> 4239 * <pre>
4247 * unaryExpression ::= 4240 * unaryExpression ::=
4248 * prefixOperator unaryExpression 4241 * prefixOperator unaryExpression
4249 * | postfixExpression 4242 * | postfixExpression
4250 * | unaryOperator 'super' 4243 * | unaryOperator 'super'
4251 * | '-' 'super' 4244 * | '-' 'super'
4252 * | incrementOperator assignableExpression 4245 * | incrementOperator assignableExpression
4253 * </pre> 4246 * </pre>
(...skipping 28 matching lines...) Expand all
4282 return new PrefixExpression.full(operator, new SuperExpression.full(an dAdvance)); 4275 return new PrefixExpression.full(operator, new SuperExpression.full(an dAdvance));
4283 } 4276 }
4284 } 4277 }
4285 return new PrefixExpression.full(operator, parseAssignableExpression(false )); 4278 return new PrefixExpression.full(operator, parseAssignableExpression(false ));
4286 } else if (matches5(TokenType.PLUS)) { 4279 } else if (matches5(TokenType.PLUS)) {
4287 reportError7(ParserErrorCode.MISSING_IDENTIFIER, []); 4280 reportError7(ParserErrorCode.MISSING_IDENTIFIER, []);
4288 return createSyntheticIdentifier(); 4281 return createSyntheticIdentifier();
4289 } 4282 }
4290 return parsePostfixExpression(); 4283 return parsePostfixExpression();
4291 } 4284 }
4292 4285
4293 /** 4286 /**
4294 * Parse a variable declaration. 4287 * Parse a variable declaration.
4295 * <pre> 4288 * <pre>
4296 * variableDeclaration ::= 4289 * variableDeclaration ::=
4297 * identifier ('=' expression)? 4290 * identifier ('=' expression)?
4298 * </pre> 4291 * </pre>
4299 * @return the variable declaration that was parsed 4292 * @return the variable declaration that was parsed
4300 */ 4293 */
4301 VariableDeclaration parseVariableDeclaration() { 4294 VariableDeclaration parseVariableDeclaration() {
4302 CommentAndMetadata commentAndMetadata = parseCommentAndMetadata(); 4295 CommentAndMetadata commentAndMetadata = parseCommentAndMetadata();
4303 SimpleIdentifier name = parseSimpleIdentifier(); 4296 SimpleIdentifier name = parseSimpleIdentifier();
4304 Token equals = null; 4297 Token equals = null;
4305 Expression initializer = null; 4298 Expression initializer = null;
4306 if (matches5(TokenType.EQ)) { 4299 if (matches5(TokenType.EQ)) {
4307 equals = andAdvance; 4300 equals = andAdvance;
4308 initializer = parseExpression2(); 4301 initializer = parseExpression2();
4309 } 4302 }
4310 return new VariableDeclaration.full(commentAndMetadata.comment, commentAndMe tadata.metadata, name, equals, initializer); 4303 return new VariableDeclaration.full(commentAndMetadata.comment, commentAndMe tadata.metadata, name, equals, initializer);
4311 } 4304 }
4312 4305
4313 /** 4306 /**
4314 * Parse a variable declaration list. 4307 * Parse a variable declaration list.
4315 * <pre> 4308 * <pre>
4316 * variableDeclarationList ::= 4309 * variableDeclarationList ::=
4317 * finalConstVarOrType variableDeclaration (',' variableDeclaration) 4310 * finalConstVarOrType variableDeclaration (',' variableDeclaration)
4318 * </pre> 4311 * </pre>
4319 * @param commentAndMetadata the metadata to be associated with the variable d eclaration list 4312 * @param commentAndMetadata the metadata to be associated with the variable d eclaration list
4320 * @return the variable declaration list that was parsed 4313 * @return the variable declaration list that was parsed
4321 */ 4314 */
4322 VariableDeclarationList parseVariableDeclarationList(CommentAndMetadata commen tAndMetadata) { 4315 VariableDeclarationList parseVariableDeclarationList(CommentAndMetadata commen tAndMetadata) {
4323 FinalConstVarOrType holder = parseFinalConstVarOrType(false); 4316 FinalConstVarOrType holder = parseFinalConstVarOrType(false);
4324 return parseVariableDeclarationList2(commentAndMetadata, holder.keyword, hol der.type); 4317 return parseVariableDeclarationList2(commentAndMetadata, holder.keyword, hol der.type);
4325 } 4318 }
4326 4319
4327 /** 4320 /**
4328 * Parse a variable declaration list. 4321 * Parse a variable declaration list.
4329 * <pre> 4322 * <pre>
4330 * variableDeclarationList ::= 4323 * variableDeclarationList ::=
4331 * finalConstVarOrType variableDeclaration (',' variableDeclaration) 4324 * finalConstVarOrType variableDeclaration (',' variableDeclaration)
4332 * </pre> 4325 * </pre>
4333 * @param commentAndMetadata the metadata to be associated with the variable d eclaration list, or{@code null} if there is no attempt at parsing the comment an d metadata 4326 * @param commentAndMetadata the metadata to be associated with the variable d eclaration list, or{@code null} if there is no attempt at parsing the comment an d metadata
4334 * @param keyword the token representing the 'final', 'const' or 'var' keyword , or {@code null} if 4327 * @param keyword the token representing the 'final', 'const' or 'var' keyword , or {@code null} if
4335 * there is no keyword 4328 * there is no keyword
4336 * @param type the type of the variables in the list 4329 * @param type the type of the variables in the list
4337 * @return the variable declaration list that was parsed 4330 * @return the variable declaration list that was parsed
4338 */ 4331 */
4339 VariableDeclarationList parseVariableDeclarationList2(CommentAndMetadata comme ntAndMetadata, Token keyword, TypeName type) { 4332 VariableDeclarationList parseVariableDeclarationList2(CommentAndMetadata comme ntAndMetadata, Token keyword, TypeName type) {
4340 List<VariableDeclaration> variables = new List<VariableDeclaration>(); 4333 List<VariableDeclaration> variables = new List<VariableDeclaration>();
4341 variables.add(parseVariableDeclaration()); 4334 variables.add(parseVariableDeclaration());
4342 while (matches5(TokenType.COMMA)) { 4335 while (matches5(TokenType.COMMA)) {
4343 advance(); 4336 advance();
4344 variables.add(parseVariableDeclaration()); 4337 variables.add(parseVariableDeclaration());
4345 } 4338 }
4346 return new VariableDeclarationList.full(commentAndMetadata != null ? comment AndMetadata.comment : null, commentAndMetadata != null ? commentAndMetadata.meta data : null, keyword, type, variables); 4339 return new VariableDeclarationList.full(commentAndMetadata != null ? comment AndMetadata.comment : null, commentAndMetadata != null ? commentAndMetadata.meta data : null, keyword, type, variables);
4347 } 4340 }
4348 4341
4349 /** 4342 /**
4350 * Parse a variable declaration statement. 4343 * Parse a variable declaration statement.
4351 * <pre> 4344 * <pre>
4352 * variableDeclarationStatement ::= 4345 * variableDeclarationStatement ::=
4353 * variableDeclarationList ';' 4346 * variableDeclarationList ';'
4354 * </pre> 4347 * </pre>
4355 * @param commentAndMetadata the metadata to be associated with the variable d eclaration 4348 * @param commentAndMetadata the metadata to be associated with the variable d eclaration
4356 * statement, or {@code null} if there is no attempt at parsing the comment an d metadata 4349 * statement, or {@code null} if there is no attempt at parsing the comment an d metadata
4357 * @return the variable declaration statement that was parsed 4350 * @return the variable declaration statement that was parsed
4358 */ 4351 */
4359 VariableDeclarationStatement parseVariableDeclarationStatement(CommentAndMetad ata commentAndMetadata) { 4352 VariableDeclarationStatement parseVariableDeclarationStatement(CommentAndMetad ata commentAndMetadata) {
4360 VariableDeclarationList variableList = parseVariableDeclarationList(commentA ndMetadata); 4353 VariableDeclarationList variableList = parseVariableDeclarationList(commentA ndMetadata);
4361 Token semicolon = expect2(TokenType.SEMICOLON); 4354 Token semicolon = expect2(TokenType.SEMICOLON);
4362 return new VariableDeclarationStatement.full(variableList, semicolon); 4355 return new VariableDeclarationStatement.full(variableList, semicolon);
4363 } 4356 }
4364 4357
4365 /** 4358 /**
4366 * Parse a variable declaration statement. 4359 * Parse a variable declaration statement.
4367 * <pre> 4360 * <pre>
4368 * variableDeclarationStatement ::= 4361 * variableDeclarationStatement ::=
4369 * variableDeclarationList ';' 4362 * variableDeclarationList ';'
4370 * </pre> 4363 * </pre>
4371 * @param commentAndMetadata the metadata to be associated with the variable d eclaration 4364 * @param commentAndMetadata the metadata to be associated with the variable d eclaration
4372 * statement, or {@code null} if there is no attempt at parsing the comment an d metadata 4365 * statement, or {@code null} if there is no attempt at parsing the comment an d metadata
4373 * @param keyword the token representing the 'final', 'const' or 'var' keyword , or {@code null} if 4366 * @param keyword the token representing the 'final', 'const' or 'var' keyword , or {@code null} if
4374 * there is no keyword 4367 * there is no keyword
4375 * @param type the type of the variables in the list 4368 * @param type the type of the variables in the list
4376 * @return the variable declaration statement that was parsed 4369 * @return the variable declaration statement that was parsed
4377 */ 4370 */
4378 VariableDeclarationStatement parseVariableDeclarationStatement2(CommentAndMeta data commentAndMetadata, Token keyword, TypeName type) { 4371 VariableDeclarationStatement parseVariableDeclarationStatement2(CommentAndMeta data commentAndMetadata, Token keyword, TypeName type) {
4379 VariableDeclarationList variableList = parseVariableDeclarationList2(comment AndMetadata, keyword, type); 4372 VariableDeclarationList variableList = parseVariableDeclarationList2(comment AndMetadata, keyword, type);
4380 Token semicolon = expect2(TokenType.SEMICOLON); 4373 Token semicolon = expect2(TokenType.SEMICOLON);
4381 return new VariableDeclarationStatement.full(variableList, semicolon); 4374 return new VariableDeclarationStatement.full(variableList, semicolon);
4382 } 4375 }
4383 4376
4384 /** 4377 /**
4385 * Parse a while statement. 4378 * Parse a while statement.
4386 * <pre> 4379 * <pre>
4387 * whileStatement ::= 4380 * whileStatement ::=
4388 * 'while' '(' expression ')' statement 4381 * 'while' '(' expression ')' statement
4389 * </pre> 4382 * </pre>
4390 * @return the while statement that was parsed 4383 * @return the while statement that was parsed
4391 */ 4384 */
4392 Statement parseWhileStatement() { 4385 Statement parseWhileStatement() {
4393 bool wasInLoop = _inLoop; 4386 bool wasInLoop = _inLoop;
4394 _inLoop = true; 4387 _inLoop = true;
4395 try { 4388 try {
4396 Token keyword = expect(Keyword.WHILE); 4389 Token keyword = expect(Keyword.WHILE);
4397 Token leftParenthesis = expect2(TokenType.OPEN_PAREN); 4390 Token leftParenthesis = expect2(TokenType.OPEN_PAREN);
4398 Expression condition = parseExpression2(); 4391 Expression condition = parseExpression2();
4399 Token rightParenthesis = expect2(TokenType.CLOSE_PAREN); 4392 Token rightParenthesis = expect2(TokenType.CLOSE_PAREN);
4400 Statement body = parseStatement2(); 4393 Statement body = parseStatement2();
4401 return new WhileStatement.full(keyword, leftParenthesis, condition, rightP arenthesis, body); 4394 return new WhileStatement.full(keyword, leftParenthesis, condition, rightP arenthesis, body);
4402 } finally { 4395 } finally {
4403 _inLoop = wasInLoop; 4396 _inLoop = wasInLoop;
4404 } 4397 }
4405 } 4398 }
4406 4399
4407 /** 4400 /**
4408 * Parse a with clause. 4401 * Parse a with clause.
4409 * <pre> 4402 * <pre>
4410 * withClause ::= 4403 * withClause ::=
4411 * 'with' typeName (',' typeName) 4404 * 'with' typeName (',' typeName)
4412 * </pre> 4405 * </pre>
4413 * @return the with clause that was parsed 4406 * @return the with clause that was parsed
4414 */ 4407 */
4415 WithClause parseWithClause() { 4408 WithClause parseWithClause() {
4416 Token with2 = expect(Keyword.WITH); 4409 Token with2 = expect(Keyword.WITH);
4417 List<TypeName> types = new List<TypeName>(); 4410 List<TypeName> types = new List<TypeName>();
4418 types.add(parseTypeName()); 4411 types.add(parseTypeName());
4419 while (optional(TokenType.COMMA)) { 4412 while (optional(TokenType.COMMA)) {
4420 types.add(parseTypeName()); 4413 types.add(parseTypeName());
4421 } 4414 }
4422 return new WithClause.full(with2, types); 4415 return new WithClause.full(with2, types);
4423 } 4416 }
4424 4417
4425 /** 4418 /**
4426 * Return the token that is immediately after the current token. This is equiv alent to{@link #peek(int) peek(1)}. 4419 * Return the token that is immediately after the current token. This is equiv alent to{@link #peek(int) peek(1)}.
4427 * @return the token that is immediately after the current token 4420 * @return the token that is immediately after the current token
4428 */ 4421 */
4429 Token peek() => _currentToken.next; 4422 Token peek() => _currentToken.next;
4430 4423
4431 /** 4424 /**
4432 * Return the token that is the given distance after the current token. 4425 * Return the token that is the given distance after the current token.
4433 * @param distance the number of tokens to look ahead, where {@code 0} is the current token,{@code 1} is the next token, etc. 4426 * @param distance the number of tokens to look ahead, where {@code 0} is the current token,{@code 1} is the next token, etc.
4434 * @return the token that is the given distance after the current token 4427 * @return the token that is the given distance after the current token
4435 */ 4428 */
4436 Token peek2(int distance) { 4429 Token peek2(int distance) {
4437 Token token = _currentToken; 4430 Token token = _currentToken;
4438 for (int i = 0; i < distance; i++) { 4431 for (int i = 0; i < distance; i++) {
4439 token = token.next; 4432 token = token.next;
4440 } 4433 }
4441 return token; 4434 return token;
4442 } 4435 }
4443 4436
4444 /** 4437 /**
4445 * Report an error with the given error code and arguments. 4438 * Report an error with the given error code and arguments.
4446 * @param errorCode the error code of the error to be reported 4439 * @param errorCode the error code of the error to be reported
4447 * @param node the node specifying the location of the error 4440 * @param node the node specifying the location of the error
4448 * @param arguments the arguments to the error, used to compose the error mess age 4441 * @param arguments the arguments to the error, used to compose the error mess age
4449 */ 4442 */
4450 void reportError(ParserErrorCode errorCode, ASTNode node, List<Object> argumen ts) { 4443 void reportError(ParserErrorCode errorCode, ASTNode node, List<Object> argumen ts) {
4451 _errorListener.onError(new AnalysisError.con2(_source, node.offset, node.len gth, errorCode, arguments)); 4444 _errorListener.onError(new AnalysisError.con2(_source, node.offset, node.len gth, errorCode, arguments));
4452 } 4445 }
4453 4446
4454 /** 4447 /**
4455 * Report an error with the given error code and arguments. 4448 * Report an error with the given error code and arguments.
4456 * @param errorCode the error code of the error to be reported 4449 * @param errorCode the error code of the error to be reported
4457 * @param arguments the arguments to the error, used to compose the error mess age 4450 * @param arguments the arguments to the error, used to compose the error mess age
4458 */ 4451 */
4459 void reportError7(ParserErrorCode errorCode, List<Object> arguments) { 4452 void reportError7(ParserErrorCode errorCode, List<Object> arguments) {
4460 reportError8(errorCode, _currentToken, arguments); 4453 reportError8(errorCode, _currentToken, arguments);
4461 } 4454 }
4462 4455
4463 /** 4456 /**
4464 * Report an error with the given error code and arguments. 4457 * Report an error with the given error code and arguments.
4465 * @param errorCode the error code of the error to be reported 4458 * @param errorCode the error code of the error to be reported
4466 * @param token the token specifying the location of the error 4459 * @param token the token specifying the location of the error
4467 * @param arguments the arguments to the error, used to compose the error mess age 4460 * @param arguments the arguments to the error, used to compose the error mess age
4468 */ 4461 */
4469 void reportError8(ParserErrorCode errorCode, Token token, List<Object> argumen ts) { 4462 void reportError8(ParserErrorCode errorCode, Token token, List<Object> argumen ts) {
4470 _errorListener.onError(new AnalysisError.con2(_source, token.offset, token.l ength, errorCode, arguments)); 4463 _errorListener.onError(new AnalysisError.con2(_source, token.offset, token.l ength, errorCode, arguments));
4471 } 4464 }
4472 4465
4473 /** 4466 /**
4474 * Parse the 'final', 'const', 'var' or type preceding a variable declaration, starting at the 4467 * Parse the 'final', 'const', 'var' or type preceding a variable declaration, starting at the
4475 * given token, without actually creating a type or changing the current token . Return the token 4468 * given token, without actually creating a type or changing the current token . Return the token
4476 * following the type that was parsed, or {@code null} if the given token is n ot the first token 4469 * following the type that was parsed, or {@code null} if the given token is n ot the first token
4477 * in a valid type. 4470 * in a valid type.
4478 * <pre> 4471 * <pre>
4479 * finalConstVarOrType ::= 4472 * finalConstVarOrType ::=
4480 * | 'final' type? 4473 * | 'final' type?
4481 * | 'const' type? 4474 * | 'const' type?
4482 * | 'var' 4475 * | 'var'
(...skipping 11 matching lines...) Expand all
4494 } else if (matches3(startToken, Keyword.VAR)) { 4487 } else if (matches3(startToken, Keyword.VAR)) {
4495 return startToken.next; 4488 return startToken.next;
4496 } else if (matchesIdentifier2(startToken)) { 4489 } else if (matchesIdentifier2(startToken)) {
4497 Token next3 = startToken.next; 4490 Token next3 = startToken.next;
4498 if (matchesIdentifier2(next3) || matches4(next3, TokenType.LT) || matches3 (next3, Keyword.THIS) || (matches4(next3, TokenType.PERIOD) && matchesIdentifier 2(next3.next) && (matchesIdentifier2(next3.next.next) || matches4(next3.next.nex t, TokenType.LT) || matches3(next3.next.next, Keyword.THIS)))) { 4491 if (matchesIdentifier2(next3) || matches4(next3, TokenType.LT) || matches3 (next3, Keyword.THIS) || (matches4(next3, TokenType.PERIOD) && matchesIdentifier 2(next3.next) && (matchesIdentifier2(next3.next.next) || matches4(next3.next.nex t, TokenType.LT) || matches3(next3.next.next, Keyword.THIS)))) {
4499 return skipReturnType(startToken); 4492 return skipReturnType(startToken);
4500 } 4493 }
4501 } 4494 }
4502 return null; 4495 return null;
4503 } 4496 }
4504 4497
4505 /** 4498 /**
4506 * Parse a list of formal parameters, starting at the given token, without act ually creating a 4499 * Parse a list of formal parameters, starting at the given token, without act ually creating a
4507 * formal parameter list or changing the current token. Return the token follo wing the formal 4500 * formal parameter list or changing the current token. Return the token follo wing the formal
4508 * parameter list that was parsed, or {@code null} if the given token is not t he first token in a 4501 * parameter list that was parsed, or {@code null} if the given token is not t he first token in a
4509 * valid list of formal parameter. 4502 * valid list of formal parameter.
4510 * <p> 4503 * <p>
4511 * Note that unlike other skip methods, this method uses a heuristic. In the w orst case, the 4504 * Note that unlike other skip methods, this method uses a heuristic. In the w orst case, the
4512 * parameters could be prefixed by metadata, which would require us to be able to skip arbitrary 4505 * parameters could be prefixed by metadata, which would require us to be able to skip arbitrary
4513 * expressions. Rather than duplicate the logic of most of the parse methods w e simply look for 4506 * expressions. Rather than duplicate the logic of most of the parse methods w e simply look for
4514 * something that is likely to be a list of parameters and then skip to return ing the token after 4507 * something that is likely to be a list of parameters and then skip to return ing the token after
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
4552 } 4545 }
4553 Token afterType = skipFinalConstVarOrType(next2); 4546 Token afterType = skipFinalConstVarOrType(next2);
4554 if (afterType == null) { 4547 if (afterType == null) {
4555 return null; 4548 return null;
4556 } 4549 }
4557 if (skipSimpleIdentifier(afterType) == null) { 4550 if (skipSimpleIdentifier(afterType) == null) {
4558 return null; 4551 return null;
4559 } 4552 }
4560 return skipPastMatchingToken(startToken); 4553 return skipPastMatchingToken(startToken);
4561 } 4554 }
4562 4555
4563 /** 4556 /**
4564 * If the given token is a begin token with an associated end token, then retu rn the token 4557 * If the given token is a begin token with an associated end token, then retu rn the token
4565 * following the end token. Otherwise, return {@code null}. 4558 * following the end token. Otherwise, return {@code null}.
4566 * @param startToken the token that is assumed to be a being token 4559 * @param startToken the token that is assumed to be a being token
4567 * @return the token following the matching end token 4560 * @return the token following the matching end token
4568 */ 4561 */
4569 Token skipPastMatchingToken(Token startToken) { 4562 Token skipPastMatchingToken(Token startToken) {
4570 if (startToken is! BeginToken) { 4563 if (startToken is! BeginToken) {
4571 return null; 4564 return null;
4572 } 4565 }
4573 Token closeParen = ((startToken as BeginToken)).endToken; 4566 Token closeParen = ((startToken as BeginToken)).endToken;
4574 if (closeParen == null) { 4567 if (closeParen == null) {
4575 return null; 4568 return null;
4576 } 4569 }
4577 return closeParen.next; 4570 return closeParen.next;
4578 } 4571 }
4579 4572
4580 /** 4573 /**
4581 * Parse a prefixed identifier, starting at the given token, without actually creating a prefixed 4574 * Parse a prefixed identifier, starting at the given token, without actually creating a prefixed
4582 * identifier or changing the current token. Return the token following the pr efixed identifier 4575 * identifier or changing the current token. Return the token following the pr efixed identifier
4583 * that was parsed, or {@code null} if the given token is not the first token in a valid prefixed 4576 * that was parsed, or {@code null} if the given token is not the first token in a valid prefixed
4584 * identifier. 4577 * identifier.
4585 * <p> 4578 * <p>
4586 * This method must be kept in sync with {@link #parsePrefixedIdentifier()}. 4579 * This method must be kept in sync with {@link #parsePrefixedIdentifier()}.
4587 * <pre> 4580 * <pre>
4588 * prefixedIdentifier ::= 4581 * prefixedIdentifier ::=
4589 * identifier ('.' identifier)? 4582 * identifier ('.' identifier)?
4590 * </pre> 4583 * </pre>
4591 * @param startToken the token at which parsing is to begin 4584 * @param startToken the token at which parsing is to begin
4592 * @return the token following the prefixed identifier that was parsed 4585 * @return the token following the prefixed identifier that was parsed
4593 */ 4586 */
4594 Token skipPrefixedIdentifier(Token startToken) { 4587 Token skipPrefixedIdentifier(Token startToken) {
4595 Token token = skipSimpleIdentifier(startToken); 4588 Token token = skipSimpleIdentifier(startToken);
4596 if (token == null) { 4589 if (token == null) {
4597 return null; 4590 return null;
4598 } else if (!matches4(token, TokenType.PERIOD)) { 4591 } else if (!matches4(token, TokenType.PERIOD)) {
4599 return token; 4592 return token;
4600 } 4593 }
4601 return skipSimpleIdentifier(token.next); 4594 return skipSimpleIdentifier(token.next);
4602 } 4595 }
4603 4596
4604 /** 4597 /**
4605 * Parse a return type, starting at the given token, without actually creating a return type or 4598 * Parse a return type, starting at the given token, without actually creating a return type or
4606 * changing the current token. Return the token following the return type that was parsed, or{@code null} if the given token is not the first token in a valid return type. 4599 * changing the current token. Return the token following the return type that was parsed, or{@code null} if the given token is not the first token in a valid return type.
4607 * <p> 4600 * <p>
4608 * This method must be kept in sync with {@link #parseReturnType()}. 4601 * This method must be kept in sync with {@link #parseReturnType()}.
4609 * <pre> 4602 * <pre>
4610 * returnType ::= 4603 * returnType ::=
4611 * 'void' 4604 * 'void'
4612 * | type 4605 * | type
4613 * </pre> 4606 * </pre>
4614 * @param startToken the token at which parsing is to begin 4607 * @param startToken the token at which parsing is to begin
4615 * @return the token following the return type that was parsed 4608 * @return the token following the return type that was parsed
4616 */ 4609 */
4617 Token skipReturnType(Token startToken) { 4610 Token skipReturnType(Token startToken) {
4618 if (matches3(startToken, Keyword.VOID)) { 4611 if (matches3(startToken, Keyword.VOID)) {
4619 return startToken.next; 4612 return startToken.next;
4620 } else { 4613 } else {
4621 return skipTypeName(startToken); 4614 return skipTypeName(startToken);
4622 } 4615 }
4623 } 4616 }
4624 4617
4625 /** 4618 /**
4626 * Parse a simple identifier, starting at the given token, without actually cr eating a simple 4619 * Parse a simple identifier, starting at the given token, without actually cr eating a simple
4627 * identifier or changing the current token. Return the token following the si mple identifier that 4620 * identifier or changing the current token. Return the token following the si mple identifier that
4628 * was parsed, or {@code null} if the given token is not the first token in a valid simple 4621 * was parsed, or {@code null} if the given token is not the first token in a valid simple
4629 * identifier. 4622 * identifier.
4630 * <p> 4623 * <p>
4631 * This method must be kept in sync with {@link #parseSimpleIdentifier()}. 4624 * This method must be kept in sync with {@link #parseSimpleIdentifier()}.
4632 * <pre> 4625 * <pre>
4633 * identifier ::= 4626 * identifier ::=
4634 * IDENTIFIER 4627 * IDENTIFIER
4635 * </pre> 4628 * </pre>
4636 * @param startToken the token at which parsing is to begin 4629 * @param startToken the token at which parsing is to begin
4637 * @return the token following the simple identifier that was parsed 4630 * @return the token following the simple identifier that was parsed
4638 */ 4631 */
4639 Token skipSimpleIdentifier(Token startToken) { 4632 Token skipSimpleIdentifier(Token startToken) {
4640 if (matches4(startToken, TokenType.IDENTIFIER) || (matches4(startToken, Toke nType.KEYWORD) && ((startToken as KeywordToken)).keyword.isPseudoKeyword())) { 4633 if (matches4(startToken, TokenType.IDENTIFIER) || (matches4(startToken, Toke nType.KEYWORD) && ((startToken as KeywordToken)).keyword.isPseudoKeyword())) {
4641 return startToken.next; 4634 return startToken.next;
4642 } 4635 }
4643 return null; 4636 return null;
4644 } 4637 }
4645 4638
4646 /** 4639 /**
4647 * Parse a string literal that contains interpolations, starting at the given token, without 4640 * Parse a string literal that contains interpolations, starting at the given token, without
4648 * actually creating a string literal or changing the current token. Return th e token following 4641 * actually creating a string literal or changing the current token. Return th e token following
4649 * the string literal that was parsed, or {@code null} if the given token is n ot the first token 4642 * the string literal that was parsed, or {@code null} if the given token is n ot the first token
4650 * in a valid string literal. 4643 * in a valid string literal.
4651 * <p> 4644 * <p>
4652 * This method must be kept in sync with {@link #parseStringInterpolation(Toke n)}. 4645 * This method must be kept in sync with {@link #parseStringInterpolation(Toke n)}.
4653 * @param startToken the token at which parsing is to begin 4646 * @param startToken the token at which parsing is to begin
4654 * @return the string literal that was parsed 4647 * @return the string literal that was parsed
4655 */ 4648 */
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
4688 token = token.next; 4681 token = token.next;
4689 } 4682 }
4690 type2 = token.type; 4683 type2 = token.type;
4691 if (identical(type2, TokenType.STRING)) { 4684 if (identical(type2, TokenType.STRING)) {
4692 token = token.next; 4685 token = token.next;
4693 type2 = token.type; 4686 type2 = token.type;
4694 } 4687 }
4695 } 4688 }
4696 return token; 4689 return token;
4697 } 4690 }
4698 4691
4699 /** 4692 /**
4700 * Parse a string literal, starting at the given token, without actually creat ing a string literal 4693 * Parse a string literal, starting at the given token, without actually creat ing a string literal
4701 * or changing the current token. Return the token following the string litera l that was parsed, 4694 * or changing the current token. Return the token following the string litera l that was parsed,
4702 * or {@code null} if the given token is not the first token in a valid string literal. 4695 * or {@code null} if the given token is not the first token in a valid string literal.
4703 * <p> 4696 * <p>
4704 * This method must be kept in sync with {@link #parseStringLiteral()}. 4697 * This method must be kept in sync with {@link #parseStringLiteral()}.
4705 * <pre> 4698 * <pre>
4706 * stringLiteral ::= 4699 * stringLiteral ::=
4707 * MULTI_LINE_STRING+ 4700 * MULTI_LINE_STRING+
4708 * | SINGLE_LINE_STRING+ 4701 * | SINGLE_LINE_STRING+
4709 * </pre> 4702 * </pre>
4710 * @param startToken the token at which parsing is to begin 4703 * @param startToken the token at which parsing is to begin
4711 * @return the token following the string literal that was parsed 4704 * @return the token following the string literal that was parsed
4712 */ 4705 */
4713 Token skipStringLiteral(Token startToken) { 4706 Token skipStringLiteral(Token startToken) {
4714 Token token = startToken; 4707 Token token = startToken;
4715 while (token != null && matches4(token, TokenType.STRING)) { 4708 while (token != null && matches4(token, TokenType.STRING)) {
4716 token = token.next; 4709 token = token.next;
4717 TokenType type2 = token.type; 4710 TokenType type2 = token.type;
4718 if (identical(type2, TokenType.STRING_INTERPOLATION_EXPRESSION) || identic al(type2, TokenType.STRING_INTERPOLATION_IDENTIFIER)) { 4711 if (identical(type2, TokenType.STRING_INTERPOLATION_EXPRESSION) || identic al(type2, TokenType.STRING_INTERPOLATION_IDENTIFIER)) {
4719 token = skipStringInterpolation(token); 4712 token = skipStringInterpolation(token);
4720 } 4713 }
4721 } 4714 }
4722 if (identical(token, startToken)) { 4715 if (identical(token, startToken)) {
4723 return null; 4716 return null;
4724 } 4717 }
4725 return token; 4718 return token;
4726 } 4719 }
4727 4720
4728 /** 4721 /**
4729 * Parse a list of type arguments, starting at the given token, without actual ly creating a type argument list 4722 * Parse a list of type arguments, starting at the given token, without actual ly creating a type argument list
4730 * or changing the current token. Return the token following the type argument list that was parsed, 4723 * or changing the current token. Return the token following the type argument list that was parsed,
4731 * or {@code null} if the given token is not the first token in a valid type a rgument list. 4724 * or {@code null} if the given token is not the first token in a valid type a rgument list.
4732 * <p> 4725 * <p>
4733 * This method must be kept in sync with {@link #parseTypeArgumentList()}. 4726 * This method must be kept in sync with {@link #parseTypeArgumentList()}.
4734 * <pre> 4727 * <pre>
4735 * typeArguments ::= 4728 * typeArguments ::=
4736 * '<' typeList '>' 4729 * '<' typeList '>'
4737 * typeList ::= 4730 * typeList ::=
(...skipping 19 matching lines...) Expand all
4757 } 4750 }
4758 if (identical(token.type, TokenType.GT)) { 4751 if (identical(token.type, TokenType.GT)) {
4759 return token.next; 4752 return token.next;
4760 } else if (identical(token.type, TokenType.GT_GT)) { 4753 } else if (identical(token.type, TokenType.GT_GT)) {
4761 Token second = new Token(TokenType.GT, token.offset + 1); 4754 Token second = new Token(TokenType.GT, token.offset + 1);
4762 second.setNextWithoutSettingPrevious(token.next); 4755 second.setNextWithoutSettingPrevious(token.next);
4763 return second; 4756 return second;
4764 } 4757 }
4765 return null; 4758 return null;
4766 } 4759 }
4767 4760
4768 /** 4761 /**
4769 * Parse a type name, starting at the given token, without actually creating a type name or 4762 * Parse a type name, starting at the given token, without actually creating a type name or
4770 * changing the current token. Return the token following the type name that w as parsed, or{@code null} if the given token is not the first token in a valid t ype name. 4763 * changing the current token. Return the token following the type name that w as parsed, or{@code null} if the given token is not the first token in a valid t ype name.
4771 * <p> 4764 * <p>
4772 * This method must be kept in sync with {@link #parseTypeName()}. 4765 * This method must be kept in sync with {@link #parseTypeName()}.
4773 * <pre> 4766 * <pre>
4774 * type ::= 4767 * type ::=
4775 * qualified typeArguments? 4768 * qualified typeArguments?
4776 * </pre> 4769 * </pre>
4777 * @param startToken the token at which parsing is to begin 4770 * @param startToken the token at which parsing is to begin
4778 * @return the token following the type name that was parsed 4771 * @return the token following the type name that was parsed
4779 */ 4772 */
4780 Token skipTypeName(Token startToken) { 4773 Token skipTypeName(Token startToken) {
4781 Token token = skipPrefixedIdentifier(startToken); 4774 Token token = skipPrefixedIdentifier(startToken);
4782 if (token == null) { 4775 if (token == null) {
4783 return null; 4776 return null;
4784 } 4777 }
4785 if (matches4(token, TokenType.LT)) { 4778 if (matches4(token, TokenType.LT)) {
4786 token = skipTypeArgumentList(token); 4779 token = skipTypeArgumentList(token);
4787 } 4780 }
4788 return token; 4781 return token;
4789 } 4782 }
4790 4783
4791 /** 4784 /**
4792 * Parse a list of type parameters, starting at the given token, without actua lly creating a type 4785 * Parse a list of type parameters, starting at the given token, without actua lly creating a type
4793 * parameter list or changing the current token. Return the token following th e type parameter 4786 * parameter list or changing the current token. Return the token following th e type parameter
4794 * list that was parsed, or {@code null} if the given token is not the first t oken in a valid type 4787 * list that was parsed, or {@code null} if the given token is not the first t oken in a valid type
4795 * parameter list. 4788 * parameter list.
4796 * <p> 4789 * <p>
4797 * This method must be kept in sync with {@link #parseTypeParameterList()}. 4790 * This method must be kept in sync with {@link #parseTypeParameterList()}.
4798 * <pre> 4791 * <pre>
4799 * typeParameterList ::= 4792 * typeParameterList ::=
4800 * '<' typeParameter (',' typeParameter)* '>' 4793 * '<' typeParameter (',' typeParameter)* '>'
(...skipping 30 matching lines...) Expand all
4831 Token fakeEquals = new Token(TokenType.EQ, next2.offset + 2); 4824 Token fakeEquals = new Token(TokenType.EQ, next2.offset + 2);
4832 fakeEquals.setNextWithoutSettingPrevious(next2.next); 4825 fakeEquals.setNextWithoutSettingPrevious(next2.next);
4833 return fakeEquals; 4826 return fakeEquals;
4834 } 4827 }
4835 depth -= 2; 4828 depth -= 2;
4836 } 4829 }
4837 next2 = next2.next; 4830 next2 = next2.next;
4838 } 4831 }
4839 return next2; 4832 return next2;
4840 } 4833 }
4841 4834
4842 /** 4835 /**
4843 * Translate the characters at the given index in the given string, appending the translated 4836 * Translate the characters at the given index in the given string, appending the translated
4844 * character to the given builder. The index is assumed to be valid. 4837 * character to the given builder. The index is assumed to be valid.
4845 * @param builder the builder to which the translated character is to be appen ded 4838 * @param builder the builder to which the translated character is to be appen ded
4846 * @param lexeme the string containing the character(s) to be translated 4839 * @param lexeme the string containing the character(s) to be translated
4847 * @param index the index of the character to be translated 4840 * @param index the index of the character to be translated
4848 * @return the index of the next character to be translated 4841 * @return the index of the next character to be translated
4849 */ 4842 */
4850 int translateCharacter(JavaStringBuilder builder, String lexeme, int index) { 4843 int translateCharacter(JavaStringBuilder builder, String lexeme, int index) {
4851 int currentChar = lexeme.codeUnitAt(index); 4844 int currentChar = lexeme.codeUnitAt(index);
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
4937 } else { 4930 } else {
4938 appendScalarValue(builder, lexeme.substring(index, currentIndex + 1), ((((((Character.digit(firstDigit, 16) << 4) + Character.digit(secondDigit, 16)) << 4) + Character.digit(thirdDigit, 16)) << 4) + Character.digit(fourthDigit, 16 )), index, currentIndex + 3); 4931 appendScalarValue(builder, lexeme.substring(index, currentIndex + 1), ((((((Character.digit(firstDigit, 16) << 4) + Character.digit(secondDigit, 16)) << 4) + Character.digit(thirdDigit, 16)) << 4) + Character.digit(fourthDigit, 16 )), index, currentIndex + 3);
4939 } 4932 }
4940 return currentIndex + 4; 4933 return currentIndex + 4;
4941 } 4934 }
4942 } else { 4935 } else {
4943 builder.appendChar(currentChar); 4936 builder.appendChar(currentChar);
4944 } 4937 }
4945 return currentIndex + 1; 4938 return currentIndex + 1;
4946 } 4939 }
4947 4940
4948 /** 4941 /**
4949 * Validate that the given parameter list does not contain any field initializ ers. 4942 * Validate that the given parameter list does not contain any field initializ ers.
4950 * @param parameterList the parameter list to be validated 4943 * @param parameterList the parameter list to be validated
4951 */ 4944 */
4952 void validateFormalParameterList(FormalParameterList parameterList) { 4945 void validateFormalParameterList(FormalParameterList parameterList) {
4953 for (FormalParameter parameter in parameterList.parameters) { 4946 for (FormalParameter parameter in parameterList.parameters) {
4954 if (parameter is FieldFormalParameter) { 4947 if (parameter is FieldFormalParameter) {
4955 reportError(ParserErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, ((par ameter as FieldFormalParameter)).identifier, []); 4948 reportError(ParserErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, ((par ameter as FieldFormalParameter)).identifier, []);
4956 } 4949 }
4957 } 4950 }
4958 } 4951 }
4959 4952
4960 /** 4953 /**
4961 * Validate that the given set of modifiers is appropriate for a class and ret urn the 'abstract' 4954 * Validate that the given set of modifiers is appropriate for a class and ret urn the 'abstract'
4962 * keyword if there is one. 4955 * keyword if there is one.
4963 * @param modifiers the modifiers being validated 4956 * @param modifiers the modifiers being validated
4964 */ 4957 */
4965 Token validateModifiersForClass(Modifiers modifiers) { 4958 Token validateModifiersForClass(Modifiers modifiers) {
4966 validateModifiersForTopLevelDeclaration(modifiers); 4959 validateModifiersForTopLevelDeclaration(modifiers);
4967 if (modifiers.constKeyword != null) { 4960 if (modifiers.constKeyword != null) {
4968 reportError8(ParserErrorCode.CONST_CLASS, modifiers.constKeyword, []); 4961 reportError8(ParserErrorCode.CONST_CLASS, modifiers.constKeyword, []);
4969 } 4962 }
4970 if (modifiers.externalKeyword != null) { 4963 if (modifiers.externalKeyword != null) {
4971 reportError8(ParserErrorCode.EXTERNAL_CLASS, modifiers.externalKeyword, [] ); 4964 reportError8(ParserErrorCode.EXTERNAL_CLASS, modifiers.externalKeyword, [] );
4972 } 4965 }
4973 if (modifiers.finalKeyword != null) { 4966 if (modifiers.finalKeyword != null) {
4974 reportError8(ParserErrorCode.FINAL_CLASS, modifiers.finalKeyword, []); 4967 reportError8(ParserErrorCode.FINAL_CLASS, modifiers.finalKeyword, []);
4975 } 4968 }
4976 if (modifiers.varKeyword != null) { 4969 if (modifiers.varKeyword != null) {
4977 reportError8(ParserErrorCode.VAR_CLASS, modifiers.varKeyword, []); 4970 reportError8(ParserErrorCode.VAR_CLASS, modifiers.varKeyword, []);
4978 } 4971 }
4979 return modifiers.abstractKeyword; 4972 return modifiers.abstractKeyword;
4980 } 4973 }
4981 4974
4982 /** 4975 /**
4983 * Validate that the given set of modifiers is appropriate for a constructor a nd return the 4976 * Validate that the given set of modifiers is appropriate for a constructor a nd return the
4984 * 'const' keyword if there is one. 4977 * 'const' keyword if there is one.
4985 * @param modifiers the modifiers being validated 4978 * @param modifiers the modifiers being validated
4986 * @return the 'const' or 'final' keyword associated with the constructor 4979 * @return the 'const' or 'final' keyword associated with the constructor
4987 */ 4980 */
4988 Token validateModifiersForConstructor(Modifiers modifiers) { 4981 Token validateModifiersForConstructor(Modifiers modifiers) {
4989 if (modifiers.abstractKeyword != null) { 4982 if (modifiers.abstractKeyword != null) {
4990 reportError7(ParserErrorCode.ABSTRACT_CLASS_MEMBER, []); 4983 reportError7(ParserErrorCode.ABSTRACT_CLASS_MEMBER, []);
4991 } 4984 }
(...skipping 10 matching lines...) Expand all
5002 Token constKeyword2 = modifiers.constKeyword; 4995 Token constKeyword2 = modifiers.constKeyword;
5003 Token factoryKeyword2 = modifiers.factoryKeyword; 4996 Token factoryKeyword2 = modifiers.factoryKeyword;
5004 if (externalKeyword2 != null && constKeyword2 != null && constKeyword2.offse t < externalKeyword2.offset) { 4997 if (externalKeyword2 != null && constKeyword2 != null && constKeyword2.offse t < externalKeyword2.offset) {
5005 reportError8(ParserErrorCode.EXTERNAL_AFTER_CONST, externalKeyword2, []); 4998 reportError8(ParserErrorCode.EXTERNAL_AFTER_CONST, externalKeyword2, []);
5006 } 4999 }
5007 if (externalKeyword2 != null && factoryKeyword2 != null && factoryKeyword2.o ffset < externalKeyword2.offset) { 5000 if (externalKeyword2 != null && factoryKeyword2 != null && factoryKeyword2.o ffset < externalKeyword2.offset) {
5008 reportError8(ParserErrorCode.EXTERNAL_AFTER_FACTORY, externalKeyword2, []) ; 5001 reportError8(ParserErrorCode.EXTERNAL_AFTER_FACTORY, externalKeyword2, []) ;
5009 } 5002 }
5010 return constKeyword2; 5003 return constKeyword2;
5011 } 5004 }
5012 5005
5013 /** 5006 /**
5014 * Validate that the given set of modifiers is appropriate for a field and ret urn the 'final', 5007 * Validate that the given set of modifiers is appropriate for a field and ret urn the 'final',
5015 * 'const' or 'var' keyword if there is one. 5008 * 'const' or 'var' keyword if there is one.
5016 * @param modifiers the modifiers being validated 5009 * @param modifiers the modifiers being validated
5017 * @return the 'final', 'const' or 'var' keyword associated with the field 5010 * @return the 'final', 'const' or 'var' keyword associated with the field
5018 */ 5011 */
5019 Token validateModifiersForField(Modifiers modifiers) { 5012 Token validateModifiersForField(Modifiers modifiers) {
5020 if (modifiers.abstractKeyword != null) { 5013 if (modifiers.abstractKeyword != null) {
5021 reportError7(ParserErrorCode.ABSTRACT_CLASS_MEMBER, []); 5014 reportError7(ParserErrorCode.ABSTRACT_CLASS_MEMBER, []);
5022 } 5015 }
(...skipping 22 matching lines...) Expand all
5045 reportError8(ParserErrorCode.FINAL_AND_VAR, varKeyword2, []); 5038 reportError8(ParserErrorCode.FINAL_AND_VAR, varKeyword2, []);
5046 } 5039 }
5047 if (staticKeyword2 != null && finalKeyword2.offset < staticKeyword2.offset ) { 5040 if (staticKeyword2 != null && finalKeyword2.offset < staticKeyword2.offset ) {
5048 reportError8(ParserErrorCode.STATIC_AFTER_FINAL, staticKeyword2, []); 5041 reportError8(ParserErrorCode.STATIC_AFTER_FINAL, staticKeyword2, []);
5049 } 5042 }
5050 } else if (varKeyword2 != null && staticKeyword2 != null && varKeyword2.offs et < staticKeyword2.offset) { 5043 } else if (varKeyword2 != null && staticKeyword2 != null && varKeyword2.offs et < staticKeyword2.offset) {
5051 reportError8(ParserErrorCode.STATIC_AFTER_VAR, staticKeyword2, []); 5044 reportError8(ParserErrorCode.STATIC_AFTER_VAR, staticKeyword2, []);
5052 } 5045 }
5053 return lexicallyFirst([constKeyword2, finalKeyword2, varKeyword2]); 5046 return lexicallyFirst([constKeyword2, finalKeyword2, varKeyword2]);
5054 } 5047 }
5055 5048
5056 /** 5049 /**
5057 * Validate that the given set of modifiers is appropriate for a getter, sette r, or method. 5050 * Validate that the given set of modifiers is appropriate for a getter, sette r, or method.
5058 * @param modifiers the modifiers being validated 5051 * @param modifiers the modifiers being validated
5059 */ 5052 */
5060 void validateModifiersForGetterOrSetterOrMethod(Modifiers modifiers) { 5053 void validateModifiersForGetterOrSetterOrMethod(Modifiers modifiers) {
5061 if (modifiers.abstractKeyword != null) { 5054 if (modifiers.abstractKeyword != null) {
5062 reportError7(ParserErrorCode.ABSTRACT_CLASS_MEMBER, []); 5055 reportError7(ParserErrorCode.ABSTRACT_CLASS_MEMBER, []);
5063 } 5056 }
5064 if (modifiers.constKeyword != null) { 5057 if (modifiers.constKeyword != null) {
5065 reportError8(ParserErrorCode.CONST_METHOD, modifiers.constKeyword, []); 5058 reportError8(ParserErrorCode.CONST_METHOD, modifiers.constKeyword, []);
5066 } 5059 }
5067 if (modifiers.factoryKeyword != null) { 5060 if (modifiers.factoryKeyword != null) {
5068 reportError8(ParserErrorCode.NON_CONSTRUCTOR_FACTORY, modifiers.factoryKey word, []); 5061 reportError8(ParserErrorCode.NON_CONSTRUCTOR_FACTORY, modifiers.factoryKey word, []);
5069 } 5062 }
5070 if (modifiers.finalKeyword != null) { 5063 if (modifiers.finalKeyword != null) {
5071 reportError8(ParserErrorCode.FINAL_METHOD, modifiers.finalKeyword, []); 5064 reportError8(ParserErrorCode.FINAL_METHOD, modifiers.finalKeyword, []);
5072 } 5065 }
5073 if (modifiers.varKeyword != null) { 5066 if (modifiers.varKeyword != null) {
5074 reportError8(ParserErrorCode.VAR_RETURN_TYPE, modifiers.varKeyword, []); 5067 reportError8(ParserErrorCode.VAR_RETURN_TYPE, modifiers.varKeyword, []);
5075 } 5068 }
5076 Token externalKeyword2 = modifiers.externalKeyword; 5069 Token externalKeyword2 = modifiers.externalKeyword;
5077 Token staticKeyword2 = modifiers.staticKeyword; 5070 Token staticKeyword2 = modifiers.staticKeyword;
5078 if (externalKeyword2 != null && staticKeyword2 != null && staticKeyword2.off set < externalKeyword2.offset) { 5071 if (externalKeyword2 != null && staticKeyword2 != null && staticKeyword2.off set < externalKeyword2.offset) {
5079 reportError8(ParserErrorCode.EXTERNAL_AFTER_STATIC, externalKeyword2, []); 5072 reportError8(ParserErrorCode.EXTERNAL_AFTER_STATIC, externalKeyword2, []);
5080 } 5073 }
5081 } 5074 }
5082 5075
5083 /** 5076 /**
5084 * Validate that the given set of modifiers is appropriate for a getter, sette r, or method. 5077 * Validate that the given set of modifiers is appropriate for a getter, sette r, or method.
5085 * @param modifiers the modifiers being validated 5078 * @param modifiers the modifiers being validated
5086 */ 5079 */
5087 void validateModifiersForOperator(Modifiers modifiers) { 5080 void validateModifiersForOperator(Modifiers modifiers) {
5088 if (modifiers.abstractKeyword != null) { 5081 if (modifiers.abstractKeyword != null) {
5089 reportError7(ParserErrorCode.ABSTRACT_CLASS_MEMBER, []); 5082 reportError7(ParserErrorCode.ABSTRACT_CLASS_MEMBER, []);
5090 } 5083 }
5091 if (modifiers.constKeyword != null) { 5084 if (modifiers.constKeyword != null) {
5092 reportError8(ParserErrorCode.CONST_METHOD, modifiers.constKeyword, []); 5085 reportError8(ParserErrorCode.CONST_METHOD, modifiers.constKeyword, []);
5093 } 5086 }
5094 if (modifiers.factoryKeyword != null) { 5087 if (modifiers.factoryKeyword != null) {
5095 reportError8(ParserErrorCode.NON_CONSTRUCTOR_FACTORY, modifiers.factoryKey word, []); 5088 reportError8(ParserErrorCode.NON_CONSTRUCTOR_FACTORY, modifiers.factoryKey word, []);
5096 } 5089 }
5097 if (modifiers.finalKeyword != null) { 5090 if (modifiers.finalKeyword != null) {
5098 reportError8(ParserErrorCode.FINAL_METHOD, modifiers.finalKeyword, []); 5091 reportError8(ParserErrorCode.FINAL_METHOD, modifiers.finalKeyword, []);
5099 } 5092 }
5100 if (modifiers.staticKeyword != null) { 5093 if (modifiers.staticKeyword != null) {
5101 reportError8(ParserErrorCode.STATIC_OPERATOR, modifiers.staticKeyword, []) ; 5094 reportError8(ParserErrorCode.STATIC_OPERATOR, modifiers.staticKeyword, []) ;
5102 } 5095 }
5103 if (modifiers.varKeyword != null) { 5096 if (modifiers.varKeyword != null) {
5104 reportError8(ParserErrorCode.VAR_RETURN_TYPE, modifiers.varKeyword, []); 5097 reportError8(ParserErrorCode.VAR_RETURN_TYPE, modifiers.varKeyword, []);
5105 } 5098 }
5106 } 5099 }
5107 5100
5108 /** 5101 /**
5109 * Validate that the given set of modifiers is appropriate for a top-level dec laration. 5102 * Validate that the given set of modifiers is appropriate for a top-level dec laration.
5110 * @param modifiers the modifiers being validated 5103 * @param modifiers the modifiers being validated
5111 */ 5104 */
5112 void validateModifiersForTopLevelDeclaration(Modifiers modifiers) { 5105 void validateModifiersForTopLevelDeclaration(Modifiers modifiers) {
5113 if (modifiers.factoryKeyword != null) { 5106 if (modifiers.factoryKeyword != null) {
5114 reportError8(ParserErrorCode.FACTORY_TOP_LEVEL_DECLARATION, modifiers.fact oryKeyword, []); 5107 reportError8(ParserErrorCode.FACTORY_TOP_LEVEL_DECLARATION, modifiers.fact oryKeyword, []);
5115 } 5108 }
5116 if (modifiers.staticKeyword != null) { 5109 if (modifiers.staticKeyword != null) {
5117 reportError8(ParserErrorCode.STATIC_TOP_LEVEL_DECLARATION, modifiers.stati cKeyword, []); 5110 reportError8(ParserErrorCode.STATIC_TOP_LEVEL_DECLARATION, modifiers.stati cKeyword, []);
5118 } 5111 }
5119 } 5112 }
5120 5113
5121 /** 5114 /**
5122 * Validate that the given set of modifiers is appropriate for a top-level fun ction. 5115 * Validate that the given set of modifiers is appropriate for a top-level fun ction.
5123 * @param modifiers the modifiers being validated 5116 * @param modifiers the modifiers being validated
5124 */ 5117 */
5125 void validateModifiersForTopLevelFunction(Modifiers modifiers) { 5118 void validateModifiersForTopLevelFunction(Modifiers modifiers) {
5126 validateModifiersForTopLevelDeclaration(modifiers); 5119 validateModifiersForTopLevelDeclaration(modifiers);
5127 if (modifiers.abstractKeyword != null) { 5120 if (modifiers.abstractKeyword != null) {
5128 reportError7(ParserErrorCode.ABSTRACT_TOP_LEVEL_FUNCTION, []); 5121 reportError7(ParserErrorCode.ABSTRACT_TOP_LEVEL_FUNCTION, []);
5129 } 5122 }
5130 if (modifiers.constKeyword != null) { 5123 if (modifiers.constKeyword != null) {
5131 reportError8(ParserErrorCode.CONST_CLASS, modifiers.constKeyword, []); 5124 reportError8(ParserErrorCode.CONST_CLASS, modifiers.constKeyword, []);
5132 } 5125 }
5133 if (modifiers.finalKeyword != null) { 5126 if (modifiers.finalKeyword != null) {
5134 reportError8(ParserErrorCode.FINAL_CLASS, modifiers.finalKeyword, []); 5127 reportError8(ParserErrorCode.FINAL_CLASS, modifiers.finalKeyword, []);
5135 } 5128 }
5136 if (modifiers.varKeyword != null) { 5129 if (modifiers.varKeyword != null) {
5137 reportError8(ParserErrorCode.VAR_RETURN_TYPE, modifiers.varKeyword, []); 5130 reportError8(ParserErrorCode.VAR_RETURN_TYPE, modifiers.varKeyword, []);
5138 } 5131 }
5139 } 5132 }
5140 5133
5141 /** 5134 /**
5142 * Validate that the given set of modifiers is appropriate for a field and ret urn the 'final', 5135 * Validate that the given set of modifiers is appropriate for a field and ret urn the 'final',
5143 * 'const' or 'var' keyword if there is one. 5136 * 'const' or 'var' keyword if there is one.
5144 * @param modifiers the modifiers being validated 5137 * @param modifiers the modifiers being validated
5145 * @return the 'final', 'const' or 'var' keyword associated with the field 5138 * @return the 'final', 'const' or 'var' keyword associated with the field
5146 */ 5139 */
5147 Token validateModifiersForTopLevelVariable(Modifiers modifiers) { 5140 Token validateModifiersForTopLevelVariable(Modifiers modifiers) {
5148 validateModifiersForTopLevelDeclaration(modifiers); 5141 validateModifiersForTopLevelDeclaration(modifiers);
5149 if (modifiers.abstractKeyword != null) { 5142 if (modifiers.abstractKeyword != null) {
5150 reportError7(ParserErrorCode.ABSTRACT_TOP_LEVEL_VARIABLE, []); 5143 reportError7(ParserErrorCode.ABSTRACT_TOP_LEVEL_VARIABLE, []);
(...skipping 11 matching lines...) Expand all
5162 if (varKeyword2 != null) { 5155 if (varKeyword2 != null) {
5163 reportError8(ParserErrorCode.CONST_AND_VAR, varKeyword2, []); 5156 reportError8(ParserErrorCode.CONST_AND_VAR, varKeyword2, []);
5164 } 5157 }
5165 } else if (finalKeyword2 != null) { 5158 } else if (finalKeyword2 != null) {
5166 if (varKeyword2 != null) { 5159 if (varKeyword2 != null) {
5167 reportError8(ParserErrorCode.FINAL_AND_VAR, varKeyword2, []); 5160 reportError8(ParserErrorCode.FINAL_AND_VAR, varKeyword2, []);
5168 } 5161 }
5169 } 5162 }
5170 return lexicallyFirst([constKeyword2, finalKeyword2, varKeyword2]); 5163 return lexicallyFirst([constKeyword2, finalKeyword2, varKeyword2]);
5171 } 5164 }
5172 5165
5173 /** 5166 /**
5174 * Validate that the given set of modifiers is appropriate for a class and ret urn the 'abstract' 5167 * Validate that the given set of modifiers is appropriate for a class and ret urn the 'abstract'
5175 * keyword if there is one. 5168 * keyword if there is one.
5176 * @param modifiers the modifiers being validated 5169 * @param modifiers the modifiers being validated
5177 */ 5170 */
5178 void validateModifiersForTypedef(Modifiers modifiers) { 5171 void validateModifiersForTypedef(Modifiers modifiers) {
5179 validateModifiersForTopLevelDeclaration(modifiers); 5172 validateModifiersForTopLevelDeclaration(modifiers);
5180 if (modifiers.abstractKeyword != null) { 5173 if (modifiers.abstractKeyword != null) {
5181 reportError8(ParserErrorCode.ABSTRACT_TYPEDEF, modifiers.abstractKeyword, []); 5174 reportError8(ParserErrorCode.ABSTRACT_TYPEDEF, modifiers.abstractKeyword, []);
5182 } 5175 }
(...skipping 15 matching lines...) Expand all
5198 KeywordToken_11(Keyword arg0, int arg1) : super(arg0, arg1); 5191 KeywordToken_11(Keyword arg0, int arg1) : super(arg0, arg1);
5199 int get length => 0; 5192 int get length => 0;
5200 } 5193 }
5201 class AnalysisErrorListener_12 implements AnalysisErrorListener { 5194 class AnalysisErrorListener_12 implements AnalysisErrorListener {
5202 List<bool> errorFound; 5195 List<bool> errorFound;
5203 AnalysisErrorListener_12(this.errorFound); 5196 AnalysisErrorListener_12(this.errorFound);
5204 void onError(AnalysisError error) { 5197 void onError(AnalysisError error) {
5205 errorFound[0] = true; 5198 errorFound[0] = true;
5206 } 5199 }
5207 } 5200 }
5208
5209 /** 5201 /**
5210 * The enumeration {@code ParserErrorCode} defines the error codes used for erro rs detected by the 5202 * The enumeration {@code ParserErrorCode} defines the error codes used for erro rs detected by the
5211 * parser. The convention for this class is for the name of the error code to in dicate the problem 5203 * parser. The convention for this class is for the name of the error code to in dicate the problem
5212 * that caused the error to be generated and for the error message to explain wh at is wrong and, 5204 * that caused the error to be generated and for the error message to explain wh at is wrong and,
5213 * when appropriate, how the problem can be corrected. 5205 * when appropriate, how the problem can be corrected.
5214 * @coverage dart.engine.parser 5206 * @coverage dart.engine.parser
5215 */ 5207 */
5216 class ParserErrorCode implements Comparable<ParserErrorCode>, ErrorCode { 5208 class ParserErrorCode implements Comparable<ParserErrorCode>, ErrorCode {
5217 static final ParserErrorCode ABSTRACT_CLASS_MEMBER = new ParserErrorCode.con2( 'ABSTRACT_CLASS_MEMBER', 0, "Members of classes cannot be declared to be 'abstra ct'"); 5209 static final ParserErrorCode ABSTRACT_CLASS_MEMBER = new ParserErrorCode.con2( 'ABSTRACT_CLASS_MEMBER', 0, "Members of classes cannot be declared to be 'abstra ct'");
5218 static final ParserErrorCode ABSTRACT_STATIC_METHOD = new ParserErrorCode.con2 ('ABSTRACT_STATIC_METHOD', 1, "Static methods cannot be declared to be 'abstract '"); 5210 static final ParserErrorCode ABSTRACT_STATIC_METHOD = new ParserErrorCode.con2 ('ABSTRACT_STATIC_METHOD', 1, "Static methods cannot be declared to be 'abstract '");
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
5327 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 ':'"); 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 ':'");
5328 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 '='"); 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 '='");
5329 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"); 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");
5330 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"); 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");
5331 static final ParserErrorCode VAR_CLASS = new ParserErrorCode.con2('VAR_CLASS', 114, "Classes cannot be declared to be 'var'"); 5323 static final ParserErrorCode VAR_CLASS = new ParserErrorCode.con2('VAR_CLASS', 114, "Classes cannot be declared to be 'var'");
5332 static final ParserErrorCode VAR_RETURN_TYPE = new ParserErrorCode.con2('VAR_R ETURN_TYPE', 115, "The return type cannot be 'var'"); 5324 static final ParserErrorCode VAR_RETURN_TYPE = new ParserErrorCode.con2('VAR_R ETURN_TYPE', 115, "The return type cannot be 'var'");
5333 static final ParserErrorCode VAR_TYPEDEF = new ParserErrorCode.con2('VAR_TYPED EF', 116, "Type aliases cannot be declared to be 'var'"); 5325 static final ParserErrorCode VAR_TYPEDEF = new ParserErrorCode.con2('VAR_TYPED EF', 116, "Type aliases cannot be declared to be 'var'");
5334 static final ParserErrorCode VOID_PARAMETER = new ParserErrorCode.con2('VOID_P ARAMETER', 117, "Parameters cannot have a type of 'void'"); 5326 static final ParserErrorCode VOID_PARAMETER = new ParserErrorCode.con2('VOID_P ARAMETER', 117, "Parameters cannot have a type of 'void'");
5335 static final ParserErrorCode VOID_VARIABLE = new ParserErrorCode.con2('VOID_VA RIABLE', 118, "Variables cannot have a type of 'void'"); 5327 static final ParserErrorCode VOID_VARIABLE = new ParserErrorCode.con2('VOID_VA RIABLE', 118, "Variables cannot have a type of 'void'");
5336 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]; 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];
5337 5329
5338 /// The name of this enum constant, as declared in the enum declaration. 5330 /// The name of this enum constant, as declared in the enum declaration.
5339 final String name; 5331 final String name;
5340 5332
5341 /// The position in the enum declaration. 5333 /// The position in the enum declaration.
5342 final int ordinal; 5334 final int ordinal;
5343 5335
5344 /** 5336 /**
5345 * The severity of this error. 5337 * The severity of this error.
5346 */ 5338 */
5347 ErrorSeverity _severity; 5339 ErrorSeverity _severity;
5348 5340
5349 /** 5341 /**
5350 * The message template used to create the message to be displayed for this er ror. 5342 * The message template used to create the message to be displayed for this er ror.
5351 */ 5343 */
5352 String _message; 5344 String _message;
5353 5345
5354 /** 5346 /**
5355 * Initialize a newly created error code to have the given severity and messag e. 5347 * Initialize a newly created error code to have the given severity and messag e.
5356 * @param severity the severity of the error 5348 * @param severity the severity of the error
5357 * @param message the message template used to create the message to be displa yed for the error 5349 * @param message the message template used to create the message to be displa yed for the error
5358 */ 5350 */
5359 ParserErrorCode.con1(this.name, this.ordinal, ErrorSeverity severity2, String message2) { 5351 ParserErrorCode.con1(this.name, this.ordinal, ErrorSeverity severity2, String message2) {
5360 _jtd_constructor_309_impl(severity2, message2); 5352 _jtd_constructor_311_impl(severity2, message2);
5361 } 5353 }
5362 _jtd_constructor_309_impl(ErrorSeverity severity2, String message2) { 5354 _jtd_constructor_311_impl(ErrorSeverity severity2, String message2) {
5363 this._severity = severity2; 5355 this._severity = severity2;
5364 this._message = message2; 5356 this._message = message2;
5365 } 5357 }
5366 5358
5367 /** 5359 /**
5368 * Initialize a newly created error code to have the given message and a sever ity of ERROR. 5360 * Initialize a newly created error code to have the given message and a sever ity of ERROR.
5369 * @param message the message template used to create the message to be displa yed for the error 5361 * @param message the message template used to create the message to be displa yed for the error
5370 */ 5362 */
5371 ParserErrorCode.con2(this.name, this.ordinal, String message) { 5363 ParserErrorCode.con2(this.name, this.ordinal, String message) {
5372 _jtd_constructor_310_impl(message); 5364 _jtd_constructor_312_impl(message);
5373 } 5365 }
5374 _jtd_constructor_310_impl(String message) { 5366 _jtd_constructor_312_impl(String message) {
5375 _jtd_constructor_309_impl(ErrorSeverity.ERROR, message); 5367 _jtd_constructor_311_impl(ErrorSeverity.ERROR, message);
5376 } 5368 }
5377 ErrorSeverity get errorSeverity => _severity; 5369 ErrorSeverity get errorSeverity => _severity;
5378 String get message => _message; 5370 String get message => _message;
5379 ErrorType get type => ErrorType.SYNTACTIC_ERROR; 5371 ErrorType get type => ErrorType.SYNTACTIC_ERROR;
5380 int compareTo(ParserErrorCode other) => ordinal - other.ordinal; 5372 int compareTo(ParserErrorCode other) => ordinal - other.ordinal;
5381 String toString() => name; 5373 String toString() => name;
5382 } 5374 }
5383
5384 /** 5375 /**
5385 * Instances of the class {link ToFormattedSourceVisitor} write a source represe ntation of a visited 5376 * Instances of the class {link ToFormattedSourceVisitor} write a source represe ntation of a visited
5386 * AST node (and all of it's children) to a writer. 5377 * AST node (and all of it's children) to a writer.
5387 */ 5378 */
5388 class ToFormattedSourceVisitor implements ASTVisitor<Object> { 5379 class ToFormattedSourceVisitor implements ASTVisitor<Object> {
5389 5380
5390 /** 5381 /**
5391 * The writer to which the source is to be written. 5382 * The writer to which the source is to be written.
5392 */ 5383 */
5393 PrintWriter _writer; 5384 PrintWriter _writer;
5394 int _indentLevel = 0; 5385 int _indentLevel = 0;
5395 String _indentString = ""; 5386 String _indentString = "";
5396 5387
5397 /** 5388 /**
5398 * Initialize a newly created visitor to write source code representing the vi sited nodes to the 5389 * Initialize a newly created visitor to write source code representing the vi sited nodes to the
5399 * given writer. 5390 * given writer.
5400 * @param writer the writer to which the source is to be written 5391 * @param writer the writer to which the source is to be written
5401 */ 5392 */
5402 ToFormattedSourceVisitor(PrintWriter writer) { 5393 ToFormattedSourceVisitor(PrintWriter writer) {
5403 this._writer = writer; 5394 this._writer = writer;
5404 } 5395 }
5405 Object visitAdjacentStrings(AdjacentStrings node) { 5396 Object visitAdjacentStrings(AdjacentStrings node) {
5406 visitList5(node.strings, " "); 5397 visitList5(node.strings, " ");
(...skipping 744 matching lines...) Expand 10 before | Expand all | Expand 10 after
6151 _indentLevel += 2; 6142 _indentLevel += 2;
6152 _indentString = StringUtils.repeat(" ", _indentLevel); 6143 _indentString = StringUtils.repeat(" ", _indentLevel);
6153 } 6144 }
6154 void nl() { 6145 void nl() {
6155 _writer.print("\n"); 6146 _writer.print("\n");
6156 } 6147 }
6157 void nl2() { 6148 void nl2() {
6158 nl(); 6149 nl();
6159 indent(); 6150 indent();
6160 } 6151 }
6161 6152
6162 /** 6153 /**
6163 * Safely visit the given node. 6154 * Safely visit the given node.
6164 * @param node the node to be visited 6155 * @param node the node to be visited
6165 */ 6156 */
6166 void visit(ASTNode node) { 6157 void visit(ASTNode node) {
6167 if (node != null) { 6158 if (node != null) {
6168 node.accept(this); 6159 node.accept(this);
6169 } 6160 }
6170 } 6161 }
6171 6162
6172 /** 6163 /**
6173 * Safely visit the given node, printing the suffix after the node if it is no n-<code>null</code>. 6164 * Safely visit the given node, printing the suffix after the node if it is no n-<code>null</code>.
6174 * @param suffix the suffix to be printed if there is a node to visit 6165 * @param suffix the suffix to be printed if there is a node to visit
6175 * @param node the node to be visited 6166 * @param node the node to be visited
6176 */ 6167 */
6177 void visit6(ASTNode node, String suffix) { 6168 void visit6(ASTNode node, String suffix) {
6178 if (node != null) { 6169 if (node != null) {
6179 node.accept(this); 6170 node.accept(this);
6180 _writer.print(suffix); 6171 _writer.print(suffix);
6181 } 6172 }
6182 } 6173 }
6183 6174
6184 /** 6175 /**
6185 * Safely visit the given node, printing the prefix before the node if it is n on-<code>null</code> 6176 * Safely visit the given node, printing the prefix before the node if it is n on-<code>null</code>
6186 * . 6177 * .
6187 * @param prefix the prefix to be printed if there is a node to visit 6178 * @param prefix the prefix to be printed if there is a node to visit
6188 * @param node the node to be visited 6179 * @param node the node to be visited
6189 */ 6180 */
6190 void visit7(String prefix, ASTNode node) { 6181 void visit7(String prefix, ASTNode node) {
6191 if (node != null) { 6182 if (node != null) {
6192 _writer.print(prefix); 6183 _writer.print(prefix);
6193 node.accept(this); 6184 node.accept(this);
6194 } 6185 }
6195 } 6186 }
6196 6187
6197 /** 6188 /**
6198 * Safely visit the given node, printing the suffix after the node if it is no n-<code>null</code>. 6189 * Safely visit the given node, printing the suffix after the node if it is no n-<code>null</code>.
6199 * @param suffix the suffix to be printed if there is a node to visit 6190 * @param suffix the suffix to be printed if there is a node to visit
6200 * @param node the node to be visited 6191 * @param node the node to be visited
6201 */ 6192 */
6202 void visit8(Token token, String suffix) { 6193 void visit8(Token token, String suffix) {
6203 if (token != null) { 6194 if (token != null) {
6204 _writer.print(token.lexeme); 6195 _writer.print(token.lexeme);
6205 _writer.print(suffix); 6196 _writer.print(suffix);
6206 } 6197 }
6207 } 6198 }
6208 6199
6209 /** 6200 /**
6210 * Print a list of nodes without any separation. 6201 * Print a list of nodes without any separation.
6211 * @param nodes the nodes to be printed 6202 * @param nodes the nodes to be printed
6212 * @param separator the separator to be printed between adjacent nodes 6203 * @param separator the separator to be printed between adjacent nodes
6213 */ 6204 */
6214 void visitList(NodeList<ASTNode> nodes) { 6205 void visitList(NodeList<ASTNode> nodes) {
6215 visitList5(nodes, ""); 6206 visitList5(nodes, "");
6216 } 6207 }
6217 6208
6218 /** 6209 /**
6219 * Print a list of nodes, separated by the given separator. 6210 * Print a list of nodes, separated by the given separator.
6220 * @param nodes the nodes to be printed 6211 * @param nodes the nodes to be printed
6221 * @param separator the separator to be printed between adjacent nodes 6212 * @param separator the separator to be printed between adjacent nodes
6222 */ 6213 */
6223 void visitList5(NodeList<ASTNode> nodes, String separator) { 6214 void visitList5(NodeList<ASTNode> nodes, String separator) {
6224 if (nodes != null) { 6215 if (nodes != null) {
6225 int size2 = nodes.length; 6216 int size2 = nodes.length;
6226 for (int i = 0; i < size2; i++) { 6217 for (int i = 0; i < size2; i++) {
6227 if ("\n" == separator) { 6218 if ("\n" == separator) {
6228 _writer.print("\n"); 6219 _writer.print("\n");
6229 indent(); 6220 indent();
6230 } else if (i > 0) { 6221 } else if (i > 0) {
6231 _writer.print(separator); 6222 _writer.print(separator);
6232 } 6223 }
6233 nodes[i].accept(this); 6224 nodes[i].accept(this);
6234 } 6225 }
6235 } 6226 }
6236 } 6227 }
6237 6228
6238 /** 6229 /**
6239 * Print a list of nodes, separated by the given separator. 6230 * Print a list of nodes, separated by the given separator.
6240 * @param nodes the nodes to be printed 6231 * @param nodes the nodes to be printed
6241 * @param separator the separator to be printed between adjacent nodes 6232 * @param separator the separator to be printed between adjacent nodes
6242 * @param suffix the suffix to be printed if the list is not empty 6233 * @param suffix the suffix to be printed if the list is not empty
6243 */ 6234 */
6244 void visitList6(NodeList<ASTNode> nodes, String separator, String suffix) { 6235 void visitList6(NodeList<ASTNode> nodes, String separator, String suffix) {
6245 if (nodes != null) { 6236 if (nodes != null) {
6246 int size2 = nodes.length; 6237 int size2 = nodes.length;
6247 if (size2 > 0) { 6238 if (size2 > 0) {
6248 for (int i = 0; i < size2; i++) { 6239 for (int i = 0; i < size2; i++) {
6249 if (i > 0) { 6240 if (i > 0) {
6250 _writer.print(separator); 6241 _writer.print(separator);
6251 } 6242 }
6252 nodes[i].accept(this); 6243 nodes[i].accept(this);
6253 } 6244 }
6254 _writer.print(suffix); 6245 _writer.print(suffix);
6255 } 6246 }
6256 } 6247 }
6257 } 6248 }
6258 6249
6259 /** 6250 /**
6260 * Print a list of nodes, separated by the given separator. 6251 * Print a list of nodes, separated by the given separator.
6261 * @param prefix the prefix to be printed if the list is not empty 6252 * @param prefix the prefix to be printed if the list is not empty
6262 * @param nodes the nodes to be printed 6253 * @param nodes the nodes to be printed
6263 * @param separator the separator to be printed between adjacent nodes 6254 * @param separator the separator to be printed between adjacent nodes
6264 */ 6255 */
6265 void visitList7(String prefix, NodeList<ASTNode> nodes, String separator) { 6256 void visitList7(String prefix, NodeList<ASTNode> nodes, String separator) {
6266 if (nodes != null) { 6257 if (nodes != null) {
6267 int size2 = nodes.length; 6258 int size2 = nodes.length;
6268 if (size2 > 0) { 6259 if (size2 > 0) {
6269 _writer.print(prefix); 6260 _writer.print(prefix);
6270 for (int i = 0; i < size2; i++) { 6261 for (int i = 0; i < size2; i++) {
6271 if (i > 0) { 6262 if (i > 0) {
6272 _writer.print(separator); 6263 _writer.print(separator);
6273 } 6264 }
6274 nodes[i].accept(this); 6265 nodes[i].accept(this);
6275 } 6266 }
6276 } 6267 }
6277 } 6268 }
6278 } 6269 }
6279 } 6270 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698