OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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.world; | 5 library dart2js.world; |
6 | 6 |
7 import 'closure.dart' show ClosureClassElement; | 7 import 'closure.dart' show ClosureClassElement; |
8 import 'common.dart'; | 8 import 'common.dart'; |
9 import 'constants/constant_system.dart'; | 9 import 'constants/constant_system.dart'; |
10 import 'common_elements.dart' show CommonElements, ElementEnvironment; | 10 import 'common_elements.dart' show CommonElements, ElementEnvironment; |
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
401 /// are included. | 401 /// are included. |
402 SUBTYPE, | 402 SUBTYPE, |
403 } | 403 } |
404 | 404 |
405 abstract class ClosedWorldBase implements ClosedWorld, ClosedWorldRefiner { | 405 abstract class ClosedWorldBase implements ClosedWorld, ClosedWorldRefiner { |
406 final ConstantSystem constantSystem; | 406 final ConstantSystem constantSystem; |
407 final NativeData nativeData; | 407 final NativeData nativeData; |
408 final InterceptorData interceptorData; | 408 final InterceptorData interceptorData; |
409 final BackendUsage backendUsage; | 409 final BackendUsage backendUsage; |
410 | 410 |
411 final FunctionSet _allFunctions; | 411 FunctionSet _allFunctions; |
412 | 412 |
413 final Set<TypedefElement> _allTypedefs; | 413 final Set<TypedefElement> _allTypedefs; |
414 | 414 |
415 final Map<ClassEntity, Set<ClassEntity>> _mixinUses; | 415 final Map<ClassEntity, Set<ClassEntity>> mixinUses; |
416 Map<ClassEntity, List<ClassEntity>> _liveMixinUses; | 416 Map<ClassEntity, List<ClassEntity>> _liveMixinUses; |
417 | 417 |
418 final Map<ClassEntity, Set<ClassEntity>> _typesImplementedBySubclasses; | 418 final Map<ClassEntity, Set<ClassEntity>> _typesImplementedBySubclasses; |
419 | 419 |
420 // We keep track of subtype and subclass relationships in four | 420 // We keep track of subtype and subclass relationships in four |
421 // distinct sets to make class hierarchy analysis faster. | 421 // distinct sets to make class hierarchy analysis faster. |
422 final Map<ClassEntity, ClassHierarchyNode> _classHierarchyNodes; | 422 final Map<ClassEntity, ClassHierarchyNode> _classHierarchyNodes; |
423 final Map<ClassEntity, ClassSet> _classSets; | 423 final Map<ClassEntity, ClassSet> _classSets; |
424 | 424 |
425 final Map<ClassEntity, Map<ClassEntity, bool>> _subtypeCoveredByCache = | 425 final Map<ClassEntity, Map<ClassEntity, bool>> _subtypeCoveredByCache = |
(...skipping 17 matching lines...) Expand all Loading... | |
443 final ElementEnvironment elementEnvironment; | 443 final ElementEnvironment elementEnvironment; |
444 final DartTypes dartTypes; | 444 final DartTypes dartTypes; |
445 final CommonElements commonElements; | 445 final CommonElements commonElements; |
446 | 446 |
447 // TODO(johnniwinther): Avoid this. | 447 // TODO(johnniwinther): Avoid this. |
448 final ResolutionWorldBuilder _resolverWorld; | 448 final ResolutionWorldBuilder _resolverWorld; |
449 | 449 |
450 // TODO(johnniwinther): Can this be derived from [ClassSet]s? | 450 // TODO(johnniwinther): Can this be derived from [ClassSet]s? |
451 final Set<ClassEntity> _implementedClasses; | 451 final Set<ClassEntity> _implementedClasses; |
452 | 452 |
453 final Iterable<MemberEntity> liveInstanceMembers; | |
454 | |
453 ClosedWorldBase( | 455 ClosedWorldBase( |
454 {this.elementEnvironment, | 456 this.elementEnvironment, |
Siggi Cherem (dart-lang)
2017/07/05 20:28:52
since we loose named arguments because of the new
Johnni Winther
2017/07/06 14:14:46
I want required named arguments - bad language!
| |
455 this.dartTypes, | 457 this.dartTypes, |
456 this.commonElements, | 458 this.commonElements, |
457 this.constantSystem, | 459 this.constantSystem, |
458 this.nativeData, | 460 this.nativeData, |
459 this.interceptorData, | 461 this.interceptorData, |
460 this.backendUsage, | 462 this.backendUsage, |
461 ResolutionWorldBuilder resolutionWorldBuilder, | 463 ResolutionWorldBuilder resolutionWorldBuilder, |
462 Set<ClassEntity> implementedClasses, | 464 Set<ClassEntity> implementedClasses, |
463 FunctionSet functionSet, | 465 this.liveInstanceMembers, |
Siggi Cherem (dart-lang)
2017/07/05 20:28:52
any reason why not create the FunctionSet eagerly
Johnni Winther
2017/07/06 14:14:46
Yes. [FunctionSet] is created lazily because it is
| |
464 Set<TypedefElement> allTypedefs, | 466 Set<TypedefElement> allTypedefs, |
465 Map<ClassEntity, Set<ClassEntity>> mixinUses, | 467 this.mixinUses, |
466 Map<ClassEntity, Set<ClassEntity>> typesImplementedBySubclasses, | 468 Map<ClassEntity, Set<ClassEntity>> typesImplementedBySubclasses, |
467 Map<ClassEntity, ClassHierarchyNode> classHierarchyNodes, | 469 Map<ClassEntity, ClassHierarchyNode> classHierarchyNodes, |
468 Map<ClassEntity, ClassSet> classSets}) | 470 Map<ClassEntity, ClassSet> classSets) |
469 : this._resolverWorld = resolutionWorldBuilder, | 471 : this._resolverWorld = resolutionWorldBuilder, |
470 this._implementedClasses = implementedClasses, | 472 this._implementedClasses = implementedClasses, |
471 this._allFunctions = functionSet, | |
472 this._allTypedefs = allTypedefs, | 473 this._allTypedefs = allTypedefs, |
473 this._mixinUses = mixinUses, | |
474 this._typesImplementedBySubclasses = typesImplementedBySubclasses, | 474 this._typesImplementedBySubclasses = typesImplementedBySubclasses, |
475 this._classHierarchyNodes = classHierarchyNodes, | 475 this._classHierarchyNodes = classHierarchyNodes, |
476 this._classSets = classSets { | 476 this._classSets = classSets { |
477 _commonMasks = new CommonMasks(this); | 477 _commonMasks = new CommonMasks(this); |
478 } | 478 } |
479 | 479 |
480 @override | 480 @override |
481 ClosedWorld get closedWorld => this; | 481 ClosedWorld get closedWorld => this; |
482 | 482 |
483 /// Cache of [FlatTypeMask]s grouped by the 8 possible values of the | 483 /// Cache of [FlatTypeMask]s grouped by the 8 possible values of the |
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
934 if (common.contains(interface)) return false; | 934 if (common.contains(interface)) return false; |
935 } | 935 } |
936 return true; | 936 return true; |
937 }); | 937 }); |
938 } | 938 } |
939 | 939 |
940 /// Returns an iterable over the live mixin applications that mixin [cls]. | 940 /// Returns an iterable over the live mixin applications that mixin [cls]. |
941 Iterable<ClassEntity> mixinUsesOf(ClassEntity cls) { | 941 Iterable<ClassEntity> mixinUsesOf(ClassEntity cls) { |
942 if (_liveMixinUses == null) { | 942 if (_liveMixinUses == null) { |
943 _liveMixinUses = new Map<ClassEntity, List<ClassEntity>>(); | 943 _liveMixinUses = new Map<ClassEntity, List<ClassEntity>>(); |
944 for (ClassEntity mixin in _mixinUses.keys) { | 944 for (ClassEntity mixin in mixinUses.keys) { |
945 List<ClassEntity> uses = <ClassEntity>[]; | 945 List<ClassEntity> uses = <ClassEntity>[]; |
946 | 946 |
947 void addLiveUse(ClassEntity mixinApplication) { | 947 void addLiveUse(ClassEntity mixinApplication) { |
948 if (isInstantiated(mixinApplication)) { | 948 if (isInstantiated(mixinApplication)) { |
949 uses.add(mixinApplication); | 949 uses.add(mixinApplication); |
950 } else if (isNamedMixinApplication(mixinApplication)) { | 950 } else if (isNamedMixinApplication(mixinApplication)) { |
951 Set<ClassEntity> next = _mixinUses[mixinApplication]; | 951 Set<ClassEntity> next = mixinUses[mixinApplication]; |
952 if (next != null) { | 952 if (next != null) { |
953 next.forEach(addLiveUse); | 953 next.forEach(addLiveUse); |
954 } | 954 } |
955 } | 955 } |
956 } | 956 } |
957 | 957 |
958 _mixinUses[mixin].forEach(addLiveUse); | 958 mixinUses[mixin].forEach(addLiveUse); |
959 if (uses.isNotEmpty) { | 959 if (uses.isNotEmpty) { |
960 _liveMixinUses[mixin] = uses; | 960 _liveMixinUses[mixin] = uses; |
961 } | 961 } |
962 } | 962 } |
963 } | 963 } |
964 Iterable<ClassEntity> uses = _liveMixinUses[cls]; | 964 Iterable<ClassEntity> uses = _liveMixinUses[cls]; |
965 return uses != null ? uses : const <ClassEntity>[]; | 965 return uses != null ? uses : const <ClassEntity>[]; |
966 } | 966 } |
967 | 967 |
968 /// Returns `true` if any live class that mixes in [mixin] is also a subclass | 968 /// Returns `true` if any live class that mixes in [mixin] is also a subclass |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1003 /// | 1003 /// |
1004 /// This method is only provided for testing. For queries on classes, use the | 1004 /// This method is only provided for testing. For queries on classes, use the |
1005 /// methods defined in [ClosedWorld]. | 1005 /// methods defined in [ClosedWorld]. |
1006 ClassSet getClassSet(ClassEntity cls) { | 1006 ClassSet getClassSet(ClassEntity cls) { |
1007 assert(checkClass(cls)); | 1007 assert(checkClass(cls)); |
1008 return _classSets[cls]; | 1008 return _classSets[cls]; |
1009 } | 1009 } |
1010 | 1010 |
1011 Iterable<TypedefElement> get allTypedefs => _allTypedefs; | 1011 Iterable<TypedefElement> get allTypedefs => _allTypedefs; |
1012 | 1012 |
1013 void _ensureFunctionSet() { | |
1014 if (_allFunctions == null) { | |
1015 _allFunctions = new FunctionSet(liveInstanceMembers); | |
1016 } | |
1017 } | |
1018 | |
1013 TypeMask computeReceiverType(Selector selector, TypeMask mask) { | 1019 TypeMask computeReceiverType(Selector selector, TypeMask mask) { |
1020 _ensureFunctionSet(); | |
1014 return _allFunctions.receiverType(selector, mask, this); | 1021 return _allFunctions.receiverType(selector, mask, this); |
1015 } | 1022 } |
1016 | 1023 |
1017 Iterable<MemberEntity> locateMembers(Selector selector, TypeMask mask) { | 1024 Iterable<MemberEntity> locateMembers(Selector selector, TypeMask mask) { |
1025 _ensureFunctionSet(); | |
1018 return _allFunctions.filter(selector, mask, this); | 1026 return _allFunctions.filter(selector, mask, this); |
1019 } | 1027 } |
1020 | 1028 |
1021 bool hasAnyUserDefinedGetter(Selector selector, TypeMask mask) { | 1029 bool hasAnyUserDefinedGetter(Selector selector, TypeMask mask) { |
1030 _ensureFunctionSet(); | |
1022 return _allFunctions | 1031 return _allFunctions |
1023 .filter(selector, mask, this) | 1032 .filter(selector, mask, this) |
1024 .any((each) => each.isGetter); | 1033 .any((each) => each.isGetter); |
1025 } | 1034 } |
1026 | 1035 |
1027 FieldEntity locateSingleField(Selector selector, TypeMask mask) { | 1036 FieldEntity locateSingleField(Selector selector, TypeMask mask) { |
1028 MemberEntity result = locateSingleElement(selector, mask); | 1037 MemberEntity result = locateSingleElement(selector, mask); |
1029 return (result != null && result.isField) ? result : null; | 1038 return (result != null && result.isField) ? result : null; |
1030 } | 1039 } |
1031 | 1040 |
(...skipping 28 matching lines...) Expand all Loading... | |
1060 return !_resolverWorld.hasInvokedSetter(element) && | 1069 return !_resolverWorld.hasInvokedSetter(element) && |
1061 !_resolverWorld.fieldSetters.contains(element); | 1070 !_resolverWorld.fieldSetters.contains(element); |
1062 } | 1071 } |
1063 return false; | 1072 return false; |
1064 } | 1073 } |
1065 | 1074 |
1066 SideEffects getSideEffectsOfSelector(Selector selector, TypeMask mask) { | 1075 SideEffects getSideEffectsOfSelector(Selector selector, TypeMask mask) { |
1067 // We're not tracking side effects of closures. | 1076 // We're not tracking side effects of closures. |
1068 if (selector.isClosureCall) return new SideEffects(); | 1077 if (selector.isClosureCall) return new SideEffects(); |
1069 SideEffects sideEffects = new SideEffects.empty(); | 1078 SideEffects sideEffects = new SideEffects.empty(); |
1079 _ensureFunctionSet(); | |
1070 for (MemberEntity e in _allFunctions.filter(selector, mask, this)) { | 1080 for (MemberEntity e in _allFunctions.filter(selector, mask, this)) { |
1071 if (e.isField) { | 1081 if (e.isField) { |
1072 if (selector.isGetter) { | 1082 if (selector.isGetter) { |
1073 if (!fieldNeverChanges(e)) { | 1083 if (!fieldNeverChanges(e)) { |
1074 sideEffects.setDependsOnInstancePropertyStore(); | 1084 sideEffects.setDependsOnInstancePropertyStore(); |
1075 } | 1085 } |
1076 } else if (selector.isSetter) { | 1086 } else if (selector.isSetter) { |
1077 sideEffects.setChangesInstanceProperty(); | 1087 sideEffects.setChangesInstanceProperty(); |
1078 } else { | 1088 } else { |
1079 assert(selector.isCall); | 1089 assert(selector.isCall); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1165 ClosedWorldImpl( | 1175 ClosedWorldImpl( |
1166 {ElementEnvironment elementEnvironment, | 1176 {ElementEnvironment elementEnvironment, |
1167 DartTypes dartTypes, | 1177 DartTypes dartTypes, |
1168 CommonElements commonElements, | 1178 CommonElements commonElements, |
1169 ConstantSystem constantSystem, | 1179 ConstantSystem constantSystem, |
1170 NativeData nativeData, | 1180 NativeData nativeData, |
1171 InterceptorData interceptorData, | 1181 InterceptorData interceptorData, |
1172 BackendUsage backendUsage, | 1182 BackendUsage backendUsage, |
1173 ResolutionWorldBuilder resolutionWorldBuilder, | 1183 ResolutionWorldBuilder resolutionWorldBuilder, |
1174 Set<ClassEntity> implementedClasses, | 1184 Set<ClassEntity> implementedClasses, |
1175 FunctionSet functionSet, | 1185 Iterable<MemberEntity> liveInstanceMembers, |
1176 Set<TypedefElement> allTypedefs, | 1186 Set<TypedefElement> allTypedefs, |
1177 Map<ClassEntity, Set<ClassEntity>> mixinUses, | 1187 Map<ClassEntity, Set<ClassEntity>> mixinUses, |
1178 Map<ClassEntity, Set<ClassEntity>> typesImplementedBySubclasses, | 1188 Map<ClassEntity, Set<ClassEntity>> typesImplementedBySubclasses, |
1179 Map<ClassEntity, ClassHierarchyNode> classHierarchyNodes, | 1189 Map<ClassEntity, ClassHierarchyNode> classHierarchyNodes, |
1180 Map<ClassEntity, ClassSet> classSets}) | 1190 Map<ClassEntity, ClassSet> classSets}) |
1181 : super( | 1191 : super( |
1182 elementEnvironment: elementEnvironment, | 1192 elementEnvironment, |
1183 dartTypes: dartTypes, | 1193 dartTypes, |
1184 commonElements: commonElements, | 1194 commonElements, |
1185 constantSystem: constantSystem, | 1195 constantSystem, |
1186 nativeData: nativeData, | 1196 nativeData, |
1187 interceptorData: interceptorData, | 1197 interceptorData, |
1188 backendUsage: backendUsage, | 1198 backendUsage, |
1189 resolutionWorldBuilder: resolutionWorldBuilder, | 1199 resolutionWorldBuilder, |
1190 implementedClasses: implementedClasses, | 1200 implementedClasses, |
1191 functionSet: functionSet, | 1201 liveInstanceMembers, |
1192 allTypedefs: allTypedefs, | 1202 allTypedefs, |
1193 mixinUses: mixinUses, | 1203 mixinUses, |
1194 typesImplementedBySubclasses: typesImplementedBySubclasses, | 1204 typesImplementedBySubclasses, |
1195 classHierarchyNodes: classHierarchyNodes, | 1205 classHierarchyNodes, |
1196 classSets: classSets); | 1206 classSets); |
1197 | 1207 |
1198 bool checkClass(ClassElement cls) => cls.isDeclaration; | 1208 bool checkClass(ClassElement cls) => cls.isDeclaration; |
1199 | 1209 |
1200 bool checkEntity(Element element) => element.isDeclaration; | 1210 bool checkEntity(Element element) => element.isDeclaration; |
1201 | 1211 |
1202 bool checkInvariants(ClassElement cls, {bool mustBeInstantiated: true}) { | 1212 bool checkInvariants(ClassElement cls, {bool mustBeInstantiated: true}) { |
1203 assert(cls.isDeclaration, failedAt(cls, '$cls must be the declaration.')); | 1213 assert(cls.isDeclaration, failedAt(cls, '$cls must be the declaration.')); |
1204 assert(cls.isResolved, failedAt(cls, '$cls must be resolved.')); | 1214 assert(cls.isResolved, failedAt(cls, '$cls must be resolved.')); |
1205 | 1215 |
1206 // TODO(johnniwinther): Reinsert this or similar invariant. Currently | 1216 // TODO(johnniwinther): Reinsert this or similar invariant. Currently |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1302 // does not see generative constructor bodies because they are | 1312 // does not see generative constructor bodies because they are |
1303 // created by the backend. Also, it does not make any distinction | 1313 // created by the backend. Also, it does not make any distinction |
1304 // between a constructor and its body for side effects. This | 1314 // between a constructor and its body for side effects. This |
1305 // implies that currently, the side effects of a constructor body | 1315 // implies that currently, the side effects of a constructor body |
1306 // contain the side effects of the initializers. | 1316 // contain the side effects of the initializers. |
1307 assert(!element.isGenerativeConstructorBody); | 1317 assert(!element.isGenerativeConstructorBody); |
1308 assert(!element.isField); | 1318 assert(!element.isField); |
1309 return super.getSideEffectsOfElement(element); | 1319 return super.getSideEffectsOfElement(element); |
1310 } | 1320 } |
1311 } | 1321 } |
OLD | NEW |