Index: tests/compiler/dart2js/js_parser_statements_test.dart |
diff --git a/tests/compiler/dart2js/js_parser_statements_test.dart b/tests/compiler/dart2js/js_parser_statements_test.dart |
index 6c18de35b7d149daf263339cb7047211d8a45fcd..9432ffb599e0ccb2cc52b2c7c82f5544dc3661a5 100644 |
--- a/tests/compiler/dart2js/js_parser_statements_test.dart |
+++ b/tests/compiler/dart2js/js_parser_statements_test.dart |
@@ -9,7 +9,6 @@ import 'mock_compiler.dart'; |
import 'package:compiler/src/js/js.dart' as jsAst; |
import 'package:compiler/src/js/js.dart' show js; |
- |
Future testStatement(String statement, arguments, String expect) { |
jsAst.Node node = js.statement(statement, arguments); |
return MockCompiler.create((MockCompiler compiler) { |
@@ -27,9 +26,11 @@ Future testError(String statement, arguments, [String expect = ""]) { |
Expect.isTrue(message.contains(expect), '"$message" contains "$expect"'); |
return true; |
} |
+ |
void action() { |
jsAst.Node node = js.statement(statement, arguments); |
} |
+ |
Expect.throws(action, doCheck); |
}); |
} |
@@ -71,9 +72,7 @@ function foo() { |
2; |
}'''; |
- |
void main() { |
- |
var eOne = js('1'); |
var eTwo = js('2'); |
var eTrue = js('true'); |
@@ -87,65 +86,58 @@ void main() { |
Expect.isTrue(block12 is jsAst.Block); |
asyncTest(() => Future.wait([ |
- // Interpolated Expressions are upgraded to ExpressionStatements. |
- testStatement('{ #; #; }', [eOne, eOne], '{\n 1;\n 1;\n}'), |
- testStatement('{ #a; #b; }', {'a': eOne, 'b': eOne}, '{\n 1;\n 1;\n}'), |
- |
- // Interpolated sub-blocks are spliced. |
- testStatement('{ #; #; }', [block12, block12], |
- '{\n 1;\n 2;\n 1;\n 2;\n}\n'), |
- testStatement('{ #a; #b; }', {'a': block12, 'b': block12}, |
- '{\n 1;\n 2;\n 1;\n 2;\n}\n'), |
- |
- // If-condition. Dart booleans are evaluated, JS Expression booleans are |
- // substituted. |
- testStatement('if (#) #', [eOne, block12], 'if (1) {\n 1;\n 2;\n}'), |
- testStatement('if (#) #;', [eTrue, block12], 'if (true) {\n 1;\n 2;\n}'), |
- testStatement('if (#) #;', [eVar, block12], 'if (x) {\n 1;\n 2;\n}'), |
- testStatement('if (#) #;', ['a', block12], 'if (a) {\n 1;\n 2;\n}'), |
- testStatement('if (#) #;', [true, block12], '{\n 1;\n 2;\n}'), |
- testStatement('if (#) #;', [false, block12], ';'), |
- testStatement('if (#) 3; else #;', [true, block12], '3;'), |
- testStatement('if (#) 3; else #;', [false, block12], '{\n 1;\n 2;\n}'), |
- testStatement('if (#a) #b', |
- {'a': eOne, 'b': block12}, |
- 'if (1) {\n 1;\n 2;\n}'), |
- testStatement('if (#a) #b;', |
- {'a': eTrue, 'b': block12}, |
- 'if (true) {\n 1;\n 2;\n}'), |
- testStatement('if (#a) #b;', |
- {'a': eVar, 'b': block12}, |
- 'if (x) {\n 1;\n 2;\n}'), |
- testStatement('if (#a) #b;', |
- {'a': 'a', 'b': block12}, |
- 'if (a) {\n 1;\n 2;\n}'), |
- testStatement('if (#a) #b;', |
- {'a': true, 'b': block12}, |
- '{\n 1;\n 2;\n}'), |
- testStatement('if (#a) #b;', |
- {'a': false, 'b': block12}, |
- ';'), |
- testStatement('if (#a) 3; else #b;', |
- {'a': true, 'b': block12}, |
- '3;'), |
- testStatement('if (#a) 3; else #b;', |
- {'a': false, 'b': block12}, |
- '{\n 1;\n 2;\n}'), |
- |
- |
- testStatement('while (#) #', [eOne, block12], 'while (1) {\n 1;\n 2;\n}'), |
- testStatement('while (#) #;', [eTrue, block12], |
- 'while (true) {\n 1;\n 2;\n}'), |
- testStatement('while (#) #;', [eVar, block12], |
- 'while (x) {\n 1;\n 2;\n}'), |
- testStatement('while (#) #;', ['a', block12], |
- 'while (a) {\n 1;\n 2;\n}'), |
- testStatement('while (#) #;', ['a', stm], |
- 'while (a)\n foo();'), |
- |
- testStatement( |
- 'do { {print(1);} do while(true); while (false) } while ( true )', [], |
- ''' |
+ // Interpolated Expressions are upgraded to ExpressionStatements. |
+ testStatement('{ #; #; }', [eOne, eOne], '{\n 1;\n 1;\n}'), |
+ testStatement( |
+ '{ #a; #b; }', {'a': eOne, 'b': eOne}, '{\n 1;\n 1;\n}'), |
+ |
+ // Interpolated sub-blocks are spliced. |
+ testStatement( |
+ '{ #; #; }', [block12, block12], '{\n 1;\n 2;\n 1;\n 2;\n}\n'), |
+ testStatement('{ #a; #b; }', {'a': block12, 'b': block12}, |
+ '{\n 1;\n 2;\n 1;\n 2;\n}\n'), |
+ |
+ // If-condition. Dart booleans are evaluated, JS Expression booleans are |
+ // substituted. |
+ testStatement('if (#) #', [eOne, block12], 'if (1) {\n 1;\n 2;\n}'), |
+ testStatement( |
+ 'if (#) #;', [eTrue, block12], 'if (true) {\n 1;\n 2;\n}'), |
+ testStatement('if (#) #;', [eVar, block12], 'if (x) {\n 1;\n 2;\n}'), |
+ testStatement('if (#) #;', ['a', block12], 'if (a) {\n 1;\n 2;\n}'), |
+ testStatement('if (#) #;', [true, block12], '{\n 1;\n 2;\n}'), |
+ testStatement('if (#) #;', [false, block12], ';'), |
+ testStatement('if (#) 3; else #;', [true, block12], '3;'), |
+ testStatement( |
+ 'if (#) 3; else #;', [false, block12], '{\n 1;\n 2;\n}'), |
+ testStatement( |
+ 'if (#a) #b', {'a': eOne, 'b': block12}, 'if (1) {\n 1;\n 2;\n}'), |
+ testStatement('if (#a) #b;', {'a': eTrue, 'b': block12}, |
+ 'if (true) {\n 1;\n 2;\n}'), |
+ testStatement('if (#a) #b;', {'a': eVar, 'b': block12}, |
+ 'if (x) {\n 1;\n 2;\n}'), |
+ testStatement( |
+ 'if (#a) #b;', {'a': 'a', 'b': block12}, 'if (a) {\n 1;\n 2;\n}'), |
+ testStatement( |
+ 'if (#a) #b;', {'a': true, 'b': block12}, '{\n 1;\n 2;\n}'), |
+ testStatement('if (#a) #b;', {'a': false, 'b': block12}, ';'), |
+ testStatement('if (#a) 3; else #b;', {'a': true, 'b': block12}, '3;'), |
+ testStatement('if (#a) 3; else #b;', {'a': false, 'b': block12}, |
+ '{\n 1;\n 2;\n}'), |
+ |
+ testStatement( |
+ 'while (#) #', [eOne, block12], 'while (1) {\n 1;\n 2;\n}'), |
+ testStatement( |
+ 'while (#) #;', [eTrue, block12], 'while (true) {\n 1;\n 2;\n}'), |
+ testStatement( |
+ 'while (#) #;', [eVar, block12], 'while (x) {\n 1;\n 2;\n}'), |
+ testStatement( |
+ 'while (#) #;', ['a', block12], 'while (a) {\n 1;\n 2;\n}'), |
+ testStatement('while (#) #;', ['a', stm], 'while (a)\n foo();'), |
+ |
+ testStatement( |
+ 'do { {print(1);} do while(true); while (false) } while ( true )', |
+ [], |
+ ''' |
do { |
print(1); |
do |
@@ -154,30 +146,35 @@ do { |
while (false); |
} while (true); |
'''), |
- testStatement('do #; while ( # )', [block12, eOne], |
- 'do {\n 1;\n 2;\n} while (1); '), |
- testStatement('do #; while ( # )', [block12, eTrue], |
- 'do {\n 1;\n 2;\n} while (true); '), |
- testStatement('do #; while ( # );', [block12, eVar], |
- 'do {\n 1;\n 2;\n} while (x);'), |
- testStatement('do { # } while ( # )', [block12, 'a'], |
- 'do {\n 1;\n 2;\n} while (a);'), |
- testStatement('do #; while ( # )', [stm, 'a'], |
- 'do\n foo();\nwhile (a);'), |
- |
- testStatement('switch (#) {}', [eOne], 'switch (1) {\n}'), |
- testStatement(''' |
+ testStatement('do #; while ( # )', [block12, eOne], |
+ 'do {\n 1;\n 2;\n} while (1); '), |
+ testStatement('do #; while ( # )', [block12, eTrue], |
+ 'do {\n 1;\n 2;\n} while (true); '), |
+ testStatement('do #; while ( # );', [block12, eVar], |
+ 'do {\n 1;\n 2;\n} while (x);'), |
+ testStatement('do { # } while ( # )', [block12, 'a'], |
+ 'do {\n 1;\n 2;\n} while (a);'), |
+ testStatement( |
+ 'do #; while ( # )', [stm, 'a'], 'do\n foo();\nwhile (a);'), |
+ |
+ testStatement('switch (#) {}', [eOne], 'switch (1) {\n}'), |
+ testStatement( |
+ ''' |
switch (#) { |
case #: { # } |
- }''', [eTrue, eOne, block12], |
- 'switch (true) {\n case 1:\n 1;\n 2;\n}'), |
- testStatement(''' |
+ }''', |
+ [eTrue, eOne, block12], |
+ 'switch (true) {\n case 1:\n 1;\n 2;\n}'), |
+ testStatement( |
+ ''' |
switch (#) { |
case #: { # } |
break; |
case #: { # } |
default: { # } |
- }''', [eTrue, eOne, block12, eTwo, block12, stm], ''' |
+ }''', |
+ [eTrue, eOne, block12, eTwo, block12, stm], |
+ ''' |
switch (true) { |
case 1: |
1; |
@@ -190,199 +187,321 @@ switch (true) { |
foo(); |
}'''), |
- testStatement(NAMED_FUNCTION_1, [eOne], NAMED_FUNCTION_1_ONE), |
- testStatement(NAMED_FUNCTION_1_NAMED_HOLE, |
- {'hole': eOne}, |
- NAMED_FUNCTION_1_ONE), |
- |
- testStatement(MISC_1, [block12], MISC_1_1), |
- testStatement(MISC_1_NAMED_HOLE, {'hole': block12}, MISC_1_1), |
- |
- // Argument list splicing. |
- testStatement('foo(#)', [[]], 'foo();'), |
- testStatement('foo(#)', [[eOne]], 'foo(1);'), |
- testStatement('foo(#)', [eOne], 'foo(1);'), |
- testStatement('foo(#)', [[eTrue,eOne]], 'foo(true, 1);'), |
- testStatement('foo(#a)', {'a': []}, 'foo();'), |
- testStatement('foo(#a)', {'a': [eOne]}, 'foo(1);'), |
- testStatement('foo(#a)', {'a': eOne}, 'foo(1);'), |
- testStatement('foo(#a)', {'a': [eTrue,eOne]}, 'foo(true, 1);'), |
- |
- testStatement('foo(2,#)', [[]], 'foo(2);'), |
- testStatement('foo(2,#)', [[eOne]], 'foo(2, 1);'), |
- testStatement('foo(2,#)', [eOne], 'foo(2, 1);'), |
- testStatement('foo(2,#)', [[eTrue,eOne]], 'foo(2, true, 1);'), |
- testStatement('foo(2,#a)', {'a': []}, 'foo(2);'), |
- testStatement('foo(2,#a)', {'a': [eOne]}, 'foo(2, 1);'), |
- testStatement('foo(2,#a)', {'a': eOne}, 'foo(2, 1);'), |
- testStatement('foo(2,#a)', {'a': [eTrue,eOne]}, 'foo(2, true, 1);'), |
- |
- testStatement('foo(#,3)', [[]], 'foo(3);'), |
- testStatement('foo(#,3)', [[eOne]], 'foo(1, 3);'), |
- testStatement('foo(#,3)', [eOne], 'foo(1, 3);'), |
- testStatement('foo(#,3)', [[eTrue,eOne]], 'foo(true, 1, 3);'), |
- testStatement('foo(#a,3)', {'a': []}, 'foo(3);'), |
- testStatement('foo(#a,3)', {'a': [eOne]}, 'foo(1, 3);'), |
- testStatement('foo(#a,3)', {'a': eOne}, 'foo(1, 3);'), |
- testStatement('foo(#a,3)', {'a': [eTrue,eOne]}, 'foo(true, 1, 3);'), |
- |
- testStatement('foo(2,#,3)', [[]], 'foo(2, 3);'), |
- testStatement('foo(2,#,3)', [[eOne]], 'foo(2, 1, 3);'), |
- testStatement('foo(2,#,3)', [eOne], 'foo(2, 1, 3);'), |
- testStatement('foo(2,#,3)', [[eTrue,eOne]], 'foo(2, true, 1, 3);'), |
- testStatement('foo(2,#a,3)', {'a': []}, 'foo(2, 3);'), |
- testStatement('foo(2,#a,3)', {'a': [eOne]}, 'foo(2, 1, 3);'), |
- testStatement('foo(2,#a,3)', {'a': eOne}, 'foo(2, 1, 3);'), |
- testStatement('foo(2,#a,3)', {'a': [eTrue,eOne]}, 'foo(2, true, 1, 3);'), |
- |
- // Interpolated Literals |
- testStatement('a = {#: 1}', [eOne], 'a = {1: 1};'), |
- testStatement('a = {#a: 1}', {'a': eOne}, 'a = {1: 1};'), |
- // Maybe we should make this work? |
- testError('a = {#: 1}', [1], 'is not a Literal: 1'), |
- testError('a = {#a: 1}', {'a': 1}, 'is not a Literal: 1'), |
- |
- // Interpolated parameter splicing. |
- testStatement('function foo(#){}', [new jsAst.Parameter('x')], |
- 'function foo(x) {\n}'), |
- testStatement('function foo(#){}', ['x'], 'function foo(x) {\n}'), |
- testStatement('function foo(#){}', [[]], 'function foo() {\n}'), |
- testStatement('function foo(#){}', [['x']], 'function foo(x) {\n}'), |
- testStatement('function foo(#){}', [['x', 'y']], 'function foo(x, y) {\n}'), |
- testStatement('function foo(#a){}', {'a': new jsAst.Parameter('x')}, |
- 'function foo(x) {\n}'), |
- testStatement('function foo(#a){}', {'a': 'x'}, 'function foo(x) {\n}'), |
- testStatement('function foo(#a){}', {'a': []}, 'function foo() {\n}'), |
- testStatement('function foo(#a){}', {'a': ['x']}, 'function foo(x) {\n}'), |
- testStatement('function foo(#a){}', |
- {'a': ['x', 'y']}, |
- 'function foo(x, y) {\n}'), |
- |
- testStatement('function foo() async {}', [], 'function foo() async {\n}'), |
- testStatement('function foo() sync* {}', [], 'function foo() sync* {\n}'), |
- testStatement('function foo() async* {}', [], 'function foo() async* {\n}'), |
- |
- testStatement('a = #.#', [eVar,eOne], 'a = x[1];'), |
- testStatement('a = #.#', [eVar,'foo'], 'a = x.foo;'), |
- testStatement('a = #a.#b', {'a': eVar, 'b': eOne}, 'a = x[1];'), |
- testStatement('a = #a.#b', {'a': eVar, 'b': 'foo'}, 'a = x.foo;'), |
- |
- testStatement('function f(#) { return #.#; }', ['x', eVar,'foo'], |
- 'function f(x) {\n return x.foo;\n}'), |
- testStatement('function f(#a) { return #b.#c; }', |
- {'a': 'x', 'b': eVar, 'c': 'foo'}, |
- 'function f(x) {\n return x.foo;\n}'), |
- |
- testStatement('#.prototype.# = function(#) { return #.# };', |
- ['className', 'getterName', ['r', 'y'], 'r', 'fieldName'], |
- 'className.prototype.getterName = function(r, y) {\n' |
- ' return r.fieldName;\n' |
- '};'), |
- testStatement('#a.prototype.#b = function(#c) { return #d.#e };', |
- {'a': 'className', |
- 'b': 'getterName', |
- 'c': ['r', 'y'], |
- 'd': 'r', |
- 'e': 'fieldName'}, |
- 'className.prototype.getterName = function(r, y) {\n' |
- ' return r.fieldName;\n' |
- '};'), |
- |
- testStatement('function foo(r, #) { return #[r](#) }', |
- [['a', 'b'], 'g', ['b', 'a']], |
- 'function foo(r, a, b) {\n return g[r](b, a);\n}'), |
- testStatement('function foo(r, #a) { return #b[r](#c) }', |
- {'a': ['a', 'b'], 'b': 'g', 'c': ['b', 'a']}, |
- 'function foo(r, a, b) {\n return g[r](b, a);\n}'), |
- |
- // Sequence is printed flattened |
- testStatement('x = #', [seq1], 'x = (1, 2, 3);'), |
- testStatement('x = (#, #)', [seq1, seq1], 'x = (1, 2, 3, 1, 2, 3);'), |
- testStatement('x = #, #', [seq1, seq1], 'x = (1, 2, 3), 1, 2, 3;'), |
- testStatement( |
- 'for (i = 0, j = #, k = 0; ; ++i, ++j, ++k){}', [seq1], |
- 'for (i = 0, j = (1, 2, 3), k = 0;; ++i, ++j, ++k) {\n}'), |
- testStatement('x = #a', {'a': seq1}, 'x = (1, 2, 3);'), |
- testStatement('x = (#a, #b)', |
- {'a': seq1, 'b': seq1}, |
- 'x = (1, 2, 3, 1, 2, 3);'), |
- testStatement('x = #a, #b', |
- {'a': seq1, 'b': seq1}, |
- 'x = (1, 2, 3), 1, 2, 3;'), |
- testStatement( |
- 'for (i = 0, j = #a, k = 0; ; ++i, ++j, ++k){}', {'a': seq1}, |
- 'for (i = 0, j = (1, 2, 3), k = 0;; ++i, ++j, ++k) {\n}'), |
- |
- // Use the same name several times. |
- testStatement('#a.prototype.#a = function(#b) { return #c.#c };', |
- {'a': 'name1_2', |
- 'b': ['r', 'y'], |
- 'c': 'name4_5'}, |
- 'name1_2.prototype.name1_2 = function(r, y) {\n' |
- ' return name4_5.name4_5;\n' |
- '};'), |
- |
- testStatement('label: while (a) { label2: break label;}', [], |
- 'label:\n while (a)\n label2:\n break label;\n '), |
- |
- |
- testStatement('var # = 3', ['x'], 'var x = 3;'), |
- testStatement('var # = 3', |
- [new jsAst.VariableDeclaration('x')], |
- 'var x = 3;'), |
- testStatement('var # = 3, # = #', |
- ['x', 'y', js.number(2)], |
- 'var x = 3, y = 2;'), |
- testStatement('var #a = 3, #b = #c', |
- {"a": 'x', "b": 'y', "c": js.number(2)}, |
- 'var x = 3, y = 2;'), |
- testStatement('function #() {}', ['x'], 'function x() {\n}'), |
- testStatement('function #() {}', |
- [new jsAst.VariableDeclaration('x')], |
- 'function x() {\n}'), |
- testStatement('try {} catch (#) {}', ['x'], 'try {\n} catch (x) {\n}'), |
- testStatement('try {} catch (#a) {}', {"a": 'x'}, 'try {\n} catch (x) {\n}'), |
- testStatement('try {} catch (#a) {}', |
- {"a": new jsAst.VariableDeclaration('x')}, |
- 'try {\n} catch (x) {\n}'), |
- |
- // Test that braces around a single-statement block are removed by printer. |
- testStatement('while (a) {foo()}', [], |
- 'while (a)\n foo();'), |
- testStatement('if (a) {foo();}', [], |
- 'if (a)\n foo();'), |
- testStatement('if (a) {foo();} else {foo2();}', [], |
- 'if (a)\n foo();\nelse\n foo2();'), |
- testStatement('if (a) foo(); else {foo2();}', [], |
- 'if (a)\n foo();\nelse\n foo2();'), |
- testStatement('do {foo();} while(a);', [], |
- 'do\n foo();\nwhile (a);'), |
- testStatement('label: {foo();}', [], |
- 'label:\n foo();'), |
- testStatement('for (var key in a) {foo();}', [], |
- 'for (var key in a)\n foo();'), |
- // `label: break label;` gives problems on IE. Test that it is avoided. |
- testStatement('label: {break label;}', [], |
- ';'), |
- // This works on IE: |
- testStatement('label: {label2: {break label;}}', [], |
- 'label:\n label2:\n break label;\n'), |
- // Test dangling else: |
- testStatement('if (a) {if (b) {foo1();}} else {foo2();}', [], """ |
+ testStatement(NAMED_FUNCTION_1, [eOne], NAMED_FUNCTION_1_ONE), |
+ testStatement( |
+ NAMED_FUNCTION_1_NAMED_HOLE, {'hole': eOne}, NAMED_FUNCTION_1_ONE), |
+ |
+ testStatement(MISC_1, [block12], MISC_1_1), |
+ testStatement(MISC_1_NAMED_HOLE, {'hole': block12}, MISC_1_1), |
+ |
+ // Argument list splicing. |
+ testStatement('foo(#)', [[]], 'foo();'), |
+ testStatement( |
+ 'foo(#)', |
+ [ |
+ [eOne] |
+ ], |
+ 'foo(1);'), |
+ testStatement('foo(#)', [eOne], 'foo(1);'), |
+ testStatement( |
+ 'foo(#)', |
+ [ |
+ [eTrue, eOne] |
+ ], |
+ 'foo(true, 1);'), |
+ testStatement('foo(#a)', {'a': []}, 'foo();'), |
+ testStatement( |
+ 'foo(#a)', |
+ { |
+ 'a': [eOne] |
+ }, |
+ 'foo(1);'), |
+ testStatement('foo(#a)', {'a': eOne}, 'foo(1);'), |
+ testStatement( |
+ 'foo(#a)', |
+ { |
+ 'a': [eTrue, eOne] |
+ }, |
+ 'foo(true, 1);'), |
+ |
+ testStatement('foo(2,#)', [[]], 'foo(2);'), |
+ testStatement( |
+ 'foo(2,#)', |
+ [ |
+ [eOne] |
+ ], |
+ 'foo(2, 1);'), |
+ testStatement('foo(2,#)', [eOne], 'foo(2, 1);'), |
+ testStatement( |
+ 'foo(2,#)', |
+ [ |
+ [eTrue, eOne] |
+ ], |
+ 'foo(2, true, 1);'), |
+ testStatement('foo(2,#a)', {'a': []}, 'foo(2);'), |
+ testStatement( |
+ 'foo(2,#a)', |
+ { |
+ 'a': [eOne] |
+ }, |
+ 'foo(2, 1);'), |
+ testStatement('foo(2,#a)', {'a': eOne}, 'foo(2, 1);'), |
+ testStatement( |
+ 'foo(2,#a)', |
+ { |
+ 'a': [eTrue, eOne] |
+ }, |
+ 'foo(2, true, 1);'), |
+ |
+ testStatement('foo(#,3)', [[]], 'foo(3);'), |
+ testStatement( |
+ 'foo(#,3)', |
+ [ |
+ [eOne] |
+ ], |
+ 'foo(1, 3);'), |
+ testStatement('foo(#,3)', [eOne], 'foo(1, 3);'), |
+ testStatement( |
+ 'foo(#,3)', |
+ [ |
+ [eTrue, eOne] |
+ ], |
+ 'foo(true, 1, 3);'), |
+ testStatement('foo(#a,3)', {'a': []}, 'foo(3);'), |
+ testStatement( |
+ 'foo(#a,3)', |
+ { |
+ 'a': [eOne] |
+ }, |
+ 'foo(1, 3);'), |
+ testStatement('foo(#a,3)', {'a': eOne}, 'foo(1, 3);'), |
+ testStatement( |
+ 'foo(#a,3)', |
+ { |
+ 'a': [eTrue, eOne] |
+ }, |
+ 'foo(true, 1, 3);'), |
+ |
+ testStatement('foo(2,#,3)', [[]], 'foo(2, 3);'), |
+ testStatement( |
+ 'foo(2,#,3)', |
+ [ |
+ [eOne] |
+ ], |
+ 'foo(2, 1, 3);'), |
+ testStatement('foo(2,#,3)', [eOne], 'foo(2, 1, 3);'), |
+ testStatement( |
+ 'foo(2,#,3)', |
+ [ |
+ [eTrue, eOne] |
+ ], |
+ 'foo(2, true, 1, 3);'), |
+ testStatement('foo(2,#a,3)', {'a': []}, 'foo(2, 3);'), |
+ testStatement( |
+ 'foo(2,#a,3)', |
+ { |
+ 'a': [eOne] |
+ }, |
+ 'foo(2, 1, 3);'), |
+ testStatement('foo(2,#a,3)', {'a': eOne}, 'foo(2, 1, 3);'), |
+ testStatement( |
+ 'foo(2,#a,3)', |
+ { |
+ 'a': [eTrue, eOne] |
+ }, |
+ 'foo(2, true, 1, 3);'), |
+ |
+ // Interpolated Literals |
+ testStatement('a = {#: 1}', [eOne], 'a = {1: 1};'), |
+ testStatement('a = {#a: 1}', {'a': eOne}, 'a = {1: 1};'), |
+ // Maybe we should make this work? |
+ testError('a = {#: 1}', [1], 'is not a Literal: 1'), |
+ testError('a = {#a: 1}', {'a': 1}, 'is not a Literal: 1'), |
+ |
+ // Interpolated parameter splicing. |
+ testStatement('function foo(#){}', [new jsAst.Parameter('x')], |
+ 'function foo(x) {\n}'), |
+ testStatement('function foo(#){}', ['x'], 'function foo(x) {\n}'), |
+ testStatement('function foo(#){}', [[]], 'function foo() {\n}'), |
+ testStatement( |
+ 'function foo(#){}', |
+ [ |
+ ['x'] |
+ ], |
+ 'function foo(x) {\n}'), |
+ testStatement( |
+ 'function foo(#){}', |
+ [ |
+ ['x', 'y'] |
+ ], |
+ 'function foo(x, y) {\n}'), |
+ testStatement('function foo(#a){}', {'a': new jsAst.Parameter('x')}, |
+ 'function foo(x) {\n}'), |
+ testStatement('function foo(#a){}', {'a': 'x'}, 'function foo(x) {\n}'), |
+ testStatement('function foo(#a){}', {'a': []}, 'function foo() {\n}'), |
+ testStatement( |
+ 'function foo(#a){}', |
+ { |
+ 'a': ['x'] |
+ }, |
+ 'function foo(x) {\n}'), |
+ testStatement( |
+ 'function foo(#a){}', |
+ { |
+ 'a': ['x', 'y'] |
+ }, |
+ 'function foo(x, y) {\n}'), |
+ |
+ testStatement( |
+ 'function foo() async {}', [], 'function foo() async {\n}'), |
+ testStatement( |
+ 'function foo() sync* {}', [], 'function foo() sync* {\n}'), |
+ testStatement( |
+ 'function foo() async* {}', [], 'function foo() async* {\n}'), |
+ |
+ testStatement('a = #.#', [eVar, eOne], 'a = x[1];'), |
+ testStatement('a = #.#', [eVar, 'foo'], 'a = x.foo;'), |
+ testStatement('a = #a.#b', {'a': eVar, 'b': eOne}, 'a = x[1];'), |
+ testStatement('a = #a.#b', {'a': eVar, 'b': 'foo'}, 'a = x.foo;'), |
+ |
+ testStatement('function f(#) { return #.#; }', ['x', eVar, 'foo'], |
+ 'function f(x) {\n return x.foo;\n}'), |
+ testStatement( |
+ 'function f(#a) { return #b.#c; }', |
+ {'a': 'x', 'b': eVar, 'c': 'foo'}, |
+ 'function f(x) {\n return x.foo;\n}'), |
+ |
+ testStatement( |
+ '#.prototype.# = function(#) { return #.# };', |
+ [ |
+ 'className', |
+ 'getterName', |
+ ['r', 'y'], |
+ 'r', |
+ 'fieldName' |
+ ], |
+ 'className.prototype.getterName = function(r, y) {\n' |
+ ' return r.fieldName;\n' |
+ '};'), |
+ testStatement( |
+ '#a.prototype.#b = function(#c) { return #d.#e };', |
+ { |
+ 'a': 'className', |
+ 'b': 'getterName', |
+ 'c': ['r', 'y'], |
+ 'd': 'r', |
+ 'e': 'fieldName' |
+ }, |
+ 'className.prototype.getterName = function(r, y) {\n' |
+ ' return r.fieldName;\n' |
+ '};'), |
+ |
+ testStatement( |
+ 'function foo(r, #) { return #[r](#) }', |
+ [ |
+ ['a', 'b'], |
+ 'g', |
+ ['b', 'a'] |
+ ], |
+ 'function foo(r, a, b) {\n return g[r](b, a);\n}'), |
+ testStatement( |
+ 'function foo(r, #a) { return #b[r](#c) }', |
+ { |
+ 'a': ['a', 'b'], |
+ 'b': 'g', |
+ 'c': ['b', 'a'] |
+ }, |
+ 'function foo(r, a, b) {\n return g[r](b, a);\n}'), |
+ |
+ // Sequence is printed flattened |
+ testStatement('x = #', [seq1], 'x = (1, 2, 3);'), |
+ testStatement('x = (#, #)', [seq1, seq1], 'x = (1, 2, 3, 1, 2, 3);'), |
+ testStatement('x = #, #', [seq1, seq1], 'x = (1, 2, 3), 1, 2, 3;'), |
+ testStatement('for (i = 0, j = #, k = 0; ; ++i, ++j, ++k){}', [seq1], |
+ 'for (i = 0, j = (1, 2, 3), k = 0;; ++i, ++j, ++k) {\n}'), |
+ testStatement('x = #a', {'a': seq1}, 'x = (1, 2, 3);'), |
+ testStatement( |
+ 'x = (#a, #b)', {'a': seq1, 'b': seq1}, 'x = (1, 2, 3, 1, 2, 3);'), |
+ testStatement( |
+ 'x = #a, #b', {'a': seq1, 'b': seq1}, 'x = (1, 2, 3), 1, 2, 3;'), |
+ testStatement( |
+ 'for (i = 0, j = #a, k = 0; ; ++i, ++j, ++k){}', |
+ {'a': seq1}, |
+ 'for (i = 0, j = (1, 2, 3), k = 0;; ++i, ++j, ++k) {\n}'), |
+ |
+ // Use the same name several times. |
+ testStatement( |
+ '#a.prototype.#a = function(#b) { return #c.#c };', |
+ { |
+ 'a': 'name1_2', |
+ 'b': ['r', 'y'], |
+ 'c': 'name4_5' |
+ }, |
+ 'name1_2.prototype.name1_2 = function(r, y) {\n' |
+ ' return name4_5.name4_5;\n' |
+ '};'), |
+ |
+ testStatement('label: while (a) { label2: break label;}', [], |
+ 'label:\n while (a)\n label2:\n break label;\n '), |
+ |
+ testStatement('var # = 3', ['x'], 'var x = 3;'), |
+ testStatement( |
+ 'var # = 3', [new jsAst.VariableDeclaration('x')], 'var x = 3;'), |
+ testStatement( |
+ 'var # = 3, # = #', ['x', 'y', js.number(2)], 'var x = 3, y = 2;'), |
+ testStatement('var #a = 3, #b = #c', |
+ {"a": 'x', "b": 'y', "c": js.number(2)}, 'var x = 3, y = 2;'), |
+ testStatement('function #() {}', ['x'], 'function x() {\n}'), |
+ testStatement('function #() {}', [new jsAst.VariableDeclaration('x')], |
+ 'function x() {\n}'), |
+ testStatement('try {} catch (#) {}', ['x'], 'try {\n} catch (x) {\n}'), |
+ testStatement( |
+ 'try {} catch (#a) {}', {"a": 'x'}, 'try {\n} catch (x) {\n}'), |
+ testStatement( |
+ 'try {} catch (#a) {}', |
+ {"a": new jsAst.VariableDeclaration('x')}, |
+ 'try {\n} catch (x) {\n}'), |
+ |
+ // Test that braces around a single-statement block are removed by printer. |
+ testStatement('while (a) {foo()}', [], 'while (a)\n foo();'), |
+ testStatement('if (a) {foo();}', [], 'if (a)\n foo();'), |
+ testStatement('if (a) {foo();} else {foo2();}', [], |
+ 'if (a)\n foo();\nelse\n foo2();'), |
+ testStatement('if (a) foo(); else {foo2();}', [], |
+ 'if (a)\n foo();\nelse\n foo2();'), |
+ testStatement('do {foo();} while(a);', [], 'do\n foo();\nwhile (a);'), |
+ testStatement('label: {foo();}', [], 'label:\n foo();'), |
+ testStatement( |
+ 'for (var key in a) {foo();}', [], 'for (var key in a)\n foo();'), |
+ // `label: break label;` gives problems on IE. Test that it is avoided. |
+ testStatement('label: {break label;}', [], ';'), |
+ // This works on IE: |
+ testStatement('label: {label2: {break label;}}', [], |
+ 'label:\n label2:\n break label;\n'), |
+ // Test dangling else: |
+ testStatement( |
+ 'if (a) {if (b) {foo1();}} else {foo2();}', |
+ [], |
+ """ |
if (a) { |
if (b) |
foo1(); |
} else |
foo2();"""), |
- testStatement('if (a) {if (b) {foo1();} else {foo2();}}', [], """ |
+ testStatement( |
+ 'if (a) {if (b) {foo1();} else {foo2();}}', |
+ [], |
+ """ |
if (a) |
if (b) |
foo1(); |
else |
foo2(); |
"""), |
- testStatement('if (a) {if (b) {foo1();} else {foo2();}} else {foo3();}', |
- [], """ |
+ testStatement( |
+ 'if (a) {if (b) {foo1();} else {foo2();}} else {foo3();}', |
+ [], |
+ """ |
if (a) |
if (b) |
foo1(); |
@@ -390,13 +509,15 @@ if (a) |
foo2(); |
else |
foo3();"""), |
- testStatement('if (a) {while (true) if (b) {foo1();}} else {foo2();}', |
- [], """ |
+ testStatement( |
+ 'if (a) {while (true) if (b) {foo1();}} else {foo2();}', |
+ [], |
+ """ |
if (a) { |
while (true) |
if (b) |
foo1(); |
} else |
foo2();"""), |
- ])); |
+ ])); |
} |