| 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 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 if (rules.isBoolType(t)) return 'boolean'; | 297 if (rules.isBoolType(t)) return 'boolean'; |
| 298 return null; | 298 return null; |
| 299 } | 299 } |
| 300 | 300 |
| 301 @override | 301 @override |
| 302 visitFunctionTypeAlias(FunctionTypeAlias node) { | 302 visitFunctionTypeAlias(FunctionTypeAlias node) { |
| 303 // If we've already emitted this class, skip it. | 303 // If we've already emitted this class, skip it. |
| 304 var type = node.element.type; | 304 var type = node.element.type; |
| 305 if (_pendingClasses.remove(node.element) == null) return null; | 305 if (_pendingClasses.remove(node.element) == null) return null; |
| 306 | 306 |
| 307 var classDecl = new JS.ClassDeclaration(new JS.ClassExpression( | 307 var name = type.name; |
| 308 new JS.Identifier(type.name), | 308 var result = js.statement('let # = dart.typedef(#, () => #);', [ |
| 309 _emitTypeName(rules.provider.functionType), [])); | 309 new JS.Identifier(name), |
| 310 js.string(name, "'"), |
| 311 _emitTypeName(node.element.type, lowerTypedef: true) |
| 312 ]); |
| 310 | 313 |
| 311 return _finishClassDef(type, classDecl); | 314 return _finishClassDef(type, result); |
| 312 } | 315 } |
| 313 | 316 |
| 314 @override | 317 @override |
| 315 JS.Expression visitTypeName(TypeName node) => _emitTypeName(node.type); | 318 JS.Expression visitTypeName(TypeName node) => _emitTypeName(node.type); |
| 316 | 319 |
| 317 @override | 320 @override |
| 318 JS.Statement visitClassTypeAlias(ClassTypeAlias node) { | 321 JS.Statement visitClassTypeAlias(ClassTypeAlias node) { |
| 319 // If we've already emitted this class, skip it. | 322 // If we've already emitted this class, skip it. |
| 320 var type = node.element.type; | 323 var type = node.element.type; |
| 321 if (_pendingClasses.remove(node.element) == null) return null; | 324 if (_pendingClasses.remove(node.element) == null) return null; |
| (...skipping 764 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1086 /// The renamer would handle this, but it would prefer to rename the | 1089 /// The renamer would handle this, but it would prefer to rename the |
| 1087 /// temporary used for the private symbol. Instead rename the parameter. | 1090 /// temporary used for the private symbol. Instead rename the parameter. |
| 1088 return new JSTemporary('${name.substring(1)}'); | 1091 return new JSTemporary('${name.substring(1)}'); |
| 1089 } | 1092 } |
| 1090 | 1093 |
| 1091 if (_isTemporary(e)) return new JSTemporary(e.name); | 1094 if (_isTemporary(e)) return new JSTemporary(e.name); |
| 1092 | 1095 |
| 1093 return new JS.Identifier(name); | 1096 return new JS.Identifier(name); |
| 1094 } | 1097 } |
| 1095 | 1098 |
| 1096 JS.Expression _emitTypeName(DartType type) { | 1099 JS.ArrayInitializer _emitTypeNames(List<DartType> types) { |
| 1100 return new JS.ArrayInitializer(types.map(_emitTypeName).toList()); |
| 1101 } |
| 1102 |
| 1103 JS.ObjectInitializer _emitTypeProperties(Map<String, DartType> types) { |
| 1104 var properties = <JS.Property>[]; |
| 1105 types.forEach((name, type) { |
| 1106 var key = new JS.LiteralString(name); |
| 1107 var value = _emitTypeName(type); |
| 1108 properties.add(new JS.Property(key, value)); |
| 1109 }); |
| 1110 return new JS.ObjectInitializer(properties); |
| 1111 } |
| 1112 |
| 1113 JS.Expression _emitTypeName(DartType type, {bool lowerTypedef: false}) { |
| 1114 // The void and dynamic types are not defined in core. |
| 1115 if (type.isVoid) { |
| 1116 return js.call('dart.void'); |
| 1117 } else if (type.isDynamic) { |
| 1118 return js.call('dart.dynamic'); |
| 1119 } |
| 1120 |
| 1097 var name = type.name; | 1121 var name = type.name; |
| 1098 var element = type.element; | 1122 var element = type.element; |
| 1099 if (name == '') { | 1123 if (name == '' || lowerTypedef && type is FunctionType) { |
| 1124 if (type is FunctionType) { |
| 1125 // TODO(vsm): Support all parameter types. |
| 1126 var returnType = type.returnType; |
| 1127 var parameterTypes = type.normalParameterTypes; |
| 1128 var optionalTypes = type.optionalParameterTypes; |
| 1129 var namedTypes = type.namedParameterTypes; |
| 1130 if (namedTypes.isEmpty) { |
| 1131 if (optionalTypes.isEmpty) { |
| 1132 return js.call('dart.functionType(#, #)', [ |
| 1133 _emitTypeName(returnType), |
| 1134 _emitTypeNames(parameterTypes) |
| 1135 ]); |
| 1136 } else { |
| 1137 return js.call('dart.functionType(#, #, #)', [ |
| 1138 _emitTypeName(returnType), |
| 1139 _emitTypeNames(parameterTypes), |
| 1140 _emitTypeNames(optionalTypes) |
| 1141 ]); |
| 1142 } |
| 1143 } else { |
| 1144 assert(optionalTypes.isEmpty); |
| 1145 return js.call('dart.functionType(#, #, #)', [ |
| 1146 _emitTypeName(returnType), |
| 1147 _emitTypeNames(parameterTypes), |
| 1148 _emitTypeProperties(namedTypes) |
| 1149 ]); |
| 1150 } |
| 1151 } |
| 1100 // TODO(jmesserly): remove when we're using coercion reifier. | 1152 // TODO(jmesserly): remove when we're using coercion reifier. |
| 1101 return _unimplementedCall('Unimplemented type $type'); | 1153 return _unimplementedCall('Unimplemented type $type'); |
| 1102 } | 1154 } |
| 1103 | 1155 |
| 1104 var typeArgs = null; | 1156 var typeArgs = null; |
| 1105 if (type is ParameterizedType) { | 1157 if (type is ParameterizedType) { |
| 1106 // TODO(jmesserly): this is a workaround for an analyzer bug, see: | 1158 // TODO(jmesserly): this is a workaround for an analyzer bug, see: |
| 1107 // https://github.com/dart-lang/dev_compiler/commit/a212d59ad046085a626dd8
d16881cdb8e8b9c3fa | 1159 // https://github.com/dart-lang/dev_compiler/commit/a212d59ad046085a626dd8
d16881cdb8e8b9c3fa |
| 1108 if (type is! FunctionType || element is FunctionTypeAlias) { | 1160 if (type is! FunctionType || element is FunctionTypeAlias) { |
| 1109 var args = type.typeArguments; | 1161 var args = type.typeArguments; |
| (...skipping 1384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2494 | 2546 |
| 2495 // TODO(jmesserly): in many cases marking the end will be unncessary. | 2547 // TODO(jmesserly): in many cases marking the end will be unncessary. |
| 2496 printer.mark(_location(node.end)); | 2548 printer.mark(_location(node.end)); |
| 2497 } | 2549 } |
| 2498 | 2550 |
| 2499 String _getIdentifier(AstNode node) { | 2551 String _getIdentifier(AstNode node) { |
| 2500 if (node is SimpleIdentifier) return node.name; | 2552 if (node is SimpleIdentifier) return node.name; |
| 2501 return null; | 2553 return null; |
| 2502 } | 2554 } |
| 2503 } | 2555 } |
| OLD | NEW |