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

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

Issue 1195523002: Handle dynamic as bottom inside of function type reps (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Fix typo in comment Created 5 years, 6 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
« no previous file with comments | « lib/runtime/dart_runtime.js ('k') | test/browser/runtime_tests.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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, SplayTreeSet; 7 import 'dart:collection' show HashSet, HashMap, SplayTreeSet;
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 629 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 var sNames = []; 640 var sNames = [];
641 for (MethodDeclaration node in methods) { 641 for (MethodDeclaration node in methods) {
642 if (!(node.isSetter || node.isGetter || node.isAbstract)) { 642 if (!(node.isSetter || node.isGetter || node.isAbstract)) {
643 var name = node.name.name; 643 var name = node.name.name;
644 var element = node.element; 644 var element = node.element;
645 var inheritedElement = 645 var inheritedElement =
646 classElem.lookUpInheritedConcreteMethod(name, currentLibrary); 646 classElem.lookUpInheritedConcreteMethod(name, currentLibrary);
647 if (inheritedElement != null && 647 if (inheritedElement != null &&
648 inheritedElement.type == element.type) continue; 648 inheritedElement.type == element.type) continue;
649 var memberName = _elementMemberName(element); 649 var memberName = _elementMemberName(element);
650 var parts = 650 var parts = _emitFunctionTypeParts(element.type);
651 _emitFunctionTypeParts(element.type, dynamicIsBottom: false);
652 var property = 651 var property =
653 new JS.Property(memberName, new JS.ArrayInitializer(parts)); 652 new JS.Property(memberName, new JS.ArrayInitializer(parts));
654 if (node.isStatic) { 653 if (node.isStatic) {
655 tStatics.add(property); 654 tStatics.add(property);
656 sNames.add(memberName); 655 sNames.add(memberName);
657 } else { 656 } else {
658 tMethods.add(property); 657 tMethods.add(property);
659 } 658 }
660 } 659 }
661 } 660 }
662 661
663 var tCtors = []; 662 var tCtors = [];
664 for (ConstructorDeclaration node in ctors) { 663 for (ConstructorDeclaration node in ctors) {
665 var memberName = _constructorName(node.element); 664 var memberName = _constructorName(node.element);
666 var element = node.element; 665 var element = node.element;
667 var parts = 666 var parts = _emitFunctionTypeParts(element.type);
668 _emitFunctionTypeParts(element.type, dynamicIsBottom: false);
669 var property = 667 var property =
670 new JS.Property(memberName, new JS.ArrayInitializer(parts)); 668 new JS.Property(memberName, new JS.ArrayInitializer(parts));
671 tCtors.add(property); 669 tCtors.add(property);
672 } 670 }
673 671
674 build(name, elements) { 672 build(name, elements) {
675 var o = 673 var o =
676 new JS.ObjectInitializer(elements, multiline: elements.length > 1); 674 new JS.ObjectInitializer(elements, multiline: elements.length > 1);
677 var e = js.call('() => #', o); 675 var e = js.call('() => #', o);
678 var p = new JS.Property(_propertyName(name), e); 676 var p = new JS.Property(_propertyName(name), e);
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after
1178 if (type is FunctionType && (name == '' || name == null)) { 1176 if (type is FunctionType && (name == '' || name == null)) {
1179 if (type.returnType.isDynamic && 1177 if (type.returnType.isDynamic &&
1180 type.optionalParameterTypes.isEmpty && 1178 type.optionalParameterTypes.isEmpty &&
1181 type.namedParameterTypes.isEmpty && 1179 type.namedParameterTypes.isEmpty &&
1182 type.normalParameterTypes.every((t) => t.isDynamic)) { 1180 type.normalParameterTypes.every((t) => t.isDynamic)) {
1183 return js.call('dart.fn(#)', [clos]); 1181 return js.call('dart.fn(#)', [clos]);
1184 } 1182 }
1185 if (lazy) { 1183 if (lazy) {
1186 return js.call('dart.fn(#, () => #)', [clos, _emitFunctionRTTI(type)]); 1184 return js.call('dart.fn(#, () => #)', [clos, _emitFunctionRTTI(type)]);
1187 } 1185 }
1188 return js.call('dart.fn(#, #)', [ 1186 return js.call('dart.fn(#, #)', [clos, _emitFunctionTypeParts(type)]);
1189 clos,
1190 _emitFunctionTypeParts(type, dynamicIsBottom: false)
1191 ]);
1192 } 1187 }
1193 throw 'Function has non function type: $type'; 1188 throw 'Function has non function type: $type';
1194 } 1189 }
1195 1190
1196 @override 1191 @override
1197 JS.Expression visitFunctionExpression(FunctionExpression node) { 1192 JS.Expression visitFunctionExpression(FunctionExpression node) {
1198 var params = _visit(node.parameters); 1193 var params = _visit(node.parameters);
1199 if (params == null) params = []; 1194 if (params == null) params = [];
1200 1195
1201 var parent = node.parent; 1196 var parent = node.parent;
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1314 return _getTemp(element, name); 1309 return _getTemp(element, name);
1315 } 1310 }
1316 } 1311 }
1317 1312
1318 return new JS.Identifier(name); 1313 return new JS.Identifier(name);
1319 } 1314 }
1320 1315
1321 JS.TemporaryId _getTemp(Object key, String name) => 1316 JS.TemporaryId _getTemp(Object key, String name) =>
1322 _temps.putIfAbsent(key, () => new JS.TemporaryId(name)); 1317 _temps.putIfAbsent(key, () => new JS.TemporaryId(name));
1323 1318
1324 JS.ArrayInitializer _emitTypeNames(List<DartType> types, 1319 JS.ArrayInitializer _emitTypeNames(List<DartType> types) {
1325 {dynamicIsBottom: false}) { 1320 var build = (t) => _emitTypeName(t);
1326 var build = (t) => _emitTypeName(t, dynamicIsBottom: dynamicIsBottom);
1327 return new JS.ArrayInitializer(types.map(build).toList()); 1321 return new JS.ArrayInitializer(types.map(build).toList());
1328 } 1322 }
1329 1323
1330 JS.ObjectInitializer _emitTypeProperties(Map<String, DartType> types, 1324 JS.ObjectInitializer _emitTypeProperties(Map<String, DartType> types) {
1331 {dynamicIsBottom: false}) {
1332 var properties = <JS.Property>[]; 1325 var properties = <JS.Property>[];
1333 types.forEach((name, type) { 1326 types.forEach((name, type) {
1334 var key = _propertyName(name); 1327 var key = _propertyName(name);
1335 var value = _emitTypeName(type, dynamicIsBottom: dynamicIsBottom); 1328 var value = _emitTypeName(type);
1336 properties.add(new JS.Property(key, value)); 1329 properties.add(new JS.Property(key, value));
1337 }); 1330 });
1338 return new JS.ObjectInitializer(properties); 1331 return new JS.ObjectInitializer(properties);
1339 } 1332 }
1340 1333
1341 /// Emit the pieces of a function type, as an array of return type, 1334 /// Emit the pieces of a function type, as an array of return type,
1342 /// regular args, and optional/named args. 1335 /// regular args, and optional/named args.
1343 /// If [dynamicIsBottom] is true, then dynamics in argument positions 1336 List<JS.Expression> _emitFunctionTypeParts(FunctionType type) {
1344 /// will be lowered to bottom instead of Object.
1345 List<JS.Expression> _emitFunctionTypeParts(FunctionType type,
1346 {bool dynamicIsBottom: true}) {
1347 var returnType = type.returnType; 1337 var returnType = type.returnType;
1348 var parameterTypes = type.normalParameterTypes; 1338 var parameterTypes = type.normalParameterTypes;
1349 var optionalTypes = type.optionalParameterTypes; 1339 var optionalTypes = type.optionalParameterTypes;
1350 var namedTypes = type.namedParameterTypes; 1340 var namedTypes = type.namedParameterTypes;
1351 var rt = _emitTypeName(returnType); 1341 var rt = _emitTypeName(returnType);
1352 var ra = _emitTypeNames(parameterTypes, dynamicIsBottom: dynamicIsBottom); 1342 var ra = _emitTypeNames(parameterTypes);
1353 if (!namedTypes.isEmpty) { 1343 if (!namedTypes.isEmpty) {
1354 assert(optionalTypes.isEmpty); 1344 assert(optionalTypes.isEmpty);
1355 var na = 1345 var na = _emitTypeProperties(namedTypes);
1356 _emitTypeProperties(namedTypes, dynamicIsBottom: dynamicIsBottom);
1357 return [rt, ra, na]; 1346 return [rt, ra, na];
1358 } 1347 }
1359 if (!optionalTypes.isEmpty) { 1348 if (!optionalTypes.isEmpty) {
1360 assert(namedTypes.isEmpty); 1349 assert(namedTypes.isEmpty);
1361 var oa = _emitTypeNames(optionalTypes, dynamicIsBottom: dynamicIsBottom); 1350 var oa = _emitTypeNames(optionalTypes);
1362 return [rt, ra, oa]; 1351 return [rt, ra, oa];
1363 } 1352 }
1364 return [rt, ra]; 1353 return [rt, ra];
1365 } 1354 }
1366 1355
1367 JS.Expression _emitFunctionRTTI(FunctionType type) { 1356 JS.Expression _emitFunctionRTTI(FunctionType type) {
1368 var parts = _emitFunctionTypeParts(type, dynamicIsBottom: false); 1357 var parts = _emitFunctionTypeParts(type);
1369 return js.call('dart.functionType(#)', [parts]); 1358 return js.call('dart.definiteFunctionType(#)', [parts]);
1370 } 1359 }
1371 1360
1372 /// Emits a Dart [type] into code. 1361 /// Emits a Dart [type] into code.
1373 /// 1362 ///
1374 /// If [lowerTypedef] is set, a typedef will be expanded as if it were a 1363 /// If [lowerTypedef] is set, a typedef will be expanded as if it were a
1375 /// function type. Similarly if [lowerGeneric] is set, the `List$()` form 1364 /// function type. Similarly if [lowerGeneric] is set, the `List$()` form
1376 /// will be used instead of `List`. These flags are used when generating 1365 /// will be used instead of `List`. These flags are used when generating
1377 /// the definitions for typedefs and generic types, respectively. 1366 /// the definitions for typedefs and generic types, respectively.
1378 JS.Expression _emitTypeName(DartType type, {bool lowerTypedef: false, 1367 JS.Expression _emitTypeName(DartType type,
1379 bool lowerGeneric: false, bool dynamicIsBottom: false}) { 1368 {bool lowerTypedef: false, bool lowerGeneric: false}) {
1380 1369
1381 // The void and dynamic types are not defined in core. 1370 // The void and dynamic types are not defined in core.
1382 if (type.isVoid) { 1371 if (type.isVoid) {
1383 return js.call('dart.void'); 1372 return js.call('dart.void');
1384 } else if (type.isDynamic) { 1373 } else if (type.isDynamic) {
1385 if (dynamicIsBottom) return js.call('dart.bottom'); 1374 return js.call('dart.dynamic');
1386 return _emitTypeName(types.objectType);
1387 } else if (type.isBottom) { 1375 } else if (type.isBottom) {
1388 return js.call('dart.bottom'); 1376 return js.call('dart.bottom');
1389 } 1377 }
1390 1378
1391 _loader.declareBeforeUse(type.element); 1379 _loader.declareBeforeUse(type.element);
1392 1380
1393 // TODO(jmesserly): like constants, should we hoist function types out of 1381 // TODO(jmesserly): like constants, should we hoist function types out of
1394 // methods? Similar issue with generic types. For all of these, we may want 1382 // methods? Similar issue with generic types. For all of these, we may want
1395 // to canonicalize them too, at least when inside the same library. 1383 // to canonicalize them too, at least when inside the same library.
1396 var name = type.name; 1384 var name = type.name;
(...skipping 1405 matching lines...) Expand 10 before | Expand all | Expand 10 after
2802 2790
2803 /// A special kind of element created by the compiler, signifying a temporary 2791 /// A special kind of element created by the compiler, signifying a temporary
2804 /// variable. These objects use instance equality, and should be shared 2792 /// variable. These objects use instance equality, and should be shared
2805 /// everywhere in the tree where they are treated as the same variable. 2793 /// everywhere in the tree where they are treated as the same variable.
2806 class TemporaryVariableElement extends LocalVariableElementImpl { 2794 class TemporaryVariableElement extends LocalVariableElementImpl {
2807 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); 2795 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name);
2808 2796
2809 int get hashCode => identityHashCode(this); 2797 int get hashCode => identityHashCode(this);
2810 bool operator ==(Object other) => identical(this, other); 2798 bool operator ==(Object other) => identical(this, other);
2811 } 2799 }
OLDNEW
« no previous file with comments | « lib/runtime/dart_runtime.js ('k') | test/browser/runtime_tests.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698