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

Side by Side Diff: lib/compiler/implementation/js/printer.dart

Issue 10825180: Add JavaScript AST. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: updated. Created 8 years, 4 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
(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 class Printer implements NodeVisitor {
6 final bool shouldCompressOutput = false;
7 Compiler compiler;
8 var positionElement;
9 CodeBuffer outBuffer;
10 int indentLevel = 0;
11 bool inForInit = false;
12 bool atStatementBegin = false;
13
14 Printer(this.compiler, this.positionElement) : outBuffer = new CodeBuffer();
15
16 void spaceOut() {
17 if (!shouldCompressOutput) out(" ");
18 }
19 void lineOut() {
20 if (!shouldCompressOutput) out("\n");
21 }
22 int lastCharCode = 0;
23 void out(String str) {
24 outBuffer.add(str);
Lasse Reichstein Nielsen 2012/08/08 11:16:38 You can move the outBuffer into the if too.
floitsch 2012/08/09 16:24:07 Done.
25 if (str != "") {
26 lastCharCode = str.charCodeAt(str.length - 1);
27 }
28 }
29 void outLn(String str) {
30 out(str);
31 lineOut();
32 }
33 void outIndent(String str) { indent(); out(str); }
34 void outIndentLn(String str) { indent(); outLn(str); }
35 void indent() {
36 if (!shouldCompressOutput) {
37 for (int i = 0; i < indentLevel; i++) out(" ");
38 }
39 }
40
41 void recordSourcePosition(Dynamic position) {
Lasse Reichstein Nielsen 2012/08/08 11:16:38 Dynamic -> var, but please find a type.
floitsch 2012/08/09 16:24:07 As discussed. I would prefer to keep var here.
42 if (position != null) {
43 outBuffer.setSourceLocation(positionElement, position);
44 }
45 }
46
47 visit(Node node) {
48 recordSourcePosition(node.sourcePosition);
49 node.accept(this);
50 recordSourcePosition(node.endSourcePosition);
51 }
52
53 visitCommaSeparated(List<Node> nodes, int hasRequiredType,
54 [bool newInForInit, bool newAtStatementBegin]) {
55 for (int i = 0; i < nodes.length; i++) {
56 if (i != 0) {
57 atStatementBegin = false;
58 out(",");
59 spaceOut();
60 }
61 visitNestedExpression(nodes[i], hasRequiredType,
62 newInForInit, newAtStatementBegin);
63 }
64 }
65
66 visitAll(List<Node> nodes) {
67 nodes.forEach(visit);
68 }
69
70 visitProgram(Program program) {
71 visitAll(program.body);
72 }
73
74 bool blockBody(Node body, [bool needsSeparation, bool needsNewline]) {
75 if (body is Block) {
76 spaceOut();
77 blockOut(body, false, needsNewline);
78 return true;
79 }
80 if (shouldCompressOutput && needsSeparation) {
81 // If [shouldCompressOutput] is false, then the 'lineOut' will insert
82 // the separation.
83 out(" ");
84 } else {
85 lineOut();
86 }
87 indentLevel++;
88 visit(body);
89 indentLevel--;
90 return false;
91 }
92
93 void blockOutWithoutBraces(Node node) {
94 if (node is Block) {
95 node.elements.forEach(blockOutWithoutBraces);
96 } else {
97 visit(node);
98 }
99 }
100
101 void blockOut(Block node, bool shouldIndent, bool needsNewline) {
102 if (shouldIndent) indent();
103 out("{");
104 lineOut();
105 indentLevel++;
106 node.elements.forEach(blockOutWithoutBraces);
107 indentLevel--;
108 indent();
109 out("}");
110 if (needsNewline) lineOut();
111 }
112
113 visitBlock(Block block) {
114 blockOut(block, true, true);
115 }
116
117 visitExpressionStatement(ExpressionStatement expressionStatement) {
118 indent();
119 visitNestedExpression(expressionStatement.expr, EXPRESSION,
120 newInForInit: false, newAtStatementBegin: true);
121 outLn(";");
122 }
123
124 visitNOP(NOP nop) {
125 outIndentLn(";");
126 }
127
128 void ifOut(If node, bool shouldIndent) {
129 Node then = node.then;
130 Node elsePart = node.otherwise;
131 bool hasElse = node.hasElse;
132 // Handle dangling elses.
133 // If the then-branch is an if, which has no else-branch, but we do
134 // have one, then we need to put the nested if into braces.
135 if (hasElse && then is If) {
136 Node nested = then;
137 do {
138 If nestedIf = nested;
139 if (!nestedIf.hasElse) {
140 then = new Block(<Statement>[then]);
141 break;
142 }
143 nested = nestedIf.otherwise;
144 } while (nested is If);
145 }
146 if (then is If && !(then as If).hasElse && hasElse) {
147 then = new Block(<Statement>[then]);
148 }
149 if (shouldIndent) indent();
150 out("if");
151 spaceOut();
152 out("(");
153 visitNestedExpression(node.test, EXPRESSION,
154 newInForInit: false, newAtStatementBegin: false);
155 out(")");
156 bool thenWasBlock =
157 blockBody(then, needsSeparation: false, needsNewline: !hasElse);
158 if (hasElse) {
159 if (thenWasBlock) {
160 spaceOut();
161 } else {
162 indent();
163 }
164 out("else");
165 if (elsePart is If) {
166 out(" ");
167 ifOut(elsePart, false);
168 } else {
169 blockBody(elsePart, needsSeparation: true, needsNewline: true);
170 }
171 }
172 }
173
174 visitIf(If node) {
175 ifOut(node, true);
176 }
177
178 visitFor(For loop) {
179 outIndent("for");
180 spaceOut();
181 out("(");
182 if (loop.init !== null) {
183 visitNestedExpression(loop.init, EXPRESSION,
184 newInForInit: true, newAtStatementBegin: false);
185 }
186 out(";");
187 if (loop.test !== null) {
188 spaceOut();
189 visitNestedExpression(loop.test, EXPRESSION,
190 newInForInit: false, newAtStatementBegin: false);
191 }
192 out(";");
193 if (loop.incr !== null) {
194 spaceOut();
195 visitNestedExpression(loop.incr, EXPRESSION,
196 newInForInit: false, newAtStatementBegin: false);
197 }
198 out(")");
199 blockBody(loop.body, needsSeparation: false, needsNewline: true);
200 }
201
202 visitForIn(ForIn loop) {
203 outIndent("for");
204 spaceOut();
205 out("(");
206 visitNestedExpression(loop.lhs, EXPRESSION,
207 newInForInit: true, newAtStatementBegin: false);
208 out(" in ");
209 visitNestedExpression(loop.obj, EXPRESSION,
210 newInForInit: false, newAtStatementBegin: false);
211 out(")");
212 blockBody(loop.body, needsSeparation: false, needsNewline: true);
213 }
214
215 visitWhile(While loop) {
216 outIndent("while");
217 spaceOut();
218 out("(");
219 visitNestedExpression(loop.test, EXPRESSION,
220 newInForInit: false, newAtStatementBegin: false);
221 out(")");
222 blockBody(loop.body, needsSeparation: false, needsNewline: true);
223 }
224
225 visitDo(Do loop) {
226 outIndent("do");
227 if (blockBody(loop.body, needsSeparation: true, needsNewline: false)) {
228 spaceOut();
229 } else {
230 indent();
231 }
232 out("while");
233 spaceOut();
234 out("(");
235 visitNestedExpression(loop.test, EXPRESSION,
236 newInForInit: false, newAtStatementBegin: false);
237 outLn(");");
238 }
239
240 visitContinue(Continue node) {
241 if (node.id == null) {
242 outIndentLn("continue;");
243 } else {
244 outIndentLn("continue ${node.id};");
245 }
246 }
247
248 visitBreak(Break node) {
249 if (node.id == null) {
250 outIndentLn("break;");
251 } else {
252 outIndentLn("break ${node.id};");
253 }
254 }
255
256 visitReturn(Return node) {
257 if (node.expr == null) {
258 outIndentLn("return;");
259 } else {
260 outIndent("return ");
261 visitNestedExpression(node.expr, EXPRESSION,
262 newInForInit: false, newAtStatementBegin: false);
263 outLn(";");
264 }
265 }
266
267 visitThrow(Throw node) {
268 outIndent("throw ");
269 visitNestedExpression(node.expr, EXPRESSION,
270 newInForInit: false, newAtStatementBegin: false);
271 outLn(";");
272 }
273
274 visitTry(Try node) {
275 outIndent("try");
276 blockBody(node.body, needsSeparation: true, needsNewline: false);
277 spaceOut();
278 if (node.catchPart !== null) {
279 visit(node.catchPart);
280 }
281 if (node.finallyPart !== null) {
282 spaceOut();
283 out("finally");
284 blockBody(node.finallyPart, needsSeparation: true, needsNewline: true);
285 } else {
286 lineOut();
287 }
288 }
289
290 visitCatch(Catch node) {
291 spaceOut();
292 out("catch");
293 spaceOut();
294 out("(");
295 // Must be a reference, so just test for a primary.
296 visitNestedExpression(node.decl, PRIMARY,
Lasse Reichstein Nielsen 2012/08/08 11:16:38 It should be able to be a declaration too.
floitsch 2012/08/09 16:24:07 changed to EXPRESSION.
297 newInForInit: false, newAtStatementBegin: false);
298 out(")");
299 blockBody(node.body, needsSeparation: false, needsNewline: true);
300 }
301
302 visitWith(With node) {
303 outIndent("with");
304 spaceOut();
305 out("(");
306 visitNestedExpression(node.object, EXPRESSION,
307 newInForInit: false, newAtStatementBegin: false);
308 out(")");
309 blockBody(node.body, needsSeparation: false, needsNewline: true);
310 }
311
312 visitSwitch(Switch node) {
313 outIndent("switch");
314 spaceOut();
315 out("(");
316 visitNestedExpression(node.key, EXPRESSION,
317 newInForInit: false, newAtStatementBegin: false);
318 out(")");
319 spaceOut();
320 outLn("{");
321 indentLevel++;
322 visitAll(node.cases);
323 indentLevel--;
324 outIndentLn("}");
325 }
326
327 visitCase(Case node) {
328 outIndent("case ");
329 visitNestedExpression(node.expr, EXPRESSION,
Lasse Reichstein Nielsen 2012/08/08 11:16:38 That's ASSIGNMENT_EXPRESSION, not EXPRESSION. You
floitsch 2012/08/09 16:24:07 ignoring comment you sent out unintentionally.
330 newInForInit: false, newAtStatementBegin: false);
331 outLn(":");
332 if (!node.body.elements.isEmpty()) {
333 indentLevel++;
334 blockOutWithoutBraces(node.body);
335 indentLevel--;
336 }
337 }
338
339 visitDefault(Default node) {
340 outIndentLn("default:");
341 if (!node.body.elements.isEmpty()) {
342 indentLevel++;
343 blockOutWithoutBraces(node.body);
344 indentLevel--;
345 }
346 }
347
348 visitLabeled(Labeled node) {
349 outIndent("${node.id}:");
350 blockBody(node.body, needsSeparation: false, needsNewline: true);
351 }
352
353 void functionOut(Fun fun, Node name) {
354 out("function");
355 if (name != null) {
356 out(" ");
357 // Name must be a [Decl]. Therefore only test for primary expressions.
358 visitNestedExpression(name, PRIMARY,
359 newInForInit: false, newAtStatementBegin: false);
360 }
361 out("(");
362 if (fun.params != null) {
363 visitCommaSeparated(fun.params, PRIMARY,
364 newInForInit: false, newAtStatementBegin: false);
365 }
366 out(")");
367 blockBody(fun.body, needsSeparation: false, needsNewline: false);
368 }
369
370 visitFunctionDeclaration(FunctionDeclaration declaration) {
371 indent();
372 functionOut(declaration.fun, declaration.id);
373 lineOut();
374 }
375
376 visitNestedExpression(Expression node, int requiredPrecedence,
377 [bool newInForInit, bool newAtStatementBegin]) {
378 bool needsParentheses =
379 // a - (b + c).
380 (requiredPrecedence != EXPRESSION &&
381 node.precedenceLevel < requiredPrecedence) ||
382 // for (a = (x in o); ... ; ... ) { ... }
383 (newInForInit && node is Binary && (node as Binary).op == "in") ||
384 // (function() { ... })().
385 // ({a: 2, b: 3}.toString()).
386 (newAtStatementBegin && (node is NamedFunction ||
387 node is Fun ||
388 node is ObjectLiteral));
389 if (needsParentheses) {
390 inForInit = false;
391 atStatementBegin = false;
392 out("(");
393 visit(node);
394 out(")");
395 } else {
396 inForInit = newInForInit;
397 atStatementBegin = newAtStatementBegin;
398 visit(node);
399 }
400 }
401
402 visitVariableDeclarationList(VariableDeclarationList list) {
403 out("var ");
404 visitCommaSeparated(list.declarations, ASSIGNMENT,
405 newInForInit: inForInit, newAtStatementBegin: false);
406 }
407
408 visitSequence(Sequence sequence) {
409 // Note that we only require that the entries are expressions and not
410 // assignments. This means that nested sequences are not put into
411 // parenthesis.
412 visitCommaSeparated(sequence.expressions, EXPRESSION,
413 newInForInit: false,
414 newAtStatementBegin: atStatementBegin);
415 }
416
417 outAssignment(Node lhs, Node value, [String op = ""]) {
418 visitNestedExpression(lhs, LHS,
419 newInForInit: inForInit,
420 newAtStatementBegin: atStatementBegin);
421 if (value !== null) {
422 spaceOut();
423 out(op);
424 out("=");
425 spaceOut();
426 visitNestedExpression(value, ASSIGNMENT,
427 newInForInit: inForInit,
428 newAtStatementBegin: false);
429 }
430 }
431
432 visitVassign(Vassign vassign) {
433 outAssignment(vassign.lhs, vassign.value);
434 }
435 visitInit(Init init) {
436 outAssignment(init.decl, init.value);
437 }
438 visitAccsign(Accsign accsign) {
439 outAssignment(accsign.lhs, accsign.value);
440 }
441
442 visitVassignOp(VassignOp vassignOp) {
443 outAssignment(vassignOp.lhs, vassignOp.value, vassignOp.op);
444 }
445
446 visitAccsignOp(AccsignOp accsignOp) {
447 outAssignment(accsignOp.lhs, accsignOp.value, accsignOp.op);
448 }
449
450 visitConditional(Conditional cond) {
451 visitNestedExpression(cond.test, LOGICAL_OR,
452 newInForInit: inForInit,
453 newAtStatementBegin: atStatementBegin);
454 spaceOut();
455 out("?");
456 spaceOut();
457 // The then part is allowed to have an 'in'.
458 visitNestedExpression(cond.then, ASSIGNMENT,
459 newInForInit: false, newAtStatementBegin: false);
460 spaceOut();
461 out(":");
462 spaceOut();
463 visitNestedExpression(cond.otherwise, ASSIGNMENT,
464 newInForInit: inForInit, newAtStatementBegin: false);
465 }
466
467 visitNew(New node) {
468 out("new ");
469 visitNestedExpression(node.cls, CALL,
470 newInForInit: inForInit, newAtStatementBegin: false);
471 out("(");
472 visitCommaSeparated(node.arguments, ASSIGNMENT,
473 newInForInit: false, newAtStatementBegin: false);
474 out(")");
475 }
476
477 visitCall(Call call) {
478 visitNestedExpression(call.target, LHS,
479 newInForInit: inForInit,
480 newAtStatementBegin: atStatementBegin);
481 out("(");
482 visitCommaSeparated(call.arguments, ASSIGNMENT,
483 newInForInit: false, newAtStatementBegin: false);
484 out(")");
485 }
486
487 visitBinary(Binary binary) {
488 Expression left = binary.left;
489 Expression right = binary.right;
490 String op = binary.op;
491 int leftPrecedenceRequirement;
492 int rightPrecedenceRequirement;
493 switch (op) {
494 case "||":
495 leftPrecedenceRequirement = LOGICAL_OR;
496 // x || (y || z) <=> (x || y) || z.
497 rightPrecedenceRequirement = LOGICAL_OR;
498 break;
499 case "&&":
500 leftPrecedenceRequirement = LOGICAL_AND;
501 // x && (y && z) <=> (x && y) && z.
502 rightPrecedenceRequirement = LOGICAL_AND;
503 break;
504 case "|":
505 leftPrecedenceRequirement = BIT_OR;
506 // x | (y | z) <=> (x | y) | z.
507 rightPrecedenceRequirement = BIT_OR;
508 break;
509 case "^":
510 leftPrecedenceRequirement = BIT_XOR;
511 // x ^ (y ^ z) <=> (x ^ y) ^ z.
512 rightPrecedenceRequirement = BIT_XOR;
513 break;
514 case "&":
515 leftPrecedenceRequirement = BIT_AND;
516 // x & (y & z) <=> (x & y) & z.
517 rightPrecedenceRequirement = BIT_AND;
518 break;
519 case "==":
520 case "!=":
521 case "===":
522 case "!==":
523 leftPrecedenceRequirement = EQUALITY;
524 rightPrecedenceRequirement = RELATIONAL;
525 break;
526 case "<":
527 case ">":
528 case "<=":
529 case ">=":
530 case "instanceof":
531 case "in":
532 leftPrecedenceRequirement = RELATIONAL;
533 rightPrecedenceRequirement = SHIFT;
534 break;
535 case ">>":
536 case "<<":
537 case ">>>":
538 leftPrecedenceRequirement = SHIFT;
539 rightPrecedenceRequirement = ADDITIVE;
540 break;
541 case "+":
542 case "-":
543 leftPrecedenceRequirement = ADDITIVE;
544 // We cannot remove parenthesis for "+" because
545 // x + (y + z) <!=> (x + y) + z:
546 // Example:
547 // "a" + (1 + 2) => "a3";
548 // ("a" + 1) + 2 => "a12";
549 rightPrecedenceRequirement = MULTIPLICATIVE;
550 break;
551 case "*":
552 case "/":
553 case "%":
554 leftPrecedenceRequirement = MULTIPLICATIVE;
555 // We cannot remove parenthesis for "*" because of precision issues.
556 rightPrecedenceRequirement = UNARY;
557 break;
558 default:
559 compiler.internalError("Forgot operator: $op");
560 }
561
562 visitNestedExpression(left, leftPrecedenceRequirement,
563 newInForInit: inForInit,
564 newAtStatementBegin: atStatementBegin);
565
566 if (op == "in" || op == "instanceof") {
567 // There are cases where the space is not required but without further
568 // analysis we cannot know.
569 out(" ");
570 out(op);
571 out(" ");
572 } else {
573 spaceOut();
574 out(op);
575 spaceOut();
576 }
577 visitNestedExpression(right, rightPrecedenceRequirement,
578 newInForInit: inForInit,
579 newAtStatementBegin: false);
580 }
581
582 visitUnary(Unary unary) {
583 String op = unary.op;
584 switch (op) {
585 case "delete":
586 case "void":
587 case "typeof":
588 // There are cases where the space is not required but without further
589 // analysis we cannot know.
590 out(op);
591 out(" ");
592 break;
593 case "+":
594 case "++":
595 if (lastCharCode == "+".charCodeAt(0)) out(" ");
Lasse Reichstein Nielsen 2012/08/08 11:16:38 If you are going to be this primitive, just store
floitsch 2012/08/09 16:24:07 Importing the charcodes from ../util/characters.da
596 out(op);
597 break;
598 case "-":
599 case "--":
600 if (lastCharCode == "-".charCodeAt(0)) out(" ");
601 out(op);
602 break;
603 default:
604 out(op);
605 }
606 visitNestedExpression(unary.arg, UNARY,
607 newInForInit: inForInit, newAtStatementBegin: false);
608 }
609
610 visitPostfix(Postfix postfix) {
611 visitNestedExpression(postfix.arg, LHS,
612 newInForInit: inForInit,
613 newAtStatementBegin: atStatementBegin);
614 out(postfix.op);
615 }
616
617 visitRef(Ref ref) {
618 out(ref.id);
619 }
620
621 visitThis(This node) {
622 out("this");
623 }
624
625 visitDecl(Decl decl) {
626 out(decl.id);
627 }
628
629 visitParam(Param param) {
630 out(param.id);
631 }
632
633 bool isDigit(int charCode) {
634 return '0'.charCodeAt(0) <= charCode && charCode <= '9'.charCodeAt(0);
635 }
636
637 bool isValidJavaScriptId(String field) {
638 if (field.length < 3) return false;
639 // Ignore the leading and trailing string-delimiter.
640 for (int i = 1; i < field.length - 1; i++) {
641 // TODO(floitsch): allow more characters.
642 int charCode = field.charCodeAt(i);
643 if (!('a'.charCodeAt(0) <= charCode && charCode <= 'z'.charCodeAt(0) ||
644 'A'.charCodeAt(0) <= charCode && charCode <= 'Z'.charCodeAt(0) ||
645 charCode == @'$'.charCodeAt(0) ||
646 charCode == '_'.charCodeAt(0) ||
647 i != 1 && isDigit(charCode))) {
648 return false;
649 }
650 }
651 // TODO(floitsch): normally we should also check that the field is not
652 // a reserved word.
653 return true;
654 }
655
656 visitAccess(Access access) {
657 visitNestedExpression(access.receiver, CALL,
658 newInForInit: inForInit,
659 newAtStatementBegin: atStatementBegin);
660 Node selector = access.selector;
661 if (selector is StringLiteral) {
662 String fieldWithQuotes = (selector as StringLiteral).value;
663 if (isValidJavaScriptId(fieldWithQuotes)) {
664 if (isDigit(lastCharCode)) out(" ");
Lasse Reichstein Nielsen 2012/08/08 11:16:38 You should be able to parenthesize the number, som
floitsch 2012/08/09 16:24:07 As discussed: we can change this later.
665 out(".");
666 out(fieldWithQuotes.substring(1, fieldWithQuotes.length - 1));
667 return;
668 }
669 }
670 out("[");
671 visitNestedExpression(selector, EXPRESSION,
672 newInForInit: false, newAtStatementBegin: false);
673 out("]");
674 }
675
676 visitNamedFunction(NamedFunction namedFunction) {
677 functionOut(namedFunction.fun, namedFunction.id);
678 }
679
680 visitFun(Fun fun) {
681 functionOut(fun, null);
682 }
683
684 visitBoolLiteral(BoolLiteral node) {
685 out(node.value ? "true" : "false");
686 }
687
688 visitStringLiteral(StringLiteral node) {
689 out(node.value);
690 }
691
692 visitNumberLiteral(NumberLiteral node) {
693 int charCode = node.value.charCodeAt(0);
694 if (charCode == '-'.charCodeAt(0) && lastCharCode == "-".charCodeAt(0)) {
695 out(" ");
696 }
697 out(node.value);
698 }
699
700 visitNullLiteral(NullLiteral node) {
701 out("null");
702 }
703
704 visitArrayLiteral(ArrayLiteral node) {
705 out("[");
706 List<ArrayElement> elements = node.elements;
707 int elementIndex = 0;
708 for (int i = 0; i < node.length; i++) {
709 if (elementIndex < elements.length &&
710 elements[elementIndex].index == i) {
711 visitNestedExpression(elements[elementIndex].value, ASSIGNMENT,
712 newInForInit: false, newAtStatementBegin: false);
713 elementIndex++;
714 // We can avoid a trailing "," if there was an element just before. So
715 // `[1]` and `[1,]` are the same, but `[,]` and `[]` are not.
716 if (i != node.length - 1) {
717 out(",");
718 spaceOut();
719 }
720 } else {
721 out(",");
722 }
723 }
724 out("]");
725 }
726
727 visitArrayElement(ArrayElement node) {
728 throw "Unreachable";
729 }
730
731 visitObjectLiteral(ObjectLiteral node) {
732 out("{");
733 List<PropertyInit> properties = node.properties;
734 for (int i = 0; i < properties.length; i++) {
735 if (i != 0) {
736 out(",");
737 spaceOut();
738 }
739 visitPropertyInit(properties[i]);
740 }
741 out("}");
742 }
743
744 visitPropertyInit(PropertyInit node) {
745 if (node.name is StringLiteral) {
746 String name = (node.name as StringLiteral).value;
747 if (isValidJavaScriptId(name)) {
748 out(name.substring(1, name.length - 1));
749 } else {
750 out(name);
751 }
752 } else {
753 assert(node.name is NumberLiteral);
754 out((node.name as NumberLiteral).value);
755 }
756 out(":");
757 spaceOut();
758 visitNestedExpression(node.value, ASSIGNMENT,
759 newInForInit: false, newAtStatementBegin: false);
760 }
761
762 visitRegExpLiteral(RegExpLiteral node) {
763 out(node.pattern);
764 }
765
766 visitExpressionBlob(ExpressionBlob node) {
767 String blob = node.blob;
768 List<Expression> data = node.data;
769
770 List<String> parts = blob.split('#');
Lasse Reichstein Nielsen 2012/08/08 11:16:38 "blob" is really the wrong name when you interpret
floitsch 2012/08/09 16:24:07 Done.
771 if (parts.length != data.length + 1) {
772 compiler.internalError('Wrong number of arguments for JS: $blob');
773 }
774 out("(");
775 out(parts[0]);
776 for (int i = 0; i < data.length; i++) {
777 visit(data[i]);
778 out(parts[i + 1]);
779 }
780 out(")");
781 }
782
783 visitStatementBlob(StatementBlob node) {
784 outLn(node.blob);
785 }
786 }
787
788 CodeBuffer prettyPrint(Node node, Compiler compiler, Dynamic positionElement) {
789 Printer printer = new Printer(compiler, positionElement);
790 printer.visit(node);
791 return printer.outBuffer;
792 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698