| 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 '../cache_strategy.dart'; | 9 import '../cache_strategy.dart'; |
| 10 import '../common.dart'; | 10 import '../common.dart'; |
| (...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 484 bool isImplemented(ClassElement cls) { | 484 bool isImplemented(ClassElement cls) { |
| 485 return _implementedClasses.contains(cls.declaration); | 485 return _implementedClasses.contains(cls.declaration); |
| 486 } | 486 } |
| 487 | 487 |
| 488 /// Register [type] as (directly) instantiated. | 488 /// Register [type] as (directly) instantiated. |
| 489 /// | 489 /// |
| 490 /// If [byMirrors] is `true`, the instantiation is through mirrors. | 490 /// If [byMirrors] is `true`, the instantiation is through mirrors. |
| 491 // TODO(johnniwinther): Fully enforce the separation between exact, through | 491 // TODO(johnniwinther): Fully enforce the separation between exact, through |
| 492 // subclass and through subtype instantiated types/classes. | 492 // subclass and through subtype instantiated types/classes. |
| 493 // TODO(johnniwinther): Support unknown type arguments for generic types. | 493 // TODO(johnniwinther): Support unknown type arguments for generic types. |
| 494 void registerTypeInstantiation(InterfaceType type, ClassUsed classUsed, | 494 void registerTypeInstantiation( |
| 495 InterfaceType type, ClassUsedCallback classUsed, |
| 495 {ConstructorElement constructor, | 496 {ConstructorElement constructor, |
| 496 bool byMirrors: false, | 497 bool byMirrors: false, |
| 497 bool isRedirection: false}) { | 498 bool isRedirection: false}) { |
| 498 ClassElement cls = type.element; | 499 ClassElement cls = type.element; |
| 499 cls.ensureResolved(_resolution); | 500 cls.ensureResolved(_resolution); |
| 500 InstantiationInfo info = | 501 InstantiationInfo info = |
| 501 _instantiationInfo.putIfAbsent(cls, () => new InstantiationInfo()); | 502 _instantiationInfo.putIfAbsent(cls, () => new InstantiationInfo()); |
| 502 Instantiation kind = Instantiation.UNINSTANTIATED; | 503 Instantiation kind = Instantiation.UNINSTANTIATED; |
| 503 bool isNative = _backend.isNative(cls); | 504 bool isNative = _backend.isNative(cls); |
| 504 if (!cls.isAbstract || | 505 if (!cls.isAbstract || |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 779 _ClassUsage _getClassUsage(ClassElement cls) { | 780 _ClassUsage _getClassUsage(ClassElement cls) { |
| 780 return _processedClasses.putIfAbsent(cls, () { | 781 return _processedClasses.putIfAbsent(cls, () { |
| 781 cls.ensureResolved(_resolution); | 782 cls.ensureResolved(_resolution); |
| 782 _ClassUsage usage = new _ClassUsage(cls); | 783 _ClassUsage usage = new _ClassUsage(cls); |
| 783 _resolution.ensureClassMembers(cls); | 784 _resolution.ensureClassMembers(cls); |
| 784 return usage; | 785 return usage; |
| 785 }); | 786 }); |
| 786 } | 787 } |
| 787 | 788 |
| 788 /// Register [cls] and all its superclasses as instantiated. | 789 /// Register [cls] and all its superclasses as instantiated. |
| 789 void _processInstantiatedClass(ClassElement cls, ClassUsed classUsed) { | 790 void _processInstantiatedClass( |
| 791 ClassElement cls, ClassUsedCallback classUsed) { |
| 790 // Registers [superclass] as instantiated. Returns `true` if it wasn't | 792 // Registers [superclass] as instantiated. Returns `true` if it wasn't |
| 791 // already instantiated and we therefore have to process its superclass as | 793 // already instantiated and we therefore have to process its superclass as |
| 792 // well. | 794 // well. |
| 793 bool processClass(ClassElement superclass) { | 795 bool processClass(ClassElement superclass) { |
| 794 _ClassUsage usage = _getClassUsage(superclass); | 796 _ClassUsage usage = _getClassUsage(superclass); |
| 795 if (!usage.isInstantiated) { | 797 if (!usage.isInstantiated) { |
| 796 classUsed(usage.cls, usage.instantiate()); | 798 classUsed(usage.cls, usage.instantiate()); |
| 797 return true; | 799 return true; |
| 798 } | 800 } |
| 799 return false; | 801 return false; |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 876 useSet.addAll(usage.write()); | 878 useSet.addAll(usage.write()); |
| 877 } | 879 } |
| 878 | 880 |
| 879 if (usage.pendingUse.contains(MemberUse.NORMAL)) { | 881 if (usage.pendingUse.contains(MemberUse.NORMAL)) { |
| 880 // The element is not yet used. Add it to the list of instance | 882 // The element is not yet used. Add it to the list of instance |
| 881 // members to still be processed. | 883 // members to still be processed. |
| 882 _instanceMembersByName | 884 _instanceMembersByName |
| 883 .putIfAbsent(memberName, () => new Set<_MemberUsage>()) | 885 .putIfAbsent(memberName, () => new Set<_MemberUsage>()) |
| 884 .add(usage); | 886 .add(usage); |
| 885 } | 887 } |
| 886 if (usage.pendingUse.contains(MemberUse.CLOSURIZE)) { | 888 if (usage.pendingUse.contains(MemberUse.CLOSURIZE_INSTANCE)) { |
| 887 // Store the member in [instanceFunctionsByName] to catch | 889 // Store the member in [instanceFunctionsByName] to catch |
| 888 // getters on the function. | 890 // getters on the function. |
| 889 _instanceFunctionsByName | 891 _instanceFunctionsByName |
| 890 .putIfAbsent(memberName, () => new Set<_MemberUsage>()) | 892 .putIfAbsent(memberName, () => new Set<_MemberUsage>()) |
| 891 .add(usage); | 893 .add(usage); |
| 892 } | 894 } |
| 893 | 895 |
| 894 memberUsed(usage.entity, useSet); | 896 memberUsed(usage.entity, useSet); |
| 895 return usage; | 897 return usage; |
| 896 }); | 898 }); |
| (...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1331 @override | 1333 @override |
| 1332 EnumSet<MemberUse> fullyUse() => read(); | 1334 EnumSet<MemberUse> fullyUse() => read(); |
| 1333 } | 1335 } |
| 1334 | 1336 |
| 1335 class _FunctionUsage extends _MemberUsage { | 1337 class _FunctionUsage extends _MemberUsage { |
| 1336 bool hasInvoke = false; | 1338 bool hasInvoke = false; |
| 1337 bool hasRead = false; | 1339 bool hasRead = false; |
| 1338 | 1340 |
| 1339 _FunctionUsage(FunctionEntity function) : super.internal(function); | 1341 _FunctionUsage(FunctionEntity function) : super.internal(function); |
| 1340 | 1342 |
| 1341 EnumSet<MemberUse> get _originalUse => MemberUses.ALL; | 1343 EnumSet<MemberUse> get _originalUse => MemberUses.ALL_INSTANCE; |
| 1342 | 1344 |
| 1343 @override | 1345 @override |
| 1344 EnumSet<MemberUse> read() => fullyUse(); | 1346 EnumSet<MemberUse> read() => fullyUse(); |
| 1345 | 1347 |
| 1346 @override | 1348 @override |
| 1347 EnumSet<MemberUse> invoke() { | 1349 EnumSet<MemberUse> invoke() { |
| 1348 if (hasInvoke) { | 1350 if (hasInvoke) { |
| 1349 return MemberUses.NONE; | 1351 return MemberUses.NONE; |
| 1350 } | 1352 } |
| 1351 hasInvoke = true; | 1353 hasInvoke = true; |
| 1352 return _pendingUse | 1354 return _pendingUse |
| 1353 .removeAll(hasRead ? MemberUses.NONE : MemberUses.NORMAL_ONLY); | 1355 .removeAll(hasRead ? MemberUses.NONE : MemberUses.NORMAL_ONLY); |
| 1354 } | 1356 } |
| 1355 | 1357 |
| 1356 @override | 1358 @override |
| 1357 EnumSet<MemberUse> fullyUse() { | 1359 EnumSet<MemberUse> fullyUse() { |
| 1358 if (hasInvoke) { | 1360 if (hasInvoke) { |
| 1359 if (hasRead) { | 1361 if (hasRead) { |
| 1360 return MemberUses.NONE; | 1362 return MemberUses.NONE; |
| 1361 } | 1363 } |
| 1362 hasRead = true; | 1364 hasRead = true; |
| 1363 return _pendingUse.removeAll(MemberUses.CLOSURIZE_ONLY); | 1365 return _pendingUse.removeAll(MemberUses.CLOSURIZE_INSTANCE_ONLY); |
| 1364 } else if (hasRead) { | 1366 } else if (hasRead) { |
| 1365 hasInvoke = true; | 1367 hasInvoke = true; |
| 1366 return _pendingUse.removeAll(MemberUses.NORMAL_ONLY); | 1368 return _pendingUse.removeAll(MemberUses.NORMAL_ONLY); |
| 1367 } else { | 1369 } else { |
| 1368 hasRead = hasInvoke = true; | 1370 hasRead = hasInvoke = true; |
| 1369 return _pendingUse.removeAll(MemberUses.ALL); | 1371 return _pendingUse.removeAll(MemberUses.ALL_INSTANCE); |
| 1370 } | 1372 } |
| 1371 } | 1373 } |
| 1372 | 1374 |
| 1373 @override | 1375 @override |
| 1374 bool get fullyUsed => hasInvoke && hasRead; | 1376 bool get fullyUsed => hasInvoke && hasRead; |
| 1375 } | 1377 } |
| 1376 | 1378 |
| 1377 class _GetterUsage extends _MemberUsage { | 1379 class _GetterUsage extends _MemberUsage { |
| 1378 bool hasRead = false; | 1380 bool hasRead = false; |
| 1379 | 1381 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1413 } | 1415 } |
| 1414 hasWrite = true; | 1416 hasWrite = true; |
| 1415 return MemberUses.NORMAL_ONLY; | 1417 return MemberUses.NORMAL_ONLY; |
| 1416 } | 1418 } |
| 1417 | 1419 |
| 1418 @override | 1420 @override |
| 1419 EnumSet<MemberUse> fullyUse() => write(); | 1421 EnumSet<MemberUse> fullyUse() => write(); |
| 1420 } | 1422 } |
| 1421 | 1423 |
| 1422 /// Enum class for the possible kind of use of [MemberEntity] objects. | 1424 /// Enum class for the possible kind of use of [MemberEntity] objects. |
| 1423 enum MemberUse { NORMAL, CLOSURIZE } | 1425 enum MemberUse { NORMAL, CLOSURIZE_INSTANCE, CLOSURIZE_STATIC } |
| 1424 | 1426 |
| 1425 /// Common [EnumSet]s used for [MemberUse]. | 1427 /// Common [EnumSet]s used for [MemberUse]. |
| 1426 class MemberUses { | 1428 class MemberUses { |
| 1427 static const EnumSet<MemberUse> NONE = const EnumSet<MemberUse>.fixed(0); | 1429 static const EnumSet<MemberUse> NONE = const EnumSet<MemberUse>.fixed(0); |
| 1428 static const EnumSet<MemberUse> NORMAL_ONLY = | 1430 static const EnumSet<MemberUse> NORMAL_ONLY = |
| 1429 const EnumSet<MemberUse>.fixed(1); | 1431 const EnumSet<MemberUse>.fixed(1); |
| 1430 static const EnumSet<MemberUse> CLOSURIZE_ONLY = | 1432 static const EnumSet<MemberUse> CLOSURIZE_INSTANCE_ONLY = |
| 1431 const EnumSet<MemberUse>.fixed(2); | 1433 const EnumSet<MemberUse>.fixed(2); |
| 1432 static const EnumSet<MemberUse> ALL = const EnumSet<MemberUse>.fixed(3); | 1434 static const EnumSet<MemberUse> CLOSURIZE_STATIC_ONLY = |
| 1435 const EnumSet<MemberUse>.fixed(4); |
| 1436 static const EnumSet<MemberUse> ALL_INSTANCE = |
| 1437 const EnumSet<MemberUse>.fixed(3); |
| 1438 static const EnumSet<MemberUse> ALL_STATIC = |
| 1439 const EnumSet<MemberUse>.fixed(5); |
| 1433 } | 1440 } |
| 1434 | 1441 |
| 1435 typedef void MemberUsedCallback(MemberEntity member, EnumSet<MemberUse> useSet); | 1442 typedef void MemberUsedCallback(MemberEntity member, EnumSet<MemberUse> useSet); |
| 1436 | 1443 |
| 1437 /// Registry for the observed use of a class [entity] in the open world. | 1444 /// Registry for the observed use of a class [entity] in the open world. |
| 1438 // TODO(johnniwinther): Merge this with [InstantiationInfo]. | 1445 // TODO(johnniwinther): Merge this with [InstantiationInfo]. |
| 1439 class _ClassUsage extends _AbstractUsage<ClassUse> { | 1446 class _ClassUsage extends _AbstractUsage<ClassUse> { |
| 1440 bool isInstantiated = false; | 1447 bool isInstantiated = false; |
| 1441 bool isImplemented = false; | 1448 bool isImplemented = false; |
| 1442 | 1449 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1472 /// Common [EnumSet]s used for [ClassUse]. | 1479 /// Common [EnumSet]s used for [ClassUse]. |
| 1473 class ClassUses { | 1480 class ClassUses { |
| 1474 static const EnumSet<ClassUse> NONE = const EnumSet<ClassUse>.fixed(0); | 1481 static const EnumSet<ClassUse> NONE = const EnumSet<ClassUse>.fixed(0); |
| 1475 static const EnumSet<ClassUse> INSTANTIATED_ONLY = | 1482 static const EnumSet<ClassUse> INSTANTIATED_ONLY = |
| 1476 const EnumSet<ClassUse>.fixed(1); | 1483 const EnumSet<ClassUse>.fixed(1); |
| 1477 static const EnumSet<ClassUse> IMPLEMENTED_ONLY = | 1484 static const EnumSet<ClassUse> IMPLEMENTED_ONLY = |
| 1478 const EnumSet<ClassUse>.fixed(2); | 1485 const EnumSet<ClassUse>.fixed(2); |
| 1479 static const EnumSet<ClassUse> ALL = const EnumSet<ClassUse>.fixed(3); | 1486 static const EnumSet<ClassUse> ALL = const EnumSet<ClassUse>.fixed(3); |
| 1480 } | 1487 } |
| 1481 | 1488 |
| 1482 typedef void ClassUsed(ClassEntity cls, EnumSet<ClassUse> useSet); | 1489 typedef void ClassUsedCallback(ClassEntity cls, EnumSet<ClassUse> useSet); |
| 1483 | 1490 |
| 1484 // TODO(johnniwinther): Merge this with [_MemberUsage]. | 1491 // TODO(johnniwinther): Merge this with [_MemberUsage]. |
| 1485 abstract class _StaticMemberUsage extends _AbstractUsage<MemberUse> { | 1492 abstract class _StaticMemberUsage extends _AbstractUsage<MemberUse> { |
| 1486 final Entity entity; | 1493 final Entity entity; |
| 1487 | 1494 |
| 1488 bool hasNormalUse = false; | 1495 bool hasNormalUse = false; |
| 1489 bool get hasClosurization => false; | 1496 bool get hasClosurization => false; |
| 1490 | 1497 |
| 1491 _StaticMemberUsage.internal(this.entity); | 1498 _StaticMemberUsage.internal(this.entity); |
| 1492 | 1499 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1515 class _StaticFunctionUsage extends _StaticMemberUsage { | 1522 class _StaticFunctionUsage extends _StaticMemberUsage { |
| 1516 bool hasClosurization = false; | 1523 bool hasClosurization = false; |
| 1517 | 1524 |
| 1518 _StaticFunctionUsage(Entity entity) : super.internal(entity); | 1525 _StaticFunctionUsage(Entity entity) : super.internal(entity); |
| 1519 | 1526 |
| 1520 EnumSet<MemberUse> tearOff() { | 1527 EnumSet<MemberUse> tearOff() { |
| 1521 if (hasClosurization) { | 1528 if (hasClosurization) { |
| 1522 return MemberUses.NONE; | 1529 return MemberUses.NONE; |
| 1523 } | 1530 } |
| 1524 hasNormalUse = hasClosurization = true; | 1531 hasNormalUse = hasClosurization = true; |
| 1525 return _pendingUse.removeAll(MemberUses.ALL); | 1532 return _pendingUse.removeAll(MemberUses.ALL_STATIC); |
| 1526 } | 1533 } |
| 1527 | 1534 |
| 1528 @override | 1535 @override |
| 1529 EnumSet<MemberUse> get _originalUse => MemberUses.ALL; | 1536 EnumSet<MemberUse> get _originalUse => MemberUses.ALL_STATIC; |
| 1530 } | 1537 } |
| OLD | NEW |