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 |