Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(353)

Side by Side Diff: lib/src/codegen/js_codegen.dart

Issue 1148333003: No dynamic at runtime (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 582 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 var name = node.name.name; 593 var name = node.name.name;
594 var element = node.element; 594 var element = node.element;
595 var inheritedElement = 595 var inheritedElement =
596 classElem.lookUpInheritedConcreteMethod(name, currentLibrary); 596 classElem.lookUpInheritedConcreteMethod(name, currentLibrary);
597 if (inheritedElement != null && 597 if (inheritedElement != null &&
598 inheritedElement.type == element.type) continue; 598 inheritedElement.type == element.type) continue;
599 var unary = node.parameters.parameters.isEmpty; 599 var unary = node.parameters.parameters.isEmpty;
600 var memberName = _emitMemberName(name, 600 var memberName = _emitMemberName(name,
601 type: cType, unary: unary, isStatic: node.isStatic); 601 type: cType, unary: unary, isStatic: node.isStatic);
602 var property = 602 var property =
603 new JS.Property(memberName, _emitTypeName(element.type)); 603 new JS.Property(memberName, _emitFunctionRTTI(element.type));
604 if (node.isStatic) { 604 if (node.isStatic) {
605 tStatics.add(property); 605 tStatics.add(property);
606 sNames.add(memberName); 606 sNames.add(memberName);
607 } else tMethods.add(property); 607 } else tMethods.add(property);
608 } 608 }
609 } 609 }
610 build(name, elements) { 610 build(name, elements) {
611 var o = 611 var o =
612 new JS.ObjectInitializer(elements, vertical: elements.length > 1); 612 new JS.ObjectInitializer(elements, vertical: elements.length > 1);
613 var e = js.call('() => #', o); 613 var e = js.call('() => #', o);
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
1018 var lazy = topLevel && !_typeIsLoaded(type); 1018 var lazy = topLevel && !_typeIsLoaded(type);
1019 1019
1020 if (type is FunctionType && (name == '' || name == null)) { 1020 if (type is FunctionType && (name == '' || name == null)) {
1021 if (type.returnType.isDynamic && 1021 if (type.returnType.isDynamic &&
1022 type.optionalParameterTypes.isEmpty && 1022 type.optionalParameterTypes.isEmpty &&
1023 type.namedParameterTypes.isEmpty && 1023 type.namedParameterTypes.isEmpty &&
1024 type.normalParameterTypes.every((t) => t.isDynamic)) { 1024 type.normalParameterTypes.every((t) => t.isDynamic)) {
1025 return js.call('dart.fn(#)', [clos]); 1025 return js.call('dart.fn(#)', [clos]);
1026 } 1026 }
1027 if (lazy) { 1027 if (lazy) {
1028 return js.call('dart.fn(#, () => #)', [clos, _emitTypeName(type)]); 1028 return js.call('dart.fn(#, () => #)', [clos, _emitFunctionRTTI(type)]);
1029 } 1029 }
1030 return js.call('dart.fn(#, #)', [clos, _emitFunctionTypeParts(type)]); 1030 return js.call('dart.fn(#, #)', [
1031 clos,
1032 _emitFunctionTypeParts(type, dynamicIsObject: true)
1033 ]);
1031 } 1034 }
1032 throw 'Function has non function type: $type'; 1035 throw 'Function has non function type: $type';
1033 } 1036 }
1034 1037
1035 @override 1038 @override
1036 JS.Expression visitFunctionExpression(FunctionExpression node) { 1039 JS.Expression visitFunctionExpression(FunctionExpression node) {
1037 var params = _visit(node.parameters); 1040 var params = _visit(node.parameters);
1038 if (params == null) params = []; 1041 if (params == null) params = [];
1039 1042
1040 var parent = node.parent; 1043 var parent = node.parent;
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
1152 return _getTemp(element, name); 1155 return _getTemp(element, name);
1153 } 1156 }
1154 } 1157 }
1155 1158
1156 return new JS.Identifier(name); 1159 return new JS.Identifier(name);
1157 } 1160 }
1158 1161
1159 JS.TemporaryId _getTemp(Object key, String name) => 1162 JS.TemporaryId _getTemp(Object key, String name) =>
1160 _temps.putIfAbsent(key, () => new JS.TemporaryId(name)); 1163 _temps.putIfAbsent(key, () => new JS.TemporaryId(name));
1161 1164
1162 JS.ArrayInitializer _emitTypeNames(List<DartType> types) { 1165 JS.ArrayInitializer _emitTypeNames(List<DartType> types,
1163 return new JS.ArrayInitializer(types.map(_emitTypeName).toList()); 1166 {dynamicIsBottom: false}) {
1167 var build = (t) => _emitTypeName(t, dynamicIsBottom: dynamicIsBottom);
1168 return new JS.ArrayInitializer(types.map(build).toList());
1164 } 1169 }
1165 1170
1166 JS.ObjectInitializer _emitTypeProperties(Map<String, DartType> types) { 1171 JS.ObjectInitializer _emitTypeProperties(Map<String, DartType> types,
1172 {dynamicIsBottom: false}) {
1167 var properties = <JS.Property>[]; 1173 var properties = <JS.Property>[];
1168 types.forEach((name, type) { 1174 types.forEach((name, type) {
1169 var key = new JS.LiteralString(name); 1175 var key = new JS.LiteralString(name);
1170 var value = _emitTypeName(type); 1176 var value = _emitTypeName(type, dynamicIsBottom: dynamicIsBottom);
1171 properties.add(new JS.Property(key, value)); 1177 properties.add(new JS.Property(key, value));
1172 }); 1178 });
1173 return new JS.ObjectInitializer(properties); 1179 return new JS.ObjectInitializer(properties);
1174 } 1180 }
1175 1181
1176 List<JS.Expression> _emitFunctionTypeParts(FunctionType type) { 1182 /// Emit the pieces of a function type, as an array of return type,
1183 /// regular args, and optional/named args.
1184 /// If [dynamicIsObject] is set, then dynamics in argument positions
1185 /// will be lowered to Object instead of bottom.
1186 List<JS.Expression> _emitFunctionTypeParts(FunctionType type,
1187 {bool dynamicIsObject: false}) {
vsm 2015/05/20 23:03:10 Perhaps use either dynamicIsBottom here or dynamic
Leaf 2015/05/20 23:35:28 Done.
1177 var returnType = type.returnType; 1188 var returnType = type.returnType;
1178 var parameterTypes = type.normalParameterTypes; 1189 var parameterTypes = type.normalParameterTypes;
1179 var optionalTypes = type.optionalParameterTypes; 1190 var optionalTypes = type.optionalParameterTypes;
1180 var namedTypes = type.namedParameterTypes; 1191 var namedTypes = type.namedParameterTypes;
1181 var rt = _emitTypeName(returnType); 1192 var rt = _emitTypeName(returnType);
1182 var ra = _emitTypeNames(parameterTypes); 1193 var ra = _emitTypeNames(parameterTypes, dynamicIsBottom: !dynamicIsObject);
1183 if (!namedTypes.isEmpty) { 1194 if (!namedTypes.isEmpty) {
1184 assert(optionalTypes.isEmpty); 1195 assert(optionalTypes.isEmpty);
1185 var na = _emitTypeProperties(namedTypes); 1196 var na =
1197 _emitTypeProperties(namedTypes, dynamicIsBottom: !dynamicIsObject);
1186 return [rt, ra, na]; 1198 return [rt, ra, na];
1187 } 1199 }
1188 if (!optionalTypes.isEmpty) { 1200 if (!optionalTypes.isEmpty) {
1189 assert(namedTypes.isEmpty); 1201 assert(namedTypes.isEmpty);
1190 var oa = _emitTypeNames(optionalTypes); 1202 var oa = _emitTypeNames(optionalTypes, dynamicIsBottom: !dynamicIsObject);
1191 return [rt, ra, oa]; 1203 return [rt, ra, oa];
1192 } 1204 }
1193 return [rt, ra]; 1205 return [rt, ra];
1194 } 1206 }
1195 1207
1208 JS.Expression _emitFunctionRTTI(FunctionType type) {
1209 var parts = _emitFunctionTypeParts(type, dynamicIsObject: true);
1210 return js.call('dart.functionType(#)', [parts]);
1211 }
1212
1196 /// Emits a Dart [type] into code. 1213 /// Emits a Dart [type] into code.
1197 /// 1214 ///
1198 /// If [lowerTypedef] is set, a typedef will be expanded as if it were a 1215 /// If [lowerTypedef] is set, a typedef will be expanded as if it were a
1199 /// function type. Similarly if [lowerGeneric] is set, the `List$()` form 1216 /// function type. Similarly if [lowerGeneric] is set, the `List$()` form
1200 /// will be used instead of `List`. These flags are used when generating 1217 /// will be used instead of `List`. These flags are used when generating
1201 /// the definitions for typedefs and generic types, respectively. 1218 /// the definitions for typedefs and generic types, respectively.
1202 JS.Expression _emitTypeName(DartType type, 1219 JS.Expression _emitTypeName(DartType type, {bool lowerTypedef: false,
1203 {bool lowerTypedef: false, bool lowerGeneric: false}) { 1220 bool lowerGeneric: false, bool dynamicIsBottom: false}) {
1204 1221
1205 // The void and dynamic types are not defined in core. 1222 // The void and dynamic types are not defined in core.
1206 if (type.isVoid) { 1223 if (type.isVoid) {
1207 return js.call('dart.void'); 1224 return js.call('dart.void');
1208 } else if (type.isDynamic) { 1225 } else if (type.isDynamic) {
1209 return js.call('dart.dynamic'); 1226 if (dynamicIsBottom) return js.call('dart.bottom');
1227 return _emitTypeName(types.objectType);
1210 } else if (type.isBottom) { 1228 } else if (type.isBottom) {
1211 return js.call('dart.bottom'); 1229 return js.call('dart.bottom');
1212 } 1230 }
1213 1231
1214 _loader.declareBeforeUse(type.element); 1232 _loader.declareBeforeUse(type.element);
1215 1233
1216 // TODO(jmesserly): like constants, should we hoist function types out of 1234 // TODO(jmesserly): like constants, should we hoist function types out of
1217 // methods? Similar issue with generic types. For all of these, we may want 1235 // methods? Similar issue with generic types. For all of these, we may want
1218 // to canonicalize them too, at least when inside the same library. 1236 // to canonicalize them too, at least when inside the same library.
1219 var name = type.name; 1237 var name = type.name;
(...skipping 1362 matching lines...) Expand 10 before | Expand all | Expand 10 after
2582 2600
2583 /// A special kind of element created by the compiler, signifying a temporary 2601 /// A special kind of element created by the compiler, signifying a temporary
2584 /// variable. These objects use instance equality, and should be shared 2602 /// variable. These objects use instance equality, and should be shared
2585 /// everywhere in the tree where they are treated as the same variable. 2603 /// everywhere in the tree where they are treated as the same variable.
2586 class TemporaryVariableElement extends LocalVariableElementImpl { 2604 class TemporaryVariableElement extends LocalVariableElementImpl {
2587 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); 2605 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name);
2588 2606
2589 int get hashCode => identityHashCode(this); 2607 int get hashCode => identityHashCode(this);
2590 bool operator ==(Object other) => identical(this, other); 2608 bool operator ==(Object other) => identical(this, other);
2591 } 2609 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698