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 | 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 1050 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1061 var name = node.name.name; | 1061 var name = node.name.name; |
1062 return new JS.Method(_propertyName(name), _visit(node.functionExpression), | 1062 return new JS.Method(_propertyName(name), _visit(node.functionExpression), |
1063 isGetter: node.isGetter, isSetter: node.isSetter); | 1063 isGetter: node.isGetter, isSetter: node.isSetter); |
1064 } | 1064 } |
1065 | 1065 |
1066 @override | 1066 @override |
1067 JS.Expression visitFunctionExpression(FunctionExpression node) { | 1067 JS.Expression visitFunctionExpression(FunctionExpression node) { |
1068 var params = _visit(node.parameters); | 1068 var params = _visit(node.parameters); |
1069 if (params == null) params = []; | 1069 if (params == null) params = []; |
1070 | 1070 |
1071 if (node.parent is FunctionDeclaration) { | 1071 var parent = node.parent; |
1072 if (parent is FunctionDeclaration && | |
Jennifer Messerly
2015/05/08 21:49:38
AST is a little wacky here... parent is a Function
| |
1073 parent.parent is! FunctionDeclarationStatement) { | |
1072 return new JS.Fun(params, _visit(node.body)); | 1074 return new JS.Fun(params, _visit(node.body)); |
1073 } else { | 1075 } else { |
1074 String code; | 1076 String code; |
1075 AstNode body; | 1077 AstNode body; |
1076 var nodeBody = node.body; | 1078 var nodeBody = node.body; |
1077 if (nodeBody is ExpressionFunctionBody) { | 1079 if (nodeBody is ExpressionFunctionBody) { |
1078 code = '(#) => #'; | 1080 code = '(#) => #'; |
1079 body = nodeBody.expression; | 1081 body = nodeBody.expression; |
1080 } else { | 1082 } else { |
1081 code = '(#) => { #; }'; | 1083 code = '(#) => { #; }'; |
1082 body = nodeBody; | 1084 body = nodeBody; |
1083 } | 1085 } |
1084 return js.call(code, [params, _visit(body)]); | 1086 return js.call(code, [params, _visit(body)]); |
1085 } | 1087 } |
1086 } | 1088 } |
1087 | 1089 |
1088 @override | 1090 @override |
1089 JS.Statement visitFunctionDeclarationStatement( | 1091 JS.Statement visitFunctionDeclarationStatement( |
1090 FunctionDeclarationStatement node) { | 1092 FunctionDeclarationStatement node) { |
1091 var func = node.functionDeclaration; | 1093 var func = node.functionDeclaration; |
1092 if (func.isGetter || func.isSetter) { | 1094 if (func.isGetter || func.isSetter) { |
1093 return js.comment('Unimplemented function get/set statement: $node'); | 1095 return js.comment('Unimplemented function get/set statement: $node'); |
1094 } | 1096 } |
1095 | 1097 |
1098 // Use an => function to bind this. | |
1099 // Technically we only need to do this if the function actually closes over | |
1100 // `this`, but it seems harmless enough to just do it always. | |
1096 var name = new JS.Identifier(func.name.name); | 1101 var name = new JS.Identifier(func.name.name); |
1097 return new JS.Block([ | 1102 return new JS.Block([ |
1098 js.comment("// Function ${func.name.name}: ${func.element.type}\n"), | 1103 js.comment("// Function ${func.name.name}: ${func.element.type}\n"), |
1099 new JS.FunctionDeclaration(name, _visit(func.functionExpression)) | 1104 js.statement('let # = #;', [name, _visit(func.functionExpression)]) |
1100 ]); | 1105 ]); |
1101 } | 1106 } |
1102 | 1107 |
1103 /// Writes a simple identifier. This can handle implicit `this` as well as | 1108 /// Writes a simple identifier. This can handle implicit `this` as well as |
1104 /// going through the qualified library name if necessary. | 1109 /// going through the qualified library name if necessary. |
1105 @override | 1110 @override |
1106 JS.Expression visitSimpleIdentifier(SimpleIdentifier node) { | 1111 JS.Expression visitSimpleIdentifier(SimpleIdentifier node) { |
1107 var accessor = node.staticElement; | 1112 var accessor = node.staticElement; |
1108 if (accessor == null) { | 1113 if (accessor == null) { |
1109 return js.commentExpression( | 1114 return js.commentExpression( |
(...skipping 1479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2589 // TODO(jmesserly): validate the library. See issue #135. | 2594 // TODO(jmesserly): validate the library. See issue #135. |
2590 bool _isJsNameAnnotation(DartObjectImpl value) => value.type.name == 'JsName'; | 2595 bool _isJsNameAnnotation(DartObjectImpl value) => value.type.name == 'JsName'; |
2591 | 2596 |
2592 bool _isJsPeerInterface(DartObjectImpl value) => | 2597 bool _isJsPeerInterface(DartObjectImpl value) => |
2593 value.type.name == 'JsPeerInterface'; | 2598 value.type.name == 'JsPeerInterface'; |
2594 | 2599 |
2595 // TODO(jacobr): we would like to do something like the following | 2600 // TODO(jacobr): we would like to do something like the following |
2596 // but we don't have summary support yet. | 2601 // but we don't have summary support yet. |
2597 // bool _supportJsExtensionMethod(AnnotatedNode node) => | 2602 // bool _supportJsExtensionMethod(AnnotatedNode node) => |
2598 // _getAnnotation(node, "SupportJsExtensionMethod") != null; | 2603 // _getAnnotation(node, "SupportJsExtensionMethod") != null; |
OLD | NEW |