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.dart'; | 9 import '../common.dart'; |
10 import '../compiler.dart' show Compiler; | 10 import '../compiler.dart' show Compiler; |
11 import '../dart_types.dart'; | 11 import '../dart_types.dart'; |
12 import '../elements/elements.dart'; | 12 import '../elements/elements.dart'; |
| 13 import '../universe/class_set.dart' show Instantiation; |
| 14 import '../util/enumset.dart'; |
13 import '../util/util.dart'; | 15 import '../util/util.dart'; |
14 import '../world.dart' show World, ClosedWorld, OpenWorld; | 16 import '../world.dart' show World, ClosedWorld, OpenWorld; |
15 import 'selector.dart' show Selector; | 17 import 'selector.dart' show Selector; |
16 import 'use.dart' show DynamicUse, DynamicUseKind, StaticUse, StaticUseKind; | 18 import 'use.dart' show DynamicUse, DynamicUseKind, StaticUse, StaticUseKind; |
17 | 19 |
18 /// The known constraint on receiver for a dynamic call site. | 20 /// The known constraint on receiver for a dynamic call site. |
19 /// | 21 /// |
20 /// This can for instance be used to constrain this dynamic call to `foo` to | 22 /// This can for instance be used to constrain this dynamic call to `foo` to |
21 /// 'receivers of the exact instance `Bar`': | 23 /// 'receivers of the exact instance `Bar`': |
22 /// | 24 /// |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 Iterable<Element> get closurizedMembers; | 151 Iterable<Element> get closurizedMembers; |
150 | 152 |
151 /// Returns `true` if [cls] is considered to be implemented by an | 153 /// Returns `true` if [cls] is considered to be implemented by an |
152 /// instantiated class, either directly, through subclasses or through | 154 /// instantiated class, either directly, through subclasses or through |
153 /// subtypes. The latter case only contains spurious information from | 155 /// subtypes. The latter case only contains spurious information from |
154 /// instantiations through factory constructors and mixins. | 156 /// instantiations through factory constructors and mixins. |
155 bool isImplemented(ClassElement cls); | 157 bool isImplemented(ClassElement cls); |
156 | 158 |
157 /// Set of all fields that are statically known to be written to. | 159 /// Set of all fields that are statically known to be written to. |
158 Iterable<Element> get fieldSetters; | 160 Iterable<Element> get fieldSetters; |
| 161 |
| 162 /// Call [f] for all directly or abstractly instantiated classes. |
| 163 void forEachInstantiatedClass( |
| 164 f(ClassElement cls, EnumSet<Instantiation> instantiations)); |
159 } | 165 } |
160 | 166 |
161 class ResolutionWorldBuilderImpl implements ResolutionWorldBuilder { | 167 class ResolutionWorldBuilderImpl implements ResolutionWorldBuilder { |
162 /// The set of all directly instantiated classes, that is, classes with a | 168 /// The set of all directly instantiated classes, that is, classes with a |
163 /// generative constructor that has been called directly and not only through | 169 /// generative constructor that has been called directly and not only through |
164 /// a super-call. | 170 /// a super-call. |
165 /// | 171 /// |
166 /// Invariant: Elements are declaration elements. | 172 /// Invariant: Elements are declaration elements. |
167 // TODO(johnniwinther): [_directlyInstantiatedClasses] and | 173 // TODO(johnniwinther): [_directlyInstantiatedClasses] and |
168 // [_instantiatedTypes] sets should be merged. | 174 // [_instantiatedTypes] sets should be merged. |
169 final Set<ClassElement> _directlyInstantiatedClasses = | 175 final Map<ClassElement, EnumSet<Instantiation>> _directlyInstantiatedClasses = |
170 new Set<ClassElement>(); | 176 <ClassElement, EnumSet<Instantiation>>{}; |
171 | 177 |
172 /// The set of all directly instantiated types, that is, the types of the | 178 /// The set of all directly instantiated types, that is, the types of the |
173 /// directly instantiated classes. | 179 /// directly instantiated classes. |
174 /// | 180 /// |
175 /// See [_directlyInstantiatedClasses]. | 181 /// See [_directlyInstantiatedClasses]. |
176 final Set<DartType> _instantiatedTypes = new Set<DartType>(); | 182 final Set<DartType> _instantiatedTypes = new Set<DartType>(); |
177 | 183 |
178 /// Classes implemented by directly instantiated classes. | 184 /// Classes implemented by directly instantiated classes. |
179 final Set<ClassElement> _implementedClasses = new Set<ClassElement>(); | 185 final Set<ClassElement> _implementedClasses = new Set<ClassElement>(); |
180 | 186 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
230 | 236 |
231 final SelectorConstraintsStrategy selectorConstraintsStrategy; | 237 final SelectorConstraintsStrategy selectorConstraintsStrategy; |
232 | 238 |
233 ResolutionWorldBuilderImpl(this.selectorConstraintsStrategy); | 239 ResolutionWorldBuilderImpl(this.selectorConstraintsStrategy); |
234 | 240 |
235 /// All directly instantiated classes, that is, classes with a generative | 241 /// All directly instantiated classes, that is, classes with a generative |
236 /// constructor that has been called directly and not only through a | 242 /// constructor that has been called directly and not only through a |
237 /// super-call. | 243 /// super-call. |
238 // TODO(johnniwinther): Improve semantic precision. | 244 // TODO(johnniwinther): Improve semantic precision. |
239 Iterable<ClassElement> get directlyInstantiatedClasses { | 245 Iterable<ClassElement> get directlyInstantiatedClasses { |
240 return _directlyInstantiatedClasses; | 246 return _directlyInstantiatedClasses.keys; |
241 } | 247 } |
242 | 248 |
243 /// All directly instantiated types, that is, the types of the directly | 249 /// All directly instantiated types, that is, the types of the directly |
244 /// instantiated classes. | 250 /// instantiated classes. |
245 /// | 251 /// |
246 /// See [directlyInstantiatedClasses]. | 252 /// See [directlyInstantiatedClasses]. |
247 // TODO(johnniwinther): Improve semantic precision. | 253 // TODO(johnniwinther): Improve semantic precision. |
248 Iterable<DartType> get instantiatedTypes => _instantiatedTypes; | 254 Iterable<DartType> get instantiatedTypes => _instantiatedTypes; |
249 | 255 |
250 /// Returns `true` if [cls] is considered to be implemented by an | 256 /// Returns `true` if [cls] is considered to be implemented by an |
(...skipping 22 matching lines...) Expand all Loading... |
273 // classes; a native abstract class may have non-abstract subclasses | 279 // classes; a native abstract class may have non-abstract subclasses |
274 // not declared to the program. Instances of these classes are | 280 // not declared to the program. Instances of these classes are |
275 // indistinguishable from the abstract class. | 281 // indistinguishable from the abstract class. |
276 || | 282 || |
277 isNative | 283 isNative |
278 // Likewise, if this registration comes from the mirror system, | 284 // Likewise, if this registration comes from the mirror system, |
279 // all bets are off. | 285 // all bets are off. |
280 // TODO(herhut): Track classes required by mirrors seperately. | 286 // TODO(herhut): Track classes required by mirrors seperately. |
281 || | 287 || |
282 byMirrors) { | 288 byMirrors) { |
283 _directlyInstantiatedClasses.add(cls); | 289 EnumSet<Instantiation> instantiations = _directlyInstantiatedClasses |
| 290 .putIfAbsent(cls, () => new EnumSet<Instantiation>()); |
| 291 if (isNative || byMirrors) { |
| 292 instantiations.add(Instantiation.ABSTRACTLY_INSTANTIATED); |
| 293 } else { |
| 294 instantiations.add(Instantiation.DIRECTLY_INSTANTIATED); |
| 295 } |
284 } | 296 } |
285 | 297 |
286 // TODO(johnniwinther): Replace this by separate more specific mappings that | 298 // TODO(johnniwinther): Replace this by separate more specific mappings that |
287 // include the type arguments. | 299 // include the type arguments. |
288 if (_implementedClasses.add(cls)) { | 300 if (_implementedClasses.add(cls)) { |
289 onImplemented(cls); | 301 onImplemented(cls); |
290 cls.allSupertypes.forEach((InterfaceType supertype) { | 302 cls.allSupertypes.forEach((InterfaceType supertype) { |
291 if (_implementedClasses.add(supertype.element)) { | 303 if (_implementedClasses.add(supertype.element)) { |
292 onImplemented(supertype.element); | 304 onImplemented(supertype.element); |
293 } | 305 } |
294 }); | 306 }); |
295 } | 307 } |
296 } | 308 } |
297 | 309 |
| 310 @override |
| 311 void forEachInstantiatedClass( |
| 312 f(ClassElement cls, EnumSet<Instantiation> instantiations)) { |
| 313 _directlyInstantiatedClasses.forEach(f); |
| 314 } |
| 315 |
298 bool _hasMatchingSelector(Map<Selector, SelectorConstraints> selectors, | 316 bool _hasMatchingSelector(Map<Selector, SelectorConstraints> selectors, |
299 Element member, OpenWorld world) { | 317 Element member, OpenWorld world) { |
300 if (selectors == null) return false; | 318 if (selectors == null) return false; |
301 for (Selector selector in selectors.keys) { | 319 for (Selector selector in selectors.keys) { |
302 if (selector.appliesUnnamed(member)) { | 320 if (selector.appliesUnnamed(member)) { |
303 SelectorConstraints masks = selectors[selector]; | 321 SelectorConstraints masks = selectors[selector]; |
304 if (masks.applies(member, selector, world)) { | 322 if (masks.applies(member, selector, world)) { |
305 return true; | 323 return true; |
306 } | 324 } |
307 } | 325 } |
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
662 | 680 |
663 void forgetElement(Element element, Compiler compiler) { | 681 void forgetElement(Element element, Compiler compiler) { |
664 _directlyInstantiatedClasses.remove(element); | 682 _directlyInstantiatedClasses.remove(element); |
665 if (element is ClassElement) { | 683 if (element is ClassElement) { |
666 assert(invariant(element, element.thisType.isRaw, | 684 assert(invariant(element, element.thisType.isRaw, |
667 message: 'Generic classes not supported (${element.thisType}).')); | 685 message: 'Generic classes not supported (${element.thisType}).')); |
668 _instantiatedTypes..remove(element.rawType)..remove(element.thisType); | 686 _instantiatedTypes..remove(element.rawType)..remove(element.thisType); |
669 } | 687 } |
670 } | 688 } |
671 } | 689 } |
OLD | NEW |