OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library dart2js.parser.node_listener; | 5 library dart2js.parser.node_listener; |
6 | 6 |
7 import '../common.dart'; | 7 import '../common.dart'; |
8 import '../elements/elements.dart' show | 8 import '../elements/elements.dart' show CompilationUnitElement; |
9 CompilationUnitElement; | |
10 import '../native/native.dart' as native; | 9 import '../native/native.dart' as native; |
11 import '../tokens/precedence_constants.dart' as Precedence show | 10 import '../tokens/precedence_constants.dart' as Precedence |
12 BAD_INPUT_INFO, | 11 show BAD_INPUT_INFO, EOF_INFO, INDEX_INFO; |
13 EOF_INFO, | 12 import '../tokens/token.dart' show ErrorToken, StringToken, Token; |
14 INDEX_INFO; | |
15 import '../tokens/token.dart' show | |
16 ErrorToken, | |
17 StringToken, | |
18 Token; | |
19 import '../tree/tree.dart'; | 13 import '../tree/tree.dart'; |
20 import '../util/util.dart' show | 14 import '../util/util.dart' show Link; |
21 Link; | |
22 | 15 |
23 import 'element_listener.dart' show | 16 import 'element_listener.dart' show ElementListener, ScannerOptions; |
24 ElementListener, | 17 import 'partial_elements.dart' show PartialFunctionElement; |
25 ScannerOptions; | |
26 import 'partial_elements.dart' show | |
27 PartialFunctionElement; | |
28 | 18 |
29 class NodeListener extends ElementListener { | 19 class NodeListener extends ElementListener { |
30 NodeListener( | 20 NodeListener(ScannerOptions scannerOptions, DiagnosticReporter reporter, |
31 ScannerOptions scannerOptions, | |
32 DiagnosticReporter reporter, | |
33 CompilationUnitElement element) | 21 CompilationUnitElement element) |
34 : super(scannerOptions, reporter, element, null); | 22 : super(scannerOptions, reporter, element, null); |
35 | 23 |
36 void addLibraryTag(LibraryTag tag) { | 24 void addLibraryTag(LibraryTag tag) { |
37 pushNode(tag); | 25 pushNode(tag); |
38 } | 26 } |
39 | 27 |
40 void addPartOfTag(PartOf tag) { | 28 void addPartOfTag(PartOf tag) { |
41 pushNode(tag); | 29 pushNode(tag); |
42 } | 30 } |
43 | 31 |
44 void endClassDeclaration(int interfacesCount, Token beginToken, | 32 void endClassDeclaration(int interfacesCount, Token beginToken, |
45 Token extendsKeyword, Token implementsKeyword, | 33 Token extendsKeyword, Token implementsKeyword, Token endToken) { |
46 Token endToken) { | |
47 NodeList body = popNode(); | 34 NodeList body = popNode(); |
48 NodeList interfaces = | 35 NodeList interfaces = |
49 makeNodeList(interfacesCount, implementsKeyword, null, ","); | 36 makeNodeList(interfacesCount, implementsKeyword, null, ","); |
50 Node supertype = popNode(); | 37 Node supertype = popNode(); |
51 NodeList typeParameters = popNode(); | 38 NodeList typeParameters = popNode(); |
52 Identifier name = popNode(); | 39 Identifier name = popNode(); |
53 Modifiers modifiers = popNode(); | 40 Modifiers modifiers = popNode(); |
54 pushNode(new ClassNode(modifiers, name, typeParameters, supertype, | 41 pushNode(new ClassNode(modifiers, name, typeParameters, supertype, |
55 interfaces, beginToken, extendsKeyword, body, | 42 interfaces, beginToken, extendsKeyword, body, endToken)); |
56 endToken)); | |
57 } | 43 } |
58 | 44 |
59 void endCompilationUnit(int count, Token token) { | 45 void endCompilationUnit(int count, Token token) { |
60 pushNode(makeNodeList(count, null, null, '\n')); | 46 pushNode(makeNodeList(count, null, null, '\n')); |
61 } | 47 } |
62 | 48 |
63 void endFunctionTypeAlias(Token typedefKeyword, Token endToken) { | 49 void endFunctionTypeAlias(Token typedefKeyword, Token endToken) { |
64 NodeList formals = popNode(); | 50 NodeList formals = popNode(); |
65 NodeList typeParameters = popNode(); | 51 NodeList typeParameters = popNode(); |
66 Identifier name = popNode(); | 52 Identifier name = popNode(); |
67 TypeAnnotation returnType = popNode(); | 53 TypeAnnotation returnType = popNode(); |
68 pushNode(new Typedef(returnType, name, typeParameters, formals, | 54 pushNode(new Typedef( |
69 typedefKeyword, endToken)); | 55 returnType, name, typeParameters, formals, typedefKeyword, endToken)); |
70 } | 56 } |
71 | 57 |
72 void endNamedMixinApplication(Token classKeyword, | 58 void endNamedMixinApplication( |
73 Token implementsKeyword, | 59 Token classKeyword, Token implementsKeyword, Token endToken) { |
74 Token endToken) { | |
75 NodeList interfaces = (implementsKeyword != null) ? popNode() : null; | 60 NodeList interfaces = (implementsKeyword != null) ? popNode() : null; |
76 Node mixinApplication = popNode(); | 61 Node mixinApplication = popNode(); |
77 Modifiers modifiers = popNode(); | 62 Modifiers modifiers = popNode(); |
78 NodeList typeParameters = popNode(); | 63 NodeList typeParameters = popNode(); |
79 Identifier name = popNode(); | 64 Identifier name = popNode(); |
80 pushNode(new NamedMixinApplication(name, typeParameters, | 65 pushNode(new NamedMixinApplication(name, typeParameters, modifiers, |
81 modifiers, mixinApplication, | 66 mixinApplication, interfaces, classKeyword, endToken)); |
82 interfaces, | |
83 classKeyword, endToken)); | |
84 } | 67 } |
85 | 68 |
86 void endEnum(Token enumKeyword, Token endBrace, int count) { | 69 void endEnum(Token enumKeyword, Token endBrace, int count) { |
87 NodeList names = makeNodeList(count, enumKeyword.next.next, endBrace, ","); | 70 NodeList names = makeNodeList(count, enumKeyword.next.next, endBrace, ","); |
88 Identifier name = popNode(); | 71 Identifier name = popNode(); |
89 pushNode(new Enum(enumKeyword, name, names)); | 72 pushNode(new Enum(enumKeyword, name, names)); |
90 } | 73 } |
91 | 74 |
92 void endClassBody(int memberCount, Token beginToken, Token endToken) { | 75 void endClassBody(int memberCount, Token beginToken, Token endToken) { |
93 pushNode(makeNodeList(memberCount, beginToken, endToken, null)); | 76 pushNode(makeNodeList(memberCount, beginToken, endToken, null)); |
94 } | 77 } |
95 | 78 |
96 void endTopLevelFields(int count, Token beginToken, Token endToken) { | 79 void endTopLevelFields(int count, Token beginToken, Token endToken) { |
97 NodeList variables = makeNodeList(count, null, endToken, ","); | 80 NodeList variables = makeNodeList(count, null, endToken, ","); |
98 TypeAnnotation type = popNode(); | 81 TypeAnnotation type = popNode(); |
99 Modifiers modifiers = popNode(); | 82 Modifiers modifiers = popNode(); |
100 pushNode(new VariableDefinitions(type, modifiers, variables)); | 83 pushNode(new VariableDefinitions(type, modifiers, variables)); |
101 } | 84 } |
102 | 85 |
103 void endTopLevelMethod(Token beginToken, Token getOrSet, Token endToken) { | 86 void endTopLevelMethod(Token beginToken, Token getOrSet, Token endToken) { |
104 popNode(); // body | 87 popNode(); // body |
105 popNode(); // formalParameters | 88 popNode(); // formalParameters |
106 Identifier name = popNode(); | 89 Identifier name = popNode(); |
107 popNode(); // type | 90 popNode(); // type |
108 Modifiers modifiers = popNode(); | 91 Modifiers modifiers = popNode(); |
109 PartialFunctionElement element = new PartialFunctionElement( | 92 PartialFunctionElement element = new PartialFunctionElement(name.source, |
110 name.source, beginToken, getOrSet, endToken, | 93 beginToken, getOrSet, endToken, modifiers, compilationUnitElement); |
111 modifiers, compilationUnitElement); | |
112 pushElement(element); | 94 pushElement(element); |
113 } | 95 } |
114 | 96 |
115 void endFormalParameter(Token thisKeyword) { | 97 void endFormalParameter(Token thisKeyword) { |
116 Expression name = popNode(); | 98 Expression name = popNode(); |
117 if (thisKeyword != null) { | 99 if (thisKeyword != null) { |
118 Identifier thisIdentifier = new Identifier(thisKeyword); | 100 Identifier thisIdentifier = new Identifier(thisKeyword); |
119 if (name.asSend() == null) { | 101 if (name.asSend() == null) { |
120 name = new Send(thisIdentifier, name); | 102 name = new Send(thisIdentifier, name); |
121 } else { | 103 } else { |
(...skipping 16 matching lines...) Expand all Loading... |
138 } | 120 } |
139 | 121 |
140 void endArguments(int count, Token beginToken, Token endToken) { | 122 void endArguments(int count, Token beginToken, Token endToken) { |
141 pushNode(makeNodeList(count, beginToken, endToken, ",")); | 123 pushNode(makeNodeList(count, beginToken, endToken, ",")); |
142 } | 124 } |
143 | 125 |
144 void handleNoArguments(Token token) { | 126 void handleNoArguments(Token token) { |
145 pushNode(null); | 127 pushNode(null); |
146 } | 128 } |
147 | 129 |
148 void endConstructorReference(Token start, Token periodBeforeName, | 130 void endConstructorReference( |
149 Token endToken) { | 131 Token start, Token periodBeforeName, Token endToken) { |
150 Identifier name = null; | 132 Identifier name = null; |
151 if (periodBeforeName != null) { | 133 if (periodBeforeName != null) { |
152 name = popNode(); | 134 name = popNode(); |
153 } | 135 } |
154 NodeList typeArguments = popNode(); | 136 NodeList typeArguments = popNode(); |
155 Node classReference = popNode(); | 137 Node classReference = popNode(); |
156 if (typeArguments != null) { | 138 if (typeArguments != null) { |
157 classReference = new TypeAnnotation(classReference, typeArguments); | 139 classReference = new TypeAnnotation(classReference, typeArguments); |
158 } else { | 140 } else { |
159 Identifier identifier = classReference.asIdentifier(); | 141 Identifier identifier = classReference.asIdentifier(); |
160 Send send = classReference.asSend(); | 142 Send send = classReference.asSend(); |
161 if (identifier != null) { | 143 if (identifier != null) { |
162 // TODO(ahe): Should be: | 144 // TODO(ahe): Should be: |
163 // classReference = new Send(null, identifier); | 145 // classReference = new Send(null, identifier); |
164 classReference = identifier; | 146 classReference = identifier; |
165 } else if (send != null) { | 147 } else if (send != null) { |
166 classReference = send; | 148 classReference = send; |
167 } else { | 149 } else { |
168 internalError(node: classReference); | 150 internalError(node: classReference); |
169 } | 151 } |
170 } | 152 } |
171 Node constructor = classReference; | 153 Node constructor = classReference; |
172 if (name != null) { | 154 if (name != null) { |
173 // Either typeName<args>.name or x.y.name. | 155 // Either typeName<args>.name or x.y.name. |
174 constructor = new Send(classReference, name); | 156 constructor = new Send(classReference, name); |
175 } | 157 } |
176 pushNode(constructor); | 158 pushNode(constructor); |
177 } | 159 } |
178 | 160 |
179 void endRedirectingFactoryBody(Token beginToken, | 161 void endRedirectingFactoryBody(Token beginToken, Token endToken) { |
180 Token endToken) { | |
181 pushNode(new RedirectingFactoryBody(beginToken, endToken, popNode())); | 162 pushNode(new RedirectingFactoryBody(beginToken, endToken, popNode())); |
182 } | 163 } |
183 | 164 |
184 void endReturnStatement(bool hasExpression, | 165 void endReturnStatement( |
185 Token beginToken, Token endToken) { | 166 bool hasExpression, Token beginToken, Token endToken) { |
186 Expression expression = hasExpression ? popNode() : null; | 167 Expression expression = hasExpression ? popNode() : null; |
187 pushNode(new Return(beginToken, endToken, expression)); | 168 pushNode(new Return(beginToken, endToken, expression)); |
188 } | 169 } |
189 | 170 |
190 void endYieldStatement(Token yieldToken, Token starToken, Token endToken) { | 171 void endYieldStatement(Token yieldToken, Token starToken, Token endToken) { |
191 Expression expression = popNode(); | 172 Expression expression = popNode(); |
192 pushNode(new Yield(yieldToken, starToken, expression, endToken)); | 173 pushNode(new Yield(yieldToken, starToken, expression, endToken)); |
193 } | 174 } |
194 | 175 |
195 void endExpressionStatement(Token token) { | 176 void endExpressionStatement(Token token) { |
196 pushNode(new ExpressionStatement(popNode(), token)); | 177 pushNode(new ExpressionStatement(popNode(), token)); |
197 } | 178 } |
198 | 179 |
199 void handleOnError(Token token, var errorInformation) { | 180 void handleOnError(Token token, var errorInformation) { |
200 reporter.internalError(token, "'${token.value}': ${errorInformation}"); | 181 reporter.internalError(token, "'${token.value}': ${errorInformation}"); |
201 } | 182 } |
202 | 183 |
203 Token expectedFunctionBody(Token token) { | 184 Token expectedFunctionBody(Token token) { |
204 if (identical(token.stringValue, 'native')) { | 185 if (identical(token.stringValue, 'native')) { |
205 return native.handleNativeFunctionBody(this, token); | 186 return native.handleNativeFunctionBody(this, token); |
206 } else if (token is ErrorToken) { | 187 } else if (token is ErrorToken) { |
207 pushNode(null); | 188 pushNode(null); |
208 reportErrorToken(token); | 189 reportErrorToken(token); |
209 } else { | 190 } else { |
210 reportFatalError(token, | 191 reportFatalError( |
211 "Expected a function body, but got '${token.value}'."); | 192 token, "Expected a function body, but got '${token.value}'."); |
212 } | 193 } |
213 return skipToEof(token); | 194 return skipToEof(token); |
214 } | 195 } |
215 | 196 |
216 Token expectedClassBody(Token token) { | 197 Token expectedClassBody(Token token) { |
217 if (token is ErrorToken) { | 198 if (token is ErrorToken) { |
218 reportErrorToken(token); | 199 reportErrorToken(token); |
219 return skipToEof(token); | 200 return skipToEof(token); |
220 } else { | 201 } else { |
221 reportFatalError(token, | 202 reportFatalError( |
222 "Expected a class body, but got '${token.value}'."); | 203 token, "Expected a class body, but got '${token.value}'."); |
223 return skipToEof(token); | 204 return skipToEof(token); |
224 } | 205 } |
225 } | 206 } |
226 | 207 |
227 void handleLiteralInt(Token token) { | 208 void handleLiteralInt(Token token) { |
228 pushNode(new LiteralInt(token, (t, e) => handleOnError(t, e))); | 209 pushNode(new LiteralInt(token, (t, e) => handleOnError(t, e))); |
229 } | 210 } |
230 | 211 |
231 void handleLiteralDouble(Token token) { | 212 void handleLiteralDouble(Token token) { |
232 pushNode(new LiteralDouble(token, (t, e) => handleOnError(t, e))); | 213 pushNode(new LiteralDouble(token, (t, e) => handleOnError(t, e))); |
(...skipping 16 matching lines...) Expand all Loading... |
249 Node argument = popNode(); | 230 Node argument = popNode(); |
250 Node receiver = popNode(); | 231 Node receiver = popNode(); |
251 String tokenString = token.stringValue; | 232 String tokenString = token.stringValue; |
252 if (identical(tokenString, '.') || | 233 if (identical(tokenString, '.') || |
253 identical(tokenString, '..') || | 234 identical(tokenString, '..') || |
254 identical(tokenString, '?.')) { | 235 identical(tokenString, '?.')) { |
255 Send argumentSend = argument.asSend(); | 236 Send argumentSend = argument.asSend(); |
256 if (argumentSend == null) { | 237 if (argumentSend == null) { |
257 // TODO(ahe): The parser should diagnose this problem, not | 238 // TODO(ahe): The parser should diagnose this problem, not |
258 // this listener. | 239 // this listener. |
259 reportFatalError(argument, | 240 reportFatalError(argument, 'Expected an identifier.'); |
260 'Expected an identifier.'); | |
261 } | 241 } |
262 if (argumentSend.receiver != null) internalError(node: argument); | 242 if (argumentSend.receiver != null) internalError(node: argument); |
263 if (argument is SendSet) internalError(node: argument); | 243 if (argument is SendSet) internalError(node: argument); |
264 pushNode(argument.asSend().copyWithReceiver(receiver, | 244 pushNode(argument |
265 identical(tokenString, '?.'))); | 245 .asSend() |
| 246 .copyWithReceiver(receiver, identical(tokenString, '?.'))); |
266 } else { | 247 } else { |
267 NodeList arguments = new NodeList.singleton(argument); | 248 NodeList arguments = new NodeList.singleton(argument); |
268 pushNode(new Send(receiver, new Operator(token), arguments)); | 249 pushNode(new Send(receiver, new Operator(token), arguments)); |
269 } | 250 } |
270 if (identical(tokenString, '===')) { | 251 if (identical(tokenString, '===')) { |
271 reporter.reportErrorMessage( | 252 reporter.reportErrorMessage(token, MessageKind.UNSUPPORTED_EQ_EQ_EQ, |
272 token, | |
273 MessageKind.UNSUPPORTED_EQ_EQ_EQ, | |
274 {'lhs': receiver, 'rhs': argument}); | 253 {'lhs': receiver, 'rhs': argument}); |
275 } | 254 } |
276 if (identical(tokenString, '!==')) { | 255 if (identical(tokenString, '!==')) { |
277 reporter.reportErrorMessage( | 256 reporter.reportErrorMessage(token, MessageKind.UNSUPPORTED_BANG_EQ_EQ, |
278 token, | |
279 MessageKind.UNSUPPORTED_BANG_EQ_EQ, | |
280 {'lhs': receiver, 'rhs': argument}); | 257 {'lhs': receiver, 'rhs': argument}); |
281 } | 258 } |
282 } | 259 } |
283 | 260 |
284 void beginCascade(Token token) { | 261 void beginCascade(Token token) { |
285 pushNode(new CascadeReceiver(popNode(), token)); | 262 pushNode(new CascadeReceiver(popNode(), token)); |
286 } | 263 } |
287 | 264 |
288 void endCascade() { | 265 void endCascade() { |
289 pushNode(new Cascade(popNode())); | 266 pushNode(new Cascade(popNode())); |
(...skipping 16 matching lines...) Expand all Loading... |
306 if (send.asSendSet() != null) internalError(node: send); | 283 if (send.asSendSet() != null) internalError(node: send); |
307 NodeList arguments; | 284 NodeList arguments; |
308 if (send.isIndex) { | 285 if (send.isIndex) { |
309 Link<Node> link = const Link<Node>().prepend(arg); | 286 Link<Node> link = const Link<Node>().prepend(arg); |
310 link = link.prepend(send.arguments.head); | 287 link = link.prepend(send.arguments.head); |
311 arguments = new NodeList(null, link); | 288 arguments = new NodeList(null, link); |
312 } else { | 289 } else { |
313 arguments = new NodeList.singleton(arg); | 290 arguments = new NodeList.singleton(arg); |
314 } | 291 } |
315 Operator op = new Operator(token); | 292 Operator op = new Operator(token); |
316 pushNode(new SendSet(send.receiver, send.selector, op, arguments, | 293 pushNode(new SendSet( |
317 send.isConditional)); | 294 send.receiver, send.selector, op, arguments, send.isConditional)); |
318 } | 295 } |
319 | 296 |
320 void reportNotAssignable(Node node) { | 297 void reportNotAssignable(Node node) { |
321 // TODO(ahe): The parser should diagnose this problem, not this | 298 // TODO(ahe): The parser should diagnose this problem, not this |
322 // listener. | 299 // listener. |
323 reportFatalError(node, | 300 reportFatalError(node, 'Not assignable.'); |
324 'Not assignable.'); | |
325 } | 301 } |
326 | 302 |
327 void handleConditionalExpression(Token question, Token colon) { | 303 void handleConditionalExpression(Token question, Token colon) { |
328 Node elseExpression = popNode(); | 304 Node elseExpression = popNode(); |
329 Node thenExpression = popNode(); | 305 Node thenExpression = popNode(); |
330 Node condition = popNode(); | 306 Node condition = popNode(); |
331 pushNode(new Conditional( | 307 pushNode(new Conditional( |
332 condition, thenExpression, elseExpression, question, colon)); | 308 condition, thenExpression, elseExpression, question, colon)); |
333 } | 309 } |
334 | 310 |
(...skipping 30 matching lines...) Expand all Loading... |
365 | 341 |
366 void endFunction(Token getOrSet, Token endToken) { | 342 void endFunction(Token getOrSet, Token endToken) { |
367 Statement body = popNode(); | 343 Statement body = popNode(); |
368 AsyncModifier asyncModifier = popNode(); | 344 AsyncModifier asyncModifier = popNode(); |
369 NodeList initializers = popNode(); | 345 NodeList initializers = popNode(); |
370 NodeList formals = popNode(); | 346 NodeList formals = popNode(); |
371 // The name can be an identifier or a send in case of named constructors. | 347 // The name can be an identifier or a send in case of named constructors. |
372 Expression name = popNode(); | 348 Expression name = popNode(); |
373 TypeAnnotation type = popNode(); | 349 TypeAnnotation type = popNode(); |
374 Modifiers modifiers = popNode(); | 350 Modifiers modifiers = popNode(); |
375 pushNode(new FunctionExpression(name, formals, body, type, | 351 pushNode(new FunctionExpression(name, formals, body, type, modifiers, |
376 modifiers, initializers, getOrSet, | 352 initializers, getOrSet, asyncModifier)); |
377 asyncModifier)); | |
378 } | 353 } |
379 | 354 |
380 void endFunctionDeclaration(Token endToken) { | 355 void endFunctionDeclaration(Token endToken) { |
381 pushNode(new FunctionDeclaration(popNode())); | 356 pushNode(new FunctionDeclaration(popNode())); |
382 } | 357 } |
383 | 358 |
384 void endVariablesDeclaration(int count, Token endToken) { | 359 void endVariablesDeclaration(int count, Token endToken) { |
385 // TODO(ahe): Pick one name for this concept, either | 360 // TODO(ahe): Pick one name for this concept, either |
386 // VariablesDeclaration or VariableDefinitions. | 361 // VariablesDeclaration or VariableDefinitions. |
387 NodeList variables = makeNodeList(count, null, endToken, ","); | 362 NodeList variables = makeNodeList(count, null, endToken, ","); |
(...skipping 11 matching lines...) Expand all Loading... |
399 pushNode(new SendSet(null, name, op, arguments)); | 374 pushNode(new SendSet(null, name, op, arguments)); |
400 } | 375 } |
401 | 376 |
402 void endIfStatement(Token ifToken, Token elseToken) { | 377 void endIfStatement(Token ifToken, Token elseToken) { |
403 Statement elsePart = (elseToken == null) ? null : popNode(); | 378 Statement elsePart = (elseToken == null) ? null : popNode(); |
404 Statement thenPart = popNode(); | 379 Statement thenPart = popNode(); |
405 ParenthesizedExpression condition = popNode(); | 380 ParenthesizedExpression condition = popNode(); |
406 pushNode(new If(condition, thenPart, elsePart, ifToken, elseToken)); | 381 pushNode(new If(condition, thenPart, elsePart, ifToken, elseToken)); |
407 } | 382 } |
408 | 383 |
409 void endForStatement(int updateExpressionCount, | 384 void endForStatement( |
410 Token beginToken, Token endToken) { | 385 int updateExpressionCount, Token beginToken, Token endToken) { |
411 Statement body = popNode(); | 386 Statement body = popNode(); |
412 NodeList updates = makeNodeList(updateExpressionCount, null, null, ','); | 387 NodeList updates = makeNodeList(updateExpressionCount, null, null, ','); |
413 Statement condition = popNode(); | 388 Statement condition = popNode(); |
414 Node initializer = popNode(); | 389 Node initializer = popNode(); |
415 pushNode(new For(initializer, condition, updates, body, beginToken)); | 390 pushNode(new For(initializer, condition, updates, body, beginToken)); |
416 } | 391 } |
417 | 392 |
418 void handleNoExpression(Token token) { | 393 void handleNoExpression(Token token) { |
419 pushNode(null); | 394 pushNode(null); |
420 } | 395 } |
421 | 396 |
422 void endDoWhileStatement(Token doKeyword, Token whileKeyword, | 397 void endDoWhileStatement( |
423 Token endToken) { | 398 Token doKeyword, Token whileKeyword, Token endToken) { |
424 Expression condition = popNode(); | 399 Expression condition = popNode(); |
425 Statement body = popNode(); | 400 Statement body = popNode(); |
426 pushNode(new DoWhile(body, condition, doKeyword, whileKeyword, endToken)); | 401 pushNode(new DoWhile(body, condition, doKeyword, whileKeyword, endToken)); |
427 } | 402 } |
428 | 403 |
429 void endWhileStatement(Token whileKeyword, Token endToken) { | 404 void endWhileStatement(Token whileKeyword, Token endToken) { |
430 Statement body = popNode(); | 405 Statement body = popNode(); |
431 Expression condition = popNode(); | 406 Expression condition = popNode(); |
432 pushNode(new While(condition, body, whileKeyword)); | 407 pushNode(new While(condition, body, whileKeyword)); |
433 } | 408 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
474 } | 449 } |
475 if (!(send.isPropertyAccess || send.isIndex)) { | 450 if (!(send.isPropertyAccess || send.isIndex)) { |
476 reportNotAssignable(node); | 451 reportNotAssignable(node); |
477 } | 452 } |
478 if (send.asSendSet() != null) internalError(node: send); | 453 if (send.asSendSet() != null) internalError(node: send); |
479 Node argument = null; | 454 Node argument = null; |
480 if (send.isIndex) argument = send.arguments.head; | 455 if (send.isIndex) argument = send.arguments.head; |
481 Operator op = new Operator(token); | 456 Operator op = new Operator(token); |
482 | 457 |
483 if (isPrefix) { | 458 if (isPrefix) { |
484 pushNode(new SendSet.prefix(send.receiver, send.selector, op, argument, | 459 pushNode(new SendSet.prefix( |
485 send.isConditional)); | 460 send.receiver, send.selector, op, argument, send.isConditional)); |
486 } else { | 461 } else { |
487 pushNode(new SendSet.postfix(send.receiver, send.selector, op, argument, | 462 pushNode(new SendSet.postfix( |
488 send.isConditional)); | 463 send.receiver, send.selector, op, argument, send.isConditional)); |
489 } | 464 } |
490 } | 465 } |
491 | 466 |
492 void handleUnaryPostfixAssignmentExpression(Token token) { | 467 void handleUnaryPostfixAssignmentExpression(Token token) { |
493 handleUnaryAssignmentExpression(token, false); | 468 handleUnaryAssignmentExpression(token, false); |
494 } | 469 } |
495 | 470 |
496 void handleUnaryPrefixAssignmentExpression(Token token) { | 471 void handleUnaryPrefixAssignmentExpression(Token token) { |
497 handleUnaryAssignmentExpression(token, true); | 472 handleUnaryAssignmentExpression(token, true); |
498 } | 473 } |
(...skipping 15 matching lines...) Expand all Loading... |
514 | 489 |
515 void endMethod(Token getOrSet, Token beginToken, Token endToken) { | 490 void endMethod(Token getOrSet, Token beginToken, Token endToken) { |
516 Statement body = popNode(); | 491 Statement body = popNode(); |
517 AsyncModifier asyncModifier = popNode(); | 492 AsyncModifier asyncModifier = popNode(); |
518 NodeList initializers = popNode(); | 493 NodeList initializers = popNode(); |
519 NodeList formalParameters = popNode(); | 494 NodeList formalParameters = popNode(); |
520 Expression name = popNode(); | 495 Expression name = popNode(); |
521 TypeAnnotation returnType = popNode(); | 496 TypeAnnotation returnType = popNode(); |
522 Modifiers modifiers = popNode(); | 497 Modifiers modifiers = popNode(); |
523 pushNode(new FunctionExpression(name, formalParameters, body, returnType, | 498 pushNode(new FunctionExpression(name, formalParameters, body, returnType, |
524 modifiers, initializers, getOrSet, | 499 modifiers, initializers, getOrSet, asyncModifier)); |
525 asyncModifier)); | |
526 } | 500 } |
527 | 501 |
528 void handleLiteralMap(int count, Token beginToken, Token constKeyword, | 502 void handleLiteralMap( |
529 Token endToken) { | 503 int count, Token beginToken, Token constKeyword, Token endToken) { |
530 NodeList entries = makeNodeList(count, beginToken, endToken, ','); | 504 NodeList entries = makeNodeList(count, beginToken, endToken, ','); |
531 NodeList typeArguments = popNode(); | 505 NodeList typeArguments = popNode(); |
532 pushNode(new LiteralMap(typeArguments, entries, constKeyword)); | 506 pushNode(new LiteralMap(typeArguments, entries, constKeyword)); |
533 } | 507 } |
534 | 508 |
535 void endLiteralMapEntry(Token colon, Token endToken) { | 509 void endLiteralMapEntry(Token colon, Token endToken) { |
536 Expression value = popNode(); | 510 Expression value = popNode(); |
537 Expression key = popNode(); | 511 Expression key = popNode(); |
538 pushNode(new LiteralMapEntry(key, colon, value)); | 512 pushNode(new LiteralMapEntry(key, colon, value)); |
539 } | 513 } |
540 | 514 |
541 void handleLiteralList(int count, Token beginToken, Token constKeyword, | 515 void handleLiteralList( |
542 Token endToken) { | 516 int count, Token beginToken, Token constKeyword, Token endToken) { |
543 NodeList elements = makeNodeList(count, beginToken, endToken, ','); | 517 NodeList elements = makeNodeList(count, beginToken, endToken, ','); |
544 pushNode(new LiteralList(popNode(), elements, constKeyword)); | 518 pushNode(new LiteralList(popNode(), elements, constKeyword)); |
545 } | 519 } |
546 | 520 |
547 void handleIndexedExpression(Token openSquareBracket, | 521 void handleIndexedExpression( |
548 Token closeSquareBracket) { | 522 Token openSquareBracket, Token closeSquareBracket) { |
549 NodeList arguments = | 523 NodeList arguments = |
550 makeNodeList(1, openSquareBracket, closeSquareBracket, null); | 524 makeNodeList(1, openSquareBracket, closeSquareBracket, null); |
551 Node receiver = popNode(); | 525 Node receiver = popNode(); |
552 Token token = new StringToken.fromString(Precedence.INDEX_INFO, '[]', | 526 Token token = new StringToken.fromString( |
553 openSquareBracket.charOffset); | 527 Precedence.INDEX_INFO, '[]', openSquareBracket.charOffset); |
554 Node selector = new Operator(token); | 528 Node selector = new Operator(token); |
555 pushNode(new Send(receiver, selector, arguments)); | 529 pushNode(new Send(receiver, selector, arguments)); |
556 } | 530 } |
557 | 531 |
558 void handleNewExpression(Token token) { | 532 void handleNewExpression(Token token) { |
559 NodeList arguments = popNode(); | 533 NodeList arguments = popNode(); |
560 Node name = popNode(); | 534 Node name = popNode(); |
561 pushNode(new NewExpression(token, new Send(null, name, arguments))); | 535 pushNode(new NewExpression(token, new Send(null, name, arguments))); |
562 } | 536 } |
563 | 537 |
(...skipping 10 matching lines...) Expand all Loading... |
574 Operator op = new Operator(token); | 548 Operator op = new Operator(token); |
575 pushNode(new Send(new Identifier(operatorKeyword), op, null)); | 549 pushNode(new Send(new Identifier(operatorKeyword), op, null)); |
576 } | 550 } |
577 | 551 |
578 void handleNamedArgument(Token colon) { | 552 void handleNamedArgument(Token colon) { |
579 Expression expression = popNode(); | 553 Expression expression = popNode(); |
580 Identifier name = popNode(); | 554 Identifier name = popNode(); |
581 pushNode(new NamedArgument(name, colon, expression)); | 555 pushNode(new NamedArgument(name, colon, expression)); |
582 } | 556 } |
583 | 557 |
584 void endOptionalFormalParameters(int count, | 558 void endOptionalFormalParameters( |
585 Token beginToken, Token endToken) { | 559 int count, Token beginToken, Token endToken) { |
586 pushNode(makeNodeList(count, beginToken, endToken, ',')); | 560 pushNode(makeNodeList(count, beginToken, endToken, ',')); |
587 } | 561 } |
588 | 562 |
589 void handleFunctionTypedFormalParameter(Token endToken) { | 563 void handleFunctionTypedFormalParameter(Token endToken) { |
590 NodeList formals = popNode(); | 564 NodeList formals = popNode(); |
591 Identifier name = popNode(); | 565 Identifier name = popNode(); |
592 TypeAnnotation returnType = popNode(); | 566 TypeAnnotation returnType = popNode(); |
593 pushNode(null); // Signal "no type" to endFormalParameter. | 567 pushNode(null); // Signal "no type" to endFormalParameter. |
594 pushNode(new FunctionExpression(name, formals, null, returnType, | 568 pushNode(new FunctionExpression( |
595 Modifiers.EMPTY, null, null, null)); | 569 name, formals, null, returnType, Modifiers.EMPTY, null, null, null)); |
596 } | 570 } |
597 | 571 |
598 void handleValuedFormalParameter(Token equals, Token token) { | 572 void handleValuedFormalParameter(Token equals, Token token) { |
599 Expression defaultValue = popNode(); | 573 Expression defaultValue = popNode(); |
600 Expression parameterName = popNode(); | 574 Expression parameterName = popNode(); |
601 pushNode(new SendSet(null, parameterName, new Operator(equals), | 575 pushNode(new SendSet(null, parameterName, new Operator(equals), |
602 new NodeList.singleton(defaultValue))); | 576 new NodeList.singleton(defaultValue))); |
603 } | 577 } |
604 | 578 |
605 void endTryStatement(int catchCount, Token tryKeyword, Token finallyKeyword) { | 579 void endTryStatement(int catchCount, Token tryKeyword, Token finallyKeyword) { |
606 Block finallyBlock = null; | 580 Block finallyBlock = null; |
607 if (finallyKeyword != null) { | 581 if (finallyKeyword != null) { |
608 finallyBlock = popNode(); | 582 finallyBlock = popNode(); |
609 } | 583 } |
610 NodeList catchBlocks = makeNodeList(catchCount, null, null, null); | 584 NodeList catchBlocks = makeNodeList(catchCount, null, null, null); |
611 Block tryBlock = popNode(); | 585 Block tryBlock = popNode(); |
612 pushNode(new TryStatement(tryBlock, catchBlocks, finallyBlock, | 586 pushNode(new TryStatement( |
613 tryKeyword, finallyKeyword)); | 587 tryBlock, catchBlocks, finallyBlock, tryKeyword, finallyKeyword)); |
614 } | 588 } |
615 | 589 |
616 void handleCaseMatch(Token caseKeyword, Token colon) { | 590 void handleCaseMatch(Token caseKeyword, Token colon) { |
617 pushNode(new CaseMatch(caseKeyword, popNode(), colon)); | 591 pushNode(new CaseMatch(caseKeyword, popNode(), colon)); |
618 } | 592 } |
619 | 593 |
620 void handleCatchBlock(Token onKeyword, Token catchKeyword) { | 594 void handleCatchBlock(Token onKeyword, Token catchKeyword) { |
621 Block block = popNode(); | 595 Block block = popNode(); |
622 NodeList formals = catchKeyword != null? popNode(): null; | 596 NodeList formals = catchKeyword != null ? popNode() : null; |
623 TypeAnnotation type = onKeyword != null ? popNode() : null; | 597 TypeAnnotation type = onKeyword != null ? popNode() : null; |
624 pushNode(new CatchBlock(type, formals, block, onKeyword, catchKeyword)); | 598 pushNode(new CatchBlock(type, formals, block, onKeyword, catchKeyword)); |
625 } | 599 } |
626 | 600 |
627 void endSwitchStatement(Token switchKeyword, Token endToken) { | 601 void endSwitchStatement(Token switchKeyword, Token endToken) { |
628 NodeList cases = popNode(); | 602 NodeList cases = popNode(); |
629 ParenthesizedExpression expression = popNode(); | 603 ParenthesizedExpression expression = popNode(); |
630 pushNode(new SwitchStatement(expression, cases, switchKeyword)); | 604 pushNode(new SwitchStatement(expression, cases, switchKeyword)); |
631 } | 605 } |
632 | 606 |
633 void endSwitchBlock(int caseCount, Token beginToken, Token endToken) { | 607 void endSwitchBlock(int caseCount, Token beginToken, Token endToken) { |
634 Link<Node> caseNodes = const Link<Node>(); | 608 Link<Node> caseNodes = const Link<Node>(); |
635 while (caseCount > 0) { | 609 while (caseCount > 0) { |
636 SwitchCase switchCase = popNode(); | 610 SwitchCase switchCase = popNode(); |
637 caseNodes = caseNodes.prepend(switchCase); | 611 caseNodes = caseNodes.prepend(switchCase); |
638 caseCount--; | 612 caseCount--; |
639 } | 613 } |
640 pushNode(new NodeList(beginToken, caseNodes, endToken, null)); | 614 pushNode(new NodeList(beginToken, caseNodes, endToken, null)); |
641 } | 615 } |
642 | 616 |
643 void handleSwitchCase(int labelCount, int caseCount, | 617 void handleSwitchCase(int labelCount, int caseCount, Token defaultKeyword, |
644 Token defaultKeyword, int statementCount, | 618 int statementCount, Token firstToken, Token endToken) { |
645 Token firstToken, Token endToken) { | |
646 NodeList statements = makeNodeList(statementCount, null, null, null); | 619 NodeList statements = makeNodeList(statementCount, null, null, null); |
647 NodeList labelsAndCases = | 620 NodeList labelsAndCases = |
648 makeNodeList(labelCount + caseCount, null, null, null); | 621 makeNodeList(labelCount + caseCount, null, null, null); |
649 pushNode(new SwitchCase(labelsAndCases, defaultKeyword, statements, | 622 pushNode( |
650 firstToken)); | 623 new SwitchCase(labelsAndCases, defaultKeyword, statements, firstToken)); |
651 } | 624 } |
652 | 625 |
653 void handleBreakStatement(bool hasTarget, | 626 void handleBreakStatement( |
654 Token breakKeyword, Token endToken) { | 627 bool hasTarget, Token breakKeyword, Token endToken) { |
655 Identifier target = null; | 628 Identifier target = null; |
656 if (hasTarget) { | 629 if (hasTarget) { |
657 target = popNode(); | 630 target = popNode(); |
658 } | 631 } |
659 pushNode(new BreakStatement(target, breakKeyword, endToken)); | 632 pushNode(new BreakStatement(target, breakKeyword, endToken)); |
660 } | 633 } |
661 | 634 |
662 void handleContinueStatement(bool hasTarget, | 635 void handleContinueStatement( |
663 Token continueKeyword, Token endToken) { | 636 bool hasTarget, Token continueKeyword, Token endToken) { |
664 Identifier target = null; | 637 Identifier target = null; |
665 if (hasTarget) { | 638 if (hasTarget) { |
666 target = popNode(); | 639 target = popNode(); |
667 } | 640 } |
668 pushNode(new ContinueStatement(target, continueKeyword, endToken)); | 641 pushNode(new ContinueStatement(target, continueKeyword, endToken)); |
669 } | 642 } |
670 | 643 |
671 void handleEmptyStatement(Token token) { | 644 void handleEmptyStatement(Token token) { |
672 pushNode(new EmptyStatement(token)); | 645 pushNode(new EmptyStatement(token)); |
673 } | 646 } |
(...skipping 17 matching lines...) Expand all Loading... |
691 handleModifier(modifier); | 664 handleModifier(modifier); |
692 modifierCount++; | 665 modifierCount++; |
693 modifier = modifier.next; | 666 modifier = modifier.next; |
694 } | 667 } |
695 assert(modifier.stringValue == "factory"); | 668 assert(modifier.stringValue == "factory"); |
696 handleModifier(modifier); | 669 handleModifier(modifier); |
697 modifierCount++; | 670 modifierCount++; |
698 handleModifiers(modifierCount); | 671 handleModifiers(modifierCount); |
699 Modifiers modifiers = popNode(); | 672 Modifiers modifiers = popNode(); |
700 | 673 |
701 pushNode(new FunctionExpression(name, formals, body, null, | 674 pushNode(new FunctionExpression( |
702 modifiers, null, null, asyncModifier)); | 675 name, formals, body, null, modifiers, null, null, asyncModifier)); |
703 } | 676 } |
704 | 677 |
705 void endForIn(Token awaitToken, Token forToken, | 678 void endForIn( |
706 Token inKeyword, Token endToken) { | 679 Token awaitToken, Token forToken, Token inKeyword, Token endToken) { |
707 Statement body = popNode(); | 680 Statement body = popNode(); |
708 Expression expression = popNode(); | 681 Expression expression = popNode(); |
709 Node declaredIdentifier = popNode(); | 682 Node declaredIdentifier = popNode(); |
710 if (awaitToken == null) { | 683 if (awaitToken == null) { |
711 pushNode(new SyncForIn(declaredIdentifier, expression, body, | 684 pushNode(new SyncForIn( |
712 forToken, inKeyword)); | 685 declaredIdentifier, expression, body, forToken, inKeyword)); |
713 } else { | 686 } else { |
714 pushNode(new AsyncForIn(declaredIdentifier, expression, body, awaitToken, | 687 pushNode(new AsyncForIn(declaredIdentifier, expression, body, awaitToken, |
715 forToken, inKeyword)); | 688 forToken, inKeyword)); |
716 } | 689 } |
717 } | 690 } |
718 | 691 |
719 void endMetadataStar(int count, bool forParameter) { | 692 void endMetadataStar(int count, bool forParameter) { |
720 // TODO(johnniwinther): Handle metadata for all node kinds. | 693 // TODO(johnniwinther): Handle metadata for all node kinds. |
721 if (forParameter) { | 694 if (forParameter) { |
722 if (0 == count) { | 695 if (0 == count) { |
723 pushNode(null); | 696 pushNode(null); |
724 } else { | 697 } else { |
725 pushNode(makeNodeList(count, null, null, ' ')); | 698 pushNode(makeNodeList(count, null, null, ' ')); |
726 } | 699 } |
727 } | 700 } |
728 } | 701 } |
729 | 702 |
730 void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) { | 703 void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) { |
731 NodeList arguments = popNode(); | 704 NodeList arguments = popNode(); |
732 if (arguments == null) { | 705 if (arguments == null) { |
733 // This is a constant expression. | 706 // This is a constant expression. |
734 Identifier name; | 707 Identifier name; |
735 if (periodBeforeName != null) { | 708 if (periodBeforeName != null) { |
736 name = popNode(); | 709 name = popNode(); |
737 } | 710 } |
738 NodeList typeArguments = popNode(); | 711 NodeList typeArguments = popNode(); |
739 Node receiver = popNode(); | 712 Node receiver = popNode(); |
740 if (typeArguments != null) { | 713 if (typeArguments != null) { |
741 receiver = new TypeAnnotation(receiver, typeArguments); | 714 receiver = new TypeAnnotation(receiver, typeArguments); |
742 recoverableError(typeArguments, | 715 recoverableError(typeArguments, 'Type arguments are not allowed here.'); |
743 'Type arguments are not allowed here.'); | |
744 } else { | 716 } else { |
745 Identifier identifier = receiver.asIdentifier(); | 717 Identifier identifier = receiver.asIdentifier(); |
746 Send send = receiver.asSend(); | 718 Send send = receiver.asSend(); |
747 if (identifier != null) { | 719 if (identifier != null) { |
748 receiver = new Send(null, identifier); | 720 receiver = new Send(null, identifier); |
749 } else if (send == null) { | 721 } else if (send == null) { |
750 internalError(node: receiver); | 722 internalError(node: receiver); |
751 } | 723 } |
752 } | 724 } |
753 Send send = receiver; | 725 Send send = receiver; |
754 if (name != null) { | 726 if (name != null) { |
755 send = new Send(receiver, name); | 727 send = new Send(receiver, name); |
756 } | 728 } |
757 pushNode(new Metadata(beginToken, send)); | 729 pushNode(new Metadata(beginToken, send)); |
758 } else { | 730 } else { |
759 // This is a const constructor call. | 731 // This is a const constructor call. |
760 endConstructorReference(beginToken, periodBeforeName, endToken); | 732 endConstructorReference(beginToken, periodBeforeName, endToken); |
761 Node constructor = popNode(); | 733 Node constructor = popNode(); |
762 pushNode(new Metadata(beginToken, | 734 pushNode(new Metadata(beginToken, |
763 new NewExpression(null, | 735 new NewExpression(null, new Send(null, constructor, arguments)))); |
764 new Send(null, constructor, arguments)))); | |
765 } | 736 } |
766 } | 737 } |
767 | 738 |
768 void handleAssertStatement(Token assertKeyword, | 739 void handleAssertStatement( |
769 Token commaToken, Token semicolonToken) { | 740 Token assertKeyword, Token commaToken, Token semicolonToken) { |
770 Node message; | 741 Node message; |
771 Node condition; | 742 Node condition; |
772 if (commaToken != null) { | 743 if (commaToken != null) { |
773 message = popNode(); | 744 message = popNode(); |
774 } | 745 } |
775 condition = popNode(); | 746 condition = popNode(); |
776 pushNode(new Assert(assertKeyword, condition, | 747 pushNode(new Assert(assertKeyword, condition, message, semicolonToken)); |
777 message, semicolonToken)); | |
778 } | 748 } |
779 | 749 |
780 void endUnnamedFunction(Token token) { | 750 void endUnnamedFunction(Token token) { |
781 Statement body = popNode(); | 751 Statement body = popNode(); |
782 AsyncModifier asyncModifier = popNode(); | 752 AsyncModifier asyncModifier = popNode(); |
783 NodeList formals = popNode(); | 753 NodeList formals = popNode(); |
784 pushNode(new FunctionExpression(null, formals, body, null, | 754 pushNode(new FunctionExpression( |
785 Modifiers.EMPTY, null, null, | 755 null, formals, body, null, Modifiers.EMPTY, null, null, asyncModifier)); |
786 asyncModifier)); | |
787 } | 756 } |
788 | 757 |
789 void handleIsOperator(Token operathor, Token not, Token endToken) { | 758 void handleIsOperator(Token operathor, Token not, Token endToken) { |
790 TypeAnnotation type = popNode(); | 759 TypeAnnotation type = popNode(); |
791 Expression expression = popNode(); | 760 Expression expression = popNode(); |
792 Node argument; | 761 Node argument; |
793 if (not != null) { | 762 if (not != null) { |
794 argument = new Send.prefix(type, new Operator(not)); | 763 argument = new Send.prefix(type, new Operator(not)); |
795 } else { | 764 } else { |
796 argument = type; | 765 argument = type; |
(...skipping 17 matching lines...) Expand all Loading... |
814 void log(message) { | 783 void log(message) { |
815 reporter.log(message); | 784 reporter.log(message); |
816 } | 785 } |
817 | 786 |
818 void internalError({Token token, Node node}) { | 787 void internalError({Token token, Node node}) { |
819 // TODO(ahe): This should call reporter.internalError. | 788 // TODO(ahe): This should call reporter.internalError. |
820 Spannable spannable = (token == null) ? node : token; | 789 Spannable spannable = (token == null) ? node : token; |
821 throw new SpannableAssertionFailure(spannable, 'Internal error in parser.'); | 790 throw new SpannableAssertionFailure(spannable, 'Internal error in parser.'); |
822 } | 791 } |
823 } | 792 } |
OLD | NEW |