| 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 '../closure.dart' show BoxLocal; | 9 import '../closure.dart' show BoxLocal; |
| 10 import '../common.dart'; | 10 import '../common.dart'; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 import '../js_backend/native_data.dart'; | 30 import '../js_backend/native_data.dart'; |
| 31 import '../js_backend/no_such_method_registry.dart'; | 31 import '../js_backend/no_such_method_registry.dart'; |
| 32 import '../js_backend/runtime_types.dart'; | 32 import '../js_backend/runtime_types.dart'; |
| 33 import '../js_model/closure.dart'; | 33 import '../js_model/closure.dart'; |
| 34 import '../js_model/elements.dart'; | 34 import '../js_model/elements.dart'; |
| 35 import '../native/enqueue.dart'; | 35 import '../native/enqueue.dart'; |
| 36 import '../native/native.dart' as native; | 36 import '../native/native.dart' as native; |
| 37 import '../native/resolver.dart'; | 37 import '../native/resolver.dart'; |
| 38 import '../ordered_typeset.dart'; | 38 import '../ordered_typeset.dart'; |
| 39 import '../options.dart'; | 39 import '../options.dart'; |
| 40 import '../ssa/kernel_impact.dart'; |
| 40 import '../universe/class_set.dart'; | 41 import '../universe/class_set.dart'; |
| 41 import '../universe/selector.dart'; | 42 import '../universe/selector.dart'; |
| 42 import '../universe/world_builder.dart'; | 43 import '../universe/world_builder.dart'; |
| 43 import '../world.dart'; | 44 import '../world.dart'; |
| 44 import '../util/util.dart' show Link, LinkBuilder; | 45 import '../util/util.dart' show Link, LinkBuilder; |
| 45 import 'element_map.dart'; | 46 import 'element_map.dart'; |
| 46 import 'element_map_mixins.dart'; | 47 import 'element_map_mixins.dart'; |
| 47 import 'elements.dart'; | 48 import 'elements.dart'; |
| 48 import 'env.dart'; | 49 import 'env.dart'; |
| 49 import 'kelements.dart'; | 50 import 'kelements.dart'; |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 } | 129 } |
| 129 | 130 |
| 130 LibraryEntity get _mainLibrary { | 131 LibraryEntity get _mainLibrary { |
| 131 return _env.mainMethod != null | 132 return _env.mainMethod != null |
| 132 ? _getLibrary(_env.mainMethod.enclosingLibrary) | 133 ? _getLibrary(_env.mainMethod.enclosingLibrary) |
| 133 : null; | 134 : null; |
| 134 } | 135 } |
| 135 | 136 |
| 136 Iterable<LibraryEntity> get _libraries; | 137 Iterable<LibraryEntity> get _libraries; |
| 137 | 138 |
| 138 SourceSpan _getSourceSpanFromTreeNode(ir.TreeNode node) { | |
| 139 // TODO(johnniwinther): Use [ir.Location] directly as a [SourceSpan]. | |
| 140 Uri uri; | |
| 141 int offset; | |
| 142 while (node != null) { | |
| 143 if (node.fileOffset != ir.TreeNode.noOffset) { | |
| 144 offset = node.fileOffset; | |
| 145 uri = Uri.parse(node.location.file); | |
| 146 break; | |
| 147 } | |
| 148 node = node.parent; | |
| 149 } | |
| 150 if (uri != null) { | |
| 151 return new SourceSpan(uri, offset, offset + 1); | |
| 152 } | |
| 153 return null; | |
| 154 } | |
| 155 | |
| 156 SourceSpan getSourceSpan(Spannable spannable, Entity currentElement) { | 139 SourceSpan getSourceSpan(Spannable spannable, Entity currentElement) { |
| 157 SourceSpan fromSpannable(Spannable spannable) { | 140 SourceSpan fromSpannable(Spannable spannable) { |
| 158 if (spannable is IndexedLibrary && | 141 if (spannable is IndexedLibrary && |
| 159 spannable.libraryIndex < _libraryEnvs.length) { | 142 spannable.libraryIndex < _libraryEnvs.length) { |
| 160 LibraryEnv env = _libraryEnvs[spannable.libraryIndex]; | 143 LibraryEnv env = _libraryEnvs[spannable.libraryIndex]; |
| 161 return _getSourceSpanFromTreeNode(env.library); | 144 return computeSourceSpanFromTreeNode(env.library); |
| 162 } else if (spannable is IndexedClass && | 145 } else if (spannable is IndexedClass && |
| 163 spannable.classIndex < _classEnvs.length) { | 146 spannable.classIndex < _classEnvs.length) { |
| 164 ClassEnv env = _classEnvs[spannable.classIndex]; | 147 ClassData data = _classData[spannable.classIndex]; |
| 165 return _getSourceSpanFromTreeNode(env.cls); | 148 return data.definition.location; |
| 166 } else if (spannable is IndexedMember && | 149 } else if (spannable is IndexedMember && |
| 167 spannable.memberIndex < _memberData.length) { | 150 spannable.memberIndex < _memberData.length) { |
| 168 MemberData data = _memberData[spannable.memberIndex]; | 151 MemberData data = _memberData[spannable.memberIndex]; |
| 169 return _getSourceSpanFromTreeNode(data.node); | 152 return data.definition.location; |
| 170 } | 153 } |
| 171 return null; | 154 return null; |
| 172 } | 155 } |
| 173 | 156 |
| 174 SourceSpan sourceSpan = fromSpannable(spannable); | 157 SourceSpan sourceSpan = fromSpannable(spannable); |
| 175 sourceSpan ??= fromSpannable(currentElement); | 158 sourceSpan ??= fromSpannable(currentElement); |
| 176 return sourceSpan; | 159 return sourceSpan; |
| 177 } | 160 } |
| 178 | 161 |
| 179 LibraryEntity lookupLibrary(Uri uri) { | 162 LibraryEntity lookupLibrary(Uri uri) { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 if (!classEnv.isUnnamedMixinApplication) { | 205 if (!classEnv.isUnnamedMixinApplication) { |
| 223 f(_getClass(classEnv.cls, classEnv)); | 206 f(_getClass(classEnv.cls, classEnv)); |
| 224 } | 207 } |
| 225 }); | 208 }); |
| 226 } | 209 } |
| 227 | 210 |
| 228 MemberEntity lookupClassMember(IndexedClass cls, String name, | 211 MemberEntity lookupClassMember(IndexedClass cls, String name, |
| 229 {bool setter: false}) { | 212 {bool setter: false}) { |
| 230 assert(checkFamily(cls)); | 213 assert(checkFamily(cls)); |
| 231 ClassEnv classEnv = _classEnvs[cls.classIndex]; | 214 ClassEnv classEnv = _classEnvs[cls.classIndex]; |
| 232 ir.Member member = classEnv.lookupMember(name, setter: setter); | 215 return classEnv.lookupMember(this, name, setter: setter); |
| 233 return member != null ? getMember(member) : null; | |
| 234 } | 216 } |
| 235 | 217 |
| 236 ConstructorEntity lookupConstructor(IndexedClass cls, String name) { | 218 ConstructorEntity lookupConstructor(IndexedClass cls, String name) { |
| 237 assert(checkFamily(cls)); | 219 assert(checkFamily(cls)); |
| 238 ClassEnv classEnv = _classEnvs[cls.classIndex]; | 220 ClassEnv classEnv = _classEnvs[cls.classIndex]; |
| 239 ir.Member member = classEnv.lookupConstructor(name); | 221 return classEnv.lookupConstructor(this, name); |
| 240 return member != null ? getConstructor(member) : null; | |
| 241 } | 222 } |
| 242 | 223 |
| 243 @override | 224 @override |
| 244 InterfaceType createInterfaceType( | 225 InterfaceType createInterfaceType( |
| 245 ir.Class cls, List<ir.DartType> typeArguments) { | 226 ir.Class cls, List<ir.DartType> typeArguments) { |
| 246 return new InterfaceType(getClass(cls), getDartTypes(typeArguments)); | 227 return new InterfaceType(getClass(cls), getDartTypes(typeArguments)); |
| 247 } | 228 } |
| 248 | 229 |
| 249 LibraryEntity getLibrary(ir.Library node) => _getLibrary(node); | 230 LibraryEntity getLibrary(ir.Library node) => _getLibrary(node); |
| 250 | 231 |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 360 | 341 |
| 361 MemberEntity getSuperMember(ir.Member context, ir.Name name, ir.Member target, | 342 MemberEntity getSuperMember(ir.Member context, ir.Name name, ir.Member target, |
| 362 {bool setter: false}) { | 343 {bool setter: false}) { |
| 363 if (target != null) { | 344 if (target != null) { |
| 364 return getMember(target); | 345 return getMember(target); |
| 365 } | 346 } |
| 366 ClassEntity cls = getMember(context).enclosingClass; | 347 ClassEntity cls = getMember(context).enclosingClass; |
| 367 IndexedClass superclass = _getSuperType(cls)?.element; | 348 IndexedClass superclass = _getSuperType(cls)?.element; |
| 368 while (superclass != null) { | 349 while (superclass != null) { |
| 369 ClassEnv env = _classEnvs[superclass.classIndex]; | 350 ClassEnv env = _classEnvs[superclass.classIndex]; |
| 370 ir.Member superMember = env.lookupMember(name.name, setter: setter); | 351 MemberEntity superMember = |
| 352 env.lookupMember(this, name.name, setter: setter); |
| 371 if (superMember != null) { | 353 if (superMember != null) { |
| 372 return getMember(superMember); | 354 return superMember; |
| 373 } | 355 } |
| 374 superclass = _getSuperType(superclass)?.element; | 356 superclass = _getSuperType(superclass)?.element; |
| 375 } | 357 } |
| 376 throw failedAt(cls, "No super method member found for ${name} in $cls."); | 358 throw failedAt(cls, "No super method member found for ${name} in $cls."); |
| 377 } | 359 } |
| 378 | 360 |
| 379 @override | 361 @override |
| 380 ConstructorEntity getConstructor(ir.Member node) => _getConstructor(node); | 362 ConstructorEntity getConstructor(ir.Member node) => _getConstructor(node); |
| 381 | 363 |
| 382 ConstructorEntity _getConstructor(ir.Member node); | 364 ConstructorEntity _getConstructor(ir.Member node); |
| 383 | 365 |
| 384 ConstructorEntity getSuperConstructor( | 366 ConstructorEntity getSuperConstructor( |
| 385 ir.Constructor sourceNode, ir.Member targetNode) { | 367 ir.Constructor sourceNode, ir.Member targetNode) { |
| 386 ConstructorEntity source = getConstructor(sourceNode); | 368 ConstructorEntity source = getConstructor(sourceNode); |
| 387 ClassEntity sourceClass = source.enclosingClass; | 369 ClassEntity sourceClass = source.enclosingClass; |
| 388 ConstructorEntity target = getConstructor(targetNode); | 370 ConstructorEntity target = getConstructor(targetNode); |
| 389 ClassEntity targetClass = target.enclosingClass; | 371 ClassEntity targetClass = target.enclosingClass; |
| 390 IndexedClass superClass = _getSuperType(sourceClass)?.element; | 372 IndexedClass superClass = _getSuperType(sourceClass)?.element; |
| 391 if (superClass == targetClass) { | 373 if (superClass == targetClass) { |
| 392 return target; | 374 return target; |
| 393 } | 375 } |
| 394 ClassEnv env = _classEnvs[superClass.classIndex]; | 376 ClassEnv env = _classEnvs[superClass.classIndex]; |
| 395 ir.Member member = env.lookupConstructor(target.name); | 377 ConstructorEntity constructor = env.lookupConstructor(this, target.name); |
| 396 if (member != null) { | 378 if (constructor != null) { |
| 397 return getConstructor(member); | 379 return constructor; |
| 398 } | 380 } |
| 399 throw failedAt(source, "Super constructor for $source not found."); | 381 throw failedAt(source, "Super constructor for $source not found."); |
| 400 } | 382 } |
| 401 | 383 |
| 402 @override | 384 @override |
| 403 FunctionEntity getMethod(ir.Procedure node) => _getMethod(node); | 385 FunctionEntity getMethod(ir.Procedure node) => _getMethod(node); |
| 404 | 386 |
| 405 FunctionEntity _getMethod(ir.Procedure node); | 387 FunctionEntity _getMethod(ir.Procedure node); |
| 406 | 388 |
| 407 @override | 389 @override |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 523 if (data.mixedInType != null) { | 505 if (data.mixedInType != null) { |
| 524 f(data.mixedInType.element); | 506 f(data.mixedInType.element); |
| 525 } | 507 } |
| 526 cls = data.supertype?.element; | 508 cls = data.supertype?.element; |
| 527 } | 509 } |
| 528 } | 510 } |
| 529 | 511 |
| 530 void _forEachConstructor(IndexedClass cls, void f(ConstructorEntity member)) { | 512 void _forEachConstructor(IndexedClass cls, void f(ConstructorEntity member)) { |
| 531 assert(checkFamily(cls)); | 513 assert(checkFamily(cls)); |
| 532 ClassEnv env = _classEnvs[cls.classIndex]; | 514 ClassEnv env = _classEnvs[cls.classIndex]; |
| 533 env.forEachConstructor((ir.Member member) { | 515 env.forEachConstructor(this, f); |
| 534 f(getConstructor(member)); | |
| 535 }); | |
| 536 } | 516 } |
| 537 | 517 |
| 538 void _forEachConstructorBody( | 518 void _forEachConstructorBody( |
| 539 IndexedClass cls, void f(ConstructorBodyEntity member)) { | 519 IndexedClass cls, void f(ConstructorBodyEntity member)) { |
| 540 throw new UnsupportedError( | 520 throw new UnsupportedError( |
| 541 'KernelToElementMapBase._forEachConstructorBody'); | 521 'KernelToElementMapBase._forEachConstructorBody'); |
| 542 } | 522 } |
| 543 | 523 |
| 544 void _forEachClassMember( | 524 void _forEachClassMember( |
| 545 IndexedClass cls, void f(ClassEntity cls, MemberEntity member)) { | 525 IndexedClass cls, void f(ClassEntity cls, MemberEntity member)) { |
| 546 assert(checkFamily(cls)); | 526 assert(checkFamily(cls)); |
| 547 ClassEnv env = _classEnvs[cls.classIndex]; | 527 ClassEnv env = _classEnvs[cls.classIndex]; |
| 548 env.forEachMember((ir.Member member) { | 528 env.forEachMember(this, (MemberEntity member) { |
| 549 f(cls, getMember(member)); | 529 f(cls, member); |
| 550 }); | 530 }); |
| 551 ClassData data = _classData[cls.classIndex]; | 531 ClassData data = _classData[cls.classIndex]; |
| 552 _ensureSupertypes(cls, data); | 532 _ensureSupertypes(cls, data); |
| 553 if (data.supertype != null) { | 533 if (data.supertype != null) { |
| 554 _forEachClassMember(data.supertype.element, f); | 534 _forEachClassMember(data.supertype.element, f); |
| 555 } | 535 } |
| 556 } | 536 } |
| 557 | 537 |
| 558 ConstantConstructor _getConstructorConstant(IndexedConstructor constructor) { | 538 ConstantConstructor _getConstructorConstant(IndexedConstructor constructor) { |
| 559 assert(checkFamily(constructor)); | 539 assert(checkFamily(constructor)); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 595 Iterable<InterfaceType> _getInterfaces(IndexedClass cls) { | 575 Iterable<InterfaceType> _getInterfaces(IndexedClass cls) { |
| 596 assert(checkFamily(cls)); | 576 assert(checkFamily(cls)); |
| 597 ClassData data = _classData[cls.classIndex]; | 577 ClassData data = _classData[cls.classIndex]; |
| 598 _ensureSupertypes(cls, data); | 578 _ensureSupertypes(cls, data); |
| 599 return data.interfaces; | 579 return data.interfaces; |
| 600 } | 580 } |
| 601 | 581 |
| 602 Spannable _getSpannable(MemberEntity member, ir.Node node) { | 582 Spannable _getSpannable(MemberEntity member, ir.Node node) { |
| 603 SourceSpan sourceSpan; | 583 SourceSpan sourceSpan; |
| 604 if (node is ir.TreeNode) { | 584 if (node is ir.TreeNode) { |
| 605 sourceSpan = _getSourceSpanFromTreeNode(node); | 585 sourceSpan = computeSourceSpanFromTreeNode(node); |
| 606 } | 586 } |
| 607 sourceSpan ??= getSourceSpan(member, null); | 587 sourceSpan ??= getSourceSpan(member, null); |
| 608 return sourceSpan; | 588 return sourceSpan; |
| 609 } | 589 } |
| 610 | 590 |
| 611 MemberDefinition _getMemberDefinition(covariant IndexedMember member) { | 591 MemberDefinition _getMemberDefinition(covariant IndexedMember member) { |
| 612 assert(checkFamily(member)); | 592 assert(checkFamily(member)); |
| 613 return _memberData[member.memberIndex].definition; | 593 return _memberData[member.memberIndex].definition; |
| 614 } | 594 } |
| 615 | 595 |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 754 name, _getParameterStructure(functionNode), | 734 name, _getParameterStructure(functionNode), |
| 755 isExternal: isExternal, | 735 isExternal: isExternal, |
| 756 isConst: node.isConst, | 736 isConst: node.isConst, |
| 757 isFromEnvironmentConstructor: isFromEnvironment); | 737 isFromEnvironmentConstructor: isFromEnvironment); |
| 758 definition = new RegularMemberDefinition(constructor, node); | 738 definition = new RegularMemberDefinition(constructor, node); |
| 759 } else { | 739 } else { |
| 760 // TODO(johnniwinther): Convert `node.location` to a [SourceSpan]. | 740 // TODO(johnniwinther): Convert `node.location` to a [SourceSpan]. |
| 761 throw failedAt( | 741 throw failedAt( |
| 762 NO_LOCATION_SPANNABLE, "Unexpected constructor node: ${node}."); | 742 NO_LOCATION_SPANNABLE, "Unexpected constructor node: ${node}."); |
| 763 } | 743 } |
| 764 _memberData.add(new ConstructorData(node, functionNode, definition)); | 744 _memberData.add(new ConstructorDataImpl(node, functionNode, definition)); |
| 765 _memberList.add(constructor); | 745 _memberList.add(constructor); |
| 766 return constructor; | 746 return constructor; |
| 767 }); | 747 }); |
| 768 } | 748 } |
| 769 | 749 |
| 750 AsyncMarker _getAsyncMarker(ir.FunctionNode node) { |
| 751 switch (node.asyncMarker) { |
| 752 case ir.AsyncMarker.Async: |
| 753 return AsyncMarker.ASYNC; |
| 754 case ir.AsyncMarker.AsyncStar: |
| 755 return AsyncMarker.ASYNC_STAR; |
| 756 case ir.AsyncMarker.Sync: |
| 757 return AsyncMarker.SYNC; |
| 758 case ir.AsyncMarker.SyncStar: |
| 759 return AsyncMarker.SYNC_STAR; |
| 760 case ir.AsyncMarker.SyncYielding: |
| 761 default: |
| 762 throw new UnsupportedError( |
| 763 "Async marker ${node.asyncMarker} is not supported."); |
| 764 } |
| 765 } |
| 766 |
| 770 FunctionEntity _getMethod(ir.Procedure node) { | 767 FunctionEntity _getMethod(ir.Procedure node) { |
| 771 return _methodMap.putIfAbsent(node, () { | 768 return _methodMap.putIfAbsent(node, () { |
| 772 int memberIndex = _memberData.length; | 769 int memberIndex = _memberData.length; |
| 773 LibraryEntity library; | 770 LibraryEntity library; |
| 774 ClassEntity enclosingClass; | 771 ClassEntity enclosingClass; |
| 775 if (node.enclosingClass != null) { | 772 if (node.enclosingClass != null) { |
| 776 enclosingClass = _getClass(node.enclosingClass); | 773 enclosingClass = _getClass(node.enclosingClass); |
| 777 library = enclosingClass.library; | 774 library = enclosingClass.library; |
| 778 } else { | 775 } else { |
| 779 library = _getLibrary(node.enclosingLibrary); | 776 library = _getLibrary(node.enclosingLibrary); |
| 780 } | 777 } |
| 781 Name name = getName(node.name); | 778 Name name = getName(node.name); |
| 782 bool isStatic = node.isStatic; | 779 bool isStatic = node.isStatic; |
| 783 bool isExternal = node.isExternal; | 780 bool isExternal = node.isExternal; |
| 784 bool isAbstract = node.isAbstract; | 781 bool isAbstract = node.isAbstract; |
| 785 IndexedFunction function; | 782 IndexedFunction function; |
| 786 AsyncMarker asyncMarker; | 783 AsyncMarker asyncMarker = _getAsyncMarker(node.function); |
| 787 switch (node.function.asyncMarker) { | |
| 788 case ir.AsyncMarker.Async: | |
| 789 asyncMarker = AsyncMarker.ASYNC; | |
| 790 break; | |
| 791 case ir.AsyncMarker.AsyncStar: | |
| 792 asyncMarker = AsyncMarker.ASYNC_STAR; | |
| 793 break; | |
| 794 case ir.AsyncMarker.Sync: | |
| 795 asyncMarker = AsyncMarker.SYNC; | |
| 796 break; | |
| 797 case ir.AsyncMarker.SyncStar: | |
| 798 asyncMarker = AsyncMarker.SYNC_STAR; | |
| 799 break; | |
| 800 case ir.AsyncMarker.SyncYielding: | |
| 801 throw new UnsupportedError( | |
| 802 "Async marker ${node.function.asyncMarker} is not supported."); | |
| 803 } | |
| 804 switch (node.kind) { | 784 switch (node.kind) { |
| 805 case ir.ProcedureKind.Factory: | 785 case ir.ProcedureKind.Factory: |
| 806 throw new UnsupportedError("Cannot create method from factory."); | 786 throw new UnsupportedError("Cannot create method from factory."); |
| 807 case ir.ProcedureKind.Getter: | 787 case ir.ProcedureKind.Getter: |
| 808 function = createGetter( | 788 function = createGetter( |
| 809 memberIndex, library, enclosingClass, name, asyncMarker, | 789 memberIndex, library, enclosingClass, name, asyncMarker, |
| 810 isStatic: isStatic, | 790 isStatic: isStatic, |
| 811 isExternal: isExternal, | 791 isExternal: isExternal, |
| 812 isAbstract: isAbstract); | 792 isAbstract: isAbstract); |
| 813 break; | 793 break; |
| 814 case ir.ProcedureKind.Method: | 794 case ir.ProcedureKind.Method: |
| 815 case ir.ProcedureKind.Operator: | 795 case ir.ProcedureKind.Operator: |
| 816 function = createMethod(memberIndex, library, enclosingClass, name, | 796 function = createMethod(memberIndex, library, enclosingClass, name, |
| 817 _getParameterStructure(node.function), asyncMarker, | 797 _getParameterStructure(node.function), asyncMarker, |
| 818 isStatic: isStatic, | 798 isStatic: isStatic, |
| 819 isExternal: isExternal, | 799 isExternal: isExternal, |
| 820 isAbstract: isAbstract); | 800 isAbstract: isAbstract); |
| 821 break; | 801 break; |
| 822 case ir.ProcedureKind.Setter: | 802 case ir.ProcedureKind.Setter: |
| 823 assert(asyncMarker == AsyncMarker.SYNC); | 803 assert(asyncMarker == AsyncMarker.SYNC); |
| 824 function = createSetter( | 804 function = createSetter( |
| 825 memberIndex, library, enclosingClass, name.setter, | 805 memberIndex, library, enclosingClass, name.setter, |
| 826 isStatic: isStatic, | 806 isStatic: isStatic, |
| 827 isExternal: isExternal, | 807 isExternal: isExternal, |
| 828 isAbstract: isAbstract); | 808 isAbstract: isAbstract); |
| 829 break; | 809 break; |
| 830 } | 810 } |
| 831 _memberData.add(new FunctionData( | 811 _memberData.add(new FunctionDataImpl( |
| 832 node, node.function, new RegularMemberDefinition(function, node))); | 812 node, node.function, new RegularMemberDefinition(function, node))); |
| 833 _memberList.add(function); | 813 _memberList.add(function); |
| 834 return function; | 814 return function; |
| 835 }); | 815 }); |
| 836 } | 816 } |
| 837 | 817 |
| 838 FieldEntity _getField(ir.Field node) { | 818 FieldEntity _getField(ir.Field node) { |
| 839 return _fieldMap.putIfAbsent(node, () { | 819 return _fieldMap.putIfAbsent(node, () { |
| 840 int memberIndex = _memberData.length; | 820 int memberIndex = _memberData.length; |
| 841 LibraryEntity library; | 821 LibraryEntity library; |
| 842 ClassEntity enclosingClass; | 822 ClassEntity enclosingClass; |
| 843 if (node.enclosingClass != null) { | 823 if (node.enclosingClass != null) { |
| 844 enclosingClass = _getClass(node.enclosingClass); | 824 enclosingClass = _getClass(node.enclosingClass); |
| 845 library = enclosingClass.library; | 825 library = enclosingClass.library; |
| 846 } else { | 826 } else { |
| 847 library = _getLibrary(node.enclosingLibrary); | 827 library = _getLibrary(node.enclosingLibrary); |
| 848 } | 828 } |
| 849 Name name = getName(node.name); | 829 Name name = getName(node.name); |
| 850 bool isStatic = node.isStatic; | 830 bool isStatic = node.isStatic; |
| 851 FieldEntity field = createField( | 831 FieldEntity field = createField( |
| 852 memberIndex, library, enclosingClass, name, | 832 memberIndex, library, enclosingClass, name, |
| 853 isStatic: isStatic, | 833 isStatic: isStatic, |
| 854 isAssignable: node.isMutable, | 834 isAssignable: node.isMutable, |
| 855 isConst: node.isConst); | 835 isConst: node.isConst); |
| 856 _memberData | 836 _memberData.add( |
| 857 .add(new FieldData(node, new RegularMemberDefinition(field, node))); | 837 new FieldDataImpl(node, new RegularMemberDefinition(field, node))); |
| 858 _memberList.add(field); | 838 _memberList.add(field); |
| 859 return field; | 839 return field; |
| 860 }); | 840 }); |
| 861 } | 841 } |
| 862 | 842 |
| 863 ParameterStructure _getParameterStructure(ir.FunctionNode node) { | 843 ParameterStructure _getParameterStructure(ir.FunctionNode node) { |
| 864 // TODO(johnniwinther): Cache the computed function type. | 844 // TODO(johnniwinther): Cache the computed function type. |
| 865 int requiredParameters = node.requiredParameterCount; | 845 int requiredParameters = node.requiredParameterCount; |
| 866 int positionalParameters = node.positionalParameters.length; | 846 int positionalParameters = node.positionalParameters.length; |
| 867 List<String> namedParameters = | 847 List<String> namedParameters = |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1032 /// compilation. | 1012 /// compilation. |
| 1033 void addProgram(ir.Program program) { | 1013 void addProgram(ir.Program program) { |
| 1034 _env.addProgram(program); | 1014 _env.addProgram(program); |
| 1035 } | 1015 } |
| 1036 | 1016 |
| 1037 @override | 1017 @override |
| 1038 native.BehaviorBuilder get nativeBehaviorBuilder => | 1018 native.BehaviorBuilder get nativeBehaviorBuilder => |
| 1039 _nativeBehaviorBuilder ??= new KernelBehaviorBuilder(commonElements); | 1019 _nativeBehaviorBuilder ??= new KernelBehaviorBuilder(commonElements); |
| 1040 | 1020 |
| 1041 ResolutionImpact computeWorldImpact(KMember member) { | 1021 ResolutionImpact computeWorldImpact(KMember member) { |
| 1042 return _memberData[member.memberIndex].getWorldImpact(this); | 1022 return buildKernelImpact( |
| 1023 _memberData[member.memberIndex].definition.node, this); |
| 1043 } | 1024 } |
| 1044 | 1025 |
| 1045 ClosureModel computeClosureModel(KMember member) { | 1026 ClosureModel computeClosureModel(KMember member) { |
| 1046 ir.Member node = _memberData[member.memberIndex].node; | 1027 ir.Member node = _memberData[member.memberIndex].definition.node; |
| 1047 return KernelClosureAnalysis.computeClosureModel(member, node); | 1028 return KernelClosureAnalysis.computeClosureModel(member, node); |
| 1048 } | 1029 } |
| 1049 | 1030 |
| 1050 /// Returns the kernel [ir.Procedure] node for the [method]. | 1031 /// Returns the kernel [ir.Procedure] node for the [method]. |
| 1051 ir.Procedure _lookupProcedure(KFunction method) { | 1032 ir.Procedure _lookupProcedure(KFunction method) { |
| 1052 return _memberData[method.memberIndex].node; | 1033 return _memberData[method.memberIndex].definition.node; |
| 1053 } | 1034 } |
| 1054 | 1035 |
| 1055 Iterable<ConstantValue> _getClassMetadata(KClass cls) { | 1036 Iterable<ConstantValue> _getClassMetadata(KClass cls) { |
| 1056 return _classData[cls.classIndex].getMetadata(this); | 1037 return _classData[cls.classIndex].getMetadata(this); |
| 1057 } | 1038 } |
| 1058 | 1039 |
| 1059 @override | 1040 @override |
| 1060 Local getLocalFunction(ir.TreeNode node) { | 1041 Local getLocalFunction(ir.TreeNode node) { |
| 1061 assert( | 1042 assert( |
| 1062 node is ir.FunctionDeclaration || node is ir.FunctionExpression, | 1043 node is ir.FunctionDeclaration || node is ir.FunctionExpression, |
| (...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1703 | 1684 |
| 1704 @override | 1685 @override |
| 1705 ElementEnvironment get elementEnvironment => elementMap.elementEnvironment; | 1686 ElementEnvironment get elementEnvironment => elementMap.elementEnvironment; |
| 1706 | 1687 |
| 1707 @override | 1688 @override |
| 1708 CommonElements get commonElements => elementMap.commonElements; | 1689 CommonElements get commonElements => elementMap.commonElements; |
| 1709 | 1690 |
| 1710 @override | 1691 @override |
| 1711 native.NativeBehavior computeNativeFieldStoreBehavior( | 1692 native.NativeBehavior computeNativeFieldStoreBehavior( |
| 1712 covariant KField field) { | 1693 covariant KField field) { |
| 1713 ir.Field node = elementMap._memberData[field.memberIndex].node; | 1694 ir.Field node = elementMap._memberData[field.memberIndex].definition.node; |
| 1714 return elementMap.getNativeBehaviorForFieldStore(node); | 1695 return elementMap.getNativeBehaviorForFieldStore(node); |
| 1715 } | 1696 } |
| 1716 | 1697 |
| 1717 @override | 1698 @override |
| 1718 native.NativeBehavior computeNativeFieldLoadBehavior(covariant KField field, | 1699 native.NativeBehavior computeNativeFieldLoadBehavior(covariant KField field, |
| 1719 {bool isJsInterop}) { | 1700 {bool isJsInterop}) { |
| 1720 ir.Field node = elementMap._memberData[field.memberIndex].node; | 1701 ir.Field node = elementMap._memberData[field.memberIndex].definition.node; |
| 1721 return elementMap.getNativeBehaviorForFieldLoad(node, | 1702 return elementMap.getNativeBehaviorForFieldLoad(node, |
| 1722 isJsInterop: isJsInterop); | 1703 isJsInterop: isJsInterop); |
| 1723 } | 1704 } |
| 1724 | 1705 |
| 1725 @override | 1706 @override |
| 1726 native.NativeBehavior computeNativeMethodBehavior( | 1707 native.NativeBehavior computeNativeMethodBehavior( |
| 1727 covariant KFunction function, | 1708 covariant KFunction function, |
| 1728 {bool isJsInterop}) { | 1709 {bool isJsInterop}) { |
| 1729 ir.Member node = elementMap._memberData[function.memberIndex].node; | 1710 ir.Member node = |
| 1711 elementMap._memberData[function.memberIndex].definition.node; |
| 1730 return elementMap.getNativeBehaviorForMethod(node, | 1712 return elementMap.getNativeBehaviorForMethod(node, |
| 1731 isJsInterop: isJsInterop); | 1713 isJsInterop: isJsInterop); |
| 1732 } | 1714 } |
| 1733 | 1715 |
| 1734 @override | 1716 @override |
| 1735 bool isNativeMethod(covariant KFunction function) { | 1717 bool isNativeMethod(covariant KFunction function) { |
| 1736 if (!native.maybeEnableNative(function.library.canonicalUri)) return false; | 1718 if (!native.maybeEnableNative(function.library.canonicalUri)) return false; |
| 1737 ir.Member node = elementMap._memberData[function.memberIndex].node; | 1719 ir.Member node = |
| 1720 elementMap._memberData[function.memberIndex].definition.node; |
| 1738 return node.isExternal && | 1721 return node.isExternal && |
| 1739 !elementMap.isForeignLibrary(node.enclosingLibrary); | 1722 !elementMap.isForeignLibrary(node.enclosingLibrary); |
| 1740 } | 1723 } |
| 1741 | 1724 |
| 1742 @override | 1725 @override |
| 1743 bool isJsInteropMember(MemberEntity element) { | 1726 bool isJsInteropMember(MemberEntity element) { |
| 1744 // TODO(redemption): Compute this. | 1727 // TODO(redemption): Compute this. |
| 1745 return false; | 1728 return false; |
| 1746 } | 1729 } |
| 1747 } | 1730 } |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1813 LibraryEntity newLibrary = _libraryList[oldLibrary.libraryIndex]; | 1796 LibraryEntity newLibrary = _libraryList[oldLibrary.libraryIndex]; |
| 1814 ClassEntity newClass = convertClass(newLibrary, oldClass); | 1797 ClassEntity newClass = convertClass(newLibrary, oldClass); |
| 1815 _classMap[env.cls] = newClass; | 1798 _classMap[env.cls] = newClass; |
| 1816 _classList.add(newClass); | 1799 _classList.add(newClass); |
| 1817 _classEnvs.add(env); | 1800 _classEnvs.add(env); |
| 1818 _classData.add(data.copy()); | 1801 _classData.add(data.copy()); |
| 1819 } | 1802 } |
| 1820 for (int memberIndex = 0; | 1803 for (int memberIndex = 0; |
| 1821 memberIndex < _elementMap._memberData.length; | 1804 memberIndex < _elementMap._memberData.length; |
| 1822 memberIndex++) { | 1805 memberIndex++) { |
| 1823 MemberData data = _elementMap._memberData[memberIndex]; | 1806 MemberDataImpl data = _elementMap._memberData[memberIndex]; |
| 1824 MemberEntity oldMember = _elementMap._memberList[memberIndex]; | 1807 MemberEntity oldMember = _elementMap._memberList[memberIndex]; |
| 1825 IndexedLibrary oldLibrary = oldMember.library; | 1808 IndexedLibrary oldLibrary = oldMember.library; |
| 1826 IndexedClass oldClass = oldMember.enclosingClass; | 1809 IndexedClass oldClass = oldMember.enclosingClass; |
| 1827 LibraryEntity newLibrary = _libraryList[oldLibrary.libraryIndex]; | 1810 LibraryEntity newLibrary = _libraryList[oldLibrary.libraryIndex]; |
| 1828 ClassEntity newClass = | 1811 ClassEntity newClass = |
| 1829 oldClass != null ? _classList[oldClass.classIndex] : null; | 1812 oldClass != null ? _classList[oldClass.classIndex] : null; |
| 1830 IndexedMember newMember = convertMember(newLibrary, newClass, oldMember); | 1813 IndexedMember newMember = convertMember(newLibrary, newClass, oldMember); |
| 1831 _memberList.add(newMember); | 1814 _memberList.add(newMember); |
| 1832 _memberData.add(data.copy()); | 1815 _memberData.add(data.copy()); |
| 1833 if (newMember.isField) { | 1816 if (newMember.isField) { |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1912 return constructor; | 1895 return constructor; |
| 1913 } | 1896 } |
| 1914 | 1897 |
| 1915 FunctionEntity getConstructorBody(ir.Constructor node) { | 1898 FunctionEntity getConstructorBody(ir.Constructor node) { |
| 1916 ConstructorEntity constructor = getConstructor(node); | 1899 ConstructorEntity constructor = getConstructor(node); |
| 1917 return _getConstructorBody(node, constructor); | 1900 return _getConstructorBody(node, constructor); |
| 1918 } | 1901 } |
| 1919 | 1902 |
| 1920 FunctionEntity _getConstructorBody( | 1903 FunctionEntity _getConstructorBody( |
| 1921 ir.Constructor node, covariant IndexedConstructor constructor) { | 1904 ir.Constructor node, covariant IndexedConstructor constructor) { |
| 1922 ConstructorData data = _memberData[constructor.memberIndex]; | 1905 ConstructorDataImpl data = _memberData[constructor.memberIndex]; |
| 1923 if (data.constructorBody == null) { | 1906 if (data.constructorBody == null) { |
| 1924 data.constructorBody = | 1907 ConstructorBodyEntity constructorBody = data.constructorBody = |
| 1925 createConstructorBody(_memberList.length, constructor); | 1908 createConstructorBody(_memberList.length, constructor); |
| 1926 _memberList.add(data.constructorBody); | 1909 _memberList.add(constructorBody); |
| 1927 _memberData.add(new FunctionData( | 1910 _memberData.add(new FunctionDataImpl( |
| 1928 node, | 1911 node, |
| 1929 node.function, | 1912 node.function, |
| 1930 new SpecialMemberDefinition( | 1913 new SpecialMemberDefinition( |
| 1931 data.constructorBody, node, MemberKind.constructorBody))); | 1914 constructorBody, node, MemberKind.constructorBody))); |
| 1915 IndexedClass cls = constructor.enclosingClass; |
| 1916 ClassEnvImpl classEnv = _classEnvs[cls.classIndex]; |
| 1917 // TODO(johnniwinther): Avoid this by only including live members in the |
| 1918 // js-model. |
| 1919 classEnv.addConstructorBody(constructorBody); |
| 1932 } | 1920 } |
| 1933 return data.constructorBody; | 1921 return data.constructorBody; |
| 1934 } | 1922 } |
| 1935 | 1923 |
| 1936 ConstructorBodyEntity createConstructorBody( | 1924 ConstructorBodyEntity createConstructorBody( |
| 1937 int memberIndex, ConstructorEntity constructor); | 1925 int memberIndex, ConstructorEntity constructor); |
| 1938 | 1926 |
| 1939 @override | 1927 @override |
| 1940 MemberDefinition getMemberDefinition(MemberEntity member) { | 1928 MemberDefinition getMemberDefinition(MemberEntity member) { |
| 1941 return _getMemberDefinition(member); | 1929 return _getMemberDefinition(member); |
| 1942 } | 1930 } |
| 1943 | 1931 |
| 1944 @override | 1932 @override |
| 1945 ClassDefinition getClassDefinition(ClassEntity cls) { | 1933 ClassDefinition getClassDefinition(ClassEntity cls) { |
| 1946 return _getClassDefinition(cls); | 1934 return _getClassDefinition(cls); |
| 1947 } | 1935 } |
| 1948 | 1936 |
| 1949 @override | 1937 @override |
| 1950 ConstantValue getFieldConstantValue(ir.Field field) { | 1938 ConstantValue getFieldConstantValue(ir.Field field) { |
| 1951 // TODO(johnniwinther): Cache the result in [FieldData]. | 1939 // TODO(johnniwinther): Cache the result in [FieldData]. |
| 1952 return getConstantValue(field.initializer, | 1940 return getConstantValue(field.initializer, |
| 1953 requireConstant: field.isConst, implicitNull: !field.isConst); | 1941 requireConstant: field.isConst, implicitNull: !field.isConst); |
| 1954 } | 1942 } |
| 1955 | 1943 |
| 1956 bool hasConstantFieldInitializer(covariant IndexedField field) { | 1944 bool hasConstantFieldInitializer(covariant IndexedField field) { |
| 1957 FieldData data = _memberData[field.memberIndex]; | 1945 FieldData data = _memberData[field.memberIndex]; |
| 1958 return getFieldConstantValue(data.node) != null; | 1946 return getFieldConstantValue(data.definition.node) != null; |
| 1959 } | 1947 } |
| 1960 | 1948 |
| 1961 ConstantValue getConstantFieldInitializer(covariant IndexedField field) { | 1949 ConstantValue getConstantFieldInitializer(covariant IndexedField field) { |
| 1962 FieldData data = _memberData[field.memberIndex]; | 1950 FieldData data = _memberData[field.memberIndex]; |
| 1963 ConstantValue value = getFieldConstantValue(data.node); | 1951 ConstantValue value = getFieldConstantValue(data.definition.node); |
| 1964 assert(value != null, | 1952 assert(value != null, |
| 1965 failedAt(field, "Field $field doesn't have a constant initial value.")); | 1953 failedAt(field, "Field $field doesn't have a constant initial value.")); |
| 1966 return value; | 1954 return value; |
| 1967 } | 1955 } |
| 1968 | 1956 |
| 1969 void forEachParameter(covariant IndexedFunction function, | 1957 void forEachParameter(covariant IndexedFunction function, |
| 1970 void f(DartType type, String name, ConstantValue defaultValue)) { | 1958 void f(DartType type, String name, ConstantValue defaultValue)) { |
| 1971 FunctionData data = _memberData[function.memberIndex]; | 1959 FunctionData data = _memberData[function.memberIndex]; |
| 1972 data.forEachParameter(this, f); | 1960 data.forEachParameter(this, f); |
| 1973 } | 1961 } |
| 1974 | 1962 |
| 1975 void _forEachConstructorBody( | 1963 void _forEachConstructorBody( |
| 1976 IndexedClass cls, void f(ConstructorBodyEntity member)) { | 1964 IndexedClass cls, void f(ConstructorBodyEntity member)) { |
| 1977 ClassEnv env = _classEnvs[cls.classIndex]; | 1965 ClassEnv env = _classEnvs[cls.classIndex]; |
| 1978 env.forEachConstructor((ir.Member member) { | 1966 env.forEachConstructorBody(f); |
| 1979 IndexedConstructor constructor = _constructorMap[member]; | |
| 1980 if (constructor == null) { | |
| 1981 // The constructor is not live. | |
| 1982 return; | |
| 1983 } | |
| 1984 ConstructorData data = _memberData[constructor.memberIndex]; | |
| 1985 if (data.constructorBody != null) { | |
| 1986 f(data.constructorBody); | |
| 1987 } | |
| 1988 }); | |
| 1989 } | 1967 } |
| 1990 | 1968 |
| 1991 KernelClosureClass constructClosureClass( | 1969 KernelClosureClass constructClosureClass( |
| 1992 MemberEntity member, | 1970 MemberEntity member, |
| 1993 ir.FunctionNode node, | 1971 ir.FunctionNode node, |
| 1994 JLibrary enclosingLibrary, | 1972 JLibrary enclosingLibrary, |
| 1995 KernelScopeInfo info, | 1973 KernelScopeInfo info, |
| 1996 ir.Location location, | 1974 ir.Location location, |
| 1997 KernelToLocalsMap localsMap, | 1975 KernelToLocalsMap localsMap, |
| 1998 InterfaceType supertype) { | 1976 InterfaceType supertype) { |
| 1999 String name = _computeClosureName(node); | 1977 String name = _computeClosureName(node); |
| 2000 KernelClosureClass cls = new KernelClosureClass.fromScopeInfo(node, name, | 1978 KernelClosureClass cls = new KernelClosureClass.fromScopeInfo( |
| 2001 _classEnvs.length, enclosingLibrary, info, location, localsMap); | 1979 node, name, _classEnvs.length, enclosingLibrary, info, localsMap); |
| 2002 _classList.add(cls); | 1980 _classList.add(cls); |
| 2003 _classEnvs.add(new ClassEnv.closureClass()); | 1981 Map<String, MemberEntity> memberMap = <String, MemberEntity>{}; |
| 1982 _classEnvs.add(new ClosureClassEnv(memberMap)); |
| 2004 | 1983 |
| 2005 // Create a classData and set up the interfaces and subclass | 1984 // Create a classData and set up the interfaces and subclass |
| 2006 // relationships that _ensureSupertypes and _ensureThisAndRawType are doing | 1985 // relationships that _ensureSupertypes and _ensureThisAndRawType are doing |
| 2007 var closureData = | 1986 var closureData = new ClassData(null, |
| 2008 new ClassData(null, new ClosureClassDefinition(cls, cls.location)); | 1987 new ClosureClassDefinition(cls, computeSourceSpanFromTreeNode(node))); |
| 2009 closureData | 1988 closureData |
| 2010 ..isMixinApplication = false | 1989 ..isMixinApplication = false |
| 2011 ..thisType = | 1990 ..thisType = |
| 2012 closureData.rawType = new InterfaceType(cls, const/*<DartType>*/ []) | 1991 closureData.rawType = new InterfaceType(cls, const/*<DartType>*/ []) |
| 2013 ..supertype = supertype | 1992 ..supertype = supertype |
| 2014 ..interfaces = const <InterfaceType>[]; | 1993 ..interfaces = const <InterfaceType>[]; |
| 2015 var setBuilder = new _KernelOrderedTypeSetBuilder(this, cls); | 1994 var setBuilder = new _KernelOrderedTypeSetBuilder(this, cls); |
| 2016 _classData.add(closureData); | 1995 _classData.add(closureData); |
| 2017 closureData.orderedTypeSet = setBuilder.createOrderedTypeSet( | 1996 closureData.orderedTypeSet = setBuilder.createOrderedTypeSet( |
| 2018 closureData.supertype, const Link<InterfaceType>()); | 1997 closureData.supertype, const Link<InterfaceType>()); |
| 2019 | 1998 |
| 2020 int i = 0; | 1999 int i = 0; |
| 2021 for (ir.VariableDeclaration variable in info.freeVariables) { | 2000 for (ir.VariableDeclaration variable in info.freeVariables) { |
| 2022 // Make a corresponding field entity in this closure class for every | 2001 // Make a corresponding field entity in this closure class for every |
| 2023 // single freeVariable in the KernelScopeInfo.freeVariable. | 2002 // single freeVariable in the KernelScopeInfo.freeVariable. |
| 2024 _constructClosureFields( | 2003 _constructClosureFields(member, cls, memberMap, variable, i, |
| 2025 member, cls, variable, i, info.capturedVariablesAccessor, localsMap); | 2004 info.capturedVariablesAccessor, localsMap); |
| 2026 i++; | 2005 i++; |
| 2027 } | 2006 } |
| 2028 | 2007 |
| 2029 cls.callMethod = new JClosureCallMethod(_memberData.length, cls, member); | 2008 FunctionEntity callMethod = cls.callMethod = new JClosureCallMethod( |
| 2009 _memberData.length, |
| 2010 cls, |
| 2011 _getParameterStructure(node), |
| 2012 _getAsyncMarker(node)); |
| 2030 _memberList.add(cls.callMethod); | 2013 _memberList.add(cls.callMethod); |
| 2031 _memberData.add(new MemberData( | |
| 2032 null, | |
| 2033 new ClosureMemberDefinition( | |
| 2034 member, cls.location, MemberKind.closureCall, node.parent))); | |
| 2035 | 2014 |
| 2036 // TODO(efortuna): Does getMetadata get called in ClassData for this object? | 2015 _memberData.add(new ClosureFunctionData( |
| 2016 new ClosureMemberDefinition(callMethod, closureData.definition.location, |
| 2017 MemberKind.closureCall, node.parent), |
| 2018 getFunctionType(node))); |
| 2019 memberMap[cls.callMethod.name] = cls.callMethod; |
| 2037 return cls; | 2020 return cls; |
| 2038 } | 2021 } |
| 2039 | 2022 |
| 2040 _constructClosureFields( | 2023 _constructClosureFields( |
| 2041 MemberEntity member, | 2024 MemberEntity member, |
| 2042 KernelClosureClass cls, | 2025 KernelClosureClass cls, |
| 2026 Map<String, MemberEntity> memberMap, |
| 2043 ir.VariableDeclaration variable, | 2027 ir.VariableDeclaration variable, |
| 2044 int fieldNumber, | 2028 int fieldNumber, |
| 2045 NodeBox box, | 2029 NodeBox box, |
| 2046 KernelToLocalsMap localsMap) { | 2030 KernelToLocalsMap localsMap) { |
| 2047 // NOTE: This construction order may be slightly different than the | 2031 // NOTE: This construction order may be slightly different than the |
| 2048 // old Element version. The old version did all the boxed items and then | 2032 // old Element version. The old version did all the boxed items and then |
| 2049 // all the others. | 2033 // all the others. |
| 2050 Local capturedLocal = localsMap.getLocalVariable(variable); | 2034 Local capturedLocal = localsMap.getLocalVariable(variable); |
| 2051 if (cls.isBoxed(capturedLocal)) { | 2035 if (cls.isBoxed(capturedLocal)) { |
| 2052 var boxedField = new JBoxedField( | 2036 FieldEntity boxedField = new JBoxedField( |
| 2053 _getClosureVariableName(capturedLocal.name, fieldNumber), | 2037 _getClosureVariableName(capturedLocal.name, fieldNumber), |
| 2054 _memberData.length, | 2038 _memberData.length, |
| 2055 new BoxLocal(box.name, | 2039 new BoxLocal(box.name, |
| 2056 localsMap.getLocalVariable(box.executableContext), member), | 2040 localsMap.getLocalVariable(box.executableContext), member), |
| 2057 cls, | 2041 cls, |
| 2058 variable.isConst, | 2042 variable.isConst, |
| 2059 variable.isFinal || variable.isConst); | 2043 variable.isFinal || variable.isConst); |
| 2060 cls.localToFieldMap[capturedLocal] = boxedField; | 2044 cls.localToFieldMap[capturedLocal] = boxedField; |
| 2061 _memberList.add(boxedField); | 2045 _memberList.add(boxedField); |
| 2062 _memberData.add(new MemberData( | 2046 _memberData.add(new ClosureFieldData(new ClosureMemberDefinition( |
| 2063 null, | 2047 boxedField, |
| 2064 new ClosureMemberDefinition(boxedField, variable.location, | 2048 computeSourceSpanFromTreeNode(variable), |
| 2065 MemberKind.closureField, variable))); | 2049 MemberKind.closureField, |
| 2050 variable))); |
| 2051 memberMap[boxedField.name] = boxedField; |
| 2066 } else { | 2052 } else { |
| 2067 var closureField = new JClosureField( | 2053 FieldEntity closureField = new JClosureField( |
| 2068 _getClosureVariableName(capturedLocal.name, fieldNumber), | 2054 _getClosureVariableName(capturedLocal.name, fieldNumber), |
| 2069 _memberData.length, | 2055 _memberData.length, |
| 2070 cls, | 2056 cls, |
| 2071 variable.isConst, | 2057 variable.isConst, |
| 2072 variable.isFinal || variable.isConst); | 2058 variable.isFinal || variable.isConst); |
| 2073 cls.localToFieldMap[capturedLocal] = closureField; | 2059 cls.localToFieldMap[capturedLocal] = closureField; |
| 2074 _memberList.add(closureField); | 2060 _memberList.add(closureField); |
| 2075 _memberData.add(new MemberData( | 2061 _memberData.add(new ClosureFieldData(new ClosureMemberDefinition( |
| 2076 null, | 2062 cls.localToFieldMap[capturedLocal], |
| 2077 new ClosureMemberDefinition(cls.localToFieldMap[capturedLocal], | 2063 computeSourceSpanFromTreeNode(variable), |
| 2078 variable.location, MemberKind.closureField, variable))); | 2064 MemberKind.closureField, |
| 2065 variable))); |
| 2066 memberMap[closureField.name] = closureField; |
| 2079 } | 2067 } |
| 2080 } | 2068 } |
| 2081 | 2069 |
| 2082 // Returns a non-unique name for the given closure element. | 2070 // Returns a non-unique name for the given closure element. |
| 2083 String _computeClosureName(ir.TreeNode treeNode) { | 2071 String _computeClosureName(ir.TreeNode treeNode) { |
| 2084 var parts = <String>[]; | 2072 var parts = <String>[]; |
| 2085 if (treeNode is ir.Field && treeNode.name.name != "") { | 2073 if (treeNode is ir.Field && treeNode.name.name != "") { |
| 2086 parts.add(treeNode.name.name); | 2074 parts.add(treeNode.name.name); |
| 2087 } else { | 2075 } else { |
| 2088 parts.add('closure'); | 2076 parts.add('closure'); |
| 2089 } | 2077 } |
| 2090 ir.TreeNode node = treeNode.parent; | 2078 ir.TreeNode node = treeNode.parent; |
| 2091 while (node != null && | 2079 while (node != null) { |
| 2092 (node is ir.Constructor || | |
| 2093 node is ir.Class || | |
| 2094 node is ir.FunctionNode || | |
| 2095 node is ir.Procedure)) { | |
| 2096 // TODO(johnniwinther): Simplify computed names. | 2080 // TODO(johnniwinther): Simplify computed names. |
| 2097 if (node is ir.Constructor || | 2081 if (node is ir.Constructor || |
| 2098 node.parent is ir.Constructor || | 2082 node.parent is ir.Constructor || |
| 2099 (node is ir.Procedure && node.kind == ir.ProcedureKind.Factory)) { | 2083 (node is ir.Procedure && node.kind == ir.ProcedureKind.Factory)) { |
| 2100 FunctionEntity entity; | 2084 FunctionEntity entity; |
| 2101 if (node.parent is ir.Constructor) { | 2085 if (node.parent is ir.Constructor) { |
| 2102 entity = getConstructorBody(node); | 2086 entity = getConstructorBody(node); |
| 2103 } else { | 2087 } else { |
| 2104 entity = getMember(node); | 2088 entity = getMember(node); |
| 2105 } | 2089 } |
| 2106 parts.add(utils.reconstructConstructorName(entity)); | 2090 parts.add(utils.reconstructConstructorName(entity)); |
| 2107 } else { | 2091 } else { |
| 2108 String surroundingName = ''; | |
| 2109 if (node is ir.Class) { | 2092 if (node is ir.Class) { |
| 2110 surroundingName = Elements.operatorNameToIdentifier(node.name); | 2093 parts.add(Elements.operatorNameToIdentifier(node.name)); |
| 2111 } else if (node is ir.Procedure) { | 2094 } else if (node is ir.Procedure) { |
| 2112 surroundingName = Elements.operatorNameToIdentifier(node.name.name); | 2095 parts.add(Elements.operatorNameToIdentifier(node.name.name)); |
| 2113 } | 2096 } |
| 2114 parts.add(surroundingName); | |
| 2115 } | 2097 } |
| 2116 // A generative constructors's parent is the class; the class name is | 2098 // A generative constructors's parent is the class; the class name is |
| 2117 // already part of the generative constructor's name. | 2099 // already part of the generative constructor's name. |
| 2118 if (node is ir.Constructor) break; | 2100 if (node is ir.Constructor) break; |
| 2119 node = node.parent; | 2101 node = node.parent; |
| 2120 } | 2102 } |
| 2121 return parts.reversed.join('_'); | 2103 return parts.reversed.join('_'); |
| 2122 } | 2104 } |
| 2123 | 2105 |
| 2124 /// Generate a unique name for the [id]th closure field, with proposed name | 2106 /// Generate a unique name for the [id]th closure field, with proposed name |
| 2125 /// [name]. | 2107 /// [name]. |
| 2126 /// | 2108 /// |
| 2127 /// The result is used as the name of [ClosureFieldElement]s, and must | 2109 /// The result is used as the name of [ClosureFieldElement]s, and must |
| 2128 /// therefore be unique to avoid breaking an invariant in the element model | 2110 /// therefore be unique to avoid breaking an invariant in the element model |
| 2129 /// (classes cannot declare multiple fields with the same name). | 2111 /// (classes cannot declare multiple fields with the same name). |
| 2130 /// | 2112 /// |
| 2131 /// Also, the names should be distinct from real field names to prevent | 2113 /// Also, the names should be distinct from real field names to prevent |
| 2132 /// clashes with selectors for those fields. | 2114 /// clashes with selectors for those fields. |
| 2133 /// | 2115 /// |
| 2134 /// These names are not used in generated code, just as element name. | 2116 /// These names are not used in generated code, just as element name. |
| 2135 String _getClosureVariableName(String name, int id) { | 2117 String _getClosureVariableName(String name, int id) { |
| 2136 return "_captured_${name}_$id"; | 2118 return "_captured_${name}_$id"; |
| 2137 } | 2119 } |
| 2138 | 2120 |
| 2139 String getDeferredUri(ir.LibraryDependency node) { | 2121 String getDeferredUri(ir.LibraryDependency node) { |
| 2140 throw new UnimplementedError('JsKernelToElementMap.getDeferredUri'); | 2122 throw new UnimplementedError('JsKernelToElementMap.getDeferredUri'); |
| 2141 } | 2123 } |
| 2142 } | 2124 } |
| OLD | NEW |