| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 library dev_compiler.src.codegen.js_codegen; | 5 library dev_compiler.src.codegen.js_codegen; |
| 6 | 6 |
| 7 import 'dart:collection' show HashSet, HashMap; | 7 import 'dart:collection' show HashSet, HashMap; |
| 8 import 'dart:io' show Directory, File; | 8 import 'dart:io' show Directory, File; |
| 9 | 9 |
| 10 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; | 10 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; |
| (...skipping 1284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1295 @override | 1295 @override |
| 1296 visitMethodInvocation(MethodInvocation node) { | 1296 visitMethodInvocation(MethodInvocation node) { |
| 1297 var target = node.isCascaded ? _cascadeTarget : node.target; | 1297 var target = node.isCascaded ? _cascadeTarget : node.target; |
| 1298 | 1298 |
| 1299 var result = _emitForeignJS(node); | 1299 var result = _emitForeignJS(node); |
| 1300 if (result != null) return result; | 1300 if (result != null) return result; |
| 1301 | 1301 |
| 1302 if (rules.isDynamicCall(node.methodName)) { | 1302 if (rules.isDynamicCall(node.methodName)) { |
| 1303 var args = _visit(node.argumentList); | 1303 var args = _visit(node.argumentList); |
| 1304 if (target != null) { | 1304 if (target != null) { |
| 1305 return js.call('dart.dinvoke(#, #, #)', [ | 1305 return js.call('dart.dsend(#, #, #)', [ |
| 1306 _visit(target), | 1306 _visit(target), |
| 1307 js.string(node.methodName.name, "'"), | 1307 js.string(node.methodName.name, "'"), |
| 1308 args | 1308 args |
| 1309 ]); | 1309 ]); |
| 1310 } else { | 1310 } else { |
| 1311 return js.call('dart.dinvokef(#, #)', [_visit(node.methodName), args]); | 1311 return js.call('dart.dcall(#, #)', [_visit(node.methodName), args]); |
| 1312 } | 1312 } |
| 1313 } | 1313 } |
| 1314 | 1314 |
| 1315 // TODO(jmesserly): if this resolves to a getter returning a function with | 1315 // TODO(jmesserly): if this resolves to a getter returning a function with |
| 1316 // a call method, we don't generate the `.call` correctly. | 1316 // a call method, we don't generate the `.call` correctly. |
| 1317 | 1317 |
| 1318 var targetJs; | 1318 var targetJs; |
| 1319 if (target != null) { | 1319 if (target != null) { |
| 1320 targetJs = js.call('#.#', [ | 1320 targetJs = js.call('#.#', [ |
| 1321 _visit(target), | 1321 _visit(target), |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1345 return result; | 1345 return result; |
| 1346 } | 1346 } |
| 1347 return null; | 1347 return null; |
| 1348 } | 1348 } |
| 1349 | 1349 |
| 1350 @override | 1350 @override |
| 1351 JS.Expression visitFunctionExpressionInvocation( | 1351 JS.Expression visitFunctionExpressionInvocation( |
| 1352 FunctionExpressionInvocation node) { | 1352 FunctionExpressionInvocation node) { |
| 1353 var code; | 1353 var code; |
| 1354 if (rules.isDynamicCall(node.function)) { | 1354 if (rules.isDynamicCall(node.function)) { |
| 1355 code = 'dart.dinvokef(#, #)'; | 1355 code = 'dart.dcall(#, #)'; |
| 1356 } else { | 1356 } else { |
| 1357 code = '#(#)'; | 1357 code = '#(#)'; |
| 1358 } | 1358 } |
| 1359 return js.call(code, [_visit(node.function), _visit(node.argumentList)]); | 1359 return js.call(code, [_visit(node.function), _visit(node.argumentList)]); |
| 1360 } | 1360 } |
| 1361 | 1361 |
| 1362 @override | 1362 @override |
| 1363 List<JS.Expression> visitArgumentList(ArgumentList node) { | 1363 List<JS.Expression> visitArgumentList(ArgumentList node) { |
| 1364 var args = <JS.Expression>[]; | 1364 var args = <JS.Expression>[]; |
| 1365 var named = <JS.Property>[]; | 1365 var named = <JS.Property>[]; |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1642 } else { | 1642 } else { |
| 1643 // TODO(vsm): When do Dart ops not map to JS? | 1643 // TODO(vsm): When do Dart ops not map to JS? |
| 1644 code = '# $op #'; | 1644 code = '# $op #'; |
| 1645 } | 1645 } |
| 1646 return js.call(code, [notNull(left), notNull(right)]); | 1646 return js.call(code, [notNull(left), notNull(right)]); |
| 1647 } else { | 1647 } else { |
| 1648 var opString = js.string(op.lexeme, "'"); | 1648 var opString = js.string(op.lexeme, "'"); |
| 1649 if (rules.isDynamicTarget(left)) { | 1649 if (rules.isDynamicTarget(left)) { |
| 1650 // dynamic dispatch | 1650 // dynamic dispatch |
| 1651 return js.call( | 1651 return js.call( |
| 1652 'dart.dbinary(#, #, #)', [_visit(left), opString, _visit(right)]); | 1652 'dart.dsend(#, #, #)', [_visit(left), opString, _visit(right)]); |
| 1653 } else if (_isJSBuiltinType(leftType)) { | 1653 } else if (_isJSBuiltinType(leftType)) { |
| 1654 // TODO(jmesserly): we'd get better readability from the static-dispatch | 1654 // TODO(jmesserly): we'd get better readability from the static-dispatch |
| 1655 // pattern below. Consider: | 1655 // pattern below. Consider: |
| 1656 // | 1656 // |
| 1657 // "hello"['+']"world" | 1657 // "hello"['+']"world" |
| 1658 // vs | 1658 // vs |
| 1659 // core.String['+']("hello", "world") | 1659 // core.String['+']("hello", "world") |
| 1660 // | 1660 // |
| 1661 // Infix notation is much more readable, which is a bit part of why | 1661 // Infix notation is much more readable, which is a bit part of why |
| 1662 // C# added its extension methods feature. However this would require | 1662 // C# added its extension methods feature. However this would require |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1853 // (for example, x is IndexExpression) we evaluate those once. | 1853 // (for example, x is IndexExpression) we evaluate those once. |
| 1854 var one = AstBuilder.integerLiteral(1) | 1854 var one = AstBuilder.integerLiteral(1) |
| 1855 ..staticType = rules.provider.intType; | 1855 ..staticType = rules.provider.intType; |
| 1856 return _emitOpAssign(expr, one, op.lexeme[0], context: expr); | 1856 return _emitOpAssign(expr, one, op.lexeme[0], context: expr); |
| 1857 } | 1857 } |
| 1858 | 1858 |
| 1859 // Call the operator | 1859 // Call the operator |
| 1860 var opString = _emitMemberName(op.lexeme, unary: true); | 1860 var opString = _emitMemberName(op.lexeme, unary: true); |
| 1861 if (rules.isDynamicTarget(expr)) { | 1861 if (rules.isDynamicTarget(expr)) { |
| 1862 // dynamic dispatch | 1862 // dynamic dispatch |
| 1863 return js.call('dart.dunary(#, #)', [opString, _visit(expr)]); | 1863 return js.call('dart.dsend(#, #)', [_visit(expr), opString]); |
| 1864 } else if (_isJSBuiltinType(dispatchType)) { | 1864 } else if (_isJSBuiltinType(dispatchType)) { |
| 1865 return js.call( | 1865 return js.call( |
| 1866 '#.#(#)', [_emitTypeName(dispatchType), opString, _visit(expr)]); | 1866 '#.#(#)', [_emitTypeName(dispatchType), opString, _visit(expr)]); |
| 1867 } else { | 1867 } else { |
| 1868 // Generic static-dispatch, user-defined operator code path. | 1868 // Generic static-dispatch, user-defined operator code path. |
| 1869 return js.call('#.#()', [_visit(expr), opString]); | 1869 return js.call('#.#()', [_visit(expr), opString]); |
| 1870 } | 1870 } |
| 1871 } | 1871 } |
| 1872 | 1872 |
| 1873 // Cascades can contain [IndexExpression], [MethodInvocation] and | 1873 // Cascades can contain [IndexExpression], [MethodInvocation] and |
| (...skipping 726 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2600 if (args.isNotEmpty && args[0] is NamedExpression) { | 2600 if (args.isNotEmpty && args[0] is NamedExpression) { |
| 2601 NamedExpression named = args[0]; | 2601 NamedExpression named = args[0]; |
| 2602 if (named.name.label.name == argName && | 2602 if (named.name.label.name == argName && |
| 2603 named.expression is StringLiteral) { | 2603 named.expression is StringLiteral) { |
| 2604 return (named.expression as StringLiteral).stringValue; | 2604 return (named.expression as StringLiteral).stringValue; |
| 2605 } | 2605 } |
| 2606 } | 2606 } |
| 2607 } | 2607 } |
| 2608 return null; | 2608 return null; |
| 2609 } | 2609 } |
| OLD | NEW |