| 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 universe; | 5 library universe; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 | 8 |
| 9 import '../common/names.dart' show | 9 import '../common/names.dart' show |
| 10 Identifiers, | 10 Identifiers, |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 final Selector selector; | 34 final Selector selector; |
| 35 final ReceiverMask mask; | 35 final ReceiverMask mask; |
| 36 | 36 |
| 37 UniverseSelector(this.selector, this.mask); | 37 UniverseSelector(this.selector, this.mask); |
| 38 | 38 |
| 39 bool appliesUnnamed(Element element, ClassWorld world) { | 39 bool appliesUnnamed(Element element, ClassWorld world) { |
| 40 return selector.appliesUnnamed(element, world) && | 40 return selector.appliesUnnamed(element, world) && |
| 41 (mask == null || mask.canHit(element, selector, world)); | 41 (mask == null || mask.canHit(element, selector, world)); |
| 42 } | 42 } |
| 43 | 43 |
| 44 int get hashCode => selector.hashCode * 13 + mask.hashCode * 17; |
| 45 |
| 46 bool operator ==(other) { |
| 47 if (identical(this, other)) return true; |
| 48 if (other is! UniverseSelector) return false; |
| 49 return selector == other.selector && mask == other.mask; |
| 50 } |
| 51 |
| 44 String toString() => '$selector,$mask'; | 52 String toString() => '$selector,$mask'; |
| 45 } | 53 } |
| 46 | 54 |
| 47 /// A potential receiver for a dynamic call site. | 55 /// A potential receiver for a dynamic call site. |
| 48 abstract class ReceiverMask { | 56 abstract class ReceiverMask { |
| 49 /// Returns whether [element] is a potential target when being | 57 /// Returns whether [element] is a potential target when being |
| 50 /// invoked on this receiver mask. [selector] is used to ensure library | 58 /// invoked on this receiver mask. [selector] is used to ensure library |
| 51 /// privacy is taken into account. | 59 /// privacy is taken into account. |
| 52 bool canHit(Element element, Selector selector, ClassWorld classWorld); | 60 bool canHit(Element element, Selector selector, ClassWorld classWorld); |
| 53 } | 61 } |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 /// | 119 /// |
| 112 /// See [_directlyInstantiatedClasses]. | 120 /// See [_directlyInstantiatedClasses]. |
| 113 final Set<DartType> _instantiatedTypes = new Set<DartType>(); | 121 final Set<DartType> _instantiatedTypes = new Set<DartType>(); |
| 114 | 122 |
| 115 /// The set of all instantiated classes, either directly, as superclasses or | 123 /// The set of all instantiated classes, either directly, as superclasses or |
| 116 /// as supertypes. | 124 /// as supertypes. |
| 117 /// | 125 /// |
| 118 /// Invariant: Elements are declaration elements. | 126 /// Invariant: Elements are declaration elements. |
| 119 final Set<ClassElement> _allInstantiatedClasses = new Set<ClassElement>(); | 127 final Set<ClassElement> _allInstantiatedClasses = new Set<ClassElement>(); |
| 120 | 128 |
| 129 /// Classes implemented by directly instantiated classes. |
| 130 final Set<ClassElement> _implementedClasses = new Set<ClassElement>(); |
| 131 |
| 121 /// The set of all referenced static fields. | 132 /// The set of all referenced static fields. |
| 122 /// | 133 /// |
| 123 /// Invariant: Elements are declaration elements. | 134 /// Invariant: Elements are declaration elements. |
| 124 final Set<FieldElement> allReferencedStaticFields = new Set<FieldElement>(); | 135 final Set<FieldElement> allReferencedStaticFields = new Set<FieldElement>(); |
| 125 | 136 |
| 126 /** | 137 /** |
| 127 * Documentation wanted -- johnniwinther | 138 * Documentation wanted -- johnniwinther |
| 128 * | 139 * |
| 129 * Invariant: Elements are declaration elements. | 140 * Invariant: Elements are declaration elements. |
| 130 */ | 141 */ |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 199 } | 210 } |
| 200 | 211 |
| 201 /// All directly instantiated types, that is, the types of the directly | 212 /// All directly instantiated types, that is, the types of the directly |
| 202 /// instantiated classes. | 213 /// instantiated classes. |
| 203 /// | 214 /// |
| 204 /// See [directlyInstantiatedClasses]. | 215 /// See [directlyInstantiatedClasses]. |
| 205 // TODO(johnniwinther): Improve semantic precision. | 216 // TODO(johnniwinther): Improve semantic precision. |
| 206 Iterable<DartType> get instantiatedTypes => _instantiatedTypes; | 217 Iterable<DartType> get instantiatedTypes => _instantiatedTypes; |
| 207 | 218 |
| 208 /// Returns `true` if [cls] is considered to be instantiated, either directly, | 219 /// Returns `true` if [cls] is considered to be instantiated, either directly, |
| 209 /// through subclasses or through subtypes. The latter case only contains | 220 /// through subclasses. |
| 210 /// spurious information from instatiations through factory constructors and | |
| 211 /// mixins. | |
| 212 // TODO(johnniwinther): Improve semantic precision. | 221 // TODO(johnniwinther): Improve semantic precision. |
| 213 bool isInstantiated(ClassElement cls) { | 222 bool isInstantiated(ClassElement cls) { |
| 214 return _allInstantiatedClasses.contains(cls); | 223 return _allInstantiatedClasses.contains(cls.declaration); |
| 224 } |
| 225 |
| 226 /// Returns `true` if [cls] is considered to be implemented by an |
| 227 /// instantiated class, either directly, through subclasses or through |
| 228 /// subtypes. The latter case only contains spurious information from |
| 229 /// instantiations through factory constructors and mixins. |
| 230 // TODO(johnniwinther): Improve semantic precision. |
| 231 bool isImplemented(ClassElement cls) { |
| 232 return _implementedClasses.contains(cls.declaration); |
| 215 } | 233 } |
| 216 | 234 |
| 217 /// Register [type] as (directly) instantiated. | 235 /// Register [type] as (directly) instantiated. |
| 218 /// | 236 /// |
| 219 /// If [byMirrors] is `true`, the instantiation is through mirrors. | 237 /// If [byMirrors] is `true`, the instantiation is through mirrors. |
| 220 // TODO(johnniwinther): Fully enforce the separation between exact, through | 238 // TODO(johnniwinther): Fully enforce the separation between exact, through |
| 221 // subclass and through subtype instantiated types/classes. | 239 // subclass and through subtype instantiated types/classes. |
| 222 // TODO(johnniwinther): Support unknown type arguments for generic types. | 240 // TODO(johnniwinther): Support unknown type arguments for generic types. |
| 223 void registerTypeInstantiation(InterfaceType type, | 241 void registerTypeInstantiation(InterfaceType type, |
| 224 {bool byMirrors: false}) { | 242 {bool byMirrors: false, |
| 243 void onImplemented(ClassElement cls)}) { |
| 225 _instantiatedTypes.add(type); | 244 _instantiatedTypes.add(type); |
| 226 ClassElement cls = type.element; | 245 ClassElement cls = type.element; |
| 227 if (!cls.isAbstract | 246 if (!cls.isAbstract |
| 228 // We can't use the closed-world assumption with native abstract | 247 // We can't use the closed-world assumption with native abstract |
| 229 // classes; a native abstract class may have non-abstract subclasses | 248 // classes; a native abstract class may have non-abstract subclasses |
| 230 // not declared to the program. Instances of these classes are | 249 // not declared to the program. Instances of these classes are |
| 231 // indistinguishable from the abstract class. | 250 // indistinguishable from the abstract class. |
| 232 || cls.isNative | 251 || cls.isNative |
| 233 // Likewise, if this registration comes from the mirror system, | 252 // Likewise, if this registration comes from the mirror system, |
| 234 // all bets are off. | 253 // all bets are off. |
| 235 // TODO(herhut): Track classes required by mirrors seperately. | 254 // TODO(herhut): Track classes required by mirrors seperately. |
| 236 || byMirrors) { | 255 || byMirrors) { |
| 237 _directlyInstantiatedClasses.add(cls); | 256 _directlyInstantiatedClasses.add(cls); |
| 238 } | 257 } |
| 239 | 258 |
| 240 // TODO(johnniwinther): Replace this by separate more specific mappings. | 259 // TODO(johnniwinther): Replace this by separate more specific mappings that |
| 241 if (!_allInstantiatedClasses.add(cls)) return; | 260 // include the type arguments. |
| 242 cls.allSupertypes.forEach((InterfaceType supertype) { | 261 if (_implementedClasses.add(cls)) { |
| 243 _allInstantiatedClasses.add(supertype.element); | 262 onImplemented(cls); |
| 244 }); | 263 cls.allSupertypes.forEach((InterfaceType supertype) { |
| 264 if (_implementedClasses.add(supertype.element)) { |
| 265 onImplemented(supertype.element); |
| 266 } |
| 267 }); |
| 268 } |
| 269 while (cls != null) { |
| 270 if (!_allInstantiatedClasses.add(cls)) { |
| 271 return; |
| 272 } |
| 273 cls = cls.superclass; |
| 274 } |
| 245 } | 275 } |
| 246 | 276 |
| 247 bool _hasMatchingSelector(Map<Selector, ReceiverMaskSet> selectors, | 277 bool _hasMatchingSelector(Map<Selector, ReceiverMaskSet> selectors, |
| 248 Element member, | 278 Element member, |
| 249 World world) { | 279 World world) { |
| 250 if (selectors == null) return false; | 280 if (selectors == null) return false; |
| 251 for (Selector selector in selectors.keys) { | 281 for (Selector selector in selectors.keys) { |
| 252 if (selector.appliesUnnamed(member, world)) { | 282 if (selector.appliesUnnamed(member, world)) { |
| 253 ReceiverMaskSet masks = selectors[selector]; | 283 ReceiverMaskSet masks = selectors[selector]; |
| 254 if (masks.applies(member, selector, world)) { | 284 if (masks.applies(member, selector, world)) { |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 366 // TODO(ahe): Replace this method with something that is O(1), for example, | 396 // TODO(ahe): Replace this method with something that is O(1), for example, |
| 367 // by using a map. | 397 // by using a map. |
| 368 List<LocalFunctionElement> slowDirectlyNestedClosures(Element element) { | 398 List<LocalFunctionElement> slowDirectlyNestedClosures(Element element) { |
| 369 // Return new list to guard against concurrent modifications. | 399 // Return new list to guard against concurrent modifications. |
| 370 return new List<LocalFunctionElement>.from( | 400 return new List<LocalFunctionElement>.from( |
| 371 allClosures.where((LocalFunctionElement closure) { | 401 allClosures.where((LocalFunctionElement closure) { |
| 372 return closure.executableContext == element; | 402 return closure.executableContext == element; |
| 373 })); | 403 })); |
| 374 } | 404 } |
| 375 } | 405 } |
| OLD | NEW |