Chromium Code Reviews| 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.world_builder; | 5 library dart2js.kernel.world_builder; |
| 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/resolution.dart'; | 10 import '../common/resolution.dart'; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 57 | 57 |
| 58 /// List of class environments by `KClass.classIndex`. This is used for | 58 /// List of class environments by `KClass.classIndex`. This is used for |
| 59 /// fast lookup into class members. | 59 /// fast lookup into class members. |
| 60 List<KClassEnv> _classEnvs = <KClassEnv>[]; | 60 List<KClassEnv> _classEnvs = <KClassEnv>[]; |
| 61 | 61 |
| 62 Map<ir.Library, KLibrary> _libraryMap = <ir.Library, KLibrary>{}; | 62 Map<ir.Library, KLibrary> _libraryMap = <ir.Library, KLibrary>{}; |
| 63 Map<ir.Class, KClass> _classMap = <ir.Class, KClass>{}; | 63 Map<ir.Class, KClass> _classMap = <ir.Class, KClass>{}; |
| 64 Map<ir.TypeParameter, KTypeVariable> _typeVariableMap = | 64 Map<ir.TypeParameter, KTypeVariable> _typeVariableMap = |
| 65 <ir.TypeParameter, KTypeVariable>{}; | 65 <ir.TypeParameter, KTypeVariable>{}; |
| 66 | 66 |
| 67 // TODO(johnniwinther): Change this to a list of 'KMemberData' class if we | 67 // TODO(johnniwinther): Change this to a list of 'KMemberData' class if we |
|
Siggi Cherem (dart-lang)
2017/04/24 19:39:39
remove TODO?
Johnni Winther
2017/04/25 08:20:44
Done.
| |
| 68 // need more data for members. | 68 // need more data for members. |
| 69 List<ir.Member> _memberList = <ir.Member>[]; | 69 List<_MemberData> _memberList = <_MemberData>[]; |
| 70 | 70 |
| 71 Map<ir.Member, KConstructor> _constructorMap = <ir.Member, KConstructor>{}; | 71 Map<ir.Member, KConstructor> _constructorMap = <ir.Member, KConstructor>{}; |
| 72 Map<KConstructor, ConstantConstructor> _constructorConstantMap = | |
| 73 <KConstructor, ConstantConstructor>{}; | |
| 74 | |
| 75 Map<ir.Procedure, KFunction> _methodMap = <ir.Procedure, KFunction>{}; | 72 Map<ir.Procedure, KFunction> _methodMap = <ir.Procedure, KFunction>{}; |
| 76 | |
| 77 Map<ir.Field, KField> _fieldMap = <ir.Field, KField>{}; | 73 Map<ir.Field, KField> _fieldMap = <ir.Field, KField>{}; |
| 78 Map<KField, ConstantExpression> _fieldConstantMap = | |
| 79 <KField, ConstantExpression>{}; | |
| 80 | 74 |
| 81 Map<ir.TreeNode, KLocalFunction> _localFunctionMap = | 75 Map<ir.TreeNode, KLocalFunction> _localFunctionMap = |
| 82 <ir.TreeNode, KLocalFunction>{}; | 76 <ir.TreeNode, KLocalFunction>{}; |
| 83 | 77 |
| 84 KernelWorldBuilder(this.reporter) { | 78 KernelWorldBuilder(this.reporter) { |
| 85 _elementEnvironment = new KernelElementEnvironment(this); | 79 _elementEnvironment = new KernelElementEnvironment(this); |
| 86 _commonElements = new CommonElements(_elementEnvironment); | 80 _commonElements = new CommonElements(_elementEnvironment); |
| 87 _constantEnvironment = new KernelConstantEnvironment(this); | 81 _constantEnvironment = new KernelConstantEnvironment(this); |
| 88 _nativeBehaviorBuilder = | 82 _nativeBehaviorBuilder = |
| 89 new KernelBehaviorBuilder(_commonElements, _constantEnvironment); | 83 new KernelBehaviorBuilder(_commonElements, _constantEnvironment); |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 243 } | 237 } |
| 244 | 238 |
| 245 KConstructor _getConstructor(ir.Member node) { | 239 KConstructor _getConstructor(ir.Member node) { |
| 246 return _constructorMap.putIfAbsent(node, () { | 240 return _constructorMap.putIfAbsent(node, () { |
| 247 int memberIndex = _memberList.length; | 241 int memberIndex = _memberList.length; |
| 248 KConstructor constructor; | 242 KConstructor constructor; |
| 249 KClass enclosingClass = _getClass(node.enclosingClass); | 243 KClass enclosingClass = _getClass(node.enclosingClass); |
| 250 Name name = getName(node.name); | 244 Name name = getName(node.name); |
| 251 bool isExternal = node.isExternal; | 245 bool isExternal = node.isExternal; |
| 252 | 246 |
| 247 ir.FunctionNode functionNode; | |
| 253 if (node is ir.Constructor) { | 248 if (node is ir.Constructor) { |
| 249 functionNode = node.function; | |
| 254 constructor = new KGenerativeConstructor(memberIndex, enclosingClass, | 250 constructor = new KGenerativeConstructor(memberIndex, enclosingClass, |
| 255 name, _getParameterStructure(node.function), | 251 name, _getParameterStructure(functionNode), |
| 256 isExternal: isExternal, isConst: node.isConst); | 252 isExternal: isExternal, isConst: node.isConst); |
| 257 } else if (node is ir.Procedure) { | 253 } else if (node is ir.Procedure) { |
| 254 functionNode = node.function; | |
| 258 constructor = new KFactoryConstructor(memberIndex, enclosingClass, name, | 255 constructor = new KFactoryConstructor(memberIndex, enclosingClass, name, |
| 259 _getParameterStructure(node.function), | 256 _getParameterStructure(functionNode), |
| 260 isExternal: isExternal, isConst: node.isConst); | 257 isExternal: isExternal, isConst: node.isConst); |
| 261 } else { | 258 } else { |
| 262 // TODO(johnniwinther): Convert `node.location` to a [SourceSpan]. | 259 // TODO(johnniwinther): Convert `node.location` to a [SourceSpan]. |
| 263 throw new SpannableAssertionFailure( | 260 throw new SpannableAssertionFailure( |
| 264 NO_LOCATION_SPANNABLE, "Unexpected constructor node: ${node}."); | 261 NO_LOCATION_SPANNABLE, "Unexpected constructor node: ${node}."); |
| 265 } | 262 } |
| 266 _memberList.add(node); | 263 _memberList.add(new _ConstructorData(node, functionNode)); |
| 267 return constructor; | 264 return constructor; |
| 268 }); | 265 }); |
| 269 } | 266 } |
| 270 | 267 |
| 271 KFunction _getMethod(ir.Procedure node) { | 268 KFunction _getMethod(ir.Procedure node) { |
| 272 return _methodMap.putIfAbsent(node, () { | 269 return _methodMap.putIfAbsent(node, () { |
| 273 int memberIndex = _memberList.length; | 270 int memberIndex = _memberList.length; |
| 274 KLibrary library; | 271 KLibrary library; |
| 275 KClass enclosingClass; | 272 KClass enclosingClass; |
| 276 if (node.enclosingClass != null) { | 273 if (node.enclosingClass != null) { |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 302 isAbstract: isAbstract); | 299 isAbstract: isAbstract); |
| 303 break; | 300 break; |
| 304 case ir.ProcedureKind.Setter: | 301 case ir.ProcedureKind.Setter: |
| 305 function = new KSetter( | 302 function = new KSetter( |
| 306 memberIndex, library, enclosingClass, getName(node.name).setter, | 303 memberIndex, library, enclosingClass, getName(node.name).setter, |
| 307 isStatic: isStatic, | 304 isStatic: isStatic, |
| 308 isExternal: isExternal, | 305 isExternal: isExternal, |
| 309 isAbstract: isAbstract); | 306 isAbstract: isAbstract); |
| 310 break; | 307 break; |
| 311 } | 308 } |
| 312 _memberList.add(node); | 309 _memberList.add(new _FunctionData(node, node.function)); |
| 313 return function; | 310 return function; |
| 314 }); | 311 }); |
| 315 } | 312 } |
| 316 | 313 |
| 317 KField _getField(ir.Field node) { | 314 KField _getField(ir.Field node) { |
| 318 return _fieldMap.putIfAbsent(node, () { | 315 return _fieldMap.putIfAbsent(node, () { |
| 319 int memberIndex = _memberList.length; | 316 int memberIndex = _memberList.length; |
| 320 KLibrary library; | 317 KLibrary library; |
| 321 KClass enclosingClass; | 318 KClass enclosingClass; |
| 322 if (node.enclosingClass != null) { | 319 if (node.enclosingClass != null) { |
| 323 enclosingClass = _getClass(node.enclosingClass); | 320 enclosingClass = _getClass(node.enclosingClass); |
| 324 library = enclosingClass.library; | 321 library = enclosingClass.library; |
| 325 } else { | 322 } else { |
| 326 library = _getLibrary(node.enclosingLibrary); | 323 library = _getLibrary(node.enclosingLibrary); |
| 327 } | 324 } |
| 328 Name name = getName(node.name); | 325 Name name = getName(node.name); |
| 329 bool isStatic = node.isStatic; | 326 bool isStatic = node.isStatic; |
| 330 _memberList.add(node); | 327 _memberList.add(new _FieldData(node)); |
| 331 return new KField(memberIndex, library, enclosingClass, name, | 328 return new KField(memberIndex, library, enclosingClass, name, |
| 332 isStatic: isStatic, | 329 isStatic: isStatic, |
| 333 isAssignable: node.isMutable, | 330 isAssignable: node.isMutable, |
| 334 isConst: node.isConst); | 331 isConst: node.isConst); |
| 335 }); | 332 }); |
| 336 } | 333 } |
| 337 | 334 |
| 338 KLocalFunction _getLocal(ir.TreeNode node) { | 335 KLocalFunction _getLocal(ir.TreeNode node) { |
| 339 return _localFunctionMap.putIfAbsent(node, () { | 336 return _localFunctionMap.putIfAbsent(node, () { |
| 340 MemberEntity memberContext; | 337 MemberEntity memberContext; |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 562 return _getMethod(node); | 559 return _getMethod(node); |
| 563 } | 560 } |
| 564 } | 561 } |
| 565 throw new UnsupportedError("Unexpected member: $node"); | 562 throw new UnsupportedError("Unexpected member: $node"); |
| 566 } | 563 } |
| 567 | 564 |
| 568 @override | 565 @override |
| 569 FunctionEntity getConstructor(ir.Member node) => _getConstructor(node); | 566 FunctionEntity getConstructor(ir.Member node) => _getConstructor(node); |
| 570 | 567 |
| 571 ConstantConstructor _getConstructorConstant(KConstructor constructor) { | 568 ConstantConstructor _getConstructorConstant(KConstructor constructor) { |
| 572 return _constructorConstantMap.putIfAbsent(constructor, () { | 569 _ConstructorData data = _memberList[constructor.memberIndex]; |
| 573 ir.Member node = _memberList[constructor.memberIndex]; | 570 return data.getConstructorConstant(this, constructor); |
| 574 if (node is ir.Constructor && node.isConst) { | |
| 575 return new Constantifier(this).computeConstantConstructor(node); | |
| 576 } | |
| 577 throw new SpannableAssertionFailure( | |
| 578 constructor, | |
| 579 "Unexpected constructor $constructor in " | |
| 580 "KernelWorldBuilder._getConstructorConstant"); | |
| 581 }); | |
| 582 } | 571 } |
| 583 | 572 |
| 584 ConstantExpression _getFieldConstant(KField field) { | 573 ConstantExpression _getFieldConstant(KField field) { |
| 585 return _fieldConstantMap.putIfAbsent(field, () { | 574 _FieldData data = _memberList[field.memberIndex]; |
| 586 ir.Field node = _memberList[field.memberIndex]; | 575 return data.getFieldConstant(this, field); |
| 587 if (node.isConst) { | 576 } |
| 588 return new Constantifier(this).visit(node.initializer); | 577 |
| 589 } | 578 FunctionType _getFunctionType(KFunction function) { |
| 590 throw new SpannableAssertionFailure( | 579 _FunctionData data = _memberList[function.memberIndex]; |
| 591 field, | 580 return data.getFunctionType(this); |
| 592 "Unexpected field $field in " | |
| 593 "KernelWorldBuilder._getConstructorConstant"); | |
| 594 }); | |
| 595 } | 581 } |
| 596 | 582 |
| 597 ResolutionImpact computeWorldImpact(KMember member) { | 583 ResolutionImpact computeWorldImpact(KMember member) { |
| 598 ir.Member node = _memberList[member.memberIndex]; | 584 return _memberList[member.memberIndex].getWorldImpact(this); |
| 599 return buildKernelImpact(node, this); | |
| 600 } | 585 } |
| 601 } | 586 } |
| 602 | 587 |
| 603 /// Environment for fast lookup of program libraries. | 588 /// Environment for fast lookup of program libraries. |
| 604 class KEnv { | 589 class KEnv { |
| 605 final Set<ir.Program> programs = new Set<ir.Program>(); | 590 final Set<ir.Program> programs = new Set<ir.Program>(); |
| 606 | 591 |
| 607 Map<Uri, KLibraryEnv> _libraryMap; | 592 Map<Uri, KLibraryEnv> _libraryMap; |
| 608 | 593 |
| 609 /// TODO(johnniwinther): Handle arbitrary load order if needed. | 594 /// TODO(johnniwinther): Handle arbitrary load order if needed. |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 775 } | 760 } |
| 776 | 761 |
| 777 Iterable<ConstantExpression> getMetadata(KernelWorldBuilder worldBuilder) { | 762 Iterable<ConstantExpression> getMetadata(KernelWorldBuilder worldBuilder) { |
| 778 if (_metadata == null) { | 763 if (_metadata == null) { |
| 779 _metadata = worldBuilder.getMetadata(cls.annotations); | 764 _metadata = worldBuilder.getMetadata(cls.annotations); |
| 780 } | 765 } |
| 781 return _metadata; | 766 return _metadata; |
| 782 } | 767 } |
| 783 } | 768 } |
| 784 | 769 |
| 770 class _MemberData { | |
| 771 final ir.Member node; | |
| 772 | |
| 773 _MemberData(this.node); | |
| 774 | |
| 775 ResolutionImpact getWorldImpact(KernelWorldBuilder worldBuilder) { | |
| 776 return buildKernelImpact(node, worldBuilder); | |
| 777 } | |
| 778 } | |
| 779 | |
| 780 class _FunctionData extends _MemberData { | |
| 781 final ir.FunctionNode functionNode; | |
| 782 FunctionType _type; | |
| 783 CallStructure _callStructure; | |
| 784 | |
| 785 _FunctionData(ir.Member node, this.functionNode) : super(node); | |
| 786 | |
| 787 FunctionType getFunctionType(KernelWorldBuilder worldBuilder) { | |
| 788 return _type ??= worldBuilder.getFunctionType(functionNode); | |
| 789 } | |
| 790 | |
| 791 CallStructure get callStructure { | |
| 792 return _callStructure ??= new CallStructure( | |
| 793 functionNode.positionalParameters.length + | |
| 794 functionNode.namedParameters.length, | |
| 795 functionNode.namedParameters.map((d) => d.name).toList()); | |
| 796 } | |
| 797 } | |
| 798 | |
| 799 class _ConstructorData extends _FunctionData { | |
| 800 ConstantConstructor _constantConstructor; | |
| 801 | |
| 802 _ConstructorData(ir.Member node, ir.FunctionNode functionNode) | |
| 803 : super(node, functionNode); | |
| 804 | |
| 805 ConstantConstructor getConstructorConstant( | |
| 806 KernelWorldBuilder worldBuilder, KConstructor constructor) { | |
| 807 if (_constantConstructor == null) { | |
| 808 if (node is ir.Constructor && constructor.isConst) { | |
| 809 _constantConstructor = | |
| 810 new Constantifier(worldBuilder).computeConstantConstructor(node); | |
| 811 } else { | |
| 812 throw new SpannableAssertionFailure( | |
| 813 constructor, | |
| 814 "Unexpected constructor $constructor in " | |
| 815 "KernelWorldBuilder._getConstructorConstant"); | |
| 816 } | |
| 817 } | |
| 818 return _constantConstructor; | |
| 819 } | |
| 820 } | |
| 821 | |
| 822 class _FieldData extends _MemberData { | |
| 823 ConstantExpression _constant; | |
| 824 | |
| 825 _FieldData(ir.Field node) : super(node); | |
| 826 | |
| 827 ir.Field get node => super.node; | |
| 828 | |
| 829 ConstantExpression getFieldConstant( | |
| 830 KernelWorldBuilder worldBuilder, KField field) { | |
| 831 if (_constant == null) { | |
| 832 if (node.isConst) { | |
| 833 _constant = new Constantifier(worldBuilder).visit(node.initializer); | |
| 834 } else { | |
| 835 throw new SpannableAssertionFailure( | |
| 836 field, | |
| 837 "Unexpected field $field in " | |
| 838 "KernelWorldBuilder._getConstructorConstant"); | |
| 839 } | |
| 840 } | |
| 841 return _constant; | |
| 842 } | |
| 843 } | |
| 844 | |
| 785 class KernelElementEnvironment implements ElementEnvironment { | 845 class KernelElementEnvironment implements ElementEnvironment { |
| 786 final KernelWorldBuilder worldBuilder; | 846 final KernelWorldBuilder worldBuilder; |
| 787 | 847 |
| 788 KernelElementEnvironment(this.worldBuilder); | 848 KernelElementEnvironment(this.worldBuilder); |
| 789 | 849 |
| 790 @override | 850 @override |
| 791 DartType get dynamicType => const DynamicType(); | 851 DartType get dynamicType => const DynamicType(); |
| 792 | 852 |
| 793 @override | 853 @override |
| 794 LibraryEntity get mainLibrary => worldBuilder._mainLibrary; | 854 LibraryEntity get mainLibrary => worldBuilder._mainLibrary; |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 821 return new InterfaceType(cls, typeArguments); | 881 return new InterfaceType(cls, typeArguments); |
| 822 } | 882 } |
| 823 | 883 |
| 824 @override | 884 @override |
| 825 bool isSubtype(DartType a, DartType b) { | 885 bool isSubtype(DartType a, DartType b) { |
| 826 return worldBuilder.types.isSubtype(a, b); | 886 return worldBuilder.types.isSubtype(a, b); |
| 827 } | 887 } |
| 828 | 888 |
| 829 @override | 889 @override |
| 830 FunctionType getFunctionType(KFunction function) { | 890 FunctionType getFunctionType(KFunction function) { |
| 831 throw new UnimplementedError('KernelElementEnvironment.getFunctionType'); | 891 return worldBuilder._getFunctionType(function); |
| 832 } | 892 } |
| 833 | 893 |
| 834 @override | 894 @override |
| 835 FunctionType getLocalFunctionType(KLocalFunction function) { | 895 FunctionType getLocalFunctionType(KLocalFunction function) { |
| 836 return function.functionType; | 896 return function.functionType; |
| 837 } | 897 } |
| 838 | 898 |
| 839 @override | 899 @override |
| 840 DartType getUnaliasedType(DartType type) => type; | 900 DartType getUnaliasedType(DartType type) => type; |
| 841 | 901 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 918 LibraryEntity library = worldBuilder.lookupLibrary(uri); | 978 LibraryEntity library = worldBuilder.lookupLibrary(uri); |
| 919 if (library == null && required) { | 979 if (library == null && required) { |
| 920 throw new SpannableAssertionFailure( | 980 throw new SpannableAssertionFailure( |
| 921 CURRENT_ELEMENT_SPANNABLE, "The library '$uri' was not found."); | 981 CURRENT_ELEMENT_SPANNABLE, "The library '$uri' was not found."); |
| 922 } | 982 } |
| 923 return library; | 983 return library; |
| 924 } | 984 } |
| 925 | 985 |
| 926 @override | 986 @override |
| 927 CallStructure getCallStructure(KFunction function) { | 987 CallStructure getCallStructure(KFunction function) { |
| 928 ir.Member member = worldBuilder._memberList[function.memberIndex]; | 988 _FunctionData data = worldBuilder._memberList[function.memberIndex]; |
| 929 ir.FunctionNode functionNode; | 989 ; |
|
Siggi Cherem (dart-lang)
2017/04/24 19:39:39
remove :)
Johnni Winther
2017/04/25 08:20:44
That was a load-bearing semicolon ;)
| |
| 930 if (member is ir.Procedure) { | 990 return data.callStructure; |
| 931 functionNode = member.function; | |
| 932 } else if (member is ir.Constructor) { | |
| 933 functionNode = member.function; | |
| 934 } else { | |
| 935 throw new SpannableAssertionFailure( | |
| 936 function, "Unexpected function node ${member} for $function."); | |
| 937 } | |
| 938 return new CallStructure( | |
| 939 functionNode.positionalParameters.length + | |
| 940 functionNode.namedParameters.length, | |
| 941 functionNode.namedParameters.map((d) => d.name).toList()); | |
| 942 } | 991 } |
| 943 | 992 |
| 944 @override | 993 @override |
| 945 bool isDeferredLoadLibraryGetter(KMember member) { | 994 bool isDeferredLoadLibraryGetter(KMember member) { |
| 946 // TODO(johnniwinther): Support these. | 995 // TODO(johnniwinther): Support these. |
| 947 return false; | 996 return false; |
| 948 } | 997 } |
| 949 } | 998 } |
| 950 | 999 |
| 951 /// Visitor that converts kernel dart types into [DartType]. | 1000 /// Visitor that converts kernel dart types into [DartType]. |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1209 } | 1258 } |
| 1210 | 1259 |
| 1211 InterfaceType getMixinTypeForClass(KClass cls) { | 1260 InterfaceType getMixinTypeForClass(KClass cls) { |
| 1212 KClassEnv env = builder._classEnvs[cls.classIndex]; | 1261 KClassEnv env = builder._classEnvs[cls.classIndex]; |
| 1213 ir.Supertype mixedInType = env.cls.mixedInType; | 1262 ir.Supertype mixedInType = env.cls.mixedInType; |
| 1214 if (mixedInType == null) return null; | 1263 if (mixedInType == null) return null; |
| 1215 return builder.createInterfaceType( | 1264 return builder.createInterfaceType( |
| 1216 mixedInType.classNode, mixedInType.typeArguments); | 1265 mixedInType.classNode, mixedInType.typeArguments); |
| 1217 } | 1266 } |
| 1218 } | 1267 } |
| OLD | NEW |