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

Side by Side Diff: pkg/compiler/lib/src/kernel/element_map_impl.dart

Issue 3000763002: Implement .getCallType (Closed)
Patch Set: Created 3 years, 4 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) 2017, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2017, 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 dart2js.kernel.element_map; 5 library dart2js.kernel.element_map;
6 6
7 import 'package:kernel/ast.dart' as ir; 7 import 'package:kernel/ast.dart' as ir;
8 8
9 import '../closure.dart' show BoxLocal; 9 import '../closure.dart' show BoxLocal;
10 import '../common.dart'; 10 import '../common.dart';
(...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after
456 ConstantValue computeConstantValue(ConstantExpression constant, 456 ConstantValue computeConstantValue(ConstantExpression constant,
457 {bool requireConstant: true}) { 457 {bool requireConstant: true}) {
458 return _constantEnvironment.getConstantValue(constant); 458 return _constantEnvironment.getConstantValue(constant);
459 } 459 }
460 460
461 DartType _substByContext(DartType type, InterfaceType context) { 461 DartType _substByContext(DartType type, InterfaceType context) {
462 return type.subst( 462 return type.subst(
463 context.typeArguments, _getThisType(context.element).typeArguments); 463 context.typeArguments, _getThisType(context.element).typeArguments);
464 } 464 }
465 465
466 void _ensureCallType(IndexedClass cls, ClassData data) {
467 if (!data.isCallTypeComputed) {
468 data.isCallTypeComputed = true;
469 MemberEntity callMethod = lookupClassMember(cls, Identifiers.call);
470 if (callMethod != null) {
471 if (callMethod.isFunction) {
472 data.callType = _getFunctionType(callMethod);
473 } else {
474 data.callType = const DynamicType();
475 }
476 return;
477 }
478
479 Set<FunctionType> inheritedCallTypes = new Set<FunctionType>();
480 bool inheritsInvalidCallMember = false;
481
482 void addCallType(InterfaceType supertype) {
483 if (supertype == null) return;
484 DartType type = _getCallType(supertype);
485 if (type == null) return;
486 if (type.isFunctionType) {
487 inheritedCallTypes.add(type);
488 } else {
489 inheritsInvalidCallMember = true;
490 }
491 }
492
493 addCallType(_getSuperType(cls));
494 _getInterfaces(cls).forEach(addCallType);
495
496 if (inheritsInvalidCallMember) {
497 data.callType = const DynamicType();
498 } else if (inheritedCallTypes.isEmpty) {
499 return;
500 } else if (inheritedCallTypes.length == 1) {
501 data.callType = inheritedCallTypes.single;
502 } else {
503 List<FunctionType> subtypesOfAllInherited = <FunctionType>[];
Siggi Cherem (dart-lang) 2017/08/11 16:14:59 I am not sure it is worth it to replicate this log
Johnni Winther 2017/08/15 14:17:37 It's there. It works. And at some point Issue 3043
504 outer:
505 for (FunctionType a in inheritedCallTypes) {
506 for (FunctionType b in inheritedCallTypes) {
507 if (identical(a, b)) continue;
508 if (!types.isSubtype(a, b)) continue outer;
Siggi Cherem (dart-lang) 2017/08/11 16:14:59 Assuming we still want to keep this logic, this pa
Johnni Winther 2017/08/15 14:17:37 For (int)->void and (num)->void both subtype the o
Siggi Cherem (dart-lang) 2017/08/15 18:10:27 but bivariance is not allowed in strong mode :) F
509 }
510 subtypesOfAllInherited.add(a);
511 }
512 if (subtypesOfAllInherited.length == 1) {
513 data.callType = subtypesOfAllInherited.single;
514 return;
515 }
516
517 // Multiple signatures with different types => create the synthesized
518 // version.
Siggi Cherem (dart-lang) 2017/08/11 16:14:59 Here too - even if we keep the lookup for a glb an
Johnni Winther 2017/08/15 14:17:37 It is actually following the spec directly. Added
519 int minRequiredParameters;
520 int maxPositionalParameters;
521 Set<String> names = new Set<String>();
522 for (FunctionType type in inheritedCallTypes) {
523 type.namedParameters.forEach((String name) => names.add(name));
524 int requiredParameters = type.parameterTypes.length;
525 int optionalParameters = type.optionalParameterTypes.length;
526 int positionalParameters = requiredParameters + optionalParameters;
527 if (minRequiredParameters == null ||
528 minRequiredParameters > requiredParameters) {
529 minRequiredParameters = requiredParameters;
530 }
531 if (maxPositionalParameters == null ||
532 maxPositionalParameters < positionalParameters) {
533 maxPositionalParameters = positionalParameters;
534 }
535 }
536 int optionalParameters =
537 maxPositionalParameters - minRequiredParameters;
538 // TODO(johnniwinther): Support function types with both optional
539 // and named parameters?
540 if (optionalParameters == 0 || names.isEmpty) {
541 DartType dynamic = const DynamicType();
542 List<DartType> requiredParameterTypes =
543 new List.filled(minRequiredParameters, dynamic);
544 List<DartType> optionalParameterTypes =
545 new List.filled(optionalParameters, dynamic);
546 List<String> namedParameters = names.toList()
547 ..sort((a, b) => a.compareTo(b));
548 List<DartType> namedParameterTypes =
549 new List.filled(namedParameters.length, dynamic);
550 data.callType = new FunctionType(dynamic, requiredParameterTypes,
551 optionalParameterTypes, namedParameters, namedParameterTypes);
552 } else {
553 // The function type is not valid.
554 data.callType = const DynamicType();
555 }
556 }
557 }
558 }
559
560 /// Returns the type of the `call` method on 'type'.
561 ///
562 /// If [type] doesn't have a `call` member `null` is returned. If [type] has
563 /// an invalid `call` member (non-method or a synthesized method with both
564 /// optional and named parameters) a [DynamicType] is returned.
565 DartType _getCallType(InterfaceType type) {
566 IndexedClass cls = type.element;
567 assert(checkFamily(cls));
568 ClassData data = _classData[cls.classIndex];
569 _ensureCallType(cls, data);
570 if (data.callType != null) {
571 return _substByContext(data.callType, type);
572 }
573 return null;
574 }
575
466 InterfaceType _getThisType(IndexedClass cls) { 576 InterfaceType _getThisType(IndexedClass cls) {
467 assert(checkFamily(cls)); 577 assert(checkFamily(cls));
468 ClassData data = _classData[cls.classIndex]; 578 ClassData data = _classData[cls.classIndex];
469 _ensureThisAndRawType(cls, data); 579 _ensureThisAndRawType(cls, data);
470 return data.thisType; 580 return data.thisType;
471 } 581 }
472 582
473 InterfaceType _getRawType(IndexedClass cls) { 583 InterfaceType _getRawType(IndexedClass cls) {
474 assert(checkFamily(cls)); 584 assert(checkFamily(cls));
475 ClassData data = _classData[cls.classIndex]; 585 ClassData data = _classData[cls.classIndex];
(...skipping 628 matching lines...) Expand 10 before | Expand all | Expand 10 after
1104 if (node is ir.FunctionDeclaration) { 1214 if (node is ir.FunctionDeclaration) {
1105 name = node.variable.name; 1215 name = node.variable.name;
1106 functionType = getFunctionType(node.function); 1216 functionType = getFunctionType(node.function);
1107 } else if (node is ir.FunctionExpression) { 1217 } else if (node is ir.FunctionExpression) {
1108 functionType = getFunctionType(node.function); 1218 functionType = getFunctionType(node.function);
1109 } 1219 }
1110 return new KLocalFunction( 1220 return new KLocalFunction(
1111 name, memberContext, executableContext, functionType); 1221 name, memberContext, executableContext, functionType);
1112 }); 1222 });
1113 } 1223 }
1224
1225 bool _implementsFunction(IndexedClass cls) {
1226 assert(checkFamily(cls));
1227 ClassData data = _classData[cls.classIndex];
1228 OrderedTypeSet orderedTypeSet = data.orderedTypeSet;
1229 InterfaceType supertype = orderedTypeSet.asInstanceOf(
1230 commonElements.functionClass,
1231 _getHierarchyDepth(commonElements.functionClass));
1232 if (supertype != null) {
1233 return true;
1234 }
1235 _ensureCallType(cls, data);
1236 return data.callType is FunctionType;
1237 }
1114 } 1238 }
1115 1239
1116 class KernelElementEnvironment implements ElementEnvironment { 1240 class KernelElementEnvironment implements ElementEnvironment {
1117 final KernelToElementMapBase elementMap; 1241 final KernelToElementMapBase elementMap;
1118 1242
1119 KernelElementEnvironment(this.elementMap); 1243 KernelElementEnvironment(this.elementMap);
1120 1244
1121 @override 1245 @override
1122 DartType get dynamicType => const DynamicType(); 1246 DartType get dynamicType => const DynamicType();
1123 1247
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after
1534 return elementMap._getOrderedTypeSet(cls).supertypes; 1658 return elementMap._getOrderedTypeSet(cls).supertypes;
1535 } 1659 }
1536 1660
1537 @override 1661 @override
1538 ClassEntity getSuperClass(ClassEntity cls) { 1662 ClassEntity getSuperClass(ClassEntity cls) {
1539 return elementMap._getSuperType(cls)?.element; 1663 return elementMap._getSuperType(cls)?.element;
1540 } 1664 }
1541 1665
1542 @override 1666 @override
1543 bool implementsFunction(ClassEntity cls) { 1667 bool implementsFunction(ClassEntity cls) {
1544 // TODO(redemption): Implement this. 1668 return elementMap._implementsFunction(cls);
1545 return false;
1546 } 1669 }
1547 1670
1548 @override 1671 @override
1549 int getHierarchyDepth(ClassEntity cls) { 1672 int getHierarchyDepth(ClassEntity cls) {
1550 return elementMap._getHierarchyDepth(cls); 1673 return elementMap._getHierarchyDepth(cls);
1551 } 1674 }
1552 1675
1553 @override 1676 @override
1554 ClassEntity getAppliedMixin(ClassEntity cls) { 1677 ClassEntity getAppliedMixin(ClassEntity cls) {
1555 return elementMap._getAppliedMixin(cls); 1678 return elementMap._getAppliedMixin(cls);
(...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after
2157 /// 2280 ///
2158 /// These names are not used in generated code, just as element name. 2281 /// These names are not used in generated code, just as element name.
2159 String _getClosureVariableName(String name, int id) { 2282 String _getClosureVariableName(String name, int id) {
2160 return "_captured_${name}_$id"; 2283 return "_captured_${name}_$id";
2161 } 2284 }
2162 2285
2163 String getDeferredUri(ir.LibraryDependency node) { 2286 String getDeferredUri(ir.LibraryDependency node) {
2164 throw new UnimplementedError('JsKernelToElementMap.getDeferredUri'); 2287 throw new UnimplementedError('JsKernelToElementMap.getDeferredUri');
2165 } 2288 }
2166 } 2289 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698