| 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 24 matching lines...) Expand all Loading... |
| 35 final Selector selector; | 35 final Selector selector; |
| 36 final ReceiverConstraint mask; | 36 final ReceiverConstraint mask; |
| 37 | 37 |
| 38 UniverseSelector(this.selector, this.mask); | 38 UniverseSelector(this.selector, this.mask); |
| 39 | 39 |
| 40 bool appliesUnnamed(Element element, ClassWorld world) { | 40 bool appliesUnnamed(Element element, ClassWorld world) { |
| 41 return selector.appliesUnnamed(element, world) && | 41 return selector.appliesUnnamed(element, world) && |
| 42 (mask == null || mask.canHit(element, selector, world)); | 42 (mask == null || mask.canHit(element, selector, world)); |
| 43 } | 43 } |
| 44 | 44 |
| 45 int get hashCode => selector.hashCode * 13 + mask.hashCode * 17; |
| 46 |
| 47 bool operator ==(other) { |
| 48 if (identical(this, other)) return true; |
| 49 if (other is! UniverseSelector) return false; |
| 50 return selector == other.selector && mask == other.mask; |
| 51 } |
| 52 |
| 45 String toString() => '$selector,$mask'; | 53 String toString() => '$selector,$mask'; |
| 46 } | 54 } |
| 47 | 55 |
| 48 /// The known constraint on receiver for a dynamic call site. | 56 /// The known constraint on receiver for a dynamic call site. |
| 49 /// | 57 /// |
| 50 /// This can for instance be used to constrain this dynamic call to `foo` to | 58 /// This can for instance be used to constrain this dynamic call to `foo` to |
| 51 /// 'receivers of the exact instance `Bar`': | 59 /// 'receivers of the exact instance `Bar`': |
| 52 /// | 60 /// |
| 53 /// class Bar { | 61 /// class Bar { |
| 54 /// void foo() {} | 62 /// void foo() {} |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 144 /// | 152 /// |
| 145 /// See [_directlyInstantiatedClasses]. | 153 /// See [_directlyInstantiatedClasses]. |
| 146 final Set<DartType> _instantiatedTypes = new Set<DartType>(); | 154 final Set<DartType> _instantiatedTypes = new Set<DartType>(); |
| 147 | 155 |
| 148 /// The set of all instantiated classes, either directly, as superclasses or | 156 /// The set of all instantiated classes, either directly, as superclasses or |
| 149 /// as supertypes. | 157 /// as supertypes. |
| 150 /// | 158 /// |
| 151 /// Invariant: Elements are declaration elements. | 159 /// Invariant: Elements are declaration elements. |
| 152 final Set<ClassElement> _allInstantiatedClasses = new Set<ClassElement>(); | 160 final Set<ClassElement> _allInstantiatedClasses = new Set<ClassElement>(); |
| 153 | 161 |
| 162 /// Classes implemented by directly instantiated classes. |
| 163 final Set<ClassElement> _implementedClasses = new Set<ClassElement>(); |
| 164 |
| 154 /// The set of all referenced static fields. | 165 /// The set of all referenced static fields. |
| 155 /// | 166 /// |
| 156 /// Invariant: Elements are declaration elements. | 167 /// Invariant: Elements are declaration elements. |
| 157 final Set<FieldElement> allReferencedStaticFields = new Set<FieldElement>(); | 168 final Set<FieldElement> allReferencedStaticFields = new Set<FieldElement>(); |
| 158 | 169 |
| 159 /** | 170 /** |
| 160 * Documentation wanted -- johnniwinther | 171 * Documentation wanted -- johnniwinther |
| 161 * | 172 * |
| 162 * Invariant: Elements are declaration elements. | 173 * Invariant: Elements are declaration elements. |
| 163 */ | 174 */ |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 232 } | 243 } |
| 233 | 244 |
| 234 /// All directly instantiated types, that is, the types of the directly | 245 /// All directly instantiated types, that is, the types of the directly |
| 235 /// instantiated classes. | 246 /// instantiated classes. |
| 236 /// | 247 /// |
| 237 /// See [directlyInstantiatedClasses]. | 248 /// See [directlyInstantiatedClasses]. |
| 238 // TODO(johnniwinther): Improve semantic precision. | 249 // TODO(johnniwinther): Improve semantic precision. |
| 239 Iterable<DartType> get instantiatedTypes => _instantiatedTypes; | 250 Iterable<DartType> get instantiatedTypes => _instantiatedTypes; |
| 240 | 251 |
| 241 /// Returns `true` if [cls] is considered to be instantiated, either directly, | 252 /// Returns `true` if [cls] is considered to be instantiated, either directly, |
| 242 /// through subclasses or through subtypes. The latter case only contains | 253 /// through subclasses. |
| 243 /// spurious information from instatiations through factory constructors and | |
| 244 /// mixins. | |
| 245 // TODO(johnniwinther): Improve semantic precision. | 254 // TODO(johnniwinther): Improve semantic precision. |
| 246 bool isInstantiated(ClassElement cls) { | 255 bool isInstantiated(ClassElement cls) { |
| 247 return _allInstantiatedClasses.contains(cls); | 256 return _allInstantiatedClasses.contains(cls.declaration); |
| 257 } |
| 258 |
| 259 /// Returns `true` if [cls] is considered to be implemented by an |
| 260 /// instantiated class, either directly, through subclasses or through |
| 261 /// subtypes. The latter case only contains spurious information from |
| 262 /// instantiations through factory constructors and mixins. |
| 263 // TODO(johnniwinther): Improve semantic precision. |
| 264 bool isImplemented(ClassElement cls) { |
| 265 return _implementedClasses.contains(cls.declaration); |
| 248 } | 266 } |
| 249 | 267 |
| 250 /// Register [type] as (directly) instantiated. | 268 /// Register [type] as (directly) instantiated. |
| 251 /// | 269 /// |
| 252 /// If [byMirrors] is `true`, the instantiation is through mirrors. | 270 /// If [byMirrors] is `true`, the instantiation is through mirrors. |
| 253 // TODO(johnniwinther): Fully enforce the separation between exact, through | 271 // TODO(johnniwinther): Fully enforce the separation between exact, through |
| 254 // subclass and through subtype instantiated types/classes. | 272 // subclass and through subtype instantiated types/classes. |
| 255 // TODO(johnniwinther): Support unknown type arguments for generic types. | 273 // TODO(johnniwinther): Support unknown type arguments for generic types. |
| 256 void registerTypeInstantiation(InterfaceType type, | 274 void registerTypeInstantiation(InterfaceType type, |
| 257 {bool byMirrors: false}) { | 275 {bool byMirrors: false, |
| 276 void onImplemented(ClassElement cls)}) { |
| 258 _instantiatedTypes.add(type); | 277 _instantiatedTypes.add(type); |
| 259 ClassElement cls = type.element; | 278 ClassElement cls = type.element; |
| 260 if (!cls.isAbstract | 279 if (!cls.isAbstract |
| 261 // We can't use the closed-world assumption with native abstract | 280 // We can't use the closed-world assumption with native abstract |
| 262 // classes; a native abstract class may have non-abstract subclasses | 281 // classes; a native abstract class may have non-abstract subclasses |
| 263 // not declared to the program. Instances of these classes are | 282 // not declared to the program. Instances of these classes are |
| 264 // indistinguishable from the abstract class. | 283 // indistinguishable from the abstract class. |
| 265 || cls.isNative | 284 || cls.isNative |
| 266 // Likewise, if this registration comes from the mirror system, | 285 // Likewise, if this registration comes from the mirror system, |
| 267 // all bets are off. | 286 // all bets are off. |
| 268 // TODO(herhut): Track classes required by mirrors seperately. | 287 // TODO(herhut): Track classes required by mirrors seperately. |
| 269 || byMirrors) { | 288 || byMirrors) { |
| 270 _directlyInstantiatedClasses.add(cls); | 289 _directlyInstantiatedClasses.add(cls); |
| 271 } | 290 } |
| 272 | 291 |
| 273 // TODO(johnniwinther): Replace this by separate more specific mappings. | 292 // TODO(johnniwinther): Replace this by separate more specific mappings that |
| 274 if (!_allInstantiatedClasses.add(cls)) return; | 293 // include the type arguments. |
| 275 cls.allSupertypes.forEach((InterfaceType supertype) { | 294 if (_implementedClasses.add(cls)) { |
| 276 _allInstantiatedClasses.add(supertype.element); | 295 onImplemented(cls); |
| 277 }); | 296 cls.allSupertypes.forEach((InterfaceType supertype) { |
| 297 if (_implementedClasses.add(supertype.element)) { |
| 298 onImplemented(supertype.element); |
| 299 } |
| 300 }); |
| 301 } |
| 302 while (cls != null) { |
| 303 if (!_allInstantiatedClasses.add(cls)) { |
| 304 return; |
| 305 } |
| 306 cls = cls.superclass; |
| 307 } |
| 278 } | 308 } |
| 279 | 309 |
| 280 bool _hasMatchingSelector(Map<Selector, SelectorConstraints> selectors, | 310 bool _hasMatchingSelector(Map<Selector, SelectorConstraints> selectors, |
| 281 Element member, | 311 Element member, |
| 282 World world) { | 312 World world) { |
| 283 if (selectors == null) return false; | 313 if (selectors == null) return false; |
| 284 for (Selector selector in selectors.keys) { | 314 for (Selector selector in selectors.keys) { |
| 285 if (selector.appliesUnnamed(member, world)) { | 315 if (selector.appliesUnnamed(member, world)) { |
| 286 SelectorConstraints masks = selectors[selector]; | 316 SelectorConstraints masks = selectors[selector]; |
| 287 if (masks.applies(member, selector, world)) { | 317 if (masks.applies(member, selector, world)) { |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 399 // TODO(ahe): Replace this method with something that is O(1), for example, | 429 // TODO(ahe): Replace this method with something that is O(1), for example, |
| 400 // by using a map. | 430 // by using a map. |
| 401 List<LocalFunctionElement> slowDirectlyNestedClosures(Element element) { | 431 List<LocalFunctionElement> slowDirectlyNestedClosures(Element element) { |
| 402 // Return new list to guard against concurrent modifications. | 432 // Return new list to guard against concurrent modifications. |
| 403 return new List<LocalFunctionElement>.from( | 433 return new List<LocalFunctionElement>.from( |
| 404 allClosures.where((LocalFunctionElement closure) { | 434 allClosures.where((LocalFunctionElement closure) { |
| 405 return closure.executableContext == element; | 435 return closure.executableContext == element; |
| 406 })); | 436 })); |
| 407 } | 437 } |
| 408 } | 438 } |
| OLD | NEW |