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

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

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

Powered by Google App Engine
This is Rietveld 408576698