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.kernel.element_map; | 5 library dart2js.kernel.element_map; |
6 | 6 |
7 import 'package:kernel/ast.dart' as ir; | 7 import 'package:kernel/ast.dart' as ir; |
8 | 8 |
9 import '../common.dart'; | 9 import '../common.dart'; |
10 import '../common/names.dart' show Identifiers; | 10 import '../common/names.dart' show Identifiers; |
(...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
507 ir.Member _getMemberNode(covariant IndexedMember member) { | 507 ir.Member _getMemberNode(covariant IndexedMember member) { |
508 return _memberData[member.memberIndex].node; | 508 return _memberData[member.memberIndex].node; |
509 } | 509 } |
510 | 510 |
511 ir.Class _getClassNode(covariant IndexedClass cls) { | 511 ir.Class _getClassNode(covariant IndexedClass cls) { |
512 return _classEnvs[cls.classIndex].cls; | 512 return _classEnvs[cls.classIndex].cls; |
513 } | 513 } |
514 } | 514 } |
515 | 515 |
516 /// Mixin that implements the abstract methods in [KernelToElementMapBase] by | 516 /// Mixin that implements the abstract methods in [KernelToElementMapBase] by |
517 /// creating K-model elements. | 517 /// creating K-model elements. |
Siggi Cherem (dart-lang)
2017/07/05 20:13:37
update doc:
- this one is basically implementing
Johnni Winther
2017/07/06 13:30:40
Done.
| |
518 abstract class KElementCreatorMixin { | 518 abstract class ElementCreatorMixin { |
519 ProgramEnv get _env; | 519 ProgramEnv get _env; |
520 List<LibraryEntity> get _libraryList; | 520 List<LibraryEntity> get _libraryList; |
521 List<LibraryEnv> get _libraryEnvs; | 521 List<LibraryEnv> get _libraryEnvs; |
522 List<ClassEntity> get _classList; | 522 List<ClassEntity> get _classList; |
523 List<ClassEnv> get _classEnvs; | 523 List<ClassEnv> get _classEnvs; |
524 List<MemberEntity> get _memberList; | 524 List<MemberEntity> get _memberList; |
525 List<MemberData> get _memberData; | 525 List<MemberData> get _memberData; |
526 | 526 |
527 Map<ir.Library, KLibrary> _libraryMap = <ir.Library, KLibrary>{}; | 527 Map<ir.Library, IndexedLibrary> _libraryMap = <ir.Library, IndexedLibrary>{}; |
528 Map<ir.Class, KClass> _classMap = <ir.Class, KClass>{}; | 528 Map<ir.Class, IndexedClass> _classMap = <ir.Class, IndexedClass>{}; |
529 Map<ir.TypeParameter, KTypeVariable> _typeVariableMap = | 529 Map<ir.TypeParameter, TypeVariableEntity> _typeVariableMap = |
530 <ir.TypeParameter, KTypeVariable>{}; | 530 <ir.TypeParameter, TypeVariableEntity>{}; |
531 Map<ir.Member, KConstructor> _constructorMap = <ir.Member, KConstructor>{}; | 531 Map<ir.Member, IndexedConstructor> _constructorMap = |
532 Map<ir.Procedure, KFunction> _methodMap = <ir.Procedure, KFunction>{}; | 532 <ir.Member, IndexedConstructor>{}; |
533 Map<ir.Field, KField> _fieldMap = <ir.Field, KField>{}; | 533 Map<ir.Procedure, IndexedFunction> _methodMap = |
534 Map<ir.TreeNode, KLocalFunction> _localFunctionMap = | 534 <ir.Procedure, IndexedFunction>{}; |
535 <ir.TreeNode, KLocalFunction>{}; | 535 Map<ir.Field, IndexedField> _fieldMap = <ir.Field, IndexedField>{}; |
536 Map<ir.TreeNode, Local> _localFunctionMap = <ir.TreeNode, Local>{}; | |
536 | 537 |
537 Name getName(ir.Name node); | 538 Name getName(ir.Name node); |
538 FunctionType getFunctionType(ir.FunctionNode node); | 539 FunctionType getFunctionType(ir.FunctionNode node); |
539 MemberEntity getMember(ir.Member node); | 540 MemberEntity getMember(ir.Member node); |
540 | 541 |
541 Iterable<LibraryEntity> get _libraries { | 542 Iterable<LibraryEntity> get _libraries { |
542 if (_env.length != _libraryMap.length) { | 543 if (_env.length != _libraryMap.length) { |
543 // Create a [KLibrary] for each library. | 544 // Create a [KLibrary] for each library. |
544 _env.forEachLibrary((LibraryEnv env) { | 545 _env.forEachLibrary((LibraryEnv env) { |
545 _getLibrary(env.library, env); | 546 _getLibrary(env.library, env); |
546 }); | 547 }); |
547 } | 548 } |
548 return _libraryMap.values; | 549 return _libraryMap.values; |
549 } | 550 } |
550 | 551 |
551 LibraryEntity _getLibrary(ir.Library node, [LibraryEnv libraryEnv]) { | 552 LibraryEntity _getLibrary(ir.Library node, [LibraryEnv libraryEnv]) { |
552 return _libraryMap.putIfAbsent(node, () { | 553 return _libraryMap.putIfAbsent(node, () { |
553 Uri canonicalUri = node.importUri; | 554 Uri canonicalUri = node.importUri; |
554 _libraryEnvs.add(libraryEnv ?? _env.lookupLibrary(canonicalUri)); | 555 _libraryEnvs.add(libraryEnv ?? _env.lookupLibrary(canonicalUri)); |
555 String name = node.name; | 556 String name = node.name; |
556 if (name == null) { | 557 if (name == null) { |
557 // Use the file name as script name. | 558 // Use the file name as script name. |
558 String path = canonicalUri.path; | 559 String path = canonicalUri.path; |
559 name = path.substring(path.lastIndexOf('/') + 1); | 560 name = path.substring(path.lastIndexOf('/') + 1); |
560 } | 561 } |
561 LibraryEntity library = | 562 LibraryEntity library = |
562 new KLibrary(_libraryMap.length, name, canonicalUri); | 563 createLibrary(_libraryMap.length, name, canonicalUri); |
563 _libraryList.add(library); | 564 _libraryList.add(library); |
564 return library; | 565 return library; |
565 }); | 566 }); |
566 } | 567 } |
567 | 568 |
568 ClassEntity _getClass(ir.Class node, [ClassEnv classEnv]) { | 569 ClassEntity _getClass(ir.Class node, [ClassEnv classEnv]) { |
569 return _classMap.putIfAbsent(node, () { | 570 return _classMap.putIfAbsent(node, () { |
570 KLibrary library = _getLibrary(node.enclosingLibrary); | 571 KLibrary library = _getLibrary(node.enclosingLibrary); |
571 if (classEnv == null) { | 572 if (classEnv == null) { |
572 classEnv = _libraryEnvs[library.libraryIndex].lookupClass(node.name); | 573 classEnv = _libraryEnvs[library.libraryIndex].lookupClass(node.name); |
573 } | 574 } |
574 _classEnvs.add(classEnv); | 575 _classEnvs.add(classEnv); |
575 ClassEntity cls = new KClass(library, _classMap.length, node.name, | 576 ClassEntity cls = createClass(library, _classMap.length, node.name, |
576 isAbstract: node.isAbstract); | 577 isAbstract: node.isAbstract); |
577 _classList.add(cls); | 578 _classList.add(cls); |
578 return cls; | 579 return cls; |
579 }); | 580 }); |
580 } | 581 } |
581 | 582 |
582 TypeVariableEntity _getTypeVariable(ir.TypeParameter node) { | 583 TypeVariableEntity _getTypeVariable(ir.TypeParameter node) { |
583 return _typeVariableMap.putIfAbsent(node, () { | 584 return _typeVariableMap.putIfAbsent(node, () { |
584 if (node.parent is ir.Class) { | 585 if (node.parent is ir.Class) { |
585 ir.Class cls = node.parent; | 586 ir.Class cls = node.parent; |
586 int index = cls.typeParameters.indexOf(node); | 587 int index = cls.typeParameters.indexOf(node); |
587 return new KTypeVariable(_getClass(cls), node.name, index); | 588 return createTypeVariable(_getClass(cls), node.name, index); |
588 } | 589 } |
589 if (node.parent is ir.FunctionNode) { | 590 if (node.parent is ir.FunctionNode) { |
590 ir.FunctionNode func = node.parent; | 591 ir.FunctionNode func = node.parent; |
591 int index = func.typeParameters.indexOf(node); | 592 int index = func.typeParameters.indexOf(node); |
592 if (func.parent is ir.Constructor) { | 593 if (func.parent is ir.Constructor) { |
593 ir.Constructor constructor = func.parent; | 594 ir.Constructor constructor = func.parent; |
594 ir.Class cls = constructor.enclosingClass; | 595 ir.Class cls = constructor.enclosingClass; |
595 return _getTypeVariable(cls.typeParameters[index]); | 596 return _getTypeVariable(cls.typeParameters[index]); |
596 } | 597 } |
597 if (func.parent is ir.Procedure) { | 598 if (func.parent is ir.Procedure) { |
598 ir.Procedure procedure = func.parent; | 599 ir.Procedure procedure = func.parent; |
599 if (procedure.kind == ir.ProcedureKind.Factory) { | 600 if (procedure.kind == ir.ProcedureKind.Factory) { |
600 ir.Class cls = procedure.enclosingClass; | 601 ir.Class cls = procedure.enclosingClass; |
601 return _getTypeVariable(cls.typeParameters[index]); | 602 return _getTypeVariable(cls.typeParameters[index]); |
602 } else { | 603 } else { |
603 return new KTypeVariable(_getMethod(procedure), node.name, index); | 604 return createTypeVariable(_getMethod(procedure), node.name, index); |
604 } | 605 } |
605 } | 606 } |
606 } | 607 } |
607 throw new UnsupportedError('Unsupported type parameter type node $node.'); | 608 throw new UnsupportedError('Unsupported type parameter type node $node.'); |
608 }); | 609 }); |
609 } | 610 } |
610 | 611 |
611 ConstructorEntity _getConstructor(ir.Member node) { | 612 ConstructorEntity _getConstructor(ir.Member node) { |
612 return _constructorMap.putIfAbsent(node, () { | 613 return _constructorMap.putIfAbsent(node, () { |
613 int memberIndex = _memberData.length; | 614 int memberIndex = _memberData.length; |
614 KConstructor constructor; | 615 KConstructor constructor; |
615 KClass enclosingClass = _getClass(node.enclosingClass); | 616 KClass enclosingClass = _getClass(node.enclosingClass); |
616 Name name = getName(node.name); | 617 Name name = getName(node.name); |
617 bool isExternal = node.isExternal; | 618 bool isExternal = node.isExternal; |
618 | 619 |
619 ir.FunctionNode functionNode; | 620 ir.FunctionNode functionNode; |
620 if (node is ir.Constructor) { | 621 if (node is ir.Constructor) { |
621 functionNode = node.function; | 622 functionNode = node.function; |
622 constructor = new KGenerativeConstructor(memberIndex, enclosingClass, | 623 constructor = createGenerativeConstructor(memberIndex, enclosingClass, |
623 name, _getParameterStructure(functionNode), | 624 name, _getParameterStructure(functionNode), |
624 isExternal: isExternal, isConst: node.isConst); | 625 isExternal: isExternal, isConst: node.isConst); |
625 } else if (node is ir.Procedure) { | 626 } else if (node is ir.Procedure) { |
626 functionNode = node.function; | 627 functionNode = node.function; |
627 bool isFromEnvironment = isExternal && | 628 bool isFromEnvironment = isExternal && |
628 name.text == 'fromEnvironment' && | 629 name.text == 'fromEnvironment' && |
629 const ['int', 'bool', 'String'].contains(enclosingClass.name); | 630 const ['int', 'bool', 'String'].contains(enclosingClass.name); |
630 constructor = new KFactoryConstructor(memberIndex, enclosingClass, name, | 631 constructor = createFactoryConstructor(memberIndex, enclosingClass, |
631 _getParameterStructure(functionNode), | 632 name, _getParameterStructure(functionNode), |
632 isExternal: isExternal, | 633 isExternal: isExternal, |
633 isConst: node.isConst, | 634 isConst: node.isConst, |
634 isFromEnvironmentConstructor: isFromEnvironment); | 635 isFromEnvironmentConstructor: isFromEnvironment); |
635 } else { | 636 } else { |
636 // TODO(johnniwinther): Convert `node.location` to a [SourceSpan]. | 637 // TODO(johnniwinther): Convert `node.location` to a [SourceSpan]. |
637 throw new SpannableAssertionFailure( | 638 throw new SpannableAssertionFailure( |
638 NO_LOCATION_SPANNABLE, "Unexpected constructor node: ${node}."); | 639 NO_LOCATION_SPANNABLE, "Unexpected constructor node: ${node}."); |
639 } | 640 } |
640 _memberData.add(new ConstructorData(node, functionNode)); | 641 _memberData.add(new ConstructorData(node, functionNode)); |
641 _memberList.add(constructor); | 642 _memberList.add(constructor); |
642 return constructor; | 643 return constructor; |
643 }); | 644 }); |
644 } | 645 } |
645 | 646 |
646 FunctionEntity _getMethod(ir.Procedure node) { | 647 FunctionEntity _getMethod(ir.Procedure node) { |
647 return _methodMap.putIfAbsent(node, () { | 648 return _methodMap.putIfAbsent(node, () { |
648 int memberIndex = _memberData.length; | 649 int memberIndex = _memberData.length; |
649 LibraryEntity library; | 650 LibraryEntity library; |
650 ClassEntity enclosingClass; | 651 ClassEntity enclosingClass; |
651 if (node.enclosingClass != null) { | 652 if (node.enclosingClass != null) { |
652 enclosingClass = _getClass(node.enclosingClass); | 653 enclosingClass = _getClass(node.enclosingClass); |
653 library = enclosingClass.library; | 654 library = enclosingClass.library; |
654 } else { | 655 } else { |
655 library = _getLibrary(node.enclosingLibrary); | 656 library = _getLibrary(node.enclosingLibrary); |
656 } | 657 } |
657 Name name = getName(node.name); | 658 Name name = getName(node.name); |
658 bool isStatic = node.isStatic; | 659 bool isStatic = node.isStatic; |
659 bool isExternal = node.isExternal; | 660 bool isExternal = node.isExternal; |
660 bool isAbstract = node.isAbstract; | 661 bool isAbstract = node.isAbstract; |
661 KFunction function; | 662 IndexedFunction function; |
662 AsyncMarker asyncMarker; | 663 AsyncMarker asyncMarker; |
663 switch (node.function.asyncMarker) { | 664 switch (node.function.asyncMarker) { |
664 case ir.AsyncMarker.Async: | 665 case ir.AsyncMarker.Async: |
665 asyncMarker = AsyncMarker.ASYNC; | 666 asyncMarker = AsyncMarker.ASYNC; |
666 break; | 667 break; |
667 case ir.AsyncMarker.AsyncStar: | 668 case ir.AsyncMarker.AsyncStar: |
668 asyncMarker = AsyncMarker.ASYNC_STAR; | 669 asyncMarker = AsyncMarker.ASYNC_STAR; |
669 break; | 670 break; |
670 case ir.AsyncMarker.Sync: | 671 case ir.AsyncMarker.Sync: |
671 asyncMarker = AsyncMarker.SYNC; | 672 asyncMarker = AsyncMarker.SYNC; |
672 break; | 673 break; |
673 case ir.AsyncMarker.SyncStar: | 674 case ir.AsyncMarker.SyncStar: |
674 asyncMarker = AsyncMarker.SYNC_STAR; | 675 asyncMarker = AsyncMarker.SYNC_STAR; |
675 break; | 676 break; |
676 case ir.AsyncMarker.SyncYielding: | 677 case ir.AsyncMarker.SyncYielding: |
677 throw new UnsupportedError( | 678 throw new UnsupportedError( |
678 "Async marker ${node.function.asyncMarker} is not supported."); | 679 "Async marker ${node.function.asyncMarker} is not supported."); |
679 } | 680 } |
680 switch (node.kind) { | 681 switch (node.kind) { |
681 case ir.ProcedureKind.Factory: | 682 case ir.ProcedureKind.Factory: |
682 throw new UnsupportedError("Cannot create method from factory."); | 683 throw new UnsupportedError("Cannot create method from factory."); |
683 case ir.ProcedureKind.Getter: | 684 case ir.ProcedureKind.Getter: |
684 function = new KGetter( | 685 function = createGetter( |
685 memberIndex, library, enclosingClass, name, asyncMarker, | 686 memberIndex, library, enclosingClass, name, asyncMarker, |
686 isStatic: isStatic, | 687 isStatic: isStatic, |
687 isExternal: isExternal, | 688 isExternal: isExternal, |
688 isAbstract: isAbstract); | 689 isAbstract: isAbstract); |
689 break; | 690 break; |
690 case ir.ProcedureKind.Method: | 691 case ir.ProcedureKind.Method: |
691 case ir.ProcedureKind.Operator: | 692 case ir.ProcedureKind.Operator: |
692 function = new KMethod(memberIndex, library, enclosingClass, name, | 693 function = createMethod(memberIndex, library, enclosingClass, name, |
693 _getParameterStructure(node.function), asyncMarker, | 694 _getParameterStructure(node.function), asyncMarker, |
694 isStatic: isStatic, | 695 isStatic: isStatic, |
695 isExternal: isExternal, | 696 isExternal: isExternal, |
696 isAbstract: isAbstract); | 697 isAbstract: isAbstract); |
697 break; | 698 break; |
698 case ir.ProcedureKind.Setter: | 699 case ir.ProcedureKind.Setter: |
699 assert(asyncMarker == AsyncMarker.SYNC); | 700 assert(asyncMarker == AsyncMarker.SYNC); |
700 function = new KSetter( | 701 function = createSetter( |
701 memberIndex, library, enclosingClass, getName(node.name).setter, | 702 memberIndex, library, enclosingClass, name.setter, |
702 isStatic: isStatic, | 703 isStatic: isStatic, |
703 isExternal: isExternal, | 704 isExternal: isExternal, |
704 isAbstract: isAbstract); | 705 isAbstract: isAbstract); |
705 break; | 706 break; |
706 } | 707 } |
707 _memberData.add(new FunctionData(node, node.function)); | 708 _memberData.add(new FunctionData(node, node.function)); |
708 _memberList.add(function); | 709 _memberList.add(function); |
709 return function; | 710 return function; |
710 }); | 711 }); |
711 } | 712 } |
712 | 713 |
713 FieldEntity _getField(ir.Field node) { | 714 FieldEntity _getField(ir.Field node) { |
714 return _fieldMap.putIfAbsent(node, () { | 715 return _fieldMap.putIfAbsent(node, () { |
715 int memberIndex = _memberData.length; | 716 int memberIndex = _memberData.length; |
716 LibraryEntity library; | 717 LibraryEntity library; |
717 ClassEntity enclosingClass; | 718 ClassEntity enclosingClass; |
718 if (node.enclosingClass != null) { | 719 if (node.enclosingClass != null) { |
719 enclosingClass = _getClass(node.enclosingClass); | 720 enclosingClass = _getClass(node.enclosingClass); |
720 library = enclosingClass.library; | 721 library = enclosingClass.library; |
721 } else { | 722 } else { |
722 library = _getLibrary(node.enclosingLibrary); | 723 library = _getLibrary(node.enclosingLibrary); |
723 } | 724 } |
724 Name name = getName(node.name); | 725 Name name = getName(node.name); |
725 bool isStatic = node.isStatic; | 726 bool isStatic = node.isStatic; |
726 _memberData.add(new FieldData(node)); | 727 _memberData.add(new FieldData(node)); |
727 FieldEntity field = new KField(memberIndex, library, enclosingClass, name, | 728 FieldEntity field = createField( |
729 memberIndex, library, enclosingClass, name, | |
728 isStatic: isStatic, | 730 isStatic: isStatic, |
729 isAssignable: node.isMutable, | 731 isAssignable: node.isMutable, |
730 isConst: node.isConst); | 732 isConst: node.isConst); |
731 _memberList.add(field); | 733 _memberList.add(field); |
732 return field; | 734 return field; |
733 }); | 735 }); |
734 } | 736 } |
735 | 737 |
736 ParameterStructure _getParameterStructure(ir.FunctionNode node) { | 738 ParameterStructure _getParameterStructure(ir.FunctionNode node) { |
737 // TODO(johnniwinther): Cache the computed function type. | 739 // TODO(johnniwinther): Cache the computed function type. |
(...skipping 10 matching lines...) Expand all Loading... | |
748 MemberEntity memberContext; | 750 MemberEntity memberContext; |
749 Entity executableContext; | 751 Entity executableContext; |
750 ir.TreeNode parent = node.parent; | 752 ir.TreeNode parent = node.parent; |
751 while (parent != null) { | 753 while (parent != null) { |
752 if (parent is ir.Member) { | 754 if (parent is ir.Member) { |
753 executableContext = memberContext = getMember(parent); | 755 executableContext = memberContext = getMember(parent); |
754 break; | 756 break; |
755 } | 757 } |
756 if (parent is ir.FunctionDeclaration || | 758 if (parent is ir.FunctionDeclaration || |
757 parent is ir.FunctionExpression) { | 759 parent is ir.FunctionExpression) { |
758 KLocalFunction localFunction = _getLocalFunction(parent); | 760 Local localFunction = _getLocalFunction(parent); |
759 executableContext = localFunction; | 761 executableContext = localFunction; |
760 memberContext = localFunction.memberContext; | 762 memberContext = localFunction.memberContext; |
761 break; | 763 break; |
762 } | 764 } |
763 parent = parent.parent; | 765 parent = parent.parent; |
764 } | 766 } |
765 String name; | 767 String name; |
766 FunctionType functionType; | 768 FunctionType functionType; |
767 if (node is ir.FunctionDeclaration) { | 769 if (node is ir.FunctionDeclaration) { |
768 name = node.variable.name; | 770 name = node.variable.name; |
769 functionType = getFunctionType(node.function); | 771 functionType = getFunctionType(node.function); |
770 } else if (node is ir.FunctionExpression) { | 772 } else if (node is ir.FunctionExpression) { |
771 functionType = getFunctionType(node.function); | 773 functionType = getFunctionType(node.function); |
772 } | 774 } |
773 return new KLocalFunction( | 775 return createLocalFunction( |
774 name, memberContext, executableContext, functionType); | 776 name, memberContext, executableContext, functionType); |
775 }); | 777 }); |
776 } | 778 } |
779 | |
780 IndexedLibrary createLibrary(int libraryIndex, String name, Uri canonicalUri); | |
781 | |
782 IndexedClass createClass(LibraryEntity library, int classIndex, String name, | |
783 {bool isAbstract}); | |
784 | |
785 TypeVariableEntity createTypeVariable( | |
786 Entity typeDeclaration, String name, int index); | |
787 | |
788 IndexedConstructor createGenerativeConstructor( | |
789 int memberIndex, | |
790 ClassEntity enclosingClass, | |
791 Name name, | |
792 ParameterStructure parameterStructure, | |
793 {bool isExternal, | |
794 bool isConst}); | |
795 | |
796 IndexedConstructor createFactoryConstructor( | |
797 int memberIndex, | |
798 ClassEntity enclosingClass, | |
799 Name name, | |
800 ParameterStructure parameterStructure, | |
801 {bool isExternal, | |
802 bool isConst, | |
803 bool isFromEnvironmentConstructor}); | |
804 | |
805 IndexedFunction createGetter(int memberIndex, LibraryEntity library, | |
806 ClassEntity enclosingClass, Name name, AsyncMarker asyncMarker, | |
807 {bool isStatic, bool isExternal, bool isAbstract}); | |
808 | |
809 IndexedFunction createMethod( | |
810 int memberIndex, | |
811 LibraryEntity library, | |
812 ClassEntity enclosingClass, | |
813 Name name, | |
814 ParameterStructure parameterStructure, | |
815 AsyncMarker asyncMarker, | |
816 {bool isStatic, | |
817 bool isExternal, | |
818 bool isAbstract}); | |
819 | |
820 IndexedFunction createSetter(int memberIndex, LibraryEntity library, | |
821 ClassEntity enclosingClass, Name name, | |
822 {bool isStatic, bool isExternal, bool isAbstract}); | |
823 | |
824 IndexedField createField(int memberIndex, LibraryEntity library, | |
825 ClassEntity enclosingClass, Name name, | |
826 {bool isStatic, bool isAssignable, bool isConst}); | |
827 | |
828 Local createLocalFunction(String name, MemberEntity memberContext, | |
829 Entity executableContext, FunctionType functionType); | |
830 } | |
831 | |
832 abstract class KElementCreatorMixin implements ElementCreatorMixin { | |
833 IndexedLibrary createLibrary( | |
834 int libraryIndex, String name, Uri canonicalUri) { | |
835 return new KLibrary(libraryIndex, name, canonicalUri); | |
836 } | |
837 | |
838 IndexedClass createClass(LibraryEntity library, int classIndex, String name, | |
839 {bool isAbstract}) { | |
840 return new KClass(library, classIndex, name, isAbstract: isAbstract); | |
841 } | |
842 | |
843 TypeVariableEntity createTypeVariable( | |
844 Entity typeDeclaration, String name, int index) { | |
845 return new KTypeVariable(typeDeclaration, name, index); | |
846 } | |
847 | |
848 IndexedConstructor createGenerativeConstructor( | |
849 int memberIndex, | |
850 ClassEntity enclosingClass, | |
851 Name name, | |
852 ParameterStructure parameterStructure, | |
853 {bool isExternal, | |
854 bool isConst}) { | |
855 return new KGenerativeConstructor( | |
856 memberIndex, enclosingClass, name, parameterStructure, | |
857 isExternal: isExternal, isConst: isConst); | |
858 } | |
859 | |
860 IndexedConstructor createFactoryConstructor( | |
861 int memberIndex, | |
862 ClassEntity enclosingClass, | |
863 Name name, | |
864 ParameterStructure parameterStructure, | |
865 {bool isExternal, | |
866 bool isConst, | |
867 bool isFromEnvironmentConstructor}) { | |
868 return new KFactoryConstructor( | |
869 memberIndex, enclosingClass, name, parameterStructure, | |
870 isExternal: isExternal, | |
871 isConst: isConst, | |
872 isFromEnvironmentConstructor: isFromEnvironmentConstructor); | |
873 } | |
874 | |
875 IndexedFunction createGetter(int memberIndex, LibraryEntity library, | |
876 ClassEntity enclosingClass, Name name, AsyncMarker asyncMarker, | |
877 {bool isStatic, bool isExternal, bool isAbstract}) { | |
878 return new KGetter(memberIndex, library, enclosingClass, name, asyncMarker, | |
879 isStatic: isStatic, isExternal: isExternal, isAbstract: isAbstract); | |
880 } | |
881 | |
882 IndexedFunction createMethod( | |
883 int memberIndex, | |
884 LibraryEntity library, | |
885 ClassEntity enclosingClass, | |
886 Name name, | |
887 ParameterStructure parameterStructure, | |
888 AsyncMarker asyncMarker, | |
889 {bool isStatic, | |
890 bool isExternal, | |
891 bool isAbstract}) { | |
892 return new KMethod(memberIndex, library, enclosingClass, name, | |
893 parameterStructure, asyncMarker, | |
894 isStatic: isStatic, isExternal: isExternal, isAbstract: isAbstract); | |
895 } | |
896 | |
897 IndexedFunction createSetter(int memberIndex, LibraryEntity library, | |
898 ClassEntity enclosingClass, Name name, | |
899 {bool isStatic, bool isExternal, bool isAbstract}) { | |
900 return new KSetter(memberIndex, library, enclosingClass, name, | |
901 isStatic: isStatic, isExternal: isExternal, isAbstract: isAbstract); | |
902 } | |
903 | |
904 IndexedField createField(int memberIndex, LibraryEntity library, | |
905 ClassEntity enclosingClass, Name name, | |
906 {bool isStatic, bool isAssignable, bool isConst}) { | |
907 return new KField(memberIndex, library, enclosingClass, name, | |
908 isStatic: isStatic, isAssignable: isAssignable, isConst: isConst); | |
909 } | |
910 | |
911 Local createLocalFunction(String name, MemberEntity memberContext, | |
912 Entity executableContext, FunctionType functionType) { | |
913 return new KLocalFunction( | |
914 name, memberContext, executableContext, functionType); | |
915 } | |
777 } | 916 } |
778 | 917 |
779 /// Implementation of [KernelToElementMapForImpact] that only supports world | 918 /// Implementation of [KernelToElementMapForImpact] that only supports world |
780 /// impact computation. | 919 /// impact computation. |
781 // TODO(johnniwinther): Merge this with [KernelToElementMapForImpactImpl] when | 920 // TODO(johnniwinther): Merge this with [KernelToElementMapForImpactImpl] when |
782 // [JsStrategy] is the default. | 921 // [JsStrategy] is the default. |
783 abstract class KernelToElementMapForImpactImpl | 922 abstract class KernelToElementMapForImpactImpl |
784 implements | 923 implements |
785 KernelToElementMapBase, | 924 KernelToElementMapBase, |
786 KernelToElementMapForImpact, | 925 KernelToElementMapForImpact, |
(...skipping 27 matching lines...) Expand all Loading... | |
814 } | 953 } |
815 | 954 |
816 /// Implementation of [KernelToElementMapForImpact] that only supports world | 955 /// Implementation of [KernelToElementMapForImpact] that only supports world |
817 /// impact computation. | 956 /// impact computation. |
818 // TODO(johnniwinther): Merge this with [KernelToElementMapForImpactImpl] when | 957 // TODO(johnniwinther): Merge this with [KernelToElementMapForImpactImpl] when |
819 // [JsStrategy] is the default. | 958 // [JsStrategy] is the default. |
820 class KernelToElementMapForImpactImpl2 extends KernelToElementMapBase | 959 class KernelToElementMapForImpactImpl2 extends KernelToElementMapBase |
821 with | 960 with |
822 KernelToElementMapForImpactMixin, | 961 KernelToElementMapForImpactMixin, |
823 KernelToElementMapForImpactImpl, | 962 KernelToElementMapForImpactImpl, |
963 ElementCreatorMixin, | |
824 KElementCreatorMixin { | 964 KElementCreatorMixin { |
825 KernelToElementMapForImpactImpl2( | 965 KernelToElementMapForImpactImpl2( |
826 DiagnosticReporter reporter, Environment environment) | 966 DiagnosticReporter reporter, Environment environment) |
827 : super(reporter, environment); | 967 : super(reporter, environment); |
828 } | 968 } |
829 | 969 |
830 /// Element builder used for creating elements and types corresponding to Kernel | 970 /// Element builder used for creating elements and types corresponding to Kernel |
831 /// IR nodes. | 971 /// IR nodes. |
832 // TODO(johnniwinther): Use this in the JsStrategy | 972 // TODO(johnniwinther): Use this in the JsStrategy |
833 class KernelToElementMapForBuildingImpl extends KernelToElementMapBase | 973 class KernelToElementMapForBuildingImpl extends KernelToElementMapBase |
834 with KernelToElementMapForBuildingMixin, KElementCreatorMixin | 974 with |
975 KernelToElementMapForBuildingMixin, | |
976 ElementCreatorMixin, | |
977 KElementCreatorMixin | |
835 implements KernelToWorldBuilder { | 978 implements KernelToWorldBuilder { |
836 KernelToElementMapForBuildingImpl( | 979 KernelToElementMapForBuildingImpl( |
837 DiagnosticReporter reporter, Environment environment) | 980 DiagnosticReporter reporter, Environment environment) |
838 : super(reporter, environment); | 981 : super(reporter, environment); |
839 | 982 |
840 ConstantEnvironment get constantEnvironment => _constantEnvironment; | 983 ConstantEnvironment get constantEnvironment => _constantEnvironment; |
841 | 984 |
842 @override | 985 @override |
843 ConstantValue getFieldConstantValue(ir.Field field) { | 986 ConstantValue getFieldConstantValue(ir.Field field) { |
844 // TODO(johnniwinther): Cache the result in [FieldData]. | 987 // TODO(johnniwinther): Cache the result in [FieldData]. |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
886 } | 1029 } |
887 } | 1030 } |
888 | 1031 |
889 /// [KernelToElementMap] implementation used for both world impact computation | 1032 /// [KernelToElementMap] implementation used for both world impact computation |
890 /// and SSA building. | 1033 /// and SSA building. |
891 // TODO(johnniwinther): Remove this when [JsStrategy] is the default. | 1034 // TODO(johnniwinther): Remove this when [JsStrategy] is the default. |
892 class KernelToElementMapImpl extends KernelToElementMapForBuildingImpl | 1035 class KernelToElementMapImpl extends KernelToElementMapForBuildingImpl |
893 with | 1036 with |
894 KernelToElementMapForImpactMixin, | 1037 KernelToElementMapForImpactMixin, |
895 KernelToElementMapForImpactImpl, | 1038 KernelToElementMapForImpactImpl, |
1039 ElementCreatorMixin, | |
896 KElementCreatorMixin | 1040 KElementCreatorMixin |
897 implements KernelToElementMapForImpactImpl2 { | 1041 implements KernelToElementMapForImpactImpl2 { |
898 KernelToElementMapImpl(DiagnosticReporter reporter, Environment environment) | 1042 KernelToElementMapImpl(DiagnosticReporter reporter, Environment environment) |
899 : super(reporter, environment); | 1043 : super(reporter, environment); |
900 } | 1044 } |
901 | 1045 |
902 class KernelElementEnvironment implements ElementEnvironment { | 1046 class KernelElementEnvironment implements ElementEnvironment { |
903 final KernelToElementMapBase elementMap; | 1047 final KernelToElementMapBase elementMap; |
904 | 1048 |
905 KernelElementEnvironment(this.elementMap); | 1049 KernelElementEnvironment(this.elementMap); |
(...skipping 620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1526 MemberEntity toBackendMember(covariant IndexedMember member) { | 1670 MemberEntity toBackendMember(covariant IndexedMember member) { |
1527 return _backend._memberList[member.memberIndex]; | 1671 return _backend._memberList[member.memberIndex]; |
1528 } | 1672 } |
1529 | 1673 |
1530 MemberEntity toFrontendMember(covariant IndexedMember member) { | 1674 MemberEntity toFrontendMember(covariant IndexedMember member) { |
1531 return _frontend._memberList[member.memberIndex]; | 1675 return _frontend._memberList[member.memberIndex]; |
1532 } | 1676 } |
1533 } | 1677 } |
1534 | 1678 |
1535 class JsKernelToElementMap extends KernelToElementMapBase | 1679 class JsKernelToElementMap extends KernelToElementMapBase |
1536 with KernelToElementMapForBuildingMixin, JsElementCreatorMixin | 1680 with |
1537 implements KernelToWorldBuilder { | 1681 KernelToElementMapForBuildingMixin, |
1682 JsElementCreatorMixin, | |
1683 // TODO(johnniwinther): Avoid mixin in [ElementCreatorMixin]. The | |
1684 // codegen world should be a strict subset of the resolution world and | |
1685 // creating elements for IR nodes should therefore not be needed. | |
1686 // Currently some are created purely for testing (like | |
1687 // `element == commonElements.foo`, where 'foo' might not be live). | |
1688 // Others are created because we do a | |
1689 // `elementEnvironment.forEachLibraryMember(...)` call on each emitted | |
1690 // library. | |
1691 ElementCreatorMixin | |
1692 implements | |
1693 KernelToWorldBuilder { | |
1538 JsToFrontendMap _jsToFrontendMap; | 1694 JsToFrontendMap _jsToFrontendMap; |
1539 | 1695 |
1540 Map<ir.Library, JLibrary> _libraryMap = <ir.Library, JLibrary>{}; | |
1541 Map<ir.Class, JClass> _classMap = <ir.Class, JClass>{}; | |
1542 Map<ir.TypeParameter, JTypeVariable> _typeVariableMap = | |
1543 <ir.TypeParameter, JTypeVariable>{}; | |
1544 Map<ir.Member, JConstructor> _constructorMap = <ir.Member, JConstructor>{}; | |
1545 Map<ir.Procedure, JFunction> _methodMap = <ir.Procedure, JFunction>{}; | |
1546 Map<ir.Field, JField> _fieldMap = <ir.Field, JField>{}; | |
1547 | |
1548 JsKernelToElementMap(DiagnosticReporter reporter, Environment environment, | 1696 JsKernelToElementMap(DiagnosticReporter reporter, Environment environment, |
1549 KernelToElementMapForImpactImpl _elementMap) | 1697 KernelToElementMapForImpactImpl _elementMap) |
1550 : super(reporter, environment) { | 1698 : super(reporter, environment) { |
1551 _jsToFrontendMap = new JsToFrontendMapImpl(_elementMap, this); | 1699 _jsToFrontendMap = new JsToFrontendMapImpl(_elementMap, this); |
1552 _env.copyFrom(_elementMap._env); | 1700 _env.copyFrom(_elementMap._env); |
1553 for (int libraryIndex = 0; | 1701 for (int libraryIndex = 0; |
1554 libraryIndex < _elementMap._libraryEnvs.length; | 1702 libraryIndex < _elementMap._libraryEnvs.length; |
1555 libraryIndex++) { | 1703 libraryIndex++) { |
1556 LibraryEnv env = _elementMap._libraryEnvs[libraryIndex]; | 1704 LibraryEnv env = _elementMap._libraryEnvs[libraryIndex]; |
1557 LibraryEntity oldLibrary = _elementMap._libraryList[libraryIndex]; | 1705 LibraryEntity oldLibrary = _elementMap._libraryList[libraryIndex]; |
1558 JLibrary newLibrary = createLibrary(oldLibrary); | 1706 LibraryEntity newLibrary = convertLibrary(oldLibrary); |
1559 _libraryMap[env.library] = newLibrary; | 1707 _libraryMap[env.library] = newLibrary; |
1560 _libraryList.add(newLibrary); | 1708 _libraryList.add(newLibrary); |
1561 _libraryEnvs.add(env); | 1709 _libraryEnvs.add(env); |
1562 } | 1710 } |
1563 for (int classIndex = 0; | 1711 for (int classIndex = 0; |
1564 classIndex < _elementMap._classEnvs.length; | 1712 classIndex < _elementMap._classEnvs.length; |
1565 classIndex++) { | 1713 classIndex++) { |
1566 ClassEnv env = _elementMap._classEnvs[classIndex]; | 1714 ClassEnv env = _elementMap._classEnvs[classIndex]; |
1567 ClassEntity oldClass = _elementMap._classList[classIndex]; | 1715 ClassEntity oldClass = _elementMap._classList[classIndex]; |
1568 IndexedLibrary oldLibrary = oldClass.library; | 1716 IndexedLibrary oldLibrary = oldClass.library; |
1569 JLibrary newLibrary = _libraryList[oldLibrary.libraryIndex]; | 1717 LibraryEntity newLibrary = _libraryList[oldLibrary.libraryIndex]; |
1570 JClass newClass = createClass(newLibrary, oldClass); | 1718 ClassEntity newClass = convertClass(newLibrary, oldClass); |
1571 _classMap[env.cls] = newClass; | 1719 _classMap[env.cls] = newClass; |
1572 _classList.add(newClass); | 1720 _classList.add(newClass); |
1573 _classEnvs.add(env); | 1721 _classEnvs.add(env); |
1574 } | 1722 } |
1575 for (int memberIndex = 0; | 1723 for (int memberIndex = 0; |
1576 memberIndex < _elementMap._memberData.length; | 1724 memberIndex < _elementMap._memberData.length; |
1577 memberIndex++) { | 1725 memberIndex++) { |
1578 MemberData data = _elementMap._memberData[memberIndex]; | 1726 MemberData data = _elementMap._memberData[memberIndex]; |
1579 MemberEntity oldMember = _elementMap._memberList[memberIndex]; | 1727 MemberEntity oldMember = _elementMap._memberList[memberIndex]; |
1580 IndexedLibrary oldLibrary = oldMember.library; | 1728 IndexedLibrary oldLibrary = oldMember.library; |
1581 IndexedClass oldClass = oldMember.enclosingClass; | 1729 IndexedClass oldClass = oldMember.enclosingClass; |
1582 JLibrary newLibrary = _libraryList[oldLibrary.libraryIndex]; | 1730 LibraryEntity newLibrary = _libraryList[oldLibrary.libraryIndex]; |
1583 JClass newClass = | 1731 ClassEntity newClass = |
1584 oldClass != null ? _classList[oldClass.classIndex] : null; | 1732 oldClass != null ? _classList[oldClass.classIndex] : null; |
1585 JMember newMember = createMember(newLibrary, newClass, oldMember); | 1733 IndexedMember newMember = convertMember(newLibrary, newClass, oldMember); |
1586 _memberList.add(newMember); | 1734 _memberList.add(newMember); |
1587 _memberData.add(data); | 1735 _memberData.add(data); |
1588 if (newMember.isField) { | 1736 if (newMember.isField) { |
1589 _fieldMap[data.node] = newMember; | 1737 _fieldMap[data.node] = newMember; |
1590 } else if (newMember.isConstructor) { | 1738 } else if (newMember.isConstructor) { |
1591 _constructorMap[data.node] = newMember; | 1739 _constructorMap[data.node] = newMember; |
1592 } else { | 1740 } else { |
1593 _methodMap[data.node] = newMember; | 1741 _methodMap[data.node] = newMember; |
1594 } | 1742 } |
1595 } | 1743 } |
(...skipping 27 matching lines...) Expand all Loading... | |
1623 ClassEntity cls = _classMap[node]; | 1771 ClassEntity cls = _classMap[node]; |
1624 assert(cls != null, "No class entity for $node"); | 1772 assert(cls != null, "No class entity for $node"); |
1625 return cls; | 1773 return cls; |
1626 } | 1774 } |
1627 | 1775 |
1628 @override | 1776 @override |
1629 TypeVariableEntity _getTypeVariable(ir.TypeParameter node) { | 1777 TypeVariableEntity _getTypeVariable(ir.TypeParameter node) { |
1630 throw new UnsupportedError("JsKernelToElementMap._getTypeVariable"); | 1778 throw new UnsupportedError("JsKernelToElementMap._getTypeVariable"); |
1631 } | 1779 } |
1632 | 1780 |
1633 @override | 1781 // TODO(johnniwinther): Reinsert these when [ElementCreatorMixin] is no longer |
1782 // mixed in. | |
1783 /*@override | |
1634 FieldEntity _getField(ir.Field node) { | 1784 FieldEntity _getField(ir.Field node) { |
1635 FieldEntity field = _fieldMap[node]; | 1785 FieldEntity field = _fieldMap[node]; |
1636 assert(field != null, "No field entity for $node"); | 1786 assert(field != null, "No field entity for $node"); |
1637 return field; | 1787 return field; |
1638 } | 1788 }*/ |
1639 | 1789 |
1640 @override | 1790 /*@override |
1641 FunctionEntity _getMethod(ir.Procedure node) { | 1791 FunctionEntity _getMethod(ir.Procedure node) { |
1642 FunctionEntity function = _methodMap[node]; | 1792 FunctionEntity function = _methodMap[node]; |
1643 assert(function != null, "No function entity for $node"); | 1793 assert(function != null, "No function entity for $node"); |
1644 return function; | 1794 return function; |
1645 } | 1795 }*/ |
1646 | 1796 |
1647 @override | 1797 @override |
1648 ConstructorEntity _getConstructor(ir.Member node) { | 1798 ConstructorEntity _getConstructor(ir.Member node) { |
1649 ConstructorEntity constructor = _constructorMap[node]; | 1799 ConstructorEntity constructor = _constructorMap[node]; |
1650 assert(constructor != null, "No constructor entity for $node"); | 1800 assert(constructor != null, "No constructor entity for $node"); |
1651 return constructor; | 1801 return constructor; |
1652 } | 1802 } |
1653 | 1803 |
1654 @override | 1804 @override |
1655 ir.Member getMemberNode(MemberEntity member) { | 1805 ir.Member getMemberNode(MemberEntity member) { |
(...skipping 21 matching lines...) Expand all Loading... | |
1677 throw new UnsupportedError( | 1827 throw new UnsupportedError( |
1678 "JsKernelToElementMap.getConstantFieldInitializer"); | 1828 "JsKernelToElementMap.getConstantFieldInitializer"); |
1679 } | 1829 } |
1680 | 1830 |
1681 @override | 1831 @override |
1682 bool hasConstantFieldInitializer(FieldEntity field) { | 1832 bool hasConstantFieldInitializer(FieldEntity field) { |
1683 throw new UnsupportedError( | 1833 throw new UnsupportedError( |
1684 "JsKernelToElementMap.hasConstantFieldInitializer"); | 1834 "JsKernelToElementMap.hasConstantFieldInitializer"); |
1685 } | 1835 } |
1686 } | 1836 } |
OLD | NEW |