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

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

Powered by Google App Engine
This is Rietveld 408576698