| 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 ddc.src.codegen.js_codegen; | 5 library ddc.src.codegen.js_codegen; |
| 6 | 6 |
| 7 import 'dart:io' show Directory, File; | 7 import 'dart:io' show Directory, File; |
| 8 | 8 |
| 9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; | 9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; |
| 10 import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator; | 10 import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator; |
| (...skipping 739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 750 var initArgs = _emitArgumentInitializers(_parametersOf(node.parent)); | 750 var initArgs = _emitArgumentInitializers(_parametersOf(node.parent)); |
| 751 var block = visitBlock(node.block); | 751 var block = visitBlock(node.block); |
| 752 if (initArgs != null) return new JS.Block([initArgs, block]); | 752 if (initArgs != null) return new JS.Block([initArgs, block]); |
| 753 return block; | 753 return block; |
| 754 } | 754 } |
| 755 | 755 |
| 756 @override | 756 @override |
| 757 JS.Block visitBlock(Block node) => new JS.Block(_visitList(node.statements)); | 757 JS.Block visitBlock(Block node) => new JS.Block(_visitList(node.statements)); |
| 758 | 758 |
| 759 @override | 759 @override |
| 760 JS.Expression visitMethodInvocation(MethodInvocation node) { | 760 visitMethodInvocation(MethodInvocation node) { |
| 761 var target = node.isCascaded ? _cascadeTarget : node.target; | 761 var target = node.isCascaded ? _cascadeTarget : node.target; |
| 762 | 762 |
| 763 var result = _emitForeignJS(node); |
| 764 if (result != null) return result; |
| 765 |
| 763 if (rules.isDynamicCall(node.methodName)) { | 766 if (rules.isDynamicCall(node.methodName)) { |
| 764 var args = node.argumentList.accept(this); | 767 var args = node.argumentList.accept(this); |
| 765 if (target != null) { | 768 if (target != null) { |
| 766 return js.call('dart.dinvoke(#, #, #)', [ | 769 return js.call('dart.dinvoke(#, #, #)', [ |
| 767 target.accept(this), | 770 target.accept(this), |
| 768 js.string(node.methodName.name, "'"), | 771 js.string(node.methodName.name, "'"), |
| 769 args | 772 args |
| 770 ]); | 773 ]); |
| 771 } else { | 774 } else { |
| 772 return js.call( | 775 return js.call( |
| 773 'dart.dinvokef(#, #)', [node.methodName.accept(this), args]); | 776 'dart.dinvokef(#, #)', [node.methodName.accept(this), args]); |
| 774 } | 777 } |
| 775 } | 778 } |
| 776 | 779 |
| 777 // TODO(jmesserly): if this resolves to a getter returning a function with | 780 // TODO(jmesserly): if this resolves to a getter returning a function with |
| 778 // a call method, we don't generate the `.call` correctly. | 781 // a call method, we don't generate the `.call` correctly. |
| 779 | 782 |
| 780 var targetJs; | 783 var targetJs; |
| 781 if (target != null) { | 784 if (target != null) { |
| 782 targetJs = js.call('#.#', [target.accept(this), node.methodName.name]); | 785 targetJs = js.call('#.#', [target.accept(this), node.methodName.name]); |
| 783 } else { | 786 } else { |
| 784 targetJs = node.methodName.accept(this); | 787 targetJs = node.methodName.accept(this); |
| 785 } | 788 } |
| 786 | 789 |
| 787 return js.call('#(#)', [targetJs, node.argumentList.accept(this)]); | 790 return js.call('#(#)', [targetJs, node.argumentList.accept(this)]); |
| 788 } | 791 } |
| 789 | 792 |
| 793 /// Emits code for the `JS(...)` builtin. |
| 794 _emitForeignJS(MethodInvocation node) { |
| 795 var e = node.methodName.staticElement; |
| 796 if (e is FunctionElement && |
| 797 e.library.name == '_foreign_helper' && |
| 798 e.name == 'JS') { |
| 799 var args = node.argumentList.arguments; |
| 800 // arg[0] is static return type, used in `RestrictedStaticTypeAnalyzer` |
| 801 var code = args[1] as StringLiteral; |
| 802 |
| 803 var template = js.parseForeignJS(code.stringValue); |
| 804 var result = template.instantiate(_visitList(args.skip(2))); |
| 805 // `throw` is emitted as a statement by `parseForeignJS`. |
| 806 assert(result is JS.Expression || node.parent is ExpressionStatement); |
| 807 return result; |
| 808 } |
| 809 return null; |
| 810 } |
| 811 |
| 790 @override | 812 @override |
| 791 JS.Expression visitFunctionExpressionInvocation( | 813 JS.Expression visitFunctionExpressionInvocation( |
| 792 FunctionExpressionInvocation node) { | 814 FunctionExpressionInvocation node) { |
| 793 var code; | 815 var code; |
| 794 if (rules.isDynamicCall(node.function)) { | 816 if (rules.isDynamicCall(node.function)) { |
| 795 code = 'dart.dinvokef(#, #)'; | 817 code = 'dart.dinvokef(#, #)'; |
| 796 } else { | 818 } else { |
| 797 code = '#(#)'; | 819 code = '#(#)'; |
| 798 } | 820 } |
| 799 return js.call( | 821 return js.call( |
| (...skipping 913 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1713 /// Choose a canonical name from the library element. | 1735 /// Choose a canonical name from the library element. |
| 1714 /// This never uses the library's name (the identifier in the `library` | 1736 /// This never uses the library's name (the identifier in the `library` |
| 1715 /// declaration) as it doesn't have any meaningful rules enforced. | 1737 /// declaration) as it doesn't have any meaningful rules enforced. |
| 1716 String jsLibraryName(LibraryElement library) => canonicalLibraryName(library); | 1738 String jsLibraryName(LibraryElement library) => canonicalLibraryName(library); |
| 1717 | 1739 |
| 1718 /// Path to file that will be generated for [info]. | 1740 /// Path to file that will be generated for [info]. |
| 1719 // TODO(jmesserly): library directory should be relative to its package | 1741 // TODO(jmesserly): library directory should be relative to its package |
| 1720 // root. For example, "package:dev_compiler/src/codegen/js_codegen.dart" would b
e: | 1742 // root. For example, "package:dev_compiler/src/codegen/js_codegen.dart" would b
e: |
| 1721 // "ddc/src/codegen/js_codegen.js" under the output directory. | 1743 // "ddc/src/codegen/js_codegen.js" under the output directory. |
| 1722 String jsOutputPath(LibraryInfo info) => '${info.name}/${info.name}.js'; | 1744 String jsOutputPath(LibraryInfo info) => '${info.name}/${info.name}.js'; |
| OLD | NEW |