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