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

Side by Side Diff: tests/compiler/dart2js/dart_printer_test.dart

Issue 250523003: dart2dart backend: AST and unparser for backend. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Minor change: removed stack dump from test. Created 6 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 | « sdk/lib/_internal/compiler/implementation/dart_backend/dart_printer.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 library dart_printer_test;
2
3 import "package:expect/expect.dart";
4 import '../../../sdk/lib/_internal/compiler/implementation/dart_backend/dart_pri nter.dart';
5 import '../../../sdk/lib/_internal/compiler/implementation/scanner/scannerlib.da rt';
6 import '../../../sdk/lib/_internal/compiler/implementation/source_file.dart';
7 import '../../../sdk/lib/_internal/compiler/implementation/dart2jslib.dart';
8 import '../../../sdk/lib/_internal/compiler/implementation/tree/tree.dart' show DartString;
9 import 'dart:mirrors';
10 import '../../../sdk/lib/_internal/compiler/implementation/tree/tree.dart' as tr ee;
11 import '../../../sdk/lib/_internal/compiler/implementation/string_validator.dart ';
12
13 /// For debugging the [AstBuilder] stack. Prints information about [x].
14 void show(x) {
15 StringBuffer buf = new StringBuffer();
16 Unparser unparser = new Unparser(buf);
17 void unparse(x) {
18 if (x is Expression)
19 unparser.writeExpression(x);
20 else if (x is TypeAnnotation)
21 unparser.writeType(x);
22 else if (x is Statement)
23 unparser.writeStatement(x);
24 else if (x is List) {
25 buf.write('[');
26 bool first = true;
27 for (var y in x) {
28 if (first)
29 first = false;
30 else
31 buf.write(', ');
32 unparse(y);
33 }
34 buf.write(']');
35 }
36 }
37 unparse(x);
38 print("${x.runtimeType}: ${buf.toString()}");
39 }
40
41 class PrintDiagnosticListener implements DiagnosticListener {
42 void log(message) {
43 print(message);
44 }
45
46 void internalError(Spannable spannable, message) {
47 print(message);
48 }
49
50 SourceSpan spanFromSpannable(Spannable node) {
51 return new SourceSpan(null, 0, 0);
52 }
53
54 void reportFatalError(Spannable node, MessageKind errorCode,
55 [Map arguments = const {}]) {
56 print(errorCode);
57 throw new Error();
58 }
59
60 void reportError(Spannable node, MessageKind errorCode,
61 [Map arguments = const {}]) {
62 print(errorCode);
63 }
64
65 void reportWarning(Spannable node, MessageKind errorCode,
66 [Map arguments = const {}]) {
67 print(errorCode);
68 }
69
70 void reportHint(Spannable node, MessageKind errorCode,
71 [Map arguments = const {}]) {
72 print(errorCode);
73 }
74
75 void reportInfo(Spannable node, MessageKind errorCode,
76 [Map arguments = const {}]) {
77 print(errorCode);
78 }
79
80 withCurrentElement(element, f()) {
81 f();
82 }
83 }
84
85 class AstBuilder extends Listener {
86 final List stack = [];
87 final StringValidator stringValidator
88 = new StringValidator(new PrintDiagnosticListener());
89
90 String asName(e) {
91 if (e is Identifier)
92 return e.name;
93 else if (e == null)
94 return null;
95 else
96 throw 'Expression is not a name: ${e.runtimeType}';
97 }
98
99 TypeAnnotation asType(x) {
100 if (x is TypeAnnotation)
101 return x;
102 if (x is Identifier)
103 return new TypeAnnotation(x.name);
104 if (x == null)
105 return null;
106 else
107 throw "Not a type: ${x.runtimeType}";
108 }
109
110 Parameter asParameter(x) {
111 if (x is Parameter)
112 return x;
113 if (x is Identifier)
114 return new Parameter(x.name);
115 else
116 throw "Not a parameter: ${x.runtimeType}";
117 }
118
119 void push(node) {
120 stack.add(node);
121 }
122 dynamic peek() {
123 return stack.last;
124 }
125 dynamic pop([coerce(x) = null]) {
126 var x = stack.removeLast();
127 if (coerce != null)
128 return coerce(x);
129 else
130 return x;
131 }
132 List popList(int count, [List result, coerce(x) = null]) {
133 if (result == null)
134 result = <Node>[];
135 for (int i=0; i<count; i++) {
136 var x = stack[stack.length-count+i];
137 if (coerce != null) {
138 x = coerce(x);
139 }
140 result.add(x);
141 }
142 stack.removeRange(stack.length-count, stack.length);
143 return result;
144 }
145 popTypeAnnotation() {
146 List<TypeAnnotation> args = pop();
147 if (args == null)
148 return null;
149 String name = pop(asName);
150 return new TypeAnnotation(name, args);
151 }
152
153 // EXPRESSIONS
154 endCascade() {
155 throw "Cascade not supported yet";
156 }
157 endIdentifierList(int count) {
158 push(popList(count, <Identifier>[]));
159 }
160 endTypeList(int count) {
161 push(popList(count, <TypeAnnotation>[], asType));
162 }
163 beginLiteralString(Token token) {
164 String source = token.value;
165 tree.StringQuoting quoting = StringValidator.quotingFromString(source);
166 push(quoting);
167 push(token); // collect token at the end
168 }
169 handleStringPart(Token token) {
170 push(token); // collect token at the end
171 }
172 endLiteralString(int interpCount) {
173 List parts = popList(2 * interpCount + 1, []);
174 tree.StringQuoting quoting = pop();
175 List<Expression> members = <Expression>[];
176 for (var i=0; i<parts.length; i++) {
177 var part = parts[i];
178 if (part is Expression) {
179 members.add(part);
180 } else {
181 assert(part is Token);
182 DartString str = stringValidator.validateInterpolationPart(
183 part as Token,
184 quoting,
185 isFirst: i == 0,
186 isLast: i == parts.length - 1);
187 members.add(new Literal(new StringConstant(str)));
188 }
189 }
190 push(new StringConcat(members));
191 }
192 handleStringJuxtaposition(int litCount) {
193 push(new StringConcat(popList(litCount, <Expression>[])));
194 }
195 endArguments(int count, begin, end) {
196 push(popList(count, <Argument>[]));
197 }
198 handleNoArguments(token) {
199 push(null);
200 }
201 handleNoTypeArguments(token) {
202 push(<TypeAnnotation>[]);
203 }
204 endTypeArguments(int count, t, y) {
205 List<TypeAnnotation> args = <TypeAnnotation>[];
206 for (var i=0; i<count; i++) {
207 args.add(popTypeAnnotation());
208 }
209 push(args.reversed.toList(growable:false));
210 }
211 handleVoidKeyword(token) {
212 push(new Identifier("void"));
213 push(<TypeAnnotation>[]); // prepare for popTypeAnnotation
214 }
215 handleQualified(Token period) {
216 String last = pop(asName);
217 String first = pop(asName);
218 push(new Identifier('$first.$last'));
219 }
220 endSend(t) {
221 List<Argument> arguments = pop();
222 if (arguments == null)
223 return; // not a function call
224 Expression selector = pop();
225 push(new CallFunction(selector, arguments));
226 }
227 endThrowExpression(t, tt) {
228 push(new Throw(pop()));
229 }
230 handleAssignmentExpression(Token token) {
231 Expression right = pop();
232 Expression left = pop();
233 push(new Assignment(left, token.value, right));
234 }
235 handleBinaryExpression(Token token) {
236 Expression right = pop();
237 Receiver left = pop();
238 String tokenString = token.stringValue;
239 if (tokenString == '.') {
240 if (right is CallFunction) {
241 String name = (right.callee as Identifier).name;
242 push(new CallMethod(left, name, right.arguments));
243 } else {
244 push(new FieldExpression(left, (right as Identifier).name));
245 }
246 } else {
247 push(new BinaryOperator(left, tokenString, right));
248 }
249 }
250 handleConditionalExpression(question, colon) {
251 Expression elseExpression = pop();
252 Expression thenExpression = pop();
253 Expression condition = pop();
254 push(new Conditional(condition, thenExpression, elseExpression));
255 }
256 handleIdentifier(Token t) {
257 push(new Identifier(t.value));
258 }
259 handleOperator(t) {
260 push(new Identifier(t.value));
261 }
262 handleIndexedExpression(open, close) {
263 Expression index = pop();
264 Receiver object = pop();
265 push(new IndexExpression(object, index));
266 }
267 handleIsOperator(operathor, not, endToken) {
268 TypeAnnotation type = popTypeAnnotation();
269 Expression exp = pop();
270 TypeOperator r = new TypeOperator(exp, 'is', type);
271 if (not != null) {
272 push(new UnaryOperator('!', r));
273 } else {
274 push(r);
275 }
276 }
277 handleAsOperator(operathor, endToken) {
278 TypeAnnotation type = popTypeAnnotation();
279 Expression exp = pop();
280 push(new TypeOperator(exp, 'as', type));
281 }
282 handleLiteralBool(Token t) {
283 bool value = t.value == 'true';
284 push(new Literal(value ? new TrueConstant() : new FalseConstant()));
285 }
286 handleLiteralDouble(t) {
287 push(new Literal(new DoubleConstant(double.parse(t.value))));
288 }
289 handleLiteralInt(Token t) {
290 push(new Literal(new IntConstant(int.parse(t.value))));
291 }
292 handleLiteralNull(t) {
293 push(new Literal(new NullConstant()));
294 }
295 endLiteralSymbol(Token hash, int idCount) {
296 List<Identifier> ids = popList(idCount, <Identifier>[]);
297 push(new LiteralSymbol(ids.map((id) => id.name).join('.')));
298 }
299 handleLiteralList(int count, begin, constKeyword, end) {
300 List<Expression> exps = popList(count, <Expression>[]);
301 List<TypeAnnotation> types = pop();
302 assert(types.length <= 1);
303 push(new LiteralList(exps,
304 isConst: constKeyword != null,
305 typeArgument: types.length == 0 ? null : types[0]
306 ));
307 }
308 handleLiteralMap(int count, begin, constKeyword, end) {
309 List<LiteralMapEntry> entries = popList(count, <LiteralMapEntry>[]);
310 List<TypeAnnotation> types = pop();
311 assert(types.length == 0 || types.length == 2);
312 push(new LiteralMap(entries,
313 isConst: constKeyword != null,
314 typeArguments: types
315 ));
316 }
317 endLiteralMapEntry(colon, endToken) {
318 Expression value = pop();
319 Expression key = pop();
320 push(new LiteralMapEntry(key,value));
321 }
322 handleNamedArgument(colon) {
323 Expression exp = pop();
324 Identifier name = pop();
325 push(new NamedArgument(name.name, exp));
326 }
327 endConstructorReference(Token start, Token period, Token end) {
328 if (period == null) {
329 push(null); // indicate missing constructor name
330 }
331 }
332 handleNewExpression(t) {
333 List<Argument> args = pop();
334 String constructorName = pop(asName);
335 TypeAnnotation type = popTypeAnnotation();
336 push(new CallNew(type, args, constructorName: constructorName));
337 }
338 handleConstExpression(t) {
339 List<Argument> args = pop();
340 String constructorName = pop(asName);
341 TypeAnnotation type = popTypeAnnotation();
342 push(new CallNew(type, args, constructorName: constructorName,
343 isConst:true));
344 }
345 handleParenthesizedExpression(t) {
346 // do nothing, just leave expression on top of stack
347 }
348 handleSuperExpression(t) {
349 push(new SuperReceiver());
350 }
351 handleThisExpression(t) {
352 push(new This());
353 }
354 handleUnaryPostfixAssignmentExpression(Token t) {
355 push(new Increment.postfix(pop(), t.value));
356 }
357 handleUnaryPrefixAssignmentExpression(Token t) {
358 push(new Increment.prefix(pop(), t.value));
359 }
360 handleUnaryPrefixExpression(Token t) {
361 push(new UnaryOperator(t.value, pop()));
362 }
363
364 handleFunctionTypedFormalParameter(tok) {
365 // handled in endFormalParameter
366 }
367 endFormalParameter(thisKeyword) {
368 Expression defaultValue = null;
369 var x = pop();
370 if (x is DefaultValue) {
371 defaultValue = x.expression;
372 x = pop();
373 }
374 if (x is Parameters) {
375 String name = pop(asName);
376 TypeAnnotation returnType = popTypeAnnotation();
377 push(new Parameter.function(name, returnType, x, defaultValue));
378 } else {
379 String name = asName(x);
380 TypeAnnotation type = popTypeAnnotation();
381 push(new Parameter(name, type:type, defaultValue:defaultValue));
382 }
383 }
384 handleValuedFormalParameter(eq, tok) {
385 push(new DefaultValue(pop()));
386 }
387 endOptionalFormalParameters(int count, begin, end) {
388 bool isNamed = end.value == '}';
389 push(popList(count, <Parameter>[], asParameter));
390 push(isNamed); // Indicate optional parameters to endFormalParameters.
391 }
392 endFormalParameters(count, begin, end) {
393 if (count == 0) {
394 push(new Parameters([]));
395 return;
396 }
397 var last = pop(); // Detect if optional parameters are present.
398 if (last is bool) { // See endOptionalFormalParameters.
399 List<Parameter> optional = pop();
400 List<Parameter> required = popList(count-1, <Parameter>[], asParameter);
401 push(new Parameters(required, optional, last));
402 } else {
403 // No optional parameters.
404 List<Parameter> required = popList(count-1, <Parameter>[], asParameter);
405 required.add(last);
406 push(new Parameters(required));
407 }
408 }
409 handleNoFormalParameters(tok) {
410 push(new Parameters([]));
411 }
412 endUnamedFunction(t) {
413 Statement body = pop();
414 Parameters parameters = pop();
415 push(new FunctionExpression(parameters, body));
416 }
417 handleNoType(Token token) {
418 push(null);
419 }
420
421 endReturnStatement(bool hasExpression, begin, end) {
422 // This is also called for functions whose body is "=> expression"
423 if (hasExpression) {
424 push(new Return(pop()));
425 } else {
426 push(new Return());
427 }
428 }
429
430 endExpressionStatement(Token token) {
431 push(new ExpressionStatement(pop()));
432 }
433
434 endDoWhileStatement(Token doKeyword, Token whileKeyword, Token end) {
435 Expression condition = pop();
436 Statement body = pop();
437 push(new DoWhile(body, condition));
438 }
439
440 endWhileStatement(Token whileKeyword, Token end) {
441 Statement body = pop();
442 Expression condition = pop();
443 push(new While(condition, body));
444 }
445
446 endBlock(int count, Token begin, Token end) {
447 push(new Block(popList(count, <Statement>[])));
448 }
449
450 endRethrowStatement(Token throwToken, Token endToken) {
451 push(new Rethrow());
452 }
453
454 endTryStatement(int catchCount, Token tryKeyword, Token finallyKeyword) {
455 Statement finallyBlock = null;
456 if (finallyKeyword != null) {
457 finallyBlock = pop();
458 }
459 List<CatchBlock> catchBlocks = popList(catchCount, <CatchBlock>[]);
460 Statement tryBlock = pop();
461 push(new Try(tryBlock, catchBlocks, finallyBlock));
462 }
463
464 void handleCatchBlock(Token onKeyword, Token catchKeyword) {
465 Statement block = pop();
466 String exceptionVar = null;
467 String stackVar = null;
468 if (catchKeyword != null) {
469 Parameters params = pop();
470 exceptionVar = params.requiredParameters[0].name;
471 if (params.requiredParameters.length > 1) {
472 stackVar = params.requiredParameters[1].name;
473 }
474 }
475 TypeAnnotation type = onKeyword == null ? null : pop();
476 push(new CatchBlock(block,
477 onType: type,
478 exceptionVar: exceptionVar,
479 stackVar: stackVar
480 ));
481 }
482
483 endSwitchStatement(Token switchKeyword, Token end) {
484 List<SwitchCase> cases = pop();
485 Expression expression = pop();
486 push(new Switch(expression, cases));
487 }
488
489 endSwitchBlock(int caseCount, Token begin, Token end) {
490 push(popList(caseCount, <SwitchCase>[]));
491 }
492
493 handleSwitchCase(int labelCount, int caseCount, Token defaultKeyword,
494 int statementCount, Token first, Token end) {
495 List<Statement> statements = popList(statementCount, <Statement>[]);
496 List<Expression> cases = popList(caseCount, <Expression>[]);
497 if (defaultKeyword != null) {
498 cases = null;
499 }
500 push(new SwitchCase(cases, statements));
501 }
502
503 handleCaseMatch(Token caseKeyword, Token colon) {
504 // do nothing, leave case expression on stack
505 }
506
507 handleBreakStatement(bool hasTarget, Token breakKeyword, Token end) {
508 String target = hasTarget ? pop(asName) : null;
509 push(new Break(target));
510 }
511
512 handleContinueStatement(bool hasTarget, Token continueKeyword, Token end) {
513 String target = hasTarget ? pop(asName) : null;
514 push(new Continue(target));
515 }
516
517 handleEmptyStatement(Token token) {
518 push(new EmptyStatement());
519 }
520
521
522 VariableDeclaration asVariableDeclaration(x) {
523 if (x is VariableDeclaration)
524 return x;
525 if (x is Identifier)
526 return new VariableDeclaration(x.name);
527 throw "Not a variable definition: ${x.runtimeType}";
528 }
529
530 endVariablesDeclaration(int count, Token end) {
531 List<VariableDeclaration> variables =
532 popList(count, <VariableDeclaration>[], asVariableDeclaration);
533 TypeAnnotation type = popTypeAnnotation();
534 push(new VariableDeclarations(variables,
535 type: type,
536 isFinal: false, // TODO(asgerf): Parse modifiers.
537 isConst: false
538 ));
539 }
540
541 endInitializer(Token assign) {
542 Expression init = pop();
543 String name = pop(asName);
544 push(new VariableDeclaration(name, init));
545 }
546
547 endIfStatement(Token ifToken, Token elseToken) {
548 Statement elsePart = (elseToken == null) ? null : pop();
549 Statement thenPart = pop();
550 Expression condition = pop();
551 push(new If(condition, thenPart, elsePart));
552 }
553
554 endForStatement(int updateCount, Token begin, Token end) {
555 Statement body = pop();
556 List<Expression> updates = popList(updateCount, <Expression>[]);
557 ExpressionStatement condition = pop(); // parsed as expression statement
558 Expression exp = condition == null ? null : condition.expression;
559 Node initializer = pop();
560 push(new For(initializer, exp, updates, body));
561 }
562
563 handleNoExpression(Token token) {
564 push(null);
565 }
566
567 endForIn(Token begin, Token inKeyword, Token end) {
568 Statement body = pop();
569 Expression exp = pop();
570 Node declaredIdentifier = pop();
571 push(new ForIn(declaredIdentifier, exp, body));
572 }
573
574 handleAssertStatement(Token assertKeyword, Token semicolonToken) {
575 Expression exp = pop();
576 Expression call = new CallFunction(new Identifier("assert"), [exp]);
577 push(new ExpressionStatement(call));
578 }
579
580 endLabeledStatement(int labelCount) {
581 Statement statement = pop();
582 for (int i=0; i<labelCount; i++) {
583 String label = pop(asName);
584 statement = new LabeledStatement(label, statement);
585 }
586 push(statement);
587 }
588
589 endFunctionDeclaration(Token end) {
590 Statement body = pop();
591 Parameters parameters = pop();
592 String name = pop(asName);
593 TypeAnnotation returnType = popTypeAnnotation();
594 push(new FunctionStatement(name, parameters, body, returnType));
595 }
596
597 endFunctionBody(int count, Token begin, Token end) {
598 push(new Block(popList(count, <Statement>[])));
599 }
600 }
601
602 class DefaultValue {
603 final Expression expression;
604 DefaultValue(this.expression);
605 }
606
607 /// Compares ASTs for structural equality.
608 void checkDeepEqual(x, y) {
609 if (x is List && y is List) {
610 if (x.length != y.length)
611 return;
612 for (var i=0; i<x.length; i++) {
613 checkDeepEqual(x[i], y[i]);
614 }
615 }
616 else if (x is Node && y is Node) {
617 if (x.runtimeType != y.runtimeType)
618 throw new Error();
619 InstanceMirror xm = reflect(x);
620 InstanceMirror ym = reflect(y);
621 for (Symbol name in xm.type.instanceMembers.keys) {
622 if (reflectClass(Object).declarations.containsKey(name)) {
623 continue; // do not check things from Object, such as hashCode
624 }
625 MethodMirror mm = xm.type.instanceMembers[name];
626 if (mm.isGetter) {
627 var xv = xm.getField(name).reflectee;
628 var yv = ym.getField(name).reflectee;
629 checkDeepEqual(xv,yv);
630 }
631 }
632 }
633 else if (x is PrimitiveConstant && y is PrimitiveConstant) {
634 checkDeepEqual(x.value, y.value);
635 }
636 else if (x is DartString && y is DartString) {
637 if (x.slowToString() != y.slowToString()) {
638 throw new Error();
639 }
640 }
641 else {
642 if (x != y) {
643 throw new Error();
644 }
645 }
646 }
647
648 Expression parseExpression(String code) {
649 SourceFile file = new StringSourceFile('', code);
650 Scanner scan = new Scanner(file);
651 Token tok = scan.tokenize();
652 AstBuilder builder = new AstBuilder();
653 Parser parser = new Parser(builder);
654 tok = parser.parseExpression(tok);
655 if (builder.stack.length != 1 || tok.kind != EOF_TOKEN) {
656 throw "Parse error in $code";
657 }
658 return builder.pop();
659 }
660 Statement parseStatement(String code) {
661 SourceFile file = new StringSourceFile('', code);
662 Scanner scan = new Scanner(file);
663 Token tok = scan.tokenize();
664 AstBuilder builder = new AstBuilder();
665 Parser parser = new Parser(builder);
666 tok = parser.parseStatement(tok);
667 if (builder.stack.length != 1 || tok.kind != EOF_TOKEN) {
668 throw "Parse error in $code";
669 }
670 return builder.pop();
671 }
672
673 String unparseExpression(Expression exp) {
674 StringBuffer buf = new StringBuffer();
675 new Unparser(buf).writeExpression(exp);
676 return buf.toString();
677 }
678 String unparseStatement(Statement stmt) {
679 StringBuffer buf = new StringBuffer();
680 new Unparser(buf).writeStatement(stmt);
681 return buf.toString();
682 }
683
684 /// Parses [code], unparses the resulting AST, then parses the unparsed text.
685 /// The ASTs from the first and second parse are then compared for structural
686 /// equality. Alternatively, if [expected] is not an empty string, the second
687 /// parse must match the AST of parsing [expected].
688 void checkFn(String code, String expected, Function parse, Function unparse) {
689 String unparsed = "";
690 try {
691 var firstParse = parse(code);
692 unparsed = unparse(firstParse);
693 var secondParse = parse(unparsed);
694 var baseline = expected == "" ? firstParse : parse(expected);
695 checkDeepEqual(baseline, secondParse);
696 } catch (e, stack) {
697 Expect.fail('"$code" was unparsed as "$unparsed"');
698 }
699 }
700
701 void checkExpression(String code, [String expected=""]) {
702 checkFn(code, expected, parseExpression, unparseExpression);
703 }
704 void checkStatement(String code, [String expected=""]) {
705 checkFn(code, expected, parseStatement, unparseStatement);
706 }
707
708 void debugTokens(String code) {
709 SourceFile file = new StringSourceFile('', code);
710 Scanner scan = new Scanner(file);
711 Token tok = scan.tokenize();
712 while (tok.next != tok) {
713 print(tok.toString());
714 tok = tok.next;
715 }
716 }
717
718 void main() {
719 // To check if these tests are effective, one should manually alter
720 // something in [Unparser] and see if a test fails.
721
722 checkExpression(" a + b + c");
723 checkExpression("(a + b) + c");
724 checkExpression(" a + (b + c)");
725
726 checkExpression(" a + b - c");
727 checkExpression("(a + b) - c");
728 checkExpression(" a + (b - c)");
729
730 checkExpression(" a - b + c");
731 checkExpression("(a - b) + c");
732 checkExpression(" a - (b + c)");
733
734 checkExpression(" a * b + c");
735 checkExpression("(a * b) + c");
736 checkExpression(" a * (b + c)");
737
738 checkExpression(" a + b * c");
739 checkExpression("(a + b) * c");
740 checkExpression(" a + (b * c)");
741
742 checkExpression(" a * b * c");
743 checkExpression("(a * b) * c");
744 checkExpression(" a * (b * c)");
745
746 checkExpression("a is T");
747 checkExpression("a is! T");
748 checkExpression("!(a is T)");
749
750 checkExpression("a is T.x");
751 checkExpression("a is! T.x");
752 checkExpression("!(a is T.x)");
753 checkExpression("!(a is T).x");
754
755 checkExpression("a as T.x");
756 checkExpression("(a as T).x");
757
758 checkExpression("a == b");
759 checkExpression("a != b");
760 checkExpression("!(a == b)", "a != b");
761
762 checkExpression("a && b ? c : d");
763 checkExpression("(a && b) ? c : d");
764 checkExpression("a && (b ? c : d)");
765
766 checkExpression("a || b ? c : d");
767 checkExpression("(a || b) ? c : d");
768 checkExpression("a || (b ? c : d)");
769
770 checkExpression(" a ? b : c && d");
771 checkExpression(" a ? b : (c && d)");
772 checkExpression("(a ? b : c) && d");
773
774 checkExpression(" a ? b : c = d");
775 checkExpression(" a ? b : (c = d)");
776
777 checkExpression("(a == b) == c");
778 checkExpression("a == (b == c)");
779
780 checkExpression(" a < b == c");
781 checkExpression("(a < b) == c");
782 checkExpression(" a < (b == c)");
783
784 checkExpression(" a == b < c");
785 checkExpression("(a == b) < c");
786 checkExpression(" a == (b < c)");
787
788 checkExpression("x.f()");
789 checkExpression("(x.f)()");
790
791 checkExpression("x.f()()");
792 checkExpression("(x.f)()()");
793
794 checkExpression("x.f().g()");
795 checkExpression("(x.f)().g()");
796
797 checkExpression("x.f()");
798 checkExpression("x.f(1 + 2)");
799 checkExpression("x.f(1 + 2, 3 + 4)");
800 checkExpression("x.f(1 + 2, foo:3 + 4)");
801 checkExpression("x.f(1 + 2, foo:3 + 4, bar: 5)");
802 checkExpression("x.f(foo:3 + 4)");
803 checkExpression("x.f(foo:3 + 4, bar: 5)");
804
805 checkExpression("x.f.g.h");
806 checkExpression("(x.f).g.h");
807 checkExpression("(x.f.g).h");
808
809 checkExpression(" a = b + c");
810 checkExpression(" a = (b + c)");
811 checkExpression("(a = b) + c");
812
813 checkExpression("a + (b = c)");
814
815 checkExpression("dx * dx + dy * dy < r * r",
816 "((dx * dx) + (dy * dy)) < (r * r)");
817 checkExpression("mid = left + right << 1",
818 "mid = ((left + right) << 1)");
819 checkExpression("a + b % c * -d ^ e - f ~/ x & ++y / z++ | w > a ? b : c");
820 checkExpression("a + b % c * -d ^ (e - f) ~/ x & ++y / z++ | w > a ? b : c");
821
822 checkExpression("'foo'");
823 checkExpression("'foo' 'bar'", "'foobar'");
824
825 checkExpression("{}.length");
826 checkExpression("{x: 1+2}.length");
827 checkExpression("<String,int>{}.length");
828 checkExpression("<String,int>{x: 1+2}.length");
829
830 checkExpression("[].length");
831 checkExpression("[1+2].length");
832 checkExpression("<num>[].length");
833 checkExpression("<num>[1+2].length");
834
835 checkExpression("x + -y");
836 checkExpression("x + --y");
837 checkExpression("x++ + y");
838 checkExpression("x + ++y");
839 checkExpression("x-- - y");
840 checkExpression("x-- - -y");
841 checkExpression("x - --y");
842
843 checkExpression("x && !y");
844 checkExpression("!x && y");
845 checkExpression("!(x && y)");
846
847 checkExpression(" super + 1 * 2");
848 checkExpression("(super + 1) * 2");
849 checkExpression(" super + (1 * 2)");
850 checkExpression("x + -super");
851 checkExpression("x-- - -super");
852 checkExpression("x - -super");
853 checkExpression("x && !super");
854
855 checkExpression("super.f(1, 2) + 3");
856 checkExpression("super.f + 3");
857
858 checkExpression(r"'foo\nbar'");
859 checkExpression(r"'foo\r\nbar'");
860 checkExpression(r"'foo\rbar'");
861 checkExpression(r"'foo\'bar'");
862 checkExpression(r"""'foo"bar'""");
863 checkExpression(r"r'foo\nbar'");
864 checkExpression("''");
865 checkExpression("r''");
866
867 var sq = "'";
868 var dq = '"';
869 checkExpression("'$dq$dq' \"$sq$sq\"");
870 checkExpression("'$dq$dq$dq$dq' \"$sq$sq$sq$sq\"");
871 checkExpression(r"'\$\$\$\$\$\$\$\$\$'");
872 checkExpression("'$dq$dq$dq' '\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n' \"$sq$sq$sq\"");
873 checkExpression("'$dq$dq$dq' '\\r\\r\\r\\r\\r\\r\\r\\r\\r\\r' \"$sq$sq$sq\"");
874 checkExpression("'$dq$dq$dq' '\\r\\n\\r\\n\\r\\n\\r\\n\\r\\n' \"$sq$sq$sq\"");
875
876 checkExpression(r"'$foo'");
877 checkExpression(r"'${foo}x'");
878 checkExpression(r"'${foo}x\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'");
879 checkExpression(r"'abc' '${foo}' r'\\\\\\\'");
880
881 checkExpression(r"'${$x}'");
882 checkExpression(r"'${$x}y'");
883
884 checkStatement("var x, y, z;");
885 checkStatement("final x, y, z;");
886 checkStatement("dynamic x, y, z;");
887 checkStatement("String x, y, z;");
888 checkStatement("List<int> x, y, z;");
889 checkStatement("final dynamic x, y, z;");
890 checkStatement("final String x, y, z;");
891 checkStatement("final List<int> x, y, z;");
892
893 checkStatement("var x = y, z;");
894 checkStatement("var x, y = z;");
895 checkStatement("var x = y = z;");
896
897 // Note: We sometimes have to pass an expected string to account for
898 // block flattening which does not preserve structural AST equality
899 checkStatement("if (x) if (y) foo(); else bar(); ");
900 checkStatement("if (x) { if (y) foo(); } else bar(); ");
901 checkStatement("if (x) { if (y) foo(); else bar(); }",
902 "if (x) if (y) foo(); else bar(); ");
903
904 checkStatement("if (x) while (y) if (z) foo(); else bar(); ");
905 checkStatement("if (x) while (y) { if (z) foo(); } else bar(); ");
906 checkStatement("if (x) while (y) { if (z) foo(); else bar(); }",
907 "if (x) while (y) if (z) foo(); else bar(); ");
908
909 checkStatement("{var x = 1; {var x = 2;} return x;}");
910 checkStatement("{var x = 1; {x = 2;} return x;}",
911 "{var x = 1; x = 2; return x;}");
912
913 checkStatement("if (x) {var x = 1;}");
914
915 checkStatement("({'foo': 1}).bar();");
916 checkStatement("({'foo': 1}).length;");
917 checkStatement("({'foo': 1}).length + 1;");
918 checkStatement("({'foo': 1})['foo'].toString();");
919 checkStatement("({'foo': 1})['foo'] = 3;");
920 checkStatement("({'foo': 1}['foo']());");
921 checkStatement("({'foo': 1}['foo'])();");
922 checkStatement("({'foo': 1})['foo'].x++;");
923 checkStatement("({'foo': 1}) is Map;");
924 checkStatement("({'foo': 1}) as Map;");
925 checkStatement("({'foo': 1}) is util.Map;");
926 checkStatement("({'foo': 1}) + 1;");
927
928 checkStatement("[1].bar();");
929 checkStatement("1.bar();");
930 checkStatement("'foo'.bar();");
931
932 checkStatement("do while(x); while (y);");
933 checkStatement("{do; while(x); while (y);}");
934
935 }
936
OLDNEW
« no previous file with comments | « sdk/lib/_internal/compiler/implementation/dart_backend/dart_printer.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698