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

Side by Side Diff: frog/leg/scanner/listener.dart

Issue 9873021: Move frog/leg to lib/compiler/implementation. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 8 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
« no previous file with comments | « frog/leg/scanner/keyword.dart ('k') | frog/leg/scanner/motile.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
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.
4
5 final bool VERBOSE = false;
6
7 class Listener {
8 void beginArguments(Token token) {
9 }
10
11 void endArguments(int count, Token beginToken, Token endToken) {
12 }
13
14 void beginBlock(Token token) {
15 }
16
17 void endBlock(int count, Token beginToken, Token endToken) {
18 }
19
20 void beginClassBody(Token token) {
21 }
22
23 void endClassBody(int memberCount, Token beginToken, Token endToken) {
24 }
25
26 void beginClassDeclaration(Token token) {
27 }
28
29 void endClassDeclaration(int interfacesCount, Token beginToken,
30 Token extendsKeyword, Token implementsKeyword,
31 Token endToken) {
32 }
33
34 void beginDoWhileStatement(Token token) {
35 }
36
37 void endDoWhileStatement(Token doKeyword, Token whileKeyword,
38 Token endToken) {
39 }
40
41 void beginExpressionStatement(Token token) {
42 }
43
44 void endExpressionStatement(Token token) {
45 }
46
47 void beginDefaultClause(Token token) {
48 }
49
50 void handleNoDefaultClause(Token token) {
51 }
52
53 void endDefaultClause(Token defaultKeyword) {
54 }
55
56 void beginFactoryMethod(Token token) {
57 }
58
59 void endFactoryMethod(Token factoryKeyword, Token periodBeforeName,
60 Token endToken) {
61 }
62
63 void beginFormalParameter(Token token) {
64 }
65
66 void endFormalParameter(Token token, Token thisKeyword) {
67 }
68
69 void beginFormalParameters(Token token) {
70 }
71
72 void endFormalParameters(int count, Token beginToken, Token endToken) {
73 }
74
75 void endFields(int count, Token beginToken, Token endToken) {
76 }
77
78 void beginForStatement(Token token) {
79 }
80
81 void endForStatement(int updateExpressionCount,
82 Token beginToken, Token endToken) {
83 }
84
85 void endForInStatement(Token beginToken, Token inKeyword, Token endToken) {
86 }
87
88 void beginFunction(Token token) {
89 }
90
91 void endFunction(Token getOrSet, Token endToken) {
92 }
93
94 void beginFunctionDeclaration(Token token) {
95 }
96
97 void endFunctionDeclaration(Token token) {
98 }
99
100 void beginFunctionBody(Token token) {
101 }
102
103 void endFunctionBody(int count, Token beginToken, Token endToken) {
104 }
105
106 void handleNoFunctionBody(Token token) {
107 }
108
109 void beginFunctionName(Token token) {
110 }
111
112 void endFunctionName(Token token) {
113 }
114
115 void beginFunctionTypeAlias(Token token) {
116 }
117
118 void endFunctionTypeAlias(Token typedefKeyword, Token endToken) {
119 }
120
121 void beginIfStatement(Token token) {
122 }
123
124 void endIfStatement(Token ifToken, Token elseToken) {
125 }
126
127 void beginInitializedIdentifier(Token token) {
128 }
129
130 void endInitializedIdentifier() {
131 }
132
133 void beginInitializer(Token token) {
134 }
135
136 void endInitializer(Token assignmentOperator) {
137 }
138
139 void beginInitializers(Token token) {
140 }
141
142 void endInitializers(int count, Token beginToken, Token endToken) {
143 }
144
145 void handleNoInitializers() {
146 }
147
148 void beginInterface(Token token) {
149 }
150
151 void endInterface(int supertypeCount, Token interfaceKeyword,
152 Token extendsKeyword, Token endToken) {
153 }
154
155 void beginLabeledStatement(Token token) {
156 }
157
158 void endLabeledStatement(Token colon) {
159 }
160
161 void beginLiteralMapEntry(Token token) {
162 }
163
164 void endLiteralMapEntry(Token colon, Token endToken) {
165 }
166
167 void beginLiteralString(Token token) {
168 }
169
170 void endLiteralString(int interpolationCount) {
171 }
172
173 void handleStringJuxtaposition(int literalCount) {
174 }
175
176 void beginMember(Token token) {
177 }
178
179 void endMethod(Token getOrSet, Token beginToken, Token endToken) {
180 }
181
182 void beginOptionalFormalParameters(Token token) {
183 }
184
185 void endOptionalFormalParameters(int count,
186 Token beginToken, Token endToken) {
187 }
188
189 void beginReturnStatement(Token token) {
190 }
191
192 void endReturnStatement(bool hasExpression,
193 Token beginToken, Token endToken) {
194 }
195
196 void beginScriptTag(Token token) {
197 }
198
199 void endScriptTag(bool hasPrefix, Token beginToken, Token endToken) {
200 }
201
202 void beginSend(Token token) {
203 }
204
205 void endSend(Token token) {
206 }
207
208 void beginSwitchStatement(Token token) {
209 }
210
211 void endSwitchStatement(Token switchKeyword, Token endToken) {
212 }
213
214 void beginSwitchBlock(Token token) {
215 }
216
217 void endSwitchBlock(int caseCount, Token beginToken, Token endToken) {
218 }
219
220 void beginThrowStatement(Token token) {
221 }
222
223 void endThrowStatement(Token throwToken, Token endToken) {
224 }
225
226 void endRethrowStatement(Token throwToken, Token endToken) {
227 }
228
229 void beginTopLevelMember(Token token) {
230 }
231
232 void endTopLevelFields(int count, Token beginToken, Token endToken) {
233 }
234
235 void endTopLevelMethod(Token beginToken, Token getOrSet, Token endToken) {
236 }
237
238 void beginTryStatement(Token token) {
239 }
240
241 void handleCatchBlock(Token catchKeyword) {
242 }
243
244 void handleFinallyBlock(Token finallyKeyword) {
245 }
246
247 void endTryStatement(int catchCount, Token tryKeyword, Token finallyKeyword) {
248 }
249
250 void endType(Token beginToken, Token endToken) {
251 }
252
253 void beginTypeArguments(Token token) {
254 }
255
256 void endTypeArguments(int count, Token beginToken, Token endToken) {
257 }
258
259 void handleNoTypeArguments(Token token) {
260 }
261
262 void beginTypeVariable(Token token) {
263 }
264
265 void endTypeVariable(Token token) {
266 }
267
268 void beginTypeVariables(Token token) {
269 }
270
271 void endTypeVariables(int count, Token beginToken, Token endToken) {
272 }
273
274 void beginUnamedFunction(Token token) {
275 }
276
277 void endUnamedFunction(Token token) {
278 }
279
280 void beginVariablesDeclaration(Token token) {
281 }
282
283 void endVariablesDeclaration(int count, Token endToken) {
284 }
285
286 void beginWhileStatement(Token token) {
287 }
288
289 void endWhileStatement(Token whileKeyword, Token endToken) {
290 }
291
292 void handleAssignmentExpression(Token token) {
293 }
294
295 void handleBinaryExpression(Token token) {
296 }
297
298 void handleConditionalExpression(Token question, Token colon) {
299 }
300
301 void handleConstExpression(Token token, bool named) {
302 }
303
304 void handleFunctionTypedFormalParameter(Token token) {
305 }
306
307 void handleIdentifier(Token token) {
308 }
309
310 void handleIndexedExpression(Token openCurlyBracket,
311 Token closeCurlyBracket) {
312 }
313
314 void handleIsOperator(Token operathor, Token not, Token endToken) {
315 // TODO(ahe): Rename [operathor] to "operator" when VM bug is fixed.
316 }
317
318 void handleLiteralBool(Token token) {
319 }
320
321 void handleBreakStatement(bool hasTarget,
322 Token breakKeyword, Token endToken) {
323 }
324
325 void handleContinueStatement(bool hasTarget,
326 Token continueKeyword, Token endToken) {
327 }
328
329 void handleEmptyStatement(Token token) {
330 }
331
332 /** Called with either the token containing a double literal, or
333 * an immediately preceding "unary plus" token.
334 */
335 void handleLiteralDouble(Token token) {
336 }
337
338 /** Called with either the token containing an integer literal,
339 * or an immediately preceding "unary plus" token.
340 */
341 void handleLiteralInt(Token token) {
342 }
343
344 void handleLiteralList(int count, Token beginToken, Token constKeyword,
345 Token endToken) {
346 }
347
348 void handleLiteralMap(int count, Token beginToken, Token constKeyword,
349 Token endToken) {
350 }
351
352 void handleLiteralNull(Token token) {
353 }
354
355 void handleModifier(Token token) {
356 }
357
358 void handleModifiers(int count) {
359 }
360
361 void handleNamedArgument(Token colon) {
362 }
363
364 void handleNewExpression(Token token, bool named) {
365 }
366
367 void handleNoArguments(Token token) {
368 }
369
370 void handleNoExpression(Token token) {
371 }
372
373 void handleNoType(Token token) {
374 }
375
376 void handleNoTypeVariables(Token token) {
377 }
378
379 void handleOperatorName(Token operatorKeyword, Token token) {
380 }
381
382 void handleParenthesizedExpression(BeginGroupToken token) {
383 }
384
385 void handleQualified(Token period) {
386 }
387
388 void handleStringPart(Token token) {
389 }
390
391 void handleSuperExpression(Token token) {
392 }
393
394 void handleSwitchCase(Token labelToken, int expressionCount,
395 Token defaultKeyword, int statementCount,
396 Token firstToken, Token endToken) {
397 }
398
399 void handleThisExpression(Token token) {
400 }
401
402 void handleUnaryPostfixAssignmentExpression(Token token) {
403 }
404
405 void handleUnaryPrefixExpression(Token token) {
406 }
407
408 void handleUnaryPrefixAssignmentExpression(Token token) {
409 }
410
411 void handleValuedFormalParameter(Token equals, Token token) {
412 }
413
414 void handleVoidKeyword(Token token) {
415 }
416
417 Token expected(String string, Token token) {
418 error("expected '$string', but got '${token.slowToString()}'", token);
419 return skipToEof(token);
420 }
421
422 void expectedIdentifier(Token token) {
423 error("expected identifier, but got '${token.slowToString()}'", token);
424 }
425
426 Token expectedType(Token token) {
427 error("expected a type, but got '${token.slowToString()}'", token);
428 return skipToEof(token);
429 }
430
431 Token expectedExpression(Token token) {
432 error("expected an expression, but got '${token.slowToString()}'", token);
433 return skipToEof(token);
434 }
435
436 Token unexpected(Token token) {
437 error("unexpected token '${token.slowToString()}'", token);
438 return skipToEof(token);
439 }
440
441 Token expectedBlockToSkip(Token token) {
442 error("expected a block, but got '${token.slowToString()}'", token);
443 return skipToEof(token);
444 }
445
446 Token expectedFunctionBody(Token token) {
447 error("expected a function body, but got '${token.slowToString()}'", token);
448 return skipToEof(token);
449 }
450
451 Token expectedClassBody(Token token) {
452 error("expected a class body, but got '${token.slowToString()}'", token);
453 return skipToEof(token);
454 }
455
456 Token expectedClassBodyToSkip(Token token) {
457 error("expected a class body, but got '${token.slowToString()}'", token);
458 return skipToEof(token);
459 }
460
461 skipToEof(Token token) {
462 while (token.info !== EOF_INFO) {
463 token = token.next;
464 }
465 return token;
466 }
467
468 void recoverableError(String message, [Token token, Node node]) {
469 if (token === null && node !== null) {
470 token = node.getBeginToken();
471 }
472 error(message, token);
473 }
474
475 void error(String message, Token token) {
476 throw new ParserError("$message @ ${token.charOffset}");
477 }
478 }
479
480 class ParserError {
481 final String reason;
482 ParserError(this.reason);
483 toString() => reason;
484 }
485
486 /**
487 * A listener for parser events.
488 */
489 class ElementListener extends Listener {
490 final DiagnosticListener listener;
491 final CompilationUnitElement compilationUnitElement;
492 final StringValidator stringValidator;
493 Link<StringQuoting> interpolationScope;
494
495 Link<Node> nodes = const EmptyLink<Node>();
496
497 ElementListener(DiagnosticListener listener,
498 CompilationUnitElement this.compilationUnitElement)
499 : this.listener = listener,
500 stringValidator = new StringValidator(listener),
501 interpolationScope = const EmptyLink<StringQuoting>();
502
503 void pushQuoting(StringQuoting quoting) {
504 interpolationScope = interpolationScope.prepend(quoting);
505 }
506
507 StringQuoting popQuoting() {
508 StringQuoting result = interpolationScope.head;
509 interpolationScope = interpolationScope.tail;
510 return result;
511 }
512
513 LiteralString popLiteralString() {
514 StringNode node = popNode();
515 // TODO(lrn): Handle interpolations in script tags.
516 if (node.isInterpolation) {
517 listener.cancel("String interpolation not supported in library tags",
518 node: node);
519 return null;
520 }
521 return node;
522 }
523
524 void endScriptTag(bool hasPrefix, Token beginToken, Token endToken) {
525 StringNode prefix = null;
526 Identifier argumentName = null;
527 if (hasPrefix) {
528 prefix = popLiteralString();
529 argumentName = popNode();
530 }
531 StringNode firstArgument = popLiteralString();
532 Identifier tag = popNode();
533 compilationUnitElement.addTag(new ScriptTag(tag, firstArgument,
534 argumentName, prefix,
535 beginToken, endToken),
536 listener);
537 }
538
539 void endClassDeclaration(int interfacesCount, Token beginToken,
540 Token extendsKeyword, Token implementsKeyword,
541 Token endToken) {
542 SourceString nativeName = native.checkForNativeClass(this);
543 NodeList interfaces =
544 makeNodeList(interfacesCount, implementsKeyword, null, ",");
545 TypeAnnotation supertype = popNode();
546 NodeList typeParameters = popNode();
547 Identifier name = popNode();
548 ClassElement element = new PartialClassElement(
549 name.source, beginToken, endToken, compilationUnitElement);
550 element.nativeName = nativeName;
551 pushElement(element);
552 }
553
554 void endDefaultClause(Token defaultKeyword) {
555 NodeList typeParameters = popNode();
556 Node name = popNode();
557 pushNode(new TypeAnnotation(name, typeParameters));
558 }
559
560 void handleNoDefaultClause(Token token) {
561 pushNode(null);
562 }
563
564 void endInterface(int supertypeCount, Token interfaceKeyword,
565 Token extendsKeyword, Token endToken) {
566 // TODO(ahe): Record the defaultClause.
567 Node defaultClause = popNode();
568 NodeList supertypes =
569 makeNodeList(supertypeCount, extendsKeyword, null, ",");
570 NodeList typeParameters = popNode();
571 Identifier name = popNode();
572 pushElement(new PartialClassElement(name.source, interfaceKeyword,
573 endToken,
574 compilationUnitElement));
575 }
576
577 void endFunctionTypeAlias(Token typedefKeyword, Token endToken) {
578 NodeList typeVariables = popNode(); // TOOD(karlklose): do not throw away.
579 Identifier name = popNode();
580 TypeAnnotation returnType = popNode();
581 pushElement(new TypedefElement(name.source, compilationUnitElement,
582 typedefKeyword));
583 }
584
585 void handleVoidKeyword(Token token) {
586 pushNode(new TypeAnnotation(new Identifier(token), null));
587 }
588
589 void endTopLevelMethod(Token beginToken, Token getOrSet, Token endToken) {
590 Identifier name = popNode();
591 Modifiers modifiers = popNode();
592 ElementKind kind;
593 if (getOrSet === null) {
594 kind = ElementKind.FUNCTION;
595 } else if (getOrSet.stringValue === 'get') {
596 kind = ElementKind.GETTER;
597 } else if (getOrSet.stringValue === 'set') {
598 kind = ElementKind.SETTER;
599 }
600 pushElement(new PartialFunctionElement(name.source, beginToken, getOrSet,
601 endToken, kind,
602 modifiers, compilationUnitElement));
603 }
604
605 void endTopLevelFields(int count, Token beginToken, Token endToken) {
606 void buildFieldElement(SourceString name, Element fields) {
607 pushElement(new VariableElement(
608 name, fields, ElementKind.FIELD, compilationUnitElement));
609 }
610 NodeList variables = makeNodeList(count, null, null, ",");
611 Modifiers modifiers = popNode();
612 buildFieldElements(modifiers, variables, compilationUnitElement,
613 buildFieldElement,
614 beginToken, endToken);
615 }
616
617 void buildFieldElements(Modifiers modifiers,
618 NodeList variables,
619 ContainerElement enclosingElement,
620 void buildFieldElement(SourceString name,
621 Element fields),
622 Token beginToken, Token endToken) {
623 Element fields = new PartialFieldListElement(beginToken,
624 endToken,
625 modifiers,
626 enclosingElement);
627 for (Link<Node> nodes = variables.nodes; !nodes.isEmpty();
628 nodes = nodes.tail) {
629 Expression initializedIdentifier = nodes.head;
630 Identifier identifier = initializedIdentifier.asIdentifier();
631 if (identifier === null) {
632 identifier = initializedIdentifier.asSendSet().selector.asIdentifier();
633 }
634 SourceString name = identifier.source;
635 buildFieldElement(name, fields);
636 }
637 }
638
639 void handleIdentifier(Token token) {
640 pushNode(new Identifier(token));
641 }
642
643 void handleQualified(Token period) {
644 Identifier last = popNode();
645 Identifier first = popNode();
646 pushNode(new Send(first, last));
647 }
648
649 void handleNoType(Token token) {
650 pushNode(null);
651 }
652
653 void endTypeVariable(Token token) {
654 TypeAnnotation bound = popNode();
655 Identifier name = popNode();
656 pushNode(new TypeVariable(name, bound));
657 }
658
659 void endTypeVariables(int count, Token beginToken, Token endToken) {
660 pushNode(makeNodeList(count, beginToken, endToken, ','));
661 }
662
663 void handleNoTypeVariables(token) {
664 pushNode(null);
665 }
666
667 void endTypeArguments(int count, Token beginToken, Token endToken) {
668 pushNode(makeNodeList(count, beginToken, endToken, ','));
669 }
670
671 void handleNoTypeArguments(Token token) {
672 pushNode(null);
673 }
674
675 void endType(Token beginToken, Token endToken) {
676 NodeList typeArguments = popNode();
677 Expression typeName = popNode();
678 pushNode(new TypeAnnotation(typeName, typeArguments));
679 }
680
681 void handleParenthesizedExpression(BeginGroupToken token) {
682 Expression expression = popNode();
683 pushNode(new ParenthesizedExpression(expression, token));
684 }
685
686 void handleModifier(Token token) {
687 pushNode(new Identifier(token));
688 }
689
690 void handleModifiers(int count) {
691 NodeList nodes = makeNodeList(count, null, null, null);
692 pushNode(new Modifiers(nodes));
693 }
694
695 Token expected(String string, Token token) {
696 listener.cancel("expected '$string', but got '${token.slowToString()}'",
697 token: token);
698 return skipToEof(token);
699 }
700
701 void expectedIdentifier(Token token) {
702 listener.cancel("expected identifier, but got '${token.slowToString()}'",
703 token: token);
704 pushNode(null);
705 }
706
707 Token expectedType(Token token) {
708 listener.cancel("expected a type, but got '${token.slowToString()}'",
709 token: token);
710 pushNode(null);
711 return skipToEof(token);
712 }
713
714 Token expectedExpression(Token token) {
715 listener.cancel("expected an expression, but got '${token.slowToString()}'",
716 token: token);
717 pushNode(null);
718 return skipToEof(token);
719 }
720
721 Token unexpected(Token token) {
722 listener.cancel("unexpected token '${token.slowToString()}'", token: token);
723 return skipToEof(token);
724 }
725
726 Token expectedBlockToSkip(Token token) {
727 if (token.stringValue === 'native') {
728 return native.handleNativeBlockToSkip(this, token);
729 } else {
730 return unexpected(token);
731 }
732 }
733
734 Token expectedFunctionBody(Token token) {
735 String printString = token.slowToString();
736 listener.cancel("expected a function body, but got '$printString'",
737 token: token);
738 return skipToEof(token);
739 }
740
741 Token expectedClassBody(Token token) {
742 listener.cancel("expected a class body, but got '${token.slowToString()}'",
743 token: token);
744 return skipToEof(token);
745 }
746
747 Token expectedClassBodyToSkip(Token token) {
748 if (token.stringValue === 'native') {
749 return native.handleNativeClassBodyToSkip(this, token);
750 } else {
751 return unexpected(token);
752 }
753 }
754
755 void recoverableError(String message, [Token token, Node node]) {
756 listener.cancel(message, token: token, node: node);
757 }
758
759 void pushElement(Element element) {
760 compilationUnitElement.addMember(element, listener);
761 }
762
763 void pushNode(Node node) {
764 nodes = nodes.prepend(node);
765 if (VERBOSE) log("push $nodes");
766 }
767
768 Node popNode() {
769 assert(!nodes.isEmpty());
770 Node node = nodes.head;
771 nodes = nodes.tail;
772 if (VERBOSE) log("pop $nodes");
773 return node;
774 }
775
776 Node peekNode() {
777 assert(!nodes.isEmpty());
778 Node node = nodes.head;
779 if (VERBOSE) log("peek $node");
780 return node;
781 }
782
783 void log(message) {
784 print(message);
785 }
786
787 NodeList makeNodeList(int count, Token beginToken, Token endToken,
788 String delimiter) {
789 Link<Node> nodes = const EmptyLink<Node>();
790 for (; count > 0; --count) {
791 // This effectively reverses the order of nodes so they end up
792 // in correct (source) order.
793 nodes = nodes.prepend(popNode());
794 }
795 SourceString sourceDelimiter =
796 (delimiter === null) ? null : new SourceString(delimiter);
797 return new NodeList(beginToken, nodes, endToken, sourceDelimiter);
798 }
799
800 void beginLiteralString(Token token) {
801 SourceString source = token.value;
802 StringQuoting quoting = StringValidator.quotingFromString(source);
803 pushQuoting(quoting);
804 // Just wrap the token for now. At the end of the interpolation,
805 // when we know how many there are, go back and validate the tokens.
806 pushNode(new LiteralString(token, null));
807 }
808
809 void handleStringPart(Token token) {
810 // Just push an unvalidated token now, and replace it when we know the
811 // end of the interpolation.
812 pushNode(new LiteralString(token, null));
813 }
814
815 void endLiteralString(int count) {
816 StringQuoting quoting = popQuoting();
817
818 Link<StringInterpolationPart> parts =
819 const EmptyLink<StringInterpolationPart>();
820 // Parts of the string interpolation are popped in reverse order,
821 // starting with the last literal string part.
822 bool isLast = true;
823 for (int i = 0; i < count; i++) {
824 LiteralString string = popNode();
825 DartString validation =
826 stringValidator.validateInterpolationPart(string.token, quoting,
827 isFirst: false,
828 isLast: isLast);
829 // Replace the unvalidated LiteralString with a new LiteralString
830 // object that has the validation result included.
831 string = new LiteralString(string.token, validation);
832 Expression expression = popNode();
833 parts = parts.prepend(new StringInterpolationPart(expression, string));
834 isLast = false;
835 }
836
837 LiteralString string = popNode();
838 DartString validation =
839 stringValidator.validateInterpolationPart(string.token, quoting,
840 isFirst: true,
841 isLast: isLast);
842 string = new LiteralString(string.token, validation);
843 if (isLast) {
844 pushNode(string);
845 } else {
846 NodeList nodes = new NodeList(null, parts, null, null);
847 pushNode(new StringInterpolation(string, nodes));
848 }
849 }
850
851 void handleStringJuxtaposition(int stringCount) {
852 assert(stringCount != 0);
853 Expression accumulator = popNode();
854 stringCount--;
855 while (stringCount > 0) {
856 Expression expression = popNode();
857 accumulator = new StringJuxtaposition(expression, accumulator);
858 stringCount--;
859 }
860 pushNode(accumulator);
861 }
862 }
863
864 class NodeListener extends ElementListener {
865 NodeListener(DiagnosticListener listener, CompilationUnitElement element)
866 : super(listener, element);
867
868 void endClassDeclaration(int interfacesCount, Token beginToken,
869 Token extendsKeyword, Token implementsKeyword,
870 Token endToken) {
871 NodeList body = popNode();
872 NodeList interfaces =
873 makeNodeList(interfacesCount, implementsKeyword, null, ",");
874 TypeAnnotation supertype = popNode();
875 NodeList typeParameters = popNode();
876 Identifier name = popNode();
877 pushNode(new ClassNode(name, typeParameters, supertype, interfaces, null,
878 beginToken, extendsKeyword, endToken));
879 }
880
881 void endFunctionTypeAlias(Token typedefKeyword, Token endToken) {
882 NodeList formals = popNode();
883 NodeList typeParameters = null; // TODO(ahe): Don't discard these.
884 Identifier name = popNode();
885 TypeAnnotation returnType = popNode();
886 pushNode(new Typedef(returnType, name, typeParameters, formals,
887 typedefKeyword, endToken));
888 }
889
890 void endInterface(int supertypeCount, Token interfaceKeyword,
891 Token extendsKeyword, Token endToken) {
892 NodeList body = popNode();
893 TypeAnnotation defaultClause = popNode();
894 NodeList supertypes = makeNodeList(supertypeCount, extendsKeyword,
895 null, ',');
896 NodeList typeParameters = popNode();
897 Identifier name = popNode();
898 pushNode(new ClassNode(name, typeParameters, null, supertypes,
899 defaultClause, interfaceKeyword, null, endToken));
900 }
901
902 void endClassBody(int memberCount, Token beginToken, Token endToken) {
903 pushNode(makeNodeList(memberCount, beginToken, endToken, null));
904 }
905
906 void endTopLevelFields(int count, Token beginToken, Token endToken) {
907 NodeList variables = makeNodeList(count, null, null, ",");
908 Modifiers modifiers = popNode();
909 pushNode(new VariableDefinitions(null, modifiers, variables, endToken));
910 }
911
912 void endTopLevelMethod(Token beginToken, Token getOrSet, Token endToken) {
913 Statement body = popNode();
914 NodeList formalParameters = popNode();
915 Identifier name = popNode();
916 Modifiers modifiers = popNode();
917 ElementKind kind;
918 if (getOrSet === null) {
919 kind = ElementKind.FUNCTION;
920 } else if (getOrSet.stringValue === 'get') {
921 kind = ElementKind.GETTER;
922 } else if (getOrSet.stringValue === 'set') {
923 kind = ElementKind.SETTER;
924 }
925 pushElement(new PartialFunctionElement(name.source, beginToken, getOrSet,
926 endToken, kind,
927 modifiers, compilationUnitElement));
928 }
929
930 void endFormalParameter(Token token, Token thisKeyword) {
931 Expression name = popNode();
932 if (thisKeyword !== null) {
933 Identifier thisIdentifier = new Identifier(thisKeyword);
934 if (name.asSend() === null) {
935 name = new Send(thisIdentifier, name);
936 } else {
937 name = name.asSend().copyWithReceiver(thisIdentifier);
938 }
939 }
940 TypeAnnotation type = popNode();
941 Modifiers modifiers = popNode();
942 pushNode(new VariableDefinitions(type, modifiers,
943 new NodeList.singleton(name), token));
944 }
945
946 void endFormalParameters(int count, Token beginToken, Token endToken) {
947 pushNode(makeNodeList(count, beginToken, endToken, ","));
948 }
949
950 void endArguments(int count, Token beginToken, Token endToken) {
951 pushNode(makeNodeList(count, beginToken, endToken, ","));
952 }
953
954 void handleNoArguments(Token token) {
955 pushNode(null);
956 }
957
958 void endReturnStatement(bool hasExpression,
959 Token beginToken, Token endToken) {
960 Expression expression = hasExpression ? popNode() : null;
961 pushNode(new Return(beginToken, endToken, expression));
962 }
963
964 void endExpressionStatement(Token token) {
965 pushNode(new ExpressionStatement(popNode(), token));
966 }
967
968 void handleOnError(Token token, var error) {
969 listener.cancel("internal error: '${token.value}': ${error}", token: token);
970 }
971
972 Token expectedFunctionBody(Token token) {
973 if (token.stringValue === 'native') {
974 return native.handleNativeFunctionBody(this, token);
975 } else {
976 listener.cancel(
977 "expected a function body, but got '${token.slowToString()}'",
978 token: token);
979 return skipToEof(token);
980 }
981 }
982
983 Token expectedClassBody(Token token) {
984 if (token.stringValue === 'native') {
985 return native.handleNativeClassBody(this, token);
986 } else {
987 listener.cancel(
988 "expected a class body, but got '${token.slowToString()}'",
989 token: token);
990 return skipToEof(token);
991 }
992 }
993
994 void handleLiteralInt(Token token) {
995 pushNode(new LiteralInt(token, (t, e) => handleOnError(t, e)));
996 }
997
998 void handleLiteralDouble(Token token) {
999 pushNode(new LiteralDouble(token, (t, e) => handleOnError(t, e)));
1000 }
1001
1002 void handleLiteralBool(Token token) {
1003 pushNode(new LiteralBool(token, (t, e) => handleOnError(t, e)));
1004 }
1005
1006 void handleLiteralNull(Token token) {
1007 pushNode(new LiteralNull(token));
1008 }
1009
1010 void handleBinaryExpression(Token token) {
1011 Node argument = popNode();
1012 Node receiver = popNode();
1013 if (token.stringValue === '.') {
1014 if (argument is !Send) internalError(node: argument);
1015 if (argument.asSend().receiver !== null) internalError(node: argument);
1016 if (argument is SendSet) internalError(node: argument);
1017 pushNode(argument.asSend().copyWithReceiver(receiver));
1018 } else {
1019 NodeList arguments = new NodeList.singleton(argument);
1020 pushNode(new Send(receiver, new Operator(token), arguments));
1021 }
1022 }
1023
1024 void handleAssignmentExpression(Token token) {
1025 Node arg = popNode();
1026 Node node = popNode();
1027 Send send = node.asSend();
1028 if (send === null) internalError(node: node);
1029 if (!(send.isPropertyAccess || send.isIndex)) internalError(node: send);
1030 if (send.asSendSet() !== null) internalError(node: send);
1031 NodeList arguments;
1032 if (send.isIndex) {
1033 Link<Node> link = new Link<Node>(arg);
1034 link = link.prepend(send.arguments.head);
1035 arguments = new NodeList(null, link);
1036 } else {
1037 arguments = new NodeList.singleton(arg);
1038 }
1039 Operator op = new Operator(token);
1040 pushNode(new SendSet(send.receiver, send.selector, op, arguments));
1041 }
1042
1043 void handleConditionalExpression(Token question, Token colon) {
1044 Node elseExpression = popNode();
1045 Node thenExpression = popNode();
1046 Node condition = popNode();
1047 pushNode(new Conditional(
1048 condition, thenExpression, elseExpression, question, colon));
1049 }
1050
1051 void endSend(Token token) {
1052 NodeList arguments = popNode();
1053 Node selector = popNode();
1054 // TODO(ahe): Handle receiver.
1055 pushNode(new Send(null, selector, arguments));
1056 }
1057
1058 void endFunctionBody(int count, Token beginToken, Token endToken) {
1059 pushNode(new Block(makeNodeList(count, beginToken, endToken, null)));
1060 }
1061
1062 void handleNoFunctionBody(Token token) {
1063 pushNode(null);
1064 }
1065
1066 void endFunction(Token getOrSet, Token endToken) {
1067 Statement body = popNode();
1068 NodeList initializers = popNode();
1069 NodeList formals = popNode();
1070 // The name can be an identifier or a send in case of named constructors.
1071 Expression name = popNode();
1072 TypeAnnotation type = popNode();
1073 Modifiers modifiers = popNode();
1074 pushNode(new FunctionExpression(name, formals, body, type,
1075 modifiers, initializers, getOrSet));
1076 }
1077
1078 void endFunctionDeclaration(Token endToken) {
1079 pushNode(new FunctionDeclaration(popNode()));
1080 }
1081
1082 void endVariablesDeclaration(int count, Token endToken) {
1083 // TODO(ahe): Pick one name for this concept, either
1084 // VariablesDeclaration or VariableDefinitions.
1085 NodeList variables = makeNodeList(count, null, null, ",");
1086 TypeAnnotation type = popNode();
1087 Modifiers modifiers = popNode();
1088 pushNode(new VariableDefinitions(type, modifiers, variables, endToken));
1089 }
1090
1091 void endInitializer(Token assignmentOperator) {
1092 Expression initializer = popNode();
1093 NodeList arguments = new NodeList.singleton(initializer);
1094 Expression name = popNode();
1095 Operator op = new Operator(assignmentOperator);
1096 pushNode(new SendSet(null, name, op, arguments));
1097 }
1098
1099 void endIfStatement(Token ifToken, Token elseToken) {
1100 Statement elsePart = (elseToken === null) ? null : popNode();
1101 Statement thenPart = popNode();
1102 ParenthesizedExpression condition = popNode();
1103 pushNode(new If(condition, thenPart, elsePart, ifToken, elseToken));
1104 }
1105
1106 void endForStatement(int updateExpressionCount,
1107 Token beginToken, Token endToken) {
1108 Statement body = popNode();
1109 NodeList updates = makeNodeList(updateExpressionCount, null, null, ',');
1110 Statement condition = popNode();
1111 Node initializer = popNode();
1112 pushNode(new For(initializer, condition, updates, body, beginToken));
1113 }
1114
1115 void handleNoExpression(Token token) {
1116 pushNode(null);
1117 }
1118
1119 void endDoWhileStatement(Token doKeyword, Token whileKeyword,
1120 Token endToken) {
1121 Expression condition = popNode();
1122 Statement body = popNode();
1123 pushNode(new DoWhile(body, condition, doKeyword, whileKeyword, endToken));
1124 }
1125
1126 void endWhileStatement(Token whileKeyword, Token endToken) {
1127 Statement body = popNode();
1128 Expression condition = popNode();
1129 pushNode(new While(condition, body, whileKeyword));
1130 }
1131
1132 void endBlock(int count, Token beginToken, Token endToken) {
1133 pushNode(new Block(makeNodeList(count, beginToken, endToken, null)));
1134 }
1135
1136 void endThrowStatement(Token throwToken, Token endToken) {
1137 Expression expression = popNode();
1138 pushNode(new Throw(expression, throwToken, endToken));
1139 }
1140
1141 void endRethrowStatement(Token throwToken, Token endToken) {
1142 pushNode(new Throw(null, throwToken, endToken));
1143 }
1144
1145 void handleUnaryPrefixExpression(Token token) {
1146 pushNode(new Send.prefix(popNode(), new Operator(token)));
1147 }
1148
1149 void handleSuperExpression(Token token) {
1150 pushNode(new Identifier(token));
1151 }
1152
1153 void handleThisExpression(Token token) {
1154 pushNode(new Identifier(token));
1155 }
1156
1157 void handleUnaryAssignmentExpression(Token token, bool isPrefix) {
1158 Node node = popNode();
1159 Send send = node.asSend();
1160 if (send === null) internalError(node: node);
1161 if (!(send.isPropertyAccess || send.isIndex)) internalError(node: send);
1162 if (send.asSendSet() !== null) internalError(node: send);
1163 Node argument = null;
1164 if (send.isIndex) argument = send.arguments.head;
1165 Operator op = new Operator(token);
1166
1167 if (isPrefix) {
1168 pushNode(new SendSet.prefix(send.receiver, send.selector, op, argument));
1169 } else {
1170 pushNode(new SendSet.postfix(send.receiver, send.selector, op, argument));
1171 }
1172 }
1173
1174 void handleUnaryPostfixAssignmentExpression(Token token) {
1175 handleUnaryAssignmentExpression(token, false);
1176 }
1177
1178 void handleUnaryPrefixAssignmentExpression(Token token) {
1179 handleUnaryAssignmentExpression(token, true);
1180 }
1181
1182 void endInitializers(int count, Token beginToken, Token endToken) {
1183 pushNode(makeNodeList(count, beginToken, null, ','));
1184 }
1185
1186 void handleNoInitializers() {
1187 pushNode(null);
1188 }
1189
1190 void endFields(int count, Token beginToken, Token endToken) {
1191 NodeList variables = makeNodeList(count, null, null, ",");
1192 Modifiers modifiers = popNode();
1193 pushNode(new VariableDefinitions(null, modifiers, variables, endToken));
1194 }
1195
1196 void endMethod(Token getOrSet, Token beginToken, Token endToken) {
1197 Statement body = popNode();
1198 NodeList initializers = popNode();
1199 NodeList formalParameters = popNode();
1200 Expression name = popNode();
1201 Modifiers modifiers = popNode();
1202 pushNode(new FunctionExpression(name, formalParameters, body, null,
1203 modifiers, initializers, getOrSet));
1204 }
1205
1206 void handleLiteralMap(int count, Token beginToken, Token constKeyword,
1207 Token endToken) {
1208 NodeList entries = makeNodeList(count, beginToken, endToken, ',');
1209 NodeList typeArguments = popNode();
1210 pushNode(new LiteralMap(typeArguments, entries));
1211 }
1212
1213 void endLiteralMapEntry(Token colon, Token endToken) {
1214 Expression value = popNode();
1215 Expression key = popNode();
1216 if (key.asLiteralString() === null) {
1217 recoverableError('expected a constant string', node: key);
1218 }
1219 pushNode(new LiteralMapEntry(key, colon, value));
1220 }
1221
1222 void handleLiteralList(int count, Token beginToken, Token constKeyword,
1223 Token endToken) {
1224 NodeList elements = makeNodeList(count, beginToken, endToken, ',');
1225 NodeList typeArguments = popNode();
1226 // TODO(ahe): Type arguments are discarded.
1227 pushNode(new LiteralList(null, elements, constKeyword));
1228 }
1229
1230 void handleIndexedExpression(Token openSquareBracket,
1231 Token closeSquareBracket) {
1232 NodeList arguments =
1233 makeNodeList(1, openSquareBracket, closeSquareBracket, null);
1234 Node receiver = popNode();
1235 Token token =
1236 new StringToken(INDEX_INFO, '[]', openSquareBracket.charOffset);
1237 Node selector = new Operator(token);
1238 pushNode(new Send(receiver, selector, arguments));
1239 }
1240
1241 void handleNewExpression(Token token, bool named) {
1242 NodeList arguments = popNode();
1243 Node name = popNode();
1244 if (named) {
1245 TypeAnnotation type = popNode();
1246 name = new Send(type, name);
1247 }
1248 pushNode(new NewExpression(token, new Send(null, name, arguments)));
1249 }
1250
1251 void handleConstExpression(Token token, bool named) {
1252 NodeList arguments = popNode();
1253 if (named) {
1254 Identifier name = popNode();
1255 }
1256 TypeAnnotation type = popNode();
1257 pushNode(new NewExpression(token, new Send(null, type, arguments)));
1258 }
1259
1260 void handleOperatorName(Token operatorKeyword, Token token) {
1261 Operator op = new Operator(token);
1262 pushNode(new Send(new Identifier(operatorKeyword), op, null));
1263 }
1264
1265 void handleNamedArgument(Token colon) {
1266 Expression expression = popNode();
1267 Identifier name = popNode();
1268 pushNode(new NamedArgument(name, colon, expression));
1269 }
1270
1271 void endOptionalFormalParameters(int count,
1272 Token beginToken, Token endToken) {
1273 pushNode(makeNodeList(count, beginToken, endToken, ','));
1274 }
1275
1276 void handleFunctionTypedFormalParameter(Token endToken) {
1277 NodeList formals = popNode();
1278 Identifier name = popNode();
1279 TypeAnnotation returnType = popNode();
1280 pushNode(null); // Signal "no type" to endFormalParameter.
1281 pushNode(new FunctionExpression(name, formals, null, returnType,
1282 null, null, null));
1283 }
1284
1285 void handleValuedFormalParameter(Token equals, Token token) {
1286 Expression defaultValue = popNode();
1287 Expression parameterName = popNode();
1288 pushNode(new SendSet(null, parameterName, new Operator(equals),
1289 new NodeList.singleton(defaultValue)));
1290 }
1291
1292 void endTryStatement(int catchCount, Token tryKeyword, Token finallyKeyword) {
1293 Block finallyBlock = null;
1294 if (finallyKeyword !== null) {
1295 finallyBlock = popNode();
1296 }
1297 NodeList catchBlocks = makeNodeList(catchCount, null, null, null);
1298 Block tryBlock = popNode();
1299 pushNode(new TryStatement(tryBlock, catchBlocks, finallyBlock,
1300 tryKeyword, finallyKeyword));
1301 }
1302
1303 void handleCatchBlock(Token catchKeyword) {
1304 Block block = popNode();
1305 NodeList formals = popNode();
1306 pushNode(new CatchBlock(formals, block, catchKeyword));
1307 }
1308
1309 void endSwitchStatement(Token switchKeyword, Token endToken) {
1310 NodeList cases = popNode();
1311 ParenthesizedExpression expression = popNode();
1312 pushNode(new SwitchStatement(expression, cases, switchKeyword));
1313 }
1314
1315 void endSwitchBlock(int caseCount, Token beginToken, Token endToken) {
1316 Link<Node> nodes = const EmptyLink<Node>();
1317 while (caseCount > 0) {
1318 SwitchCase switchCase = popNode();
1319 nodes = nodes.prepend(switchCase);
1320 caseCount--;
1321 }
1322 pushNode(new NodeList(beginToken, nodes, endToken, null));
1323 }
1324
1325 void handleSwitchCase(Token labelToken, int expressionCount,
1326 Token defaultKeyword, int statementCount,
1327 Token firstToken, Token endToken) {
1328 NodeList statements = makeNodeList(statementCount, null, null, null);
1329 NodeList expressions = makeNodeList(expressionCount, null, null, null);
1330 Identifier label = null;
1331 if (labelToken !== null) {
1332 label = popNode();
1333 }
1334 pushNode(new SwitchCase(label, expressions, defaultKeyword, statements,
1335 firstToken));
1336 }
1337
1338 void handleBreakStatement(bool hasTarget,
1339 Token breakKeyword, Token endToken) {
1340 Identifier target = null;
1341 if (hasTarget) {
1342 target = popNode();
1343 }
1344 pushNode(new BreakStatement(target, breakKeyword, endToken));
1345 }
1346
1347 void handleContinueStatement(bool hasTarget,
1348 Token continueKeyword, Token endToken) {
1349 Identifier target = null;
1350 if (hasTarget) {
1351 target = popNode();
1352 }
1353 pushNode(new ContinueStatement(target, continueKeyword, endToken));
1354 }
1355
1356 void handleEmptyStatement(Token token) {
1357 pushNode(new EmptyStatement(token));
1358 }
1359
1360 void endFactoryMethod(Token factoryKeyword, Token periodBeforeName,
1361 Token endToken) {
1362 Statement body = popNode();
1363 NodeList formals = popNode();
1364 NodeList typeParameters = popNode(); // TODO(karlklose): don't throw away.
1365 Node name = popNode();
1366 if (periodBeforeName !== null) {
1367 // A library prefix was handled in [handleQualified].
1368 name = new Send(popNode(), name);
1369 }
1370 handleModifier(factoryKeyword);
1371 handleModifiers(1);
1372 Modifiers modifiers = popNode();
1373 pushNode(new FunctionExpression(name, formals, body, null,
1374 modifiers, null, null));
1375 }
1376
1377 void endForInStatement(Token beginToken, Token inKeyword, Token endToken) {
1378 Statement body = popNode();
1379 Expression expression = popNode();
1380 Node declaredIdentifier = popNode();
1381 pushNode(new ForInStatement(declaredIdentifier, expression, body,
1382 beginToken, inKeyword));
1383 }
1384
1385 void endUnamedFunction(Token token) {
1386 Statement body = popNode();
1387 NodeList formals = popNode();
1388 pushNode(new FunctionExpression(null, formals, body, null,
1389 null, null, null));
1390 }
1391
1392 void handleIsOperator(Token operathor, Token not, Token endToken) {
1393 TypeAnnotation type = popNode();
1394 Expression expression = popNode();
1395 Node argument;
1396 if (not != null) {
1397 argument = new Send.prefix(type, new Operator(not));
1398 } else {
1399 argument = type;
1400 }
1401
1402 NodeList arguments = new NodeList.singleton(argument);
1403 pushNode(new Send(expression, new Operator(operathor), arguments));
1404 }
1405
1406 void endLabeledStatement(Token colon) {
1407 Statement statement = popNode();
1408 Identifier label = popNode();
1409 pushNode(new LabeledStatement(label, colon, statement));
1410 }
1411
1412 void log(message) {
1413 listener.log(message);
1414 }
1415
1416 void internalError([Token token, Node node]) {
1417 listener.cancel('internal error', token: token, node: node);
1418 throw 'internal error';
1419 }
1420 }
1421
1422 class PartialFunctionElement extends FunctionElement {
1423 final Token beginToken;
1424 final Token getOrSet;
1425 final Token endToken;
1426
1427 PartialFunctionElement(SourceString name,
1428 Token this.beginToken,
1429 Token this.getOrSet,
1430 Token this.endToken,
1431 ElementKind kind,
1432 Modifiers modifiers,
1433 Element enclosing)
1434 : super(name, kind, modifiers, enclosing);
1435
1436 FunctionExpression parseNode(DiagnosticListener listener) {
1437 if (cachedNode != null) return cachedNode;
1438 cachedNode = parse(listener,
1439 getCompilationUnit(),
1440 (p) => p.parseFunction(beginToken, getOrSet));
1441 return cachedNode;
1442 }
1443
1444 Token position() => findMyName(beginToken);
1445 }
1446
1447 class PartialFieldListElement extends VariableListElement {
1448 final Token beginToken;
1449 final Token endToken;
1450
1451 PartialFieldListElement(Token this.beginToken,
1452 Token this.endToken,
1453 Modifiers modifiers,
1454 Element enclosing)
1455 : super(ElementKind.VARIABLE_LIST, modifiers, enclosing);
1456
1457 VariableDefinitions parseNode(DiagnosticListener listener) {
1458 if (cachedNode != null) return cachedNode;
1459 cachedNode = parse(listener,
1460 getCompilationUnit(),
1461 (p) => p.parseVariablesDeclaration(beginToken));
1462 return cachedNode;
1463 }
1464
1465 Token position() => beginToken; // findMyName doesn't work. I'm nameless.
1466 }
1467
1468 Node parse(DiagnosticListener diagnosticListener,
1469 CompilationUnitElement element,
1470 doParse(Parser parser)) {
1471 NodeListener listener = new NodeListener(diagnosticListener, element);
1472 doParse(new Parser(listener));
1473 Node node = listener.popNode();
1474 assert(listener.nodes.isEmpty());
1475 return node;
1476 }
OLDNEW
« no previous file with comments | « frog/leg/scanner/keyword.dart ('k') | frog/leg/scanner/motile.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698