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 |
11 Compiler; | 11 Compiler; |
12 import '../elements/elements.dart'; | 12 import '../elements/elements.dart'; |
13 import '../dart_types.dart'; | 13 import '../dart_types.dart'; |
14 import '../util/util.dart'; | 14 import '../util/util.dart'; |
15 import '../world.dart' show | 15 import '../world.dart' show |
16 ClassWorld, | 16 ClassWorld, |
17 World; | 17 World; |
18 | 18 |
19 import 'selector.dart' show | 19 import 'selector.dart' show |
20 Selector; | 20 Selector; |
| 21 import 'use.dart' show |
| 22 StaticUse, |
| 23 StaticUseKind; |
21 | 24 |
| 25 enum DynamicUseKind { |
| 26 INVOKE, |
| 27 GET, |
| 28 SET, |
| 29 } |
| 30 |
| 31 // TODO(johnniwinther): Rename to `DynamicUse` and move to 'use.dart'. |
22 class UniverseSelector { | 32 class UniverseSelector { |
23 final Selector selector; | 33 final Selector selector; |
24 final ReceiverConstraint mask; | 34 final ReceiverConstraint mask; |
25 | 35 |
26 UniverseSelector(this.selector, this.mask); | 36 UniverseSelector(this.selector, this.mask); |
27 | 37 |
28 bool appliesUnnamed(Element element, ClassWorld world) { | 38 bool appliesUnnamed(Element element, ClassWorld world) { |
29 return selector.appliesUnnamed(element, world) && | 39 return selector.appliesUnnamed(element, world) && |
30 (mask == null || mask.canHit(element, selector, world)); | 40 (mask == null || mask.canHit(element, selector, world)); |
31 } | 41 } |
32 | 42 |
| 43 DynamicUseKind get kind { |
| 44 if (selector.isGetter) { |
| 45 return DynamicUseKind.GET; |
| 46 } else if (selector.isSetter) { |
| 47 return DynamicUseKind.SET; |
| 48 } else { |
| 49 return DynamicUseKind.INVOKE; |
| 50 } |
| 51 } |
| 52 |
33 int get hashCode => selector.hashCode * 13 + mask.hashCode * 17; | 53 int get hashCode => selector.hashCode * 13 + mask.hashCode * 17; |
34 | 54 |
35 bool operator ==(other) { | 55 bool operator ==(other) { |
36 if (identical(this, other)) return true; | 56 if (identical(this, other)) return true; |
37 if (other is! UniverseSelector) return false; | 57 if (other is! UniverseSelector) return false; |
38 return selector == other.selector && mask == other.mask; | 58 return selector == other.selector && mask == other.mask; |
39 } | 59 } |
40 | 60 |
41 String toString() => '$selector,$mask'; | 61 String toString() => '$selector,$mask'; |
42 } | 62 } |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 } | 336 } |
317 | 337 |
318 bool hasInvokedGetter(Element member, World world) { | 338 bool hasInvokedGetter(Element member, World world) { |
319 return _hasMatchingSelector(_invokedGetters[member.name], member, world); | 339 return _hasMatchingSelector(_invokedGetters[member.name], member, world); |
320 } | 340 } |
321 | 341 |
322 bool hasInvokedSetter(Element member, World world) { | 342 bool hasInvokedSetter(Element member, World world) { |
323 return _hasMatchingSelector(_invokedSetters[member.name], member, world); | 343 return _hasMatchingSelector(_invokedSetters[member.name], member, world); |
324 } | 344 } |
325 | 345 |
326 bool registerInvocation(UniverseSelector selector) { | 346 bool registerDynamicUse(UniverseSelector selector) { |
327 return _registerNewSelector(selector, _invokedNames); | 347 switch (selector.kind) { |
328 } | 348 case DynamicUseKind.INVOKE: |
329 | 349 return _registerNewSelector(selector, _invokedNames); |
330 bool registerInvokedGetter(UniverseSelector selector) { | 350 case DynamicUseKind.GET: |
331 return _registerNewSelector(selector, _invokedGetters); | 351 return _registerNewSelector(selector, _invokedGetters); |
332 } | 352 case DynamicUseKind.SET: |
333 | 353 return _registerNewSelector(selector, _invokedSetters); |
334 bool registerInvokedSetter(UniverseSelector selector) { | 354 } |
335 return _registerNewSelector(selector, _invokedSetters); | |
336 } | 355 } |
337 | 356 |
338 bool _registerNewSelector( | 357 bool _registerNewSelector( |
339 UniverseSelector universeSelector, | 358 UniverseSelector universeSelector, |
340 Map<String, Map<Selector, SelectorConstraints>> selectorMap) { | 359 Map<String, Map<Selector, SelectorConstraints>> selectorMap) { |
341 Selector selector = universeSelector.selector; | 360 Selector selector = universeSelector.selector; |
342 String name = selector.name; | 361 String name = selector.name; |
343 ReceiverConstraint mask = universeSelector.mask; | 362 ReceiverConstraint mask = universeSelector.mask; |
344 Map<Selector, SelectorConstraints> selectors = selectorMap.putIfAbsent( | 363 Map<Selector, SelectorConstraints> selectors = selectorMap.putIfAbsent( |
345 name, () => new Maplet<Selector, SelectorConstraints>()); | 364 name, () => new Maplet<Selector, SelectorConstraints>()); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
384 DartType registerIsCheck(DartType type, Compiler compiler) { | 403 DartType registerIsCheck(DartType type, Compiler compiler) { |
385 type.computeUnaliased(compiler.resolution); | 404 type.computeUnaliased(compiler.resolution); |
386 type = type.unaliased; | 405 type = type.unaliased; |
387 // Even in checked mode, type annotations for return type and argument | 406 // Even in checked mode, type annotations for return type and argument |
388 // types do not imply type checks, so there should never be a check | 407 // types do not imply type checks, so there should never be a check |
389 // against the type variable of a typedef. | 408 // against the type variable of a typedef. |
390 isChecks.add(type); | 409 isChecks.add(type); |
391 return type; | 410 return type; |
392 } | 411 } |
393 | 412 |
394 void registerStaticFieldUse(FieldElement staticField) { | 413 void registerStaticUse(StaticUse staticUse) { |
395 assert(Elements.isStaticOrTopLevel(staticField) && staticField.isField); | 414 Element element = staticUse.element; |
396 assert(staticField.isDeclaration); | 415 if (Elements.isStaticOrTopLevel(element) && element.isField) { |
397 | 416 allReferencedStaticFields.add(element); |
398 allReferencedStaticFields.add(staticField); | 417 } |
| 418 switch (staticUse.kind) { |
| 419 case StaticUseKind.STATIC_TEAR_OFF: |
| 420 staticFunctionsNeedingGetter.add(element); |
| 421 break; |
| 422 case StaticUseKind.FIELD_GET: |
| 423 fieldGetters.add(element); |
| 424 break; |
| 425 case StaticUseKind.FIELD_SET: |
| 426 fieldSetters.add(element); |
| 427 break; |
| 428 case StaticUseKind.SUPER_TEAR_OFF: |
| 429 methodsNeedingSuperGetter.add(element); |
| 430 break; |
| 431 case StaticUseKind.GENERAL: |
| 432 break; |
| 433 } |
399 } | 434 } |
400 | 435 |
401 void forgetElement(Element element, Compiler compiler) { | 436 void forgetElement(Element element, Compiler compiler) { |
402 allClosures.remove(element); | 437 allClosures.remove(element); |
403 slowDirectlyNestedClosures(element).forEach(compiler.forgetElement); | 438 slowDirectlyNestedClosures(element).forEach(compiler.forgetElement); |
404 closurizedMembers.remove(element); | 439 closurizedMembers.remove(element); |
405 fieldSetters.remove(element); | 440 fieldSetters.remove(element); |
406 fieldGetters.remove(element); | 441 fieldGetters.remove(element); |
407 _directlyInstantiatedClasses.remove(element); | 442 _directlyInstantiatedClasses.remove(element); |
408 _allInstantiatedClasses.remove(element); | 443 _allInstantiatedClasses.remove(element); |
(...skipping 10 matching lines...) Expand all Loading... |
419 // TODO(ahe): Replace this method with something that is O(1), for example, | 454 // TODO(ahe): Replace this method with something that is O(1), for example, |
420 // by using a map. | 455 // by using a map. |
421 List<LocalFunctionElement> slowDirectlyNestedClosures(Element element) { | 456 List<LocalFunctionElement> slowDirectlyNestedClosures(Element element) { |
422 // Return new list to guard against concurrent modifications. | 457 // Return new list to guard against concurrent modifications. |
423 return new List<LocalFunctionElement>.from( | 458 return new List<LocalFunctionElement>.from( |
424 allClosures.where((LocalFunctionElement closure) { | 459 allClosures.where((LocalFunctionElement closure) { |
425 return closure.executableContext == element; | 460 return closure.executableContext == element; |
426 })); | 461 })); |
427 } | 462 } |
428 } | 463 } |
OLD | NEW |