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 | 10 import '../compiler.dart' show Compiler; |
11 Compiler; | |
12 import '../elements/elements.dart'; | 11 import '../elements/elements.dart'; |
13 import '../dart_types.dart'; | 12 import '../dart_types.dart'; |
14 import '../util/util.dart'; | 13 import '../util/util.dart'; |
15 import '../world.dart' show | 14 import '../world.dart' show ClassWorld, World; |
16 ClassWorld, | |
17 World; | |
18 | 15 |
19 import 'selector.dart' show | 16 import 'selector.dart' show Selector; |
20 Selector; | 17 import 'use.dart' show DynamicUse, DynamicUseKind, StaticUse, StaticUseKind; |
21 import 'use.dart' show | |
22 DynamicUse, | |
23 DynamicUseKind, | |
24 StaticUse, | |
25 StaticUseKind; | |
26 | 18 |
27 /// The known constraint on receiver for a dynamic call site. | 19 /// The known constraint on receiver for a dynamic call site. |
28 /// | 20 /// |
29 /// This can for instance be used to constrain this dynamic call to `foo` to | 21 /// This can for instance be used to constrain this dynamic call to `foo` to |
30 /// 'receivers of the exact instance `Bar`': | 22 /// 'receivers of the exact instance `Bar`': |
31 /// | 23 /// |
32 /// class Bar { | 24 /// class Bar { |
33 /// void foo() {} | 25 /// void foo() {} |
34 /// } | 26 /// } |
35 /// main() => new Bar().foo(); | 27 /// main() => new Bar().foo(); |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 return _implementedClasses.contains(cls.declaration); | 212 return _implementedClasses.contains(cls.declaration); |
221 } | 213 } |
222 | 214 |
223 /// Register [type] as (directly) instantiated. | 215 /// Register [type] as (directly) instantiated. |
224 /// | 216 /// |
225 /// If [byMirrors] is `true`, the instantiation is through mirrors. | 217 /// If [byMirrors] is `true`, the instantiation is through mirrors. |
226 // TODO(johnniwinther): Fully enforce the separation between exact, through | 218 // TODO(johnniwinther): Fully enforce the separation between exact, through |
227 // subclass and through subtype instantiated types/classes. | 219 // subclass and through subtype instantiated types/classes. |
228 // TODO(johnniwinther): Support unknown type arguments for generic types. | 220 // TODO(johnniwinther): Support unknown type arguments for generic types. |
229 void registerTypeInstantiation(InterfaceType type, | 221 void registerTypeInstantiation(InterfaceType type, |
230 {bool byMirrors: false, | 222 {bool byMirrors: false, |
231 bool isNative: false, | 223 bool isNative: false, |
232 void onImplemented(ClassElement cls)}) { | 224 void onImplemented(ClassElement cls)}) { |
233 _instantiatedTypes.add(type); | 225 _instantiatedTypes.add(type); |
234 ClassElement cls = type.element; | 226 ClassElement cls = type.element; |
235 if (!cls.isAbstract | 227 if (!cls.isAbstract |
236 // We can't use the closed-world assumption with native abstract | 228 // We can't use the closed-world assumption with native abstract |
237 // classes; a native abstract class may have non-abstract subclasses | 229 // classes; a native abstract class may have non-abstract subclasses |
238 // not declared to the program. Instances of these classes are | 230 // not declared to the program. Instances of these classes are |
239 // indistinguishable from the abstract class. | 231 // indistinguishable from the abstract class. |
240 || isNative | 232 || |
| 233 isNative |
241 // Likewise, if this registration comes from the mirror system, | 234 // Likewise, if this registration comes from the mirror system, |
242 // all bets are off. | 235 // all bets are off. |
243 // TODO(herhut): Track classes required by mirrors seperately. | 236 // TODO(herhut): Track classes required by mirrors seperately. |
244 || byMirrors) { | 237 || |
| 238 byMirrors) { |
245 _directlyInstantiatedClasses.add(cls); | 239 _directlyInstantiatedClasses.add(cls); |
246 } | 240 } |
247 | 241 |
248 // TODO(johnniwinther): Replace this by separate more specific mappings that | 242 // TODO(johnniwinther): Replace this by separate more specific mappings that |
249 // include the type arguments. | 243 // include the type arguments. |
250 if (_implementedClasses.add(cls)) { | 244 if (_implementedClasses.add(cls)) { |
251 onImplemented(cls); | 245 onImplemented(cls); |
252 cls.allSupertypes.forEach((InterfaceType supertype) { | 246 cls.allSupertypes.forEach((InterfaceType supertype) { |
253 if (_implementedClasses.add(supertype.element)) { | 247 if (_implementedClasses.add(supertype.element)) { |
254 onImplemented(supertype.element); | 248 onImplemented(supertype.element); |
255 } | 249 } |
256 }); | 250 }); |
257 } | 251 } |
258 } | 252 } |
259 | 253 |
260 bool _hasMatchingSelector(Map<Selector, SelectorConstraints> selectors, | 254 bool _hasMatchingSelector(Map<Selector, SelectorConstraints> selectors, |
261 Element member, | 255 Element member, World world) { |
262 World world) { | |
263 if (selectors == null) return false; | 256 if (selectors == null) return false; |
264 for (Selector selector in selectors.keys) { | 257 for (Selector selector in selectors.keys) { |
265 if (selector.appliesUnnamed(member, world)) { | 258 if (selector.appliesUnnamed(member, world)) { |
266 SelectorConstraints masks = selectors[selector]; | 259 SelectorConstraints masks = selectors[selector]; |
267 if (masks.applies(member, selector, world)) { | 260 if (masks.applies(member, selector, world)) { |
268 return true; | 261 return true; |
269 } | 262 } |
270 } | 263 } |
271 } | 264 } |
272 return false; | 265 return false; |
(...skipping 16 matching lines...) Expand all Loading... |
289 switch (dynamicUse.kind) { | 282 switch (dynamicUse.kind) { |
290 case DynamicUseKind.INVOKE: | 283 case DynamicUseKind.INVOKE: |
291 return _registerNewSelector(dynamicUse, _invokedNames); | 284 return _registerNewSelector(dynamicUse, _invokedNames); |
292 case DynamicUseKind.GET: | 285 case DynamicUseKind.GET: |
293 return _registerNewSelector(dynamicUse, _invokedGetters); | 286 return _registerNewSelector(dynamicUse, _invokedGetters); |
294 case DynamicUseKind.SET: | 287 case DynamicUseKind.SET: |
295 return _registerNewSelector(dynamicUse, _invokedSetters); | 288 return _registerNewSelector(dynamicUse, _invokedSetters); |
296 } | 289 } |
297 } | 290 } |
298 | 291 |
299 bool _registerNewSelector( | 292 bool _registerNewSelector(DynamicUse dynamicUse, |
300 DynamicUse dynamicUse, | |
301 Map<String, Map<Selector, SelectorConstraints>> selectorMap) { | 293 Map<String, Map<Selector, SelectorConstraints>> selectorMap) { |
302 Selector selector = dynamicUse.selector; | 294 Selector selector = dynamicUse.selector; |
303 String name = selector.name; | 295 String name = selector.name; |
304 ReceiverConstraint mask = dynamicUse.mask; | 296 ReceiverConstraint mask = dynamicUse.mask; |
305 Map<Selector, SelectorConstraints> selectors = selectorMap.putIfAbsent( | 297 Map<Selector, SelectorConstraints> selectors = selectorMap.putIfAbsent( |
306 name, () => new Maplet<Selector, SelectorConstraints>()); | 298 name, () => new Maplet<Selector, SelectorConstraints>()); |
307 UniverseSelectorConstraints constraints = selectors.putIfAbsent( | 299 UniverseSelectorConstraints constraints = |
308 selector, () { | 300 selectors.putIfAbsent(selector, () { |
309 return selectorConstraintsStrategy.createSelectorConstraints(selector); | 301 return selectorConstraintsStrategy.createSelectorConstraints(selector); |
310 }); | 302 }); |
311 return constraints.addReceiverConstraint(mask); | 303 return constraints.addReceiverConstraint(mask); |
312 } | 304 } |
313 | 305 |
314 Map<Selector, SelectorConstraints> _asUnmodifiable( | 306 Map<Selector, SelectorConstraints> _asUnmodifiable( |
315 Map<Selector, SelectorConstraints> map) { | 307 Map<Selector, SelectorConstraints> map) { |
316 if (map == null) return null; | 308 if (map == null) return null; |
317 return new UnmodifiableMapView(map); | 309 return new UnmodifiableMapView(map); |
318 } | 310 } |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 } | 374 } |
383 | 375 |
384 void forgetElement(Element element, Compiler compiler) { | 376 void forgetElement(Element element, Compiler compiler) { |
385 allClosures.remove(element); | 377 allClosures.remove(element); |
386 slowDirectlyNestedClosures(element).forEach(compiler.forgetElement); | 378 slowDirectlyNestedClosures(element).forEach(compiler.forgetElement); |
387 closurizedMembers.remove(element); | 379 closurizedMembers.remove(element); |
388 fieldSetters.remove(element); | 380 fieldSetters.remove(element); |
389 fieldGetters.remove(element); | 381 fieldGetters.remove(element); |
390 _directlyInstantiatedClasses.remove(element); | 382 _directlyInstantiatedClasses.remove(element); |
391 if (element is ClassElement) { | 383 if (element is ClassElement) { |
392 assert(invariant( | 384 assert(invariant(element, element.thisType.isRaw, |
393 element, element.thisType.isRaw, | |
394 message: 'Generic classes not supported (${element.thisType}).')); | 385 message: 'Generic classes not supported (${element.thisType}).')); |
395 _instantiatedTypes | 386 _instantiatedTypes..remove(element.rawType)..remove(element.thisType); |
396 ..remove(element.rawType) | |
397 ..remove(element.thisType); | |
398 } | 387 } |
399 } | 388 } |
400 | 389 |
401 // TODO(ahe): Replace this method with something that is O(1), for example, | 390 // TODO(ahe): Replace this method with something that is O(1), for example, |
402 // by using a map. | 391 // by using a map. |
403 List<LocalFunctionElement> slowDirectlyNestedClosures(Element element) { | 392 List<LocalFunctionElement> slowDirectlyNestedClosures(Element element) { |
404 // Return new list to guard against concurrent modifications. | 393 // Return new list to guard against concurrent modifications. |
405 return new List<LocalFunctionElement>.from( | 394 return new List<LocalFunctionElement>.from( |
406 allClosures.where((LocalFunctionElement closure) { | 395 allClosures.where((LocalFunctionElement closure) { |
407 return closure.executableContext == element; | 396 return closure.executableContext == element; |
408 })); | 397 })); |
409 } | 398 } |
410 } | 399 } |
OLD | NEW |