| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 import 'dart:async'; | 5 import 'dart:async'; |
| 6 import 'package:expect/expect.dart'; | 6 import 'package:expect/expect.dart'; |
| 7 import 'package:async_helper/async_helper.dart'; | 7 import 'package:async_helper/async_helper.dart'; |
| 8 import 'mock_compiler.dart'; | 8 import 'mock_compiler.dart'; |
| 9 import 'package:compiler/src/js/js.dart' as jsAst; | 9 import 'package:compiler/src/js/js.dart' as jsAst; |
| 10 import 'package:compiler/src/js/js.dart' show js; | 10 import 'package:compiler/src/js/js.dart' show js; |
| 11 | 11 |
| 12 | |
| 13 Future testStatement(String statement, arguments, String expect) { | 12 Future testStatement(String statement, arguments, String expect) { |
| 14 jsAst.Node node = js.statement(statement, arguments); | 13 jsAst.Node node = js.statement(statement, arguments); |
| 15 return MockCompiler.create((MockCompiler compiler) { | 14 return MockCompiler.create((MockCompiler compiler) { |
| 16 String jsText = | 15 String jsText = |
| 17 jsAst.prettyPrint(node, compiler, allowVariableMinification: false); | 16 jsAst.prettyPrint(node, compiler, allowVariableMinification: false); |
| 18 | 17 |
| 19 Expect.stringEquals(expect.trim(), jsText.trim()); | 18 Expect.stringEquals(expect.trim(), jsText.trim()); |
| 20 }); | 19 }); |
| 21 } | 20 } |
| 22 | 21 |
| 23 Future testError(String statement, arguments, [String expect = ""]) { | 22 Future testError(String statement, arguments, [String expect = ""]) { |
| 24 return new Future.sync(() { | 23 return new Future.sync(() { |
| 25 bool doCheck(exception) { | 24 bool doCheck(exception) { |
| 26 String message = '$exception'; | 25 String message = '$exception'; |
| 27 Expect.isTrue(message.contains(expect), '"$message" contains "$expect"'); | 26 Expect.isTrue(message.contains(expect), '"$message" contains "$expect"'); |
| 28 return true; | 27 return true; |
| 29 } | 28 } |
| 29 |
| 30 void action() { | 30 void action() { |
| 31 jsAst.Node node = js.statement(statement, arguments); | 31 jsAst.Node node = js.statement(statement, arguments); |
| 32 } | 32 } |
| 33 |
| 33 Expect.throws(action, doCheck); | 34 Expect.throws(action, doCheck); |
| 34 }); | 35 }); |
| 35 } | 36 } |
| 36 | 37 |
| 37 // Function declaration and named function. | 38 // Function declaration and named function. |
| 38 const NAMED_FUNCTION_1 = r''' | 39 const NAMED_FUNCTION_1 = r''' |
| 39 function foo/*function declaration*/() { | 40 function foo/*function declaration*/() { |
| 40 return function harry/*named function*/() { return #; } | 41 return function harry/*named function*/() { return #; } |
| 41 }'''; | 42 }'''; |
| 42 | 43 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 64 #hole; | 65 #hole; |
| 65 }'''; | 66 }'''; |
| 66 | 67 |
| 67 const MISC_1_1 = r''' | 68 const MISC_1_1 = r''' |
| 68 function foo() { | 69 function foo() { |
| 69 /a/; | 70 /a/; |
| 70 1; | 71 1; |
| 71 2; | 72 2; |
| 72 }'''; | 73 }'''; |
| 73 | 74 |
| 74 | |
| 75 void main() { | 75 void main() { |
| 76 | |
| 77 var eOne = js('1'); | 76 var eOne = js('1'); |
| 78 var eTwo = js('2'); | 77 var eTwo = js('2'); |
| 79 var eTrue = js('true'); | 78 var eTrue = js('true'); |
| 80 var eVar = js('x'); | 79 var eVar = js('x'); |
| 81 var block12 = js.statement('{ 1; 2; }'); | 80 var block12 = js.statement('{ 1; 2; }'); |
| 82 var stm = js.statement('foo();'); | 81 var stm = js.statement('foo();'); |
| 83 var seq1 = js('1, 2, 3'); | 82 var seq1 = js('1, 2, 3'); |
| 84 | 83 |
| 85 Expect.isTrue(eOne is jsAst.LiteralNumber); | 84 Expect.isTrue(eOne is jsAst.LiteralNumber); |
| 86 Expect.isTrue(eTrue is jsAst.LiteralBool); | 85 Expect.isTrue(eTrue is jsAst.LiteralBool); |
| 87 Expect.isTrue(block12 is jsAst.Block); | 86 Expect.isTrue(block12 is jsAst.Block); |
| 88 | 87 |
| 89 asyncTest(() => Future.wait([ | 88 asyncTest(() => Future.wait([ |
| 90 // Interpolated Expressions are upgraded to ExpressionStatements. | 89 // Interpolated Expressions are upgraded to ExpressionStatements. |
| 91 testStatement('{ #; #; }', [eOne, eOne], '{\n 1;\n 1;\n}'), | 90 testStatement('{ #; #; }', [eOne, eOne], '{\n 1;\n 1;\n}'), |
| 92 testStatement('{ #a; #b; }', {'a': eOne, 'b': eOne}, '{\n 1;\n 1;\n}'), | 91 testStatement( |
| 92 '{ #a; #b; }', {'a': eOne, 'b': eOne}, '{\n 1;\n 1;\n}'), |
| 93 | 93 |
| 94 // Interpolated sub-blocks are spliced. | 94 // Interpolated sub-blocks are spliced. |
| 95 testStatement('{ #; #; }', [block12, block12], | 95 testStatement( |
| 96 '{\n 1;\n 2;\n 1;\n 2;\n}\n'), | 96 '{ #; #; }', [block12, block12], '{\n 1;\n 2;\n 1;\n 2;\n}\n'), |
| 97 testStatement('{ #a; #b; }', {'a': block12, 'b': block12}, | 97 testStatement('{ #a; #b; }', {'a': block12, 'b': block12}, |
| 98 '{\n 1;\n 2;\n 1;\n 2;\n}\n'), | 98 '{\n 1;\n 2;\n 1;\n 2;\n}\n'), |
| 99 | 99 |
| 100 // If-condition. Dart booleans are evaluated, JS Expression booleans are | 100 // If-condition. Dart booleans are evaluated, JS Expression booleans ar
e |
| 101 // substituted. | 101 // substituted. |
| 102 testStatement('if (#) #', [eOne, block12], 'if (1) {\n 1;\n 2;\n}'), | 102 testStatement('if (#) #', [eOne, block12], 'if (1) {\n 1;\n 2;\n}'), |
| 103 testStatement('if (#) #;', [eTrue, block12], 'if (true) {\n 1;\n 2;\n}'), | 103 testStatement( |
| 104 testStatement('if (#) #;', [eVar, block12], 'if (x) {\n 1;\n 2;\n}'), | 104 'if (#) #;', [eTrue, block12], 'if (true) {\n 1;\n 2;\n}'), |
| 105 testStatement('if (#) #;', ['a', block12], 'if (a) {\n 1;\n 2;\n}'), | 105 testStatement('if (#) #;', [eVar, block12], 'if (x) {\n 1;\n 2;\n}'), |
| 106 testStatement('if (#) #;', [true, block12], '{\n 1;\n 2;\n}'), | 106 testStatement('if (#) #;', ['a', block12], 'if (a) {\n 1;\n 2;\n}'), |
| 107 testStatement('if (#) #;', [false, block12], ';'), | 107 testStatement('if (#) #;', [true, block12], '{\n 1;\n 2;\n}'), |
| 108 testStatement('if (#) 3; else #;', [true, block12], '3;'), | 108 testStatement('if (#) #;', [false, block12], ';'), |
| 109 testStatement('if (#) 3; else #;', [false, block12], '{\n 1;\n 2;\n}'), | 109 testStatement('if (#) 3; else #;', [true, block12], '3;'), |
| 110 testStatement('if (#a) #b', | 110 testStatement( |
| 111 {'a': eOne, 'b': block12}, | 111 'if (#) 3; else #;', [false, block12], '{\n 1;\n 2;\n}'), |
| 112 'if (1) {\n 1;\n 2;\n}'), | 112 testStatement( |
| 113 testStatement('if (#a) #b;', | 113 'if (#a) #b', {'a': eOne, 'b': block12}, 'if (1) {\n 1;\n 2;\n}'), |
| 114 {'a': eTrue, 'b': block12}, | 114 testStatement('if (#a) #b;', {'a': eTrue, 'b': block12}, |
| 115 'if (true) {\n 1;\n 2;\n}'), | 115 'if (true) {\n 1;\n 2;\n}'), |
| 116 testStatement('if (#a) #b;', | 116 testStatement('if (#a) #b;', {'a': eVar, 'b': block12}, |
| 117 {'a': eVar, 'b': block12}, | 117 'if (x) {\n 1;\n 2;\n}'), |
| 118 'if (x) {\n 1;\n 2;\n}'), | 118 testStatement( |
| 119 testStatement('if (#a) #b;', | 119 'if (#a) #b;', {'a': 'a', 'b': block12}, 'if (a) {\n 1;\n 2;\n}'), |
| 120 {'a': 'a', 'b': block12}, | 120 testStatement( |
| 121 'if (a) {\n 1;\n 2;\n}'), | 121 'if (#a) #b;', {'a': true, 'b': block12}, '{\n 1;\n 2;\n}'), |
| 122 testStatement('if (#a) #b;', | 122 testStatement('if (#a) #b;', {'a': false, 'b': block12}, ';'), |
| 123 {'a': true, 'b': block12}, | 123 testStatement('if (#a) 3; else #b;', {'a': true, 'b': block12}, '3;'), |
| 124 '{\n 1;\n 2;\n}'), | 124 testStatement('if (#a) 3; else #b;', {'a': false, 'b': block12}, |
| 125 testStatement('if (#a) #b;', | 125 '{\n 1;\n 2;\n}'), |
| 126 {'a': false, 'b': block12}, | |
| 127 ';'), | |
| 128 testStatement('if (#a) 3; else #b;', | |
| 129 {'a': true, 'b': block12}, | |
| 130 '3;'), | |
| 131 testStatement('if (#a) 3; else #b;', | |
| 132 {'a': false, 'b': block12}, | |
| 133 '{\n 1;\n 2;\n}'), | |
| 134 | 126 |
| 127 testStatement( |
| 128 'while (#) #', [eOne, block12], 'while (1) {\n 1;\n 2;\n}'), |
| 129 testStatement( |
| 130 'while (#) #;', [eTrue, block12], 'while (true) {\n 1;\n 2;\n}'), |
| 131 testStatement( |
| 132 'while (#) #;', [eVar, block12], 'while (x) {\n 1;\n 2;\n}'), |
| 133 testStatement( |
| 134 'while (#) #;', ['a', block12], 'while (a) {\n 1;\n 2;\n}'), |
| 135 testStatement('while (#) #;', ['a', stm], 'while (a)\n foo();'), |
| 135 | 136 |
| 136 testStatement('while (#) #', [eOne, block12], 'while (1) {\n 1;\n 2;\n}'), | 137 testStatement( |
| 137 testStatement('while (#) #;', [eTrue, block12], | 138 'do { {print(1);} do while(true); while (false) } while ( true )', |
| 138 'while (true) {\n 1;\n 2;\n}'), | 139 [], |
| 139 testStatement('while (#) #;', [eVar, block12], | 140 ''' |
| 140 'while (x) {\n 1;\n 2;\n}'), | |
| 141 testStatement('while (#) #;', ['a', block12], | |
| 142 'while (a) {\n 1;\n 2;\n}'), | |
| 143 testStatement('while (#) #;', ['a', stm], | |
| 144 'while (a)\n foo();'), | |
| 145 | |
| 146 testStatement( | |
| 147 'do { {print(1);} do while(true); while (false) } while ( true )', [], | |
| 148 ''' | |
| 149 do { | 141 do { |
| 150 print(1); | 142 print(1); |
| 151 do | 143 do |
| 152 while (true) | 144 while (true) |
| 153 ; | 145 ; |
| 154 while (false); | 146 while (false); |
| 155 } while (true); | 147 } while (true); |
| 156 '''), | 148 '''), |
| 157 testStatement('do #; while ( # )', [block12, eOne], | 149 testStatement('do #; while ( # )', [block12, eOne], |
| 158 'do {\n 1;\n 2;\n} while (1); '), | 150 'do {\n 1;\n 2;\n} while (1); '), |
| 159 testStatement('do #; while ( # )', [block12, eTrue], | 151 testStatement('do #; while ( # )', [block12, eTrue], |
| 160 'do {\n 1;\n 2;\n} while (true); '), | 152 'do {\n 1;\n 2;\n} while (true); '), |
| 161 testStatement('do #; while ( # );', [block12, eVar], | 153 testStatement('do #; while ( # );', [block12, eVar], |
| 162 'do {\n 1;\n 2;\n} while (x);'), | 154 'do {\n 1;\n 2;\n} while (x);'), |
| 163 testStatement('do { # } while ( # )', [block12, 'a'], | 155 testStatement('do { # } while ( # )', [block12, 'a'], |
| 164 'do {\n 1;\n 2;\n} while (a);'), | 156 'do {\n 1;\n 2;\n} while (a);'), |
| 165 testStatement('do #; while ( # )', [stm, 'a'], | 157 testStatement( |
| 166 'do\n foo();\nwhile (a);'), | 158 'do #; while ( # )', [stm, 'a'], 'do\n foo();\nwhile (a);'), |
| 167 | 159 |
| 168 testStatement('switch (#) {}', [eOne], 'switch (1) {\n}'), | 160 testStatement('switch (#) {}', [eOne], 'switch (1) {\n}'), |
| 169 testStatement(''' | 161 testStatement( |
| 162 ''' |
| 170 switch (#) { | 163 switch (#) { |
| 171 case #: { # } | 164 case #: { # } |
| 172 }''', [eTrue, eOne, block12], | 165 }''', |
| 173 'switch (true) {\n case 1:\n 1;\n 2;\n}'), | 166 [eTrue, eOne, block12], |
| 174 testStatement(''' | 167 'switch (true) {\n case 1:\n 1;\n 2;\n}'), |
| 168 testStatement( |
| 169 ''' |
| 175 switch (#) { | 170 switch (#) { |
| 176 case #: { # } | 171 case #: { # } |
| 177 break; | 172 break; |
| 178 case #: { # } | 173 case #: { # } |
| 179 default: { # } | 174 default: { # } |
| 180 }''', [eTrue, eOne, block12, eTwo, block12, stm], ''' | 175 }''', |
| 176 [eTrue, eOne, block12, eTwo, block12, stm], |
| 177 ''' |
| 181 switch (true) { | 178 switch (true) { |
| 182 case 1: | 179 case 1: |
| 183 1; | 180 1; |
| 184 2; | 181 2; |
| 185 break; | 182 break; |
| 186 case 2: | 183 case 2: |
| 187 1; | 184 1; |
| 188 2; | 185 2; |
| 189 default: | 186 default: |
| 190 foo(); | 187 foo(); |
| 191 }'''), | 188 }'''), |
| 192 | 189 |
| 193 testStatement(NAMED_FUNCTION_1, [eOne], NAMED_FUNCTION_1_ONE), | 190 testStatement(NAMED_FUNCTION_1, [eOne], NAMED_FUNCTION_1_ONE), |
| 194 testStatement(NAMED_FUNCTION_1_NAMED_HOLE, | 191 testStatement( |
| 195 {'hole': eOne}, | 192 NAMED_FUNCTION_1_NAMED_HOLE, {'hole': eOne}, NAMED_FUNCTION_1_ONE), |
| 196 NAMED_FUNCTION_1_ONE), | 193 |
| 197 | 194 testStatement(MISC_1, [block12], MISC_1_1), |
| 198 testStatement(MISC_1, [block12], MISC_1_1), | 195 testStatement(MISC_1_NAMED_HOLE, {'hole': block12}, MISC_1_1), |
| 199 testStatement(MISC_1_NAMED_HOLE, {'hole': block12}, MISC_1_1), | 196 |
| 200 | 197 // Argument list splicing. |
| 201 // Argument list splicing. | 198 testStatement('foo(#)', [[]], 'foo();'), |
| 202 testStatement('foo(#)', [[]], 'foo();'), | 199 testStatement( |
| 203 testStatement('foo(#)', [[eOne]], 'foo(1);'), | 200 'foo(#)', |
| 204 testStatement('foo(#)', [eOne], 'foo(1);'), | 201 [ |
| 205 testStatement('foo(#)', [[eTrue,eOne]], 'foo(true, 1);'), | 202 [eOne] |
| 206 testStatement('foo(#a)', {'a': []}, 'foo();'), | 203 ], |
| 207 testStatement('foo(#a)', {'a': [eOne]}, 'foo(1);'), | 204 'foo(1);'), |
| 208 testStatement('foo(#a)', {'a': eOne}, 'foo(1);'), | 205 testStatement('foo(#)', [eOne], 'foo(1);'), |
| 209 testStatement('foo(#a)', {'a': [eTrue,eOne]}, 'foo(true, 1);'), | 206 testStatement( |
| 210 | 207 'foo(#)', |
| 211 testStatement('foo(2,#)', [[]], 'foo(2);'), | 208 [ |
| 212 testStatement('foo(2,#)', [[eOne]], 'foo(2, 1);'), | 209 [eTrue, eOne] |
| 213 testStatement('foo(2,#)', [eOne], 'foo(2, 1);'), | 210 ], |
| 214 testStatement('foo(2,#)', [[eTrue,eOne]], 'foo(2, true, 1);'), | 211 'foo(true, 1);'), |
| 215 testStatement('foo(2,#a)', {'a': []}, 'foo(2);'), | 212 testStatement('foo(#a)', {'a': []}, 'foo();'), |
| 216 testStatement('foo(2,#a)', {'a': [eOne]}, 'foo(2, 1);'), | 213 testStatement( |
| 217 testStatement('foo(2,#a)', {'a': eOne}, 'foo(2, 1);'), | 214 'foo(#a)', |
| 218 testStatement('foo(2,#a)', {'a': [eTrue,eOne]}, 'foo(2, true, 1);'), | 215 { |
| 219 | 216 'a': [eOne] |
| 220 testStatement('foo(#,3)', [[]], 'foo(3);'), | 217 }, |
| 221 testStatement('foo(#,3)', [[eOne]], 'foo(1, 3);'), | 218 'foo(1);'), |
| 222 testStatement('foo(#,3)', [eOne], 'foo(1, 3);'), | 219 testStatement('foo(#a)', {'a': eOne}, 'foo(1);'), |
| 223 testStatement('foo(#,3)', [[eTrue,eOne]], 'foo(true, 1, 3);'), | 220 testStatement( |
| 224 testStatement('foo(#a,3)', {'a': []}, 'foo(3);'), | 221 'foo(#a)', |
| 225 testStatement('foo(#a,3)', {'a': [eOne]}, 'foo(1, 3);'), | 222 { |
| 226 testStatement('foo(#a,3)', {'a': eOne}, 'foo(1, 3);'), | 223 'a': [eTrue, eOne] |
| 227 testStatement('foo(#a,3)', {'a': [eTrue,eOne]}, 'foo(true, 1, 3);'), | 224 }, |
| 228 | 225 'foo(true, 1);'), |
| 229 testStatement('foo(2,#,3)', [[]], 'foo(2, 3);'), | 226 |
| 230 testStatement('foo(2,#,3)', [[eOne]], 'foo(2, 1, 3);'), | 227 testStatement('foo(2,#)', [[]], 'foo(2);'), |
| 231 testStatement('foo(2,#,3)', [eOne], 'foo(2, 1, 3);'), | 228 testStatement( |
| 232 testStatement('foo(2,#,3)', [[eTrue,eOne]], 'foo(2, true, 1, 3);'), | 229 'foo(2,#)', |
| 233 testStatement('foo(2,#a,3)', {'a': []}, 'foo(2, 3);'), | 230 [ |
| 234 testStatement('foo(2,#a,3)', {'a': [eOne]}, 'foo(2, 1, 3);'), | 231 [eOne] |
| 235 testStatement('foo(2,#a,3)', {'a': eOne}, 'foo(2, 1, 3);'), | 232 ], |
| 236 testStatement('foo(2,#a,3)', {'a': [eTrue,eOne]}, 'foo(2, true, 1, 3);'), | 233 'foo(2, 1);'), |
| 237 | 234 testStatement('foo(2,#)', [eOne], 'foo(2, 1);'), |
| 238 // Interpolated Literals | 235 testStatement( |
| 239 testStatement('a = {#: 1}', [eOne], 'a = {1: 1};'), | 236 'foo(2,#)', |
| 240 testStatement('a = {#a: 1}', {'a': eOne}, 'a = {1: 1};'), | 237 [ |
| 241 // Maybe we should make this work? | 238 [eTrue, eOne] |
| 242 testError('a = {#: 1}', [1], 'is not a Literal: 1'), | 239 ], |
| 243 testError('a = {#a: 1}', {'a': 1}, 'is not a Literal: 1'), | 240 'foo(2, true, 1);'), |
| 244 | 241 testStatement('foo(2,#a)', {'a': []}, 'foo(2);'), |
| 245 // Interpolated parameter splicing. | 242 testStatement( |
| 246 testStatement('function foo(#){}', [new jsAst.Parameter('x')], | 243 'foo(2,#a)', |
| 247 'function foo(x) {\n}'), | 244 { |
| 248 testStatement('function foo(#){}', ['x'], 'function foo(x) {\n}'), | 245 'a': [eOne] |
| 249 testStatement('function foo(#){}', [[]], 'function foo() {\n}'), | 246 }, |
| 250 testStatement('function foo(#){}', [['x']], 'function foo(x) {\n}'), | 247 'foo(2, 1);'), |
| 251 testStatement('function foo(#){}', [['x', 'y']], 'function foo(x, y) {\n}'), | 248 testStatement('foo(2,#a)', {'a': eOne}, 'foo(2, 1);'), |
| 252 testStatement('function foo(#a){}', {'a': new jsAst.Parameter('x')}, | 249 testStatement( |
| 253 'function foo(x) {\n}'), | 250 'foo(2,#a)', |
| 254 testStatement('function foo(#a){}', {'a': 'x'}, 'function foo(x) {\n}'), | 251 { |
| 255 testStatement('function foo(#a){}', {'a': []}, 'function foo() {\n}'), | 252 'a': [eTrue, eOne] |
| 256 testStatement('function foo(#a){}', {'a': ['x']}, 'function foo(x) {\n}'), | 253 }, |
| 257 testStatement('function foo(#a){}', | 254 'foo(2, true, 1);'), |
| 258 {'a': ['x', 'y']}, | 255 |
| 259 'function foo(x, y) {\n}'), | 256 testStatement('foo(#,3)', [[]], 'foo(3);'), |
| 260 | 257 testStatement( |
| 261 testStatement('function foo() async {}', [], 'function foo() async {\n}'), | 258 'foo(#,3)', |
| 262 testStatement('function foo() sync* {}', [], 'function foo() sync* {\n}'), | 259 [ |
| 263 testStatement('function foo() async* {}', [], 'function foo() async* {\n}'), | 260 [eOne] |
| 264 | 261 ], |
| 265 testStatement('a = #.#', [eVar,eOne], 'a = x[1];'), | 262 'foo(1, 3);'), |
| 266 testStatement('a = #.#', [eVar,'foo'], 'a = x.foo;'), | 263 testStatement('foo(#,3)', [eOne], 'foo(1, 3);'), |
| 267 testStatement('a = #a.#b', {'a': eVar, 'b': eOne}, 'a = x[1];'), | 264 testStatement( |
| 268 testStatement('a = #a.#b', {'a': eVar, 'b': 'foo'}, 'a = x.foo;'), | 265 'foo(#,3)', |
| 269 | 266 [ |
| 270 testStatement('function f(#) { return #.#; }', ['x', eVar,'foo'], | 267 [eTrue, eOne] |
| 271 'function f(x) {\n return x.foo;\n}'), | 268 ], |
| 272 testStatement('function f(#a) { return #b.#c; }', | 269 'foo(true, 1, 3);'), |
| 273 {'a': 'x', 'b': eVar, 'c': 'foo'}, | 270 testStatement('foo(#a,3)', {'a': []}, 'foo(3);'), |
| 274 'function f(x) {\n return x.foo;\n}'), | 271 testStatement( |
| 275 | 272 'foo(#a,3)', |
| 276 testStatement('#.prototype.# = function(#) { return #.# };', | 273 { |
| 277 ['className', 'getterName', ['r', 'y'], 'r', 'fieldName'], | 274 'a': [eOne] |
| 278 'className.prototype.getterName = function(r, y) {\n' | 275 }, |
| 279 ' return r.fieldName;\n' | 276 'foo(1, 3);'), |
| 280 '};'), | 277 testStatement('foo(#a,3)', {'a': eOne}, 'foo(1, 3);'), |
| 281 testStatement('#a.prototype.#b = function(#c) { return #d.#e };', | 278 testStatement( |
| 282 {'a': 'className', | 279 'foo(#a,3)', |
| 283 'b': 'getterName', | 280 { |
| 284 'c': ['r', 'y'], | 281 'a': [eTrue, eOne] |
| 285 'd': 'r', | 282 }, |
| 286 'e': 'fieldName'}, | 283 'foo(true, 1, 3);'), |
| 287 'className.prototype.getterName = function(r, y) {\n' | 284 |
| 288 ' return r.fieldName;\n' | 285 testStatement('foo(2,#,3)', [[]], 'foo(2, 3);'), |
| 289 '};'), | 286 testStatement( |
| 290 | 287 'foo(2,#,3)', |
| 291 testStatement('function foo(r, #) { return #[r](#) }', | 288 [ |
| 292 [['a', 'b'], 'g', ['b', 'a']], | 289 [eOne] |
| 293 'function foo(r, a, b) {\n return g[r](b, a);\n}'), | 290 ], |
| 294 testStatement('function foo(r, #a) { return #b[r](#c) }', | 291 'foo(2, 1, 3);'), |
| 295 {'a': ['a', 'b'], 'b': 'g', 'c': ['b', 'a']}, | 292 testStatement('foo(2,#,3)', [eOne], 'foo(2, 1, 3);'), |
| 296 'function foo(r, a, b) {\n return g[r](b, a);\n}'), | 293 testStatement( |
| 297 | 294 'foo(2,#,3)', |
| 298 // Sequence is printed flattened | 295 [ |
| 299 testStatement('x = #', [seq1], 'x = (1, 2, 3);'), | 296 [eTrue, eOne] |
| 300 testStatement('x = (#, #)', [seq1, seq1], 'x = (1, 2, 3, 1, 2, 3);'), | 297 ], |
| 301 testStatement('x = #, #', [seq1, seq1], 'x = (1, 2, 3), 1, 2, 3;'), | 298 'foo(2, true, 1, 3);'), |
| 302 testStatement( | 299 testStatement('foo(2,#a,3)', {'a': []}, 'foo(2, 3);'), |
| 303 'for (i = 0, j = #, k = 0; ; ++i, ++j, ++k){}', [seq1], | 300 testStatement( |
| 304 'for (i = 0, j = (1, 2, 3), k = 0;; ++i, ++j, ++k) {\n}'), | 301 'foo(2,#a,3)', |
| 305 testStatement('x = #a', {'a': seq1}, 'x = (1, 2, 3);'), | 302 { |
| 306 testStatement('x = (#a, #b)', | 303 'a': [eOne] |
| 307 {'a': seq1, 'b': seq1}, | 304 }, |
| 308 'x = (1, 2, 3, 1, 2, 3);'), | 305 'foo(2, 1, 3);'), |
| 309 testStatement('x = #a, #b', | 306 testStatement('foo(2,#a,3)', {'a': eOne}, 'foo(2, 1, 3);'), |
| 310 {'a': seq1, 'b': seq1}, | 307 testStatement( |
| 311 'x = (1, 2, 3), 1, 2, 3;'), | 308 'foo(2,#a,3)', |
| 312 testStatement( | 309 { |
| 313 'for (i = 0, j = #a, k = 0; ; ++i, ++j, ++k){}', {'a': seq1}, | 310 'a': [eTrue, eOne] |
| 314 'for (i = 0, j = (1, 2, 3), k = 0;; ++i, ++j, ++k) {\n}'), | 311 }, |
| 315 | 312 'foo(2, true, 1, 3);'), |
| 316 // Use the same name several times. | 313 |
| 317 testStatement('#a.prototype.#a = function(#b) { return #c.#c };', | 314 // Interpolated Literals |
| 318 {'a': 'name1_2', | 315 testStatement('a = {#: 1}', [eOne], 'a = {1: 1};'), |
| 319 'b': ['r', 'y'], | 316 testStatement('a = {#a: 1}', {'a': eOne}, 'a = {1: 1};'), |
| 320 'c': 'name4_5'}, | 317 // Maybe we should make this work? |
| 321 'name1_2.prototype.name1_2 = function(r, y) {\n' | 318 testError('a = {#: 1}', [1], 'is not a Literal: 1'), |
| 322 ' return name4_5.name4_5;\n' | 319 testError('a = {#a: 1}', {'a': 1}, 'is not a Literal: 1'), |
| 323 '};'), | 320 |
| 324 | 321 // Interpolated parameter splicing. |
| 325 testStatement('label: while (a) { label2: break label;}', [], | 322 testStatement('function foo(#){}', [new jsAst.Parameter('x')], |
| 326 'label:\n while (a)\n label2:\n break label;\n '), | 323 'function foo(x) {\n}'), |
| 327 | 324 testStatement('function foo(#){}', ['x'], 'function foo(x) {\n}'), |
| 328 | 325 testStatement('function foo(#){}', [[]], 'function foo() {\n}'), |
| 329 testStatement('var # = 3', ['x'], 'var x = 3;'), | 326 testStatement( |
| 330 testStatement('var # = 3', | 327 'function foo(#){}', |
| 331 [new jsAst.VariableDeclaration('x')], | 328 [ |
| 332 'var x = 3;'), | 329 ['x'] |
| 333 testStatement('var # = 3, # = #', | 330 ], |
| 334 ['x', 'y', js.number(2)], | 331 'function foo(x) {\n}'), |
| 335 'var x = 3, y = 2;'), | 332 testStatement( |
| 336 testStatement('var #a = 3, #b = #c', | 333 'function foo(#){}', |
| 337 {"a": 'x', "b": 'y', "c": js.number(2)}, | 334 [ |
| 338 'var x = 3, y = 2;'), | 335 ['x', 'y'] |
| 339 testStatement('function #() {}', ['x'], 'function x() {\n}'), | 336 ], |
| 340 testStatement('function #() {}', | 337 'function foo(x, y) {\n}'), |
| 341 [new jsAst.VariableDeclaration('x')], | 338 testStatement('function foo(#a){}', {'a': new jsAst.Parameter('x')}, |
| 342 'function x() {\n}'), | 339 'function foo(x) {\n}'), |
| 343 testStatement('try {} catch (#) {}', ['x'], 'try {\n} catch (x) {\n}'), | 340 testStatement('function foo(#a){}', {'a': 'x'}, 'function foo(x) {\n}'), |
| 344 testStatement('try {} catch (#a) {}', {"a": 'x'}, 'try {\n} catch (x) {\n}')
, | 341 testStatement('function foo(#a){}', {'a': []}, 'function foo() {\n}'), |
| 345 testStatement('try {} catch (#a) {}', | 342 testStatement( |
| 346 {"a": new jsAst.VariableDeclaration('x')}, | 343 'function foo(#a){}', |
| 347 'try {\n} catch (x) {\n}'), | 344 { |
| 348 | 345 'a': ['x'] |
| 349 // Test that braces around a single-statement block are removed by printer. | 346 }, |
| 350 testStatement('while (a) {foo()}', [], | 347 'function foo(x) {\n}'), |
| 351 'while (a)\n foo();'), | 348 testStatement( |
| 352 testStatement('if (a) {foo();}', [], | 349 'function foo(#a){}', |
| 353 'if (a)\n foo();'), | 350 { |
| 354 testStatement('if (a) {foo();} else {foo2();}', [], | 351 'a': ['x', 'y'] |
| 355 'if (a)\n foo();\nelse\n foo2();'), | 352 }, |
| 356 testStatement('if (a) foo(); else {foo2();}', [], | 353 'function foo(x, y) {\n}'), |
| 357 'if (a)\n foo();\nelse\n foo2();'), | 354 |
| 358 testStatement('do {foo();} while(a);', [], | 355 testStatement( |
| 359 'do\n foo();\nwhile (a);'), | 356 'function foo() async {}', [], 'function foo() async {\n}'), |
| 360 testStatement('label: {foo();}', [], | 357 testStatement( |
| 361 'label:\n foo();'), | 358 'function foo() sync* {}', [], 'function foo() sync* {\n}'), |
| 362 testStatement('for (var key in a) {foo();}', [], | 359 testStatement( |
| 363 'for (var key in a)\n foo();'), | 360 'function foo() async* {}', [], 'function foo() async* {\n}'), |
| 364 // `label: break label;` gives problems on IE. Test that it is avoided. | 361 |
| 365 testStatement('label: {break label;}', [], | 362 testStatement('a = #.#', [eVar, eOne], 'a = x[1];'), |
| 366 ';'), | 363 testStatement('a = #.#', [eVar, 'foo'], 'a = x.foo;'), |
| 367 // This works on IE: | 364 testStatement('a = #a.#b', {'a': eVar, 'b': eOne}, 'a = x[1];'), |
| 368 testStatement('label: {label2: {break label;}}', [], | 365 testStatement('a = #a.#b', {'a': eVar, 'b': 'foo'}, 'a = x.foo;'), |
| 369 'label:\n label2:\n break label;\n'), | 366 |
| 370 // Test dangling else: | 367 testStatement('function f(#) { return #.#; }', ['x', eVar, 'foo'], |
| 371 testStatement('if (a) {if (b) {foo1();}} else {foo2();}', [], """ | 368 'function f(x) {\n return x.foo;\n}'), |
| 369 testStatement( |
| 370 'function f(#a) { return #b.#c; }', |
| 371 {'a': 'x', 'b': eVar, 'c': 'foo'}, |
| 372 'function f(x) {\n return x.foo;\n}'), |
| 373 |
| 374 testStatement( |
| 375 '#.prototype.# = function(#) { return #.# };', |
| 376 [ |
| 377 'className', |
| 378 'getterName', |
| 379 ['r', 'y'], |
| 380 'r', |
| 381 'fieldName' |
| 382 ], |
| 383 'className.prototype.getterName = function(r, y) {\n' |
| 384 ' return r.fieldName;\n' |
| 385 '};'), |
| 386 testStatement( |
| 387 '#a.prototype.#b = function(#c) { return #d.#e };', |
| 388 { |
| 389 'a': 'className', |
| 390 'b': 'getterName', |
| 391 'c': ['r', 'y'], |
| 392 'd': 'r', |
| 393 'e': 'fieldName' |
| 394 }, |
| 395 'className.prototype.getterName = function(r, y) {\n' |
| 396 ' return r.fieldName;\n' |
| 397 '};'), |
| 398 |
| 399 testStatement( |
| 400 'function foo(r, #) { return #[r](#) }', |
| 401 [ |
| 402 ['a', 'b'], |
| 403 'g', |
| 404 ['b', 'a'] |
| 405 ], |
| 406 'function foo(r, a, b) {\n return g[r](b, a);\n}'), |
| 407 testStatement( |
| 408 'function foo(r, #a) { return #b[r](#c) }', |
| 409 { |
| 410 'a': ['a', 'b'], |
| 411 'b': 'g', |
| 412 'c': ['b', 'a'] |
| 413 }, |
| 414 'function foo(r, a, b) {\n return g[r](b, a);\n}'), |
| 415 |
| 416 // Sequence is printed flattened |
| 417 testStatement('x = #', [seq1], 'x = (1, 2, 3);'), |
| 418 testStatement('x = (#, #)', [seq1, seq1], 'x = (1, 2, 3, 1, 2, 3);'), |
| 419 testStatement('x = #, #', [seq1, seq1], 'x = (1, 2, 3), 1, 2, 3;'), |
| 420 testStatement('for (i = 0, j = #, k = 0; ; ++i, ++j, ++k){}', [seq1], |
| 421 'for (i = 0, j = (1, 2, 3), k = 0;; ++i, ++j, ++k) {\n}'), |
| 422 testStatement('x = #a', {'a': seq1}, 'x = (1, 2, 3);'), |
| 423 testStatement( |
| 424 'x = (#a, #b)', {'a': seq1, 'b': seq1}, 'x = (1, 2, 3, 1, 2, 3);'), |
| 425 testStatement( |
| 426 'x = #a, #b', {'a': seq1, 'b': seq1}, 'x = (1, 2, 3), 1, 2, 3;'), |
| 427 testStatement( |
| 428 'for (i = 0, j = #a, k = 0; ; ++i, ++j, ++k){}', |
| 429 {'a': seq1}, |
| 430 'for (i = 0, j = (1, 2, 3), k = 0;; ++i, ++j, ++k) {\n}'), |
| 431 |
| 432 // Use the same name several times. |
| 433 testStatement( |
| 434 '#a.prototype.#a = function(#b) { return #c.#c };', |
| 435 { |
| 436 'a': 'name1_2', |
| 437 'b': ['r', 'y'], |
| 438 'c': 'name4_5' |
| 439 }, |
| 440 'name1_2.prototype.name1_2 = function(r, y) {\n' |
| 441 ' return name4_5.name4_5;\n' |
| 442 '};'), |
| 443 |
| 444 testStatement('label: while (a) { label2: break label;}', [], |
| 445 'label:\n while (a)\n label2:\n break label;\n '), |
| 446 |
| 447 testStatement('var # = 3', ['x'], 'var x = 3;'), |
| 448 testStatement( |
| 449 'var # = 3', [new jsAst.VariableDeclaration('x')], 'var x = 3;'), |
| 450 testStatement( |
| 451 'var # = 3, # = #', ['x', 'y', js.number(2)], 'var x = 3, y = 2;'), |
| 452 testStatement('var #a = 3, #b = #c', |
| 453 {"a": 'x', "b": 'y', "c": js.number(2)}, 'var x = 3, y = 2;'), |
| 454 testStatement('function #() {}', ['x'], 'function x() {\n}'), |
| 455 testStatement('function #() {}', [new jsAst.VariableDeclaration('x')], |
| 456 'function x() {\n}'), |
| 457 testStatement('try {} catch (#) {}', ['x'], 'try {\n} catch (x) {\n}'), |
| 458 testStatement( |
| 459 'try {} catch (#a) {}', {"a": 'x'}, 'try {\n} catch (x) {\n}'), |
| 460 testStatement( |
| 461 'try {} catch (#a) {}', |
| 462 {"a": new jsAst.VariableDeclaration('x')}, |
| 463 'try {\n} catch (x) {\n}'), |
| 464 |
| 465 // Test that braces around a single-statement block are removed by print
er. |
| 466 testStatement('while (a) {foo()}', [], 'while (a)\n foo();'), |
| 467 testStatement('if (a) {foo();}', [], 'if (a)\n foo();'), |
| 468 testStatement('if (a) {foo();} else {foo2();}', [], |
| 469 'if (a)\n foo();\nelse\n foo2();'), |
| 470 testStatement('if (a) foo(); else {foo2();}', [], |
| 471 'if (a)\n foo();\nelse\n foo2();'), |
| 472 testStatement('do {foo();} while(a);', [], 'do\n foo();\nwhile (a);'), |
| 473 testStatement('label: {foo();}', [], 'label:\n foo();'), |
| 474 testStatement( |
| 475 'for (var key in a) {foo();}', [], 'for (var key in a)\n foo();'), |
| 476 // `label: break label;` gives problems on IE. Test that it is avoided. |
| 477 testStatement('label: {break label;}', [], ';'), |
| 478 // This works on IE: |
| 479 testStatement('label: {label2: {break label;}}', [], |
| 480 'label:\n label2:\n break label;\n'), |
| 481 // Test dangling else: |
| 482 testStatement( |
| 483 'if (a) {if (b) {foo1();}} else {foo2();}', |
| 484 [], |
| 485 """ |
| 372 if (a) { | 486 if (a) { |
| 373 if (b) | 487 if (b) |
| 374 foo1(); | 488 foo1(); |
| 375 } else | 489 } else |
| 376 foo2();"""), | 490 foo2();"""), |
| 377 testStatement('if (a) {if (b) {foo1();} else {foo2();}}', [], """ | 491 testStatement( |
| 492 'if (a) {if (b) {foo1();} else {foo2();}}', |
| 493 [], |
| 494 """ |
| 378 if (a) | 495 if (a) |
| 379 if (b) | 496 if (b) |
| 380 foo1(); | 497 foo1(); |
| 381 else | 498 else |
| 382 foo2(); | 499 foo2(); |
| 383 """), | 500 """), |
| 384 testStatement('if (a) {if (b) {foo1();} else {foo2();}} else {foo3();}', | 501 testStatement( |
| 385 [], """ | 502 'if (a) {if (b) {foo1();} else {foo2();}} else {foo3();}', |
| 503 [], |
| 504 """ |
| 386 if (a) | 505 if (a) |
| 387 if (b) | 506 if (b) |
| 388 foo1(); | 507 foo1(); |
| 389 else | 508 else |
| 390 foo2(); | 509 foo2(); |
| 391 else | 510 else |
| 392 foo3();"""), | 511 foo3();"""), |
| 393 testStatement('if (a) {while (true) if (b) {foo1();}} else {foo2();}', | 512 testStatement( |
| 394 [], """ | 513 'if (a) {while (true) if (b) {foo1();}} else {foo2();}', |
| 514 [], |
| 515 """ |
| 395 if (a) { | 516 if (a) { |
| 396 while (true) | 517 while (true) |
| 397 if (b) | 518 if (b) |
| 398 foo1(); | 519 foo1(); |
| 399 } else | 520 } else |
| 400 foo2();"""), | 521 foo2();"""), |
| 401 ])); | 522 ])); |
| 402 } | 523 } |
| OLD | NEW |