| OLD | NEW |
| 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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 dart2js.js_model.elements; | 5 library dart2js.js_model.elements; |
| 6 | 6 |
| 7 import '../common_elements.dart'; | |
| 8 import '../constants/constant_system.dart'; | |
| 9 import '../elements/elements.dart'; | |
| 10 import '../elements/entities.dart'; | 7 import '../elements/entities.dart'; |
| 11 import '../elements/names.dart'; | 8 import '../elements/names.dart'; |
| 12 import '../elements/types.dart'; | 9 import '../elements/types.dart'; |
| 13 import '../js_backend/backend_usage.dart'; | |
| 14 import '../js_backend/interceptor_data.dart'; | |
| 15 import '../js_backend/native_data.dart'; | |
| 16 import '../js_backend/runtime_types.dart'; | |
| 17 import '../kernel/elements.dart'; | 10 import '../kernel/elements.dart'; |
| 18 import '../kernel/element_map_impl.dart'; | 11 import '../kernel/element_map_impl.dart'; |
| 19 import '../native/behavior.dart'; | |
| 20 import '../universe/class_set.dart'; | |
| 21 import '../world.dart'; | |
| 22 | 12 |
| 23 /// Bidirectional map between 'frontend' and 'backend' elements. | 13 /// Map from 'frontend' to 'backend' elements. |
| 24 /// | 14 /// |
| 25 /// Frontend elements are what we read in, these typically represents concepts | 15 /// Frontend elements are what we read in, these typically represents concepts |
| 26 /// in Dart. Backend elements are what we generate, these may include elements | 16 /// in Dart. Backend elements are what we generate, these may include elements |
| 27 /// that do not correspond to a Dart concept, such as closure classes. | 17 /// that do not correspond to a Dart concept, such as closure classes. |
| 28 /// | 18 /// |
| 29 /// Querying for the frontend element for a backend-only element throws an | 19 /// Querying for the frontend element for a backend-only element throws an |
| 30 /// exception. | 20 /// exception. |
| 31 class JsToFrontendMap { | 21 class JsToFrontendMap { |
| 32 LibraryEntity toBackendLibrary(LibraryEntity library) => library; | 22 LibraryEntity toBackendLibrary(LibraryEntity library) => library; |
| 33 LibraryEntity toFrontendLibrary(LibraryEntity library) => library; | |
| 34 | 23 |
| 35 ClassEntity toBackendClass(ClassEntity cls) => cls; | 24 ClassEntity toBackendClass(ClassEntity cls) => cls; |
| 36 ClassEntity toFrontendClass(ClassEntity cls) => cls; | |
| 37 | 25 |
| 38 MemberEntity toBackendMember(MemberEntity member) => member; | 26 MemberEntity toBackendMember(MemberEntity member) => member; |
| 39 MemberEntity toFrontendMember(MemberEntity member) => member; | |
| 40 | 27 |
| 41 DartType toBackendType(DartType type) => type; | 28 DartType toBackendType(DartType type) => type; |
| 42 DartType toFrontendType(DartType type) => type; | 29 |
| 30 Set<LibraryEntity> toBackendLibrarySet(Iterable<LibraryEntity> set) { |
| 31 return set.map(toBackendLibrary).toSet(); |
| 32 } |
| 33 |
| 34 Set<ClassEntity> toBackendClassSet(Iterable<ClassEntity> set) { |
| 35 return set.map(toBackendClass).toSet(); |
| 36 } |
| 37 |
| 38 Set<MemberEntity> toBackendMemberSet(Iterable<MemberEntity> set) { |
| 39 return set.map(toBackendMember).toSet(); |
| 40 } |
| 41 |
| 42 Set<FunctionEntity> toBackendFunctionSet(Iterable<FunctionEntity> set) { |
| 43 Set<FunctionEntity> newSet = new Set<FunctionEntity>(); |
| 44 for (FunctionEntity element in set) { |
| 45 newSet.add(toBackendMember(element)); |
| 46 } |
| 47 return newSet; |
| 48 } |
| 49 |
| 50 Map<LibraryEntity, V> toBackendLibraryMap<V>( |
| 51 Map<LibraryEntity, V> map, V convert(V value)) { |
| 52 return convertMap(map, toBackendLibrary, convert); |
| 53 } |
| 54 |
| 55 Map<ClassEntity, V> toBackendClassMap<V>( |
| 56 Map<ClassEntity, V> map, V convert(V value)) { |
| 57 return convertMap(map, toBackendClass, convert); |
| 58 } |
| 59 |
| 60 Map<MemberEntity, V> toBackendMemberMap<V>( |
| 61 Map<MemberEntity, V> map, V convert(V value)) { |
| 62 return convertMap(map, toBackendMember, convert); |
| 63 } |
| 43 } | 64 } |
| 44 | 65 |
| 45 abstract class JsToFrontendMapBase implements JsToFrontendMap { | 66 E identity<E>(E element) => element; |
| 67 |
| 68 Map<K, V> convertMap<K, V>( |
| 69 Map<K, V> map, K convertKey(K key), V convertValue(V value)) { |
| 70 Map<K, V> newMap = <K, V>{}; |
| 71 map.forEach((K key, V value) { |
| 72 newMap[convertKey(key)] = convertValue(value); |
| 73 }); |
| 74 return newMap; |
| 75 } |
| 76 |
| 77 abstract class JsToFrontendMapBase extends JsToFrontendMap { |
| 46 DartType toBackendType(DartType type) => | 78 DartType toBackendType(DartType type) => |
| 47 const TypeConverter().visit(type, _toBackendEntity); | 79 const TypeConverter().visit(type, _toBackendEntity); |
| 48 DartType toFrontendType(DartType type) => | |
| 49 const TypeConverter().visit(type, _toFrontendEntity); | |
| 50 | 80 |
| 51 Entity _toBackendEntity(Entity entity) { | 81 Entity _toBackendEntity(Entity entity) { |
| 52 if (entity is ClassEntity) return toBackendClass(entity); | 82 if (entity is ClassEntity) return toBackendClass(entity); |
| 53 assert(entity is TypeVariableEntity); | 83 assert(entity is TypeVariableEntity); |
| 54 return toBackendTypeVariable(entity); | 84 return toBackendTypeVariable(entity); |
| 55 } | 85 } |
| 56 | 86 |
| 57 Entity _toFrontendEntity(Entity entity) { | |
| 58 if (entity is ClassEntity) return toFrontendClass(entity); | |
| 59 assert(entity is TypeVariableEntity); | |
| 60 TypeVariableEntity typeVariable = toFrontendTypeVariable(entity); | |
| 61 assert(typeVariable != null, "No front end type variable for $entity"); | |
| 62 return typeVariable; | |
| 63 } | |
| 64 | |
| 65 TypeVariableEntity toBackendTypeVariable(TypeVariableEntity typeVariable); | 87 TypeVariableEntity toBackendTypeVariable(TypeVariableEntity typeVariable); |
| 66 TypeVariableEntity toFrontendTypeVariable(TypeVariableEntity typeVariable); | |
| 67 } | 88 } |
| 68 | 89 |
| 69 // TODO(johnniwinther): Merge this with [JsKernelToElementMap]. | 90 // TODO(johnniwinther): Merge this with [JsKernelToElementMap]. |
| 70 class JsElementCreatorMixin { | 91 class JsElementCreatorMixin { |
| 71 IndexedLibrary createLibrary( | 92 IndexedLibrary createLibrary( |
| 72 int libraryIndex, String name, Uri canonicalUri) { | 93 int libraryIndex, String name, Uri canonicalUri) { |
| 73 return new JLibrary(libraryIndex, name, canonicalUri); | 94 return new JLibrary(libraryIndex, name, canonicalUri); |
| 74 } | 95 } |
| 75 | 96 |
| 76 IndexedClass createClass(LibraryEntity library, int classIndex, String name, | 97 IndexedClass createClass(LibraryEntity library, int classIndex, String name, |
| (...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 527 final MemberEntity memberContext; | 548 final MemberEntity memberContext; |
| 528 final Entity executableContext; | 549 final Entity executableContext; |
| 529 final FunctionType functionType; | 550 final FunctionType functionType; |
| 530 | 551 |
| 531 JLocalFunction( | 552 JLocalFunction( |
| 532 this.name, this.memberContext, this.executableContext, this.functionType); | 553 this.name, this.memberContext, this.executableContext, this.functionType); |
| 533 | 554 |
| 534 String toString() => '${jsElementPrefix}local_function' | 555 String toString() => '${jsElementPrefix}local_function' |
| 535 '(${memberContext.name}.${name ?? '<anonymous>'})'; | 556 '(${memberContext.name}.${name ?? '<anonymous>'})'; |
| 536 } | 557 } |
| 537 | |
| 538 class JsClosedWorld extends ClosedWorldBase with KernelClosedWorldMixin { | |
| 539 final JsKernelToElementMap elementMap; | |
| 540 final RuntimeTypesNeed rtiNeed; | |
| 541 | |
| 542 JsClosedWorld(this.elementMap, | |
| 543 {ElementEnvironment elementEnvironment, | |
| 544 DartTypes dartTypes, | |
| 545 CommonElements commonElements, | |
| 546 ConstantSystem constantSystem, | |
| 547 NativeData nativeData, | |
| 548 InterceptorData interceptorData, | |
| 549 BackendUsage backendUsage, | |
| 550 this.rtiNeed, | |
| 551 Set<ClassEntity> implementedClasses, | |
| 552 Iterable<ClassEntity> liveNativeClasses, | |
| 553 Iterable<MemberEntity> liveInstanceMembers, | |
| 554 Iterable<MemberEntity> assignedInstanceMembers, | |
| 555 Set<TypedefElement> allTypedefs, | |
| 556 Map<ClassEntity, Set<ClassEntity>> mixinUses, | |
| 557 Map<ClassEntity, Set<ClassEntity>> typesImplementedBySubclasses, | |
| 558 Map<ClassEntity, ClassHierarchyNode> classHierarchyNodes, | |
| 559 Map<ClassEntity, ClassSet> classSets}) | |
| 560 : super( | |
| 561 elementEnvironment, | |
| 562 dartTypes, | |
| 563 commonElements, | |
| 564 constantSystem, | |
| 565 nativeData, | |
| 566 interceptorData, | |
| 567 backendUsage, | |
| 568 implementedClasses, | |
| 569 liveNativeClasses, | |
| 570 liveInstanceMembers, | |
| 571 assignedInstanceMembers, | |
| 572 allTypedefs, | |
| 573 mixinUses, | |
| 574 typesImplementedBySubclasses, | |
| 575 classHierarchyNodes, | |
| 576 classSets); | |
| 577 | |
| 578 @override | |
| 579 void registerClosureClass(ClassElement cls) { | |
| 580 throw new UnimplementedError('JsClosedWorld.registerClosureClass'); | |
| 581 } | |
| 582 } | |
| 583 | |
| 584 class JsNativeData implements NativeData { | |
| 585 final JsToFrontendMap _map; | |
| 586 final NativeData _nativeData; | |
| 587 | |
| 588 JsNativeData(this._map, this._nativeData); | |
| 589 | |
| 590 @override | |
| 591 bool isNativeClass(ClassEntity element) { | |
| 592 return _nativeData.isNativeClass(_map.toFrontendClass(element)); | |
| 593 } | |
| 594 | |
| 595 @override | |
| 596 String computeUnescapedJSInteropName(String name) { | |
| 597 return _nativeData.computeUnescapedJSInteropName(name); | |
| 598 } | |
| 599 | |
| 600 @override | |
| 601 String getJsInteropMemberName(MemberEntity element) { | |
| 602 return _nativeData.getJsInteropMemberName(_map.toFrontendMember(element)); | |
| 603 } | |
| 604 | |
| 605 @override | |
| 606 String getJsInteropClassName(ClassEntity element) { | |
| 607 return _nativeData.getJsInteropClassName(_map.toFrontendClass(element)); | |
| 608 } | |
| 609 | |
| 610 @override | |
| 611 bool isAnonymousJsInteropClass(ClassEntity element) { | |
| 612 return _nativeData.isAnonymousJsInteropClass(_map.toFrontendClass(element)); | |
| 613 } | |
| 614 | |
| 615 @override | |
| 616 String getJsInteropLibraryName(LibraryEntity element) { | |
| 617 return _nativeData.getJsInteropLibraryName(_map.toFrontendLibrary(element)); | |
| 618 } | |
| 619 | |
| 620 @override | |
| 621 bool isJsInteropMember(MemberEntity element) { | |
| 622 return _nativeData.isJsInteropMember(_map.toFrontendMember(element)); | |
| 623 } | |
| 624 | |
| 625 @override | |
| 626 String getFixedBackendMethodPath(FunctionEntity element) { | |
| 627 return _nativeData | |
| 628 .getFixedBackendMethodPath(_map.toFrontendMember(element)); | |
| 629 } | |
| 630 | |
| 631 @override | |
| 632 String getFixedBackendName(MemberEntity element) { | |
| 633 return _nativeData.getFixedBackendName(_map.toFrontendMember(element)); | |
| 634 } | |
| 635 | |
| 636 @override | |
| 637 bool hasFixedBackendName(MemberEntity element) { | |
| 638 return _nativeData.hasFixedBackendName(_map.toFrontendMember(element)); | |
| 639 } | |
| 640 | |
| 641 @override | |
| 642 NativeBehavior getNativeFieldStoreBehavior(FieldEntity field) { | |
| 643 return _nativeData | |
| 644 .getNativeFieldStoreBehavior(_map.toFrontendMember(field)); | |
| 645 } | |
| 646 | |
| 647 @override | |
| 648 NativeBehavior getNativeFieldLoadBehavior(FieldEntity field) { | |
| 649 return _nativeData.getNativeFieldLoadBehavior(_map.toFrontendMember(field)); | |
| 650 } | |
| 651 | |
| 652 @override | |
| 653 NativeBehavior getNativeMethodBehavior(FunctionEntity method) { | |
| 654 return _nativeData.getNativeMethodBehavior(_map.toFrontendMember(method)); | |
| 655 } | |
| 656 | |
| 657 @override | |
| 658 bool isNativeMember(MemberEntity element) { | |
| 659 return _nativeData.isNativeMember(_map.toFrontendMember(element)); | |
| 660 } | |
| 661 | |
| 662 @override | |
| 663 bool isJsInteropClass(ClassEntity element) { | |
| 664 return _nativeData.isJsInteropClass(_map.toFrontendClass(element)); | |
| 665 } | |
| 666 | |
| 667 @override | |
| 668 bool isJsInteropLibrary(LibraryEntity element) { | |
| 669 return _nativeData.isJsInteropLibrary(_map.toFrontendLibrary(element)); | |
| 670 } | |
| 671 | |
| 672 @override | |
| 673 bool get isJsInteropUsed { | |
| 674 return _nativeData.isJsInteropUsed; | |
| 675 } | |
| 676 | |
| 677 @override | |
| 678 bool isNativeOrExtendsNative(ClassEntity element) { | |
| 679 return _nativeData.isNativeOrExtendsNative(_map.toFrontendClass(element)); | |
| 680 } | |
| 681 | |
| 682 @override | |
| 683 bool hasNativeTagsForcedNonLeaf(ClassEntity cls) { | |
| 684 return _nativeData.hasNativeTagsForcedNonLeaf(_map.toFrontendClass(cls)); | |
| 685 } | |
| 686 | |
| 687 @override | |
| 688 List<String> getNativeTagsOfClass(ClassEntity cls) { | |
| 689 return _nativeData.getNativeTagsOfClass(_map.toFrontendClass(cls)); | |
| 690 } | |
| 691 } | |
| 692 | |
| 693 class JsBackendUsage implements BackendUsage { | |
| 694 final JsToFrontendMap _map; | |
| 695 final BackendUsage _backendUsage; | |
| 696 | |
| 697 @override | |
| 698 bool needToInitializeIsolateAffinityTag; | |
| 699 @override | |
| 700 bool needToInitializeDispatchProperty; | |
| 701 | |
| 702 JsBackendUsage(this._map, this._backendUsage) { | |
| 703 needToInitializeIsolateAffinityTag = | |
| 704 _backendUsage.needToInitializeIsolateAffinityTag; | |
| 705 needToInitializeDispatchProperty = | |
| 706 _backendUsage.needToInitializeDispatchProperty; | |
| 707 } | |
| 708 | |
| 709 @override | |
| 710 bool isFunctionUsedByBackend(FunctionEntity element) { | |
| 711 return _backendUsage | |
| 712 .isFunctionUsedByBackend(_map.toFrontendMember(element)); | |
| 713 } | |
| 714 | |
| 715 @override | |
| 716 bool isFieldUsedByBackend(FieldEntity element) { | |
| 717 return _backendUsage.isFieldUsedByBackend(_map.toFrontendMember(element)); | |
| 718 } | |
| 719 | |
| 720 @override | |
| 721 Iterable<FunctionEntity> get globalFunctionDependencies { | |
| 722 FunctionEntity f(FunctionEntity e) => _map.toBackendMember(e); | |
| 723 return _backendUsage.globalFunctionDependencies.map(f); | |
| 724 } | |
| 725 | |
| 726 @override | |
| 727 Iterable<ClassEntity> get globalClassDependencies { | |
| 728 return _backendUsage.globalClassDependencies.map(_map.toBackendClass); | |
| 729 } | |
| 730 | |
| 731 @override | |
| 732 bool get requiresPreamble => _backendUsage.requiresPreamble; | |
| 733 | |
| 734 @override | |
| 735 bool get isInvokeOnUsed => _backendUsage.isInvokeOnUsed; | |
| 736 | |
| 737 @override | |
| 738 bool get isRuntimeTypeUsed => _backendUsage.isRuntimeTypeUsed; | |
| 739 | |
| 740 @override | |
| 741 bool get isIsolateInUse => _backendUsage.isIsolateInUse; | |
| 742 | |
| 743 @override | |
| 744 bool get isFunctionApplyUsed => _backendUsage.isFunctionApplyUsed; | |
| 745 | |
| 746 @override | |
| 747 bool get isMirrorsUsed => _backendUsage.isMirrorsUsed; | |
| 748 | |
| 749 @override | |
| 750 bool get isNoSuchMethodUsed => _backendUsage.isNoSuchMethodUsed; | |
| 751 } | |
| OLD | NEW |