Chromium Code Reviews| 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 |