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 import 'package:kernel/clone.dart'; |
| 9 import 'package:kernel/type_algebra.dart'; |
8 | 10 |
9 import '../common.dart'; | 11 import '../common.dart'; |
10 import '../common/names.dart' show Identifiers; | 12 import '../common/names.dart' show Identifiers; |
11 import '../common/resolution.dart'; | 13 import '../common/resolution.dart'; |
12 import '../compile_time_constants.dart'; | 14 import '../compile_time_constants.dart'; |
13 import '../constants/constant_system.dart'; | 15 import '../constants/constant_system.dart'; |
14 import '../constants/constructors.dart'; | 16 import '../constants/constructors.dart'; |
15 import '../constants/evaluation.dart'; | 17 import '../constants/evaluation.dart'; |
16 import '../constants/expressions.dart'; | 18 import '../constants/expressions.dart'; |
17 import '../constants/values.dart'; | 19 import '../constants/values.dart'; |
(...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
612 if (node.kind == ir.ProcedureKind.Factory) { | 614 if (node.kind == ir.ProcedureKind.Factory) { |
613 return _getConstructor(node); | 615 return _getConstructor(node); |
614 } else { | 616 } else { |
615 return _getMethod(node); | 617 return _getMethod(node); |
616 } | 618 } |
617 } | 619 } |
618 throw new UnsupportedError("Unexpected member: $node"); | 620 throw new UnsupportedError("Unexpected member: $node"); |
619 } | 621 } |
620 | 622 |
621 @override | 623 @override |
622 FunctionEntity getConstructor(ir.Member node) => _getConstructor(node); | 624 ConstructorEntity getConstructor(ir.Member node) => _getConstructor(node); |
| 625 |
| 626 @override |
| 627 ConstructorEntity getSuperConstructor( |
| 628 ir.Constructor sourceNode, ir.Member targetNode) { |
| 629 KConstructor source = getConstructor(sourceNode); |
| 630 KClass sourceClass = source.enclosingClass; |
| 631 KConstructor target = getConstructor(targetNode); |
| 632 KClass targetClass = target.enclosingClass; |
| 633 KClass superClass = _getSuperType(sourceClass)?.element; |
| 634 if (superClass == targetClass) { |
| 635 return target; |
| 636 } |
| 637 _KClassEnv env = _classEnvs[superClass.classIndex]; |
| 638 ir.Member member = env.lookupConstructor(target.name); |
| 639 if (member != null) { |
| 640 return getConstructor(member); |
| 641 } |
| 642 throw new SpannableAssertionFailure( |
| 643 source, "Super constructor for $source not found."); |
| 644 } |
623 | 645 |
624 ConstantConstructor _getConstructorConstant(KConstructor constructor) { | 646 ConstantConstructor _getConstructorConstant(KConstructor constructor) { |
625 _ConstructorData data = _memberList[constructor.memberIndex]; | 647 _ConstructorData data = _memberList[constructor.memberIndex]; |
626 return data.getConstructorConstant(this, constructor); | 648 return data.getConstructorConstant(this, constructor); |
627 } | 649 } |
628 | 650 |
629 ConstantExpression _getFieldConstant(KField field) { | 651 ConstantExpression _getFieldConstant(KField field) { |
630 _FieldData data = _memberList[field.memberIndex]; | 652 _FieldData data = _memberList[field.memberIndex]; |
631 return data.getFieldConstant(this, field); | 653 return data.getFieldConstant(this, field); |
632 } | 654 } |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
779 | 801 |
780 Map<String, ir.Member> _constructorMap; | 802 Map<String, ir.Member> _constructorMap; |
781 Map<String, ir.Member> _memberMap; | 803 Map<String, ir.Member> _memberMap; |
782 Map<String, ir.Member> _setterMap; | 804 Map<String, ir.Member> _setterMap; |
783 | 805 |
784 Iterable<ConstantValue> _metadata; | 806 Iterable<ConstantValue> _metadata; |
785 | 807 |
786 _KClassEnv(this.cls) | 808 _KClassEnv(this.cls) |
787 // TODO(johnniwinther): Change this to use a property on [cls] when such | 809 // TODO(johnniwinther): Change this to use a property on [cls] when such |
788 // is added to kernel. | 810 // is added to kernel. |
789 : isUnnamedMixinApplication = cls.name.contains('+'); | 811 : isUnnamedMixinApplication = |
| 812 cls.name.contains('+') || cls.name.contains('&'); |
| 813 |
| 814 /// Copied from 'package:kernel/transformations/mixin_full_resolution.dart'. |
| 815 ir.Constructor _buildForwardingConstructor( |
| 816 CloneVisitor cloner, ir.Constructor superclassConstructor) { |
| 817 var superFunction = superclassConstructor.function; |
| 818 |
| 819 // We keep types and default values for the parameters but always mark the |
| 820 // parameters as final (since we just forward them to the super |
| 821 // constructor). |
| 822 ir.VariableDeclaration cloneVariable(ir.VariableDeclaration variable) { |
| 823 ir.VariableDeclaration clone = cloner.clone(variable); |
| 824 clone.isFinal = true; |
| 825 return clone; |
| 826 } |
| 827 |
| 828 // Build a [FunctionNode] which has the same parameters as the one in the |
| 829 // superclass constructor. |
| 830 var positionalParameters = |
| 831 superFunction.positionalParameters.map(cloneVariable).toList(); |
| 832 var namedParameters = |
| 833 superFunction.namedParameters.map(cloneVariable).toList(); |
| 834 var function = new ir.FunctionNode(new ir.EmptyStatement(), |
| 835 positionalParameters: positionalParameters, |
| 836 namedParameters: namedParameters, |
| 837 requiredParameterCount: superFunction.requiredParameterCount, |
| 838 returnType: const ir.VoidType()); |
| 839 |
| 840 // Build a [SuperInitializer] which takes all positional/named parameters |
| 841 // and forward them to the super class constructor. |
| 842 var positionalArguments = <ir.Expression>[]; |
| 843 for (var variable in positionalParameters) { |
| 844 positionalArguments.add(new ir.VariableGet(variable)); |
| 845 } |
| 846 var namedArguments = <ir.NamedExpression>[]; |
| 847 for (var variable in namedParameters) { |
| 848 namedArguments.add( |
| 849 new ir.NamedExpression(variable.name, new ir.VariableGet(variable))); |
| 850 } |
| 851 var superInitializer = new ir.SuperInitializer(superclassConstructor, |
| 852 new ir.Arguments(positionalArguments, named: namedArguments)); |
| 853 |
| 854 // Assemble the constructor. |
| 855 return new ir.Constructor(function, |
| 856 name: superclassConstructor.name, |
| 857 initializers: <ir.Initializer>[superInitializer]); |
| 858 } |
790 | 859 |
791 void _ensureMaps() { | 860 void _ensureMaps() { |
792 if (_memberMap == null) { | 861 if (_memberMap == null) { |
793 _memberMap = <String, ir.Member>{}; | 862 _memberMap = <String, ir.Member>{}; |
794 _setterMap = <String, ir.Member>{}; | 863 _setterMap = <String, ir.Member>{}; |
795 _constructorMap = <String, ir.Member>{}; | 864 _constructorMap = <String, ir.Member>{}; |
796 | 865 |
797 void addMembers(ir.Class c, {bool includeStatic}) { | 866 void addMembers(ir.Class c, {bool includeStatic}) { |
798 for (ir.Member member in c.members) { | 867 for (ir.Member member in c.members) { |
799 if (member is ir.Constructor || | 868 if (member is ir.Constructor || |
(...skipping 19 matching lines...) Expand all Loading... |
819 throw new SpannableAssertionFailure( | 888 throw new SpannableAssertionFailure( |
820 NO_LOCATION_SPANNABLE, "Unexpected class member node: $member"); | 889 NO_LOCATION_SPANNABLE, "Unexpected class member node: $member"); |
821 } | 890 } |
822 } | 891 } |
823 } | 892 } |
824 | 893 |
825 if (cls.mixedInClass != null) { | 894 if (cls.mixedInClass != null) { |
826 addMembers(cls.mixedInClass, includeStatic: false); | 895 addMembers(cls.mixedInClass, includeStatic: false); |
827 } | 896 } |
828 addMembers(cls, includeStatic: true); | 897 addMembers(cls, includeStatic: true); |
| 898 |
| 899 if (isUnnamedMixinApplication && _constructorMap.isEmpty) { |
| 900 // Unnamed mixin applications have no constructors when read from .dill. |
| 901 // For each generative constructor in the superclass we make a |
| 902 // corresponding forwarding constructor in the subclass. |
| 903 // |
| 904 // This code is copied from |
| 905 // 'package:kernel/transformations/mixin_full_resolution.dart' |
| 906 var superclassSubstitution = getSubstitutionMap(cls.supertype); |
| 907 var superclassCloner = |
| 908 new CloneVisitor(typeSubstitution: superclassSubstitution); |
| 909 for (var superclassConstructor in cls.superclass.constructors) { |
| 910 var forwardingConstructor = _buildForwardingConstructor( |
| 911 superclassCloner, superclassConstructor); |
| 912 cls.addMember(forwardingConstructor); |
| 913 _constructorMap[forwardingConstructor.name.name] = |
| 914 forwardingConstructor; |
| 915 } |
| 916 } |
829 } | 917 } |
830 } | 918 } |
831 | 919 |
832 /// Return the [ir.Member] for the member [name] in [library]. | 920 /// Return the [ir.Member] for the member [name] in [library]. |
833 ir.Member lookupMember(String name, {bool setter: false}) { | 921 ir.Member lookupMember(String name, {bool setter: false}) { |
834 _ensureMaps(); | 922 _ensureMaps(); |
835 return setter ? _setterMap[name] : _memberMap[name]; | 923 return setter ? _setterMap[name] : _memberMap[name]; |
836 } | 924 } |
837 | 925 |
838 /// Return the [ir.Member] for the member [name] in [library]. | 926 /// Return the [ir.Member] for the member [name] in [library]. |
(...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1396 return node.isExternal && | 1484 return node.isExternal && |
1397 !elementMap.isForeignLibrary(node.enclosingLibrary); | 1485 !elementMap.isForeignLibrary(node.enclosingLibrary); |
1398 } | 1486 } |
1399 | 1487 |
1400 @override | 1488 @override |
1401 bool isJsInteropMember(MemberEntity element) { | 1489 bool isJsInteropMember(MemberEntity element) { |
1402 // TODO(johnniwinther): Compute this. | 1490 // TODO(johnniwinther): Compute this. |
1403 return false; | 1491 return false; |
1404 } | 1492 } |
1405 } | 1493 } |
OLD | NEW |