| 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 |