Chromium Code Reviews| 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 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 471 | 471 |
| 472 final Map<ClassElement, Set<MixinApplicationElement>> _mixinUses = | 472 final Map<ClassElement, Set<MixinApplicationElement>> _mixinUses = |
| 473 new Map<ClassElement, Set<MixinApplicationElement>>(); | 473 new Map<ClassElement, Set<MixinApplicationElement>>(); |
| 474 | 474 |
| 475 // We keep track of subtype and subclass relationships in four | 475 // We keep track of subtype and subclass relationships in four |
| 476 // distinct sets to make class hierarchy analysis faster. | 476 // distinct sets to make class hierarchy analysis faster. |
| 477 final Map<ClassElement, ClassHierarchyNode> _classHierarchyNodes = | 477 final Map<ClassElement, ClassHierarchyNode> _classHierarchyNodes = |
| 478 <ClassElement, ClassHierarchyNode>{}; | 478 <ClassElement, ClassHierarchyNode>{}; |
| 479 final Map<ClassElement, ClassSet> _classSets = <ClassElement, ClassSet>{}; | 479 final Map<ClassElement, ClassSet> _classSets = <ClassElement, ClassSet>{}; |
| 480 | 480 |
| 481 final Map<ClassElement, Map<ClassElement, bool>> _subtypeCoveredByCache = | |
|
Johnni Winther
2016/12/21 14:37:19
Only needed in ClosedWorldImpl
| |
| 482 <ClassElement, Map<ClassElement, bool>>{}; | |
| 483 | |
| 484 final Set<Element> alreadyPopulated; | 481 final Set<Element> alreadyPopulated; |
| 485 | 482 |
| 486 final CacheStrategy cacheStrategy; | 483 final CacheStrategy cacheStrategy; |
| 487 | 484 |
| 488 bool get isClosed => _closed; | 485 bool get isClosed => _closed; |
| 489 | 486 |
| 490 ResolutionWorldBuilderImpl(Backend backend, Resolution resolution, | 487 ResolutionWorldBuilderImpl(Backend backend, Resolution resolution, |
| 491 CacheStrategy cacheStrategy, this.selectorConstraintsStrategy) | 488 CacheStrategy cacheStrategy, this.selectorConstraintsStrategy) |
| 492 : this._backend = backend, | 489 : this._backend = backend, |
| 493 this._resolution = resolution, | 490 this._resolution = resolution, |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 674 } | 671 } |
| 675 | 672 |
| 676 bool hasInvokedSetter(Element member) { | 673 bool hasInvokedSetter(Element member) { |
| 677 return _hasMatchingSelector(_invokedSetters[member.name], member); | 674 return _hasMatchingSelector(_invokedSetters[member.name], member); |
| 678 } | 675 } |
| 679 | 676 |
| 680 void registerDynamicUse( | 677 void registerDynamicUse( |
| 681 DynamicUse dynamicUse, MemberUsedCallback memberUsed) { | 678 DynamicUse dynamicUse, MemberUsedCallback memberUsed) { |
| 682 Selector selector = dynamicUse.selector; | 679 Selector selector = dynamicUse.selector; |
| 683 String methodName = selector.name; | 680 String methodName = selector.name; |
| 681 | |
| 682 void _process(Map<String, Set<_MemberUsage>> memberMap, | |
| 683 EnumSet<MemberUse> action(_MemberUsage usage)) { | |
| 684 _processSet(memberMap, methodName, (_MemberUsage usage) { | |
| 685 if (dynamicUse.appliesUnnamed(usage.entity, this)) { | |
| 686 memberUsed(usage.entity, action(usage)); | |
| 687 return true; | |
| 688 } | |
| 689 return false; | |
| 690 }); | |
| 691 } | |
| 692 | |
| 684 switch (dynamicUse.kind) { | 693 switch (dynamicUse.kind) { |
| 685 case DynamicUseKind.INVOKE: | 694 case DynamicUseKind.INVOKE: |
| 686 if (_registerNewSelector(dynamicUse, _invokedNames)) { | 695 if (_registerNewSelector(dynamicUse, _invokedNames)) { |
| 687 _processInstanceMembers(methodName, (_MemberUsage usage) { | 696 _process(_instanceMembersByName, (m) => m.invoke()); |
| 688 if (dynamicUse.appliesUnnamed(usage.entity, this)) { | |
| 689 memberUsed(usage.entity, usage.invoke()); | |
| 690 return true; | |
| 691 } | |
| 692 return false; | |
| 693 }); | |
| 694 } | 697 } |
| 695 break; | 698 break; |
| 696 case DynamicUseKind.GET: | 699 case DynamicUseKind.GET: |
| 697 if (_registerNewSelector(dynamicUse, _invokedGetters)) { | 700 if (_registerNewSelector(dynamicUse, _invokedGetters)) { |
| 698 _processInstanceMembers(methodName, (_MemberUsage usage) { | 701 _process(_instanceMembersByName, (m) => m.read()); |
| 699 if (dynamicUse.appliesUnnamed(usage.entity, this)) { | 702 _process(_instanceFunctionsByName, (m) => m.read()); |
| 700 memberUsed(usage.entity, usage.read()); | |
| 701 return true; | |
| 702 } | |
| 703 return false; | |
| 704 }); | |
| 705 _processInstanceFunctions(methodName, (_MemberUsage usage) { | |
| 706 if (dynamicUse.appliesUnnamed(usage.entity, this)) { | |
| 707 memberUsed(usage.entity, usage.read()); | |
| 708 return true; | |
| 709 } | |
| 710 return false; | |
| 711 }); | |
| 712 } | 703 } |
| 713 break; | 704 break; |
| 714 case DynamicUseKind.SET: | 705 case DynamicUseKind.SET: |
| 715 if (_registerNewSelector(dynamicUse, _invokedSetters)) { | 706 if (_registerNewSelector(dynamicUse, _invokedSetters)) { |
| 716 _processInstanceMembers(methodName, (_MemberUsage usage) { | 707 _process(_instanceMembersByName, (m) => m.write()); |
| 717 if (dynamicUse.appliesUnnamed(usage.entity, this)) { | |
| 718 memberUsed(usage.entity, usage.write()); | |
| 719 return true; | |
| 720 } | |
| 721 return false; | |
| 722 }); | |
| 723 } | 708 } |
| 724 break; | 709 break; |
| 725 } | 710 } |
| 726 } | 711 } |
| 727 | 712 |
| 728 bool _registerNewSelector(DynamicUse dynamicUse, | 713 bool _registerNewSelector(DynamicUse dynamicUse, |
| 729 Map<String, Map<Selector, SelectorConstraints>> selectorMap) { | 714 Map<String, Map<Selector, SelectorConstraints>> selectorMap) { |
| 730 Selector selector = dynamicUse.selector; | 715 Selector selector = dynamicUse.selector; |
| 731 String name = selector.name; | 716 String name = selector.name; |
| 732 ReceiverConstraint mask = dynamicUse.mask; | 717 ReceiverConstraint mask = dynamicUse.mask; |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 887 // so we create a new list for [: map[memberName] :] and prepend the | 872 // so we create a new list for [: map[memberName] :] and prepend the |
| 888 // [remaining] members after the loop. | 873 // [remaining] members after the loop. |
| 889 map[memberName] = new Set<_MemberUsage>(); | 874 map[memberName] = new Set<_MemberUsage>(); |
| 890 Set<_MemberUsage> remaining = new Set<_MemberUsage>(); | 875 Set<_MemberUsage> remaining = new Set<_MemberUsage>(); |
| 891 for (_MemberUsage usage in members) { | 876 for (_MemberUsage usage in members) { |
| 892 if (!updateUsage(usage)) remaining.add(usage); | 877 if (!updateUsage(usage)) remaining.add(usage); |
| 893 } | 878 } |
| 894 map[memberName].addAll(remaining); | 879 map[memberName].addAll(remaining); |
| 895 } | 880 } |
| 896 | 881 |
| 897 void _processInstanceMembers(String name, bool updateUsage(_MemberUsage e)) { | |
| 898 _processSet(_instanceMembersByName, name, updateUsage); | |
| 899 } | |
| 900 | |
| 901 void _processInstanceFunctions( | |
| 902 String name, bool updateUsage(_MemberUsage e)) { | |
| 903 _processSet(_instanceFunctionsByName, name, updateUsage); | |
| 904 } | |
| 905 | |
| 906 void _processInstantiatedClassMember( | 882 void _processInstantiatedClassMember( |
| 907 ClassElement cls, MemberElement member, MemberUsedCallback memberUsed) { | 883 ClassElement cls, MemberElement member, MemberUsedCallback memberUsed) { |
| 908 assert(invariant(member, member.isDeclaration)); | 884 assert(invariant(member, member.isDeclaration)); |
| 909 if (!member.isInstanceMember) return; | 885 if (!member.isInstanceMember) return; |
| 910 String memberName = member.name; | 886 String memberName = member.name; |
| 911 member.computeType(_resolution); | 887 member.computeType(_resolution); |
| 912 // The obvious thing to test here would be "member.isNative", | 888 // The obvious thing to test here would be "member.isNative", |
| 913 // however, that only works after metadata has been parsed/analyzed, | 889 // however, that only works after metadata has been parsed/analyzed, |
| 914 // and that may not have happened yet. | 890 // and that may not have happened yet. |
| 915 // So instead we use the enclosing class, which we know have had | 891 // So instead we use the enclosing class, which we know have had |
| (...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1313 } | 1289 } |
| 1314 | 1290 |
| 1315 bool hasInvokedSetter(Element member, ClosedWorld world) { | 1291 bool hasInvokedSetter(Element member, ClosedWorld world) { |
| 1316 return _hasMatchingSelector(_invokedSetters[member.name], member, world); | 1292 return _hasMatchingSelector(_invokedSetters[member.name], member, world); |
| 1317 } | 1293 } |
| 1318 | 1294 |
| 1319 bool registerDynamicUse( | 1295 bool registerDynamicUse( |
| 1320 DynamicUse dynamicUse, MemberUsedCallback memberUsed) { | 1296 DynamicUse dynamicUse, MemberUsedCallback memberUsed) { |
| 1321 Selector selector = dynamicUse.selector; | 1297 Selector selector = dynamicUse.selector; |
| 1322 String methodName = selector.name; | 1298 String methodName = selector.name; |
| 1299 | |
| 1300 void _process(Map<String, Set<_MemberUsage>> memberMap, | |
| 1301 EnumSet<MemberUse> action(_MemberUsage usage)) { | |
| 1302 _processSet(memberMap, methodName, (_MemberUsage usage) { | |
| 1303 if (dynamicUse.appliesUnnamed(usage.entity, _world)) { | |
| 1304 memberUsed(usage.entity, action(usage)); | |
| 1305 return true; | |
| 1306 } | |
| 1307 return false; | |
| 1308 }); | |
| 1309 } | |
| 1310 | |
| 1323 switch (dynamicUse.kind) { | 1311 switch (dynamicUse.kind) { |
| 1324 case DynamicUseKind.INVOKE: | 1312 case DynamicUseKind.INVOKE: |
| 1325 if (_registerNewSelector(dynamicUse, _invokedNames)) { | 1313 if (_registerNewSelector(dynamicUse, _invokedNames)) { |
| 1326 _processInstanceMembers(methodName, (_MemberUsage member) { | 1314 _process(_instanceMembersByName, (m) => m.invoke()); |
| 1327 if (dynamicUse.appliesUnnamed(member.entity, _world)) { | |
| 1328 memberUsed(member.entity, member.invoke()); | |
| 1329 return true; | |
| 1330 } | |
| 1331 return false; | |
| 1332 }); | |
| 1333 return true; | 1315 return true; |
| 1334 } | 1316 } |
| 1335 break; | 1317 break; |
| 1336 case DynamicUseKind.GET: | 1318 case DynamicUseKind.GET: |
| 1337 if (_registerNewSelector(dynamicUse, _invokedGetters)) { | 1319 if (_registerNewSelector(dynamicUse, _invokedGetters)) { |
| 1338 _processInstanceMembers(methodName, (_MemberUsage member) { | 1320 _process(_instanceMembersByName, (m) => m.read()); |
| 1339 if (dynamicUse.appliesUnnamed(member.entity, _world)) { | 1321 _process(_instanceFunctionsByName, (m) => m.read()); |
| 1340 memberUsed(member.entity, member.read()); | |
| 1341 return true; | |
| 1342 } | |
| 1343 return false; | |
| 1344 }); | |
| 1345 _processInstanceFunctions(methodName, (_MemberUsage member) { | |
| 1346 if (dynamicUse.appliesUnnamed(member.entity, _world)) { | |
| 1347 memberUsed(member.entity, member.read()); | |
| 1348 return true; | |
| 1349 } | |
| 1350 return false; | |
| 1351 }); | |
| 1352 return true; | 1322 return true; |
| 1353 } | 1323 } |
| 1354 break; | 1324 break; |
| 1355 case DynamicUseKind.SET: | 1325 case DynamicUseKind.SET: |
| 1356 if (_registerNewSelector(dynamicUse, _invokedSetters)) { | 1326 if (_registerNewSelector(dynamicUse, _invokedSetters)) { |
| 1357 _processInstanceMembers(methodName, (_MemberUsage member) { | 1327 _process(_instanceMembersByName, (m) => m.write()); |
| 1358 if (dynamicUse.appliesUnnamed(member.entity, _world)) { | |
| 1359 memberUsed(member.entity, member.write()); | |
| 1360 return true; | |
| 1361 } | |
| 1362 return false; | |
| 1363 }); | |
| 1364 return true; | 1328 return true; |
| 1365 } | 1329 } |
| 1366 break; | 1330 break; |
| 1367 } | 1331 } |
| 1368 return false; | 1332 return false; |
| 1369 } | 1333 } |
| 1370 | 1334 |
| 1371 bool _registerNewSelector(DynamicUse dynamicUse, | 1335 bool _registerNewSelector(DynamicUse dynamicUse, |
| 1372 Map<String, Map<Selector, SelectorConstraints>> selectorMap) { | 1336 Map<String, Map<Selector, SelectorConstraints>> selectorMap) { |
| 1373 Selector selector = dynamicUse.selector; | 1337 Selector selector = dynamicUse.selector; |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1571 // so we create a new list for [: map[memberName] :] and prepend the | 1535 // so we create a new list for [: map[memberName] :] and prepend the |
| 1572 // [remaining] members after the loop. | 1536 // [remaining] members after the loop. |
| 1573 map[memberName] = new Set<_MemberUsage>(); | 1537 map[memberName] = new Set<_MemberUsage>(); |
| 1574 Set<_MemberUsage> remaining = new Set<_MemberUsage>(); | 1538 Set<_MemberUsage> remaining = new Set<_MemberUsage>(); |
| 1575 for (_MemberUsage member in members) { | 1539 for (_MemberUsage member in members) { |
| 1576 if (!f(member)) remaining.add(member); | 1540 if (!f(member)) remaining.add(member); |
| 1577 } | 1541 } |
| 1578 map[memberName].addAll(remaining); | 1542 map[memberName].addAll(remaining); |
| 1579 } | 1543 } |
| 1580 | 1544 |
| 1581 void _processInstanceMembers(String n, bool f(_MemberUsage e)) { | |
| 1582 _processSet(_instanceMembersByName, n, f); | |
| 1583 } | |
| 1584 | |
| 1585 void _processInstanceFunctions(String n, bool f(_MemberUsage e)) { | |
| 1586 _processSet(_instanceFunctionsByName, n, f); | |
| 1587 } | |
| 1588 | |
| 1589 /// Return the canonical [_ClassUsage] for [cls]. | 1545 /// Return the canonical [_ClassUsage] for [cls]. |
| 1590 _ClassUsage _getClassUsage(ClassElement cls) { | 1546 _ClassUsage _getClassUsage(ClassElement cls) { |
| 1591 return _processedClasses.putIfAbsent(cls, () => new _ClassUsage(cls)); | 1547 return _processedClasses.putIfAbsent(cls, () => new _ClassUsage(cls)); |
| 1592 } | 1548 } |
| 1593 | 1549 |
| 1594 void _processInstantiatedClass( | 1550 void _processInstantiatedClass( |
| 1595 ClassElement cls, ClassUsedCallback classUsed) { | 1551 ClassElement cls, ClassUsedCallback classUsed) { |
| 1596 // Registers [superclass] as instantiated. Returns `true` if it wasn't | 1552 // Registers [superclass] as instantiated. Returns `true` if it wasn't |
| 1597 // already instantiated and we therefore have to process its superclass as | 1553 // already instantiated and we therefore have to process its superclass as |
| 1598 // well. | 1554 // well. |
| (...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1983 @override | 1939 @override |
| 1984 EnumSet<MemberUse> get _originalUse => MemberUses.ALL_STATIC; | 1940 EnumSet<MemberUse> get _originalUse => MemberUses.ALL_STATIC; |
| 1985 } | 1941 } |
| 1986 | 1942 |
| 1987 void removeFromSet(Map<String, Set<_MemberUsage>> map, Element element) { | 1943 void removeFromSet(Map<String, Set<_MemberUsage>> map, Element element) { |
| 1988 Set<_MemberUsage> set = map[element.name]; | 1944 Set<_MemberUsage> set = map[element.name]; |
| 1989 if (set == null) return; | 1945 if (set == null) return; |
| 1990 set.removeAll( | 1946 set.removeAll( |
| 1991 set.where((_MemberUsage usage) => usage.entity == element).toList()); | 1947 set.where((_MemberUsage usage) => usage.entity == element).toList()); |
| 1992 } | 1948 } |
| OLD | NEW |