Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(688)

Side by Side Diff: pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart

Issue 2925263002: A step towards handling `new Object()` in compile_from_dill_test (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library dart2js.js_emitter.program_builder; 5 library dart2js.js_emitter.program_builder;
6 6
7 import 'dart:io'; 7 import 'dart:io';
8 import 'dart:convert' show JSON; 8 import 'dart:convert' show JSON;
9 9
10 import '../../closure.dart' show ClosureTask, ClosureFieldElement; 10 import '../../closure.dart' show ClosureTask, ClosureFieldElement;
11 import '../../common.dart'; 11 import '../../common.dart';
12 import '../../common/names.dart' show Names, Selectors; 12 import '../../common/names.dart' show Names, Selectors;
13 import '../../constants/values.dart' 13 import '../../constants/values.dart'
14 show ConstantValue, InterceptorConstantValue; 14 show ConstantValue, InterceptorConstantValue;
15 import '../../common_elements.dart' show CommonElements, ElementEnvironment; 15 import '../../common_elements.dart' show CommonElements, ElementEnvironment;
16 import '../../deferred_load.dart' show DeferredLoadTask, OutputUnit; 16 import '../../deferred_load.dart' show DeferredLoadTask, OutputUnit;
17 import '../../elements/elements.dart' 17 import '../../elements/elements.dart'
18 show 18 show
19 ClassElement, 19 ClassElement,
20 ConstructorBodyElement,
20 Element, 21 Element,
21 Elements, 22 Elements,
22 FieldElement, 23 FieldElement,
23 FunctionElement, 24 FunctionElement,
24 FunctionSignature, 25 FunctionSignature,
25 GetterElement, 26 GetterElement,
26 LibraryElement, 27 LibraryElement,
27 MemberElement, 28 MemberElement,
28 MethodElement, 29 MethodElement,
29 ParameterElement, 30 ParameterElement,
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 if (superclass != null) { 230 if (superclass != null) {
230 c.setSuperclass(_classes[superclass]); 231 c.setSuperclass(_classes[superclass]);
231 assert( 232 assert(
232 c.superclass != null, 233 c.superclass != null,
233 failedAt( 234 failedAt(
234 cls, 235 cls,
235 "No Class for has been created for superclass " 236 "No Class for has been created for superclass "
236 "${superclass} of $c.")); 237 "${superclass} of $c."));
237 } 238 }
238 if (c is MixinApplication) { 239 if (c is MixinApplication) {
239 c.setMixinClass(_classes[computeMixinClass(cls)]); 240 c.setMixinClass(_classes[computeMixinClass(cls)]);
Siggi Cherem (dart-lang) 2017/06/08 18:01:46 should we do here the same fix you did in the othe
Johnni Winther 2017/06/09 09:28:49 ElementEnvironment.forEachMixin returns all mixins
Siggi Cherem (dart-lang) 2017/06/14 18:13:24 are you saying that the code in program_builder/co
Johnni Winther 2017/06/15 07:44:11 It wasn't - just weird: computeMixinClass didn't m
240 assert(c.mixinClass != null); 241 assert(c.mixinClass != null);
241 } 242 }
242 }); 243 });
243 244
244 List<Class> nativeClasses = collector.nativeClassesAndSubclasses 245 List<Class> nativeClasses = collector.nativeClassesAndSubclasses
245 .map((ClassEntity classElement) => _classes[classElement]) 246 .map((ClassEntity classElement) => _classes[classElement])
246 .toList(); 247 .toList();
247 248
248 Set<ClassEntity> interceptorClassesNeededByConstants = 249 Set<ClassEntity> interceptorClassesNeededByConstants =
249 collector.computeInterceptorsReferencedFromConstants(); 250 collector.computeInterceptorsReferencedFromConstants();
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 // Interceptor class with implementations that directly call the 511 // Interceptor class with implementations that directly call the
511 // corresponding JavaScript member. We do not attempt to bind this when 512 // corresponding JavaScript member. We do not attempt to bind this when
512 // tearing off JavaScript methods as we cannot distinguish between calling 513 // tearing off JavaScript methods as we cannot distinguish between calling
513 // a regular getter that returns a JavaScript function and tearing off 514 // a regular getter that returns a JavaScript function and tearing off
514 // a method in the case where there exist multiple JavaScript classes 515 // a method in the case where there exist multiple JavaScript classes
515 // that conflict on whether the member is a getter or a method. 516 // that conflict on whether the member is a getter or a method.
516 var interceptorClass = _classes[_commonElements.jsJavaScriptObjectClass]; 517 var interceptorClass = _classes[_commonElements.jsJavaScriptObjectClass];
517 var stubNames = new Set<String>(); 518 var stubNames = new Set<String>();
518 librariesMap 519 librariesMap
519 .forEach((LibraryEntity library, List<ClassEntity> classElements, _) { 520 .forEach((LibraryEntity library, List<ClassEntity> classElements, _) {
520 for (ClassElement e in classElements) { 521 for (ClassEntity cls in classElements) {
521 if (_nativeData.isJsInteropClass(e)) { 522 if (_nativeData.isJsInteropClass(cls)) {
523 // TODO(johnniwinther): Handle class entities.
524 ClassElement e = cls;
522 e.declaration.forEachMember((_, Element member) { 525 e.declaration.forEachMember((_, Element member) {
523 var jsName = _nativeData.computeUnescapedJSInteropName(member.name); 526 var jsName = _nativeData.computeUnescapedJSInteropName(member.name);
524 if (!member.isInstanceMember) return; 527 if (!member.isInstanceMember) return;
525 if (member.isGetter || member.isField || member.isFunction) { 528 if (member.isGetter || member.isField || member.isFunction) {
526 var selectors = 529 var selectors =
527 _worldBuilder.getterInvocationsByName(member.name); 530 _worldBuilder.getterInvocationsByName(member.name);
528 if (selectors != null && !selectors.isEmpty) { 531 if (selectors != null && !selectors.isEmpty) {
529 for (var selector in selectors.keys) { 532 for (var selector in selectors.keys) {
530 var stubName = _namer.invocationName(selector); 533 var stubName = _namer.invocationName(selector);
531 if (stubNames.add(stubName.key)) { 534 if (stubNames.add(stubName.key)) {
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
656 .toList(growable: false); 659 .toList(growable: false);
657 660
658 bool visitStatics = true; 661 bool visitStatics = true;
659 List<Field> staticFieldsForReflection = 662 List<Field> staticFieldsForReflection =
660 _buildFields(library: library, visitStatics: visitStatics); 663 _buildFields(library: library, visitStatics: visitStatics);
661 664
662 return new Library( 665 return new Library(
663 library, uri, statics, classes, staticFieldsForReflection); 666 library, uri, statics, classes, staticFieldsForReflection);
664 } 667 }
665 668
666 bool _isSoftDeferred(ClassElement element) { 669 bool _isSoftDeferred(ClassEntity element) {
667 return _notSoftDeferred != null && !_notSoftDeferred.contains(element); 670 return _notSoftDeferred != null && !_notSoftDeferred.contains(element);
668 } 671 }
669 672
670 Class _buildClass(ClassElement element) { 673 Class _buildClass(ClassEntity cls) {
671 bool onlyForRti = collector.classesOnlyNeededForRti.contains(element); 674 bool onlyForRti = collector.classesOnlyNeededForRti.contains(cls);
672 bool hasRtiField = _rtiNeed.classNeedsRtiField(element); 675 bool hasRtiField = _rtiNeed.classNeedsRtiField(cls);
673 if (_nativeData.isJsInteropClass(element)) { 676 if (_nativeData.isJsInteropClass(cls)) {
674 // TODO(jacobr): check whether the class has any active static fields 677 // TODO(jacobr): check whether the class has any active static fields
675 // if it does not we can suppress it completely. 678 // if it does not we can suppress it completely.
676 onlyForRti = true; 679 onlyForRti = true;
677 } 680 }
678 bool isClosureBaseClass = element == _commonElements.closureClass; 681 bool isClosureBaseClass = cls == _commonElements.closureClass;
679 682
680 List<Method> methods = []; 683 List<Method> methods = [];
681 List<StubMethod> callStubs = <StubMethod>[]; 684 List<StubMethod> callStubs = <StubMethod>[];
682 685
683 ClassStubGenerator classStubGenerator = new ClassStubGenerator( 686 ClassStubGenerator classStubGenerator = new ClassStubGenerator(
684 _task.emitter, _commonElements, _namer, _worldBuilder, _closedWorld, 687 _task.emitter, _commonElements, _namer, _worldBuilder, _closedWorld,
685 enableMinification: _options.enableMinification); 688 enableMinification: _options.enableMinification);
686 RuntimeTypeGenerator runtimeTypeGenerator = new RuntimeTypeGenerator( 689 RuntimeTypeGenerator runtimeTypeGenerator = new RuntimeTypeGenerator(
687 _commonElements, 690 _commonElements,
688 _closureToClassMapper, 691 _closureToClassMapper,
689 _task, 692 _task,
690 _namer, 693 _namer,
691 _nativeData, 694 _nativeData,
692 _rtiChecks, 695 _rtiChecks,
693 _rtiEncoder, 696 _rtiEncoder,
694 _rtiNeed, 697 _rtiNeed,
695 _rtiSubstitutions, 698 _rtiSubstitutions,
696 _jsInteropAnalysis); 699 _jsInteropAnalysis);
697 700
698 void visitMember(ClassElement enclosing, MemberElement member) { 701 void visitMember(ClassEntity declarer, MemberEntity member) {
699 assert(member.isDeclaration, failedAt(element)); 702 if (cls != declarer) return;
700 assert(element == enclosing, failedAt(element));
701 703
702 if (Elements.isNonAbstractInstanceMember(member)) { 704 if (member.isInstanceMember && !member.isAbstract && !member.isField) {
703 // TODO(herhut): Remove once _buildMethod can no longer return null. 705 // TODO(herhut): Remove once _buildMethod can no longer return null.
704 Method method = _buildMethod(member); 706 Method method = _buildMethod(member);
705 if (method != null) methods.add(method); 707 if (method != null) methods.add(method);
706 } 708 }
707 if (member.isGetter || member.isField) { 709 if (member.isGetter || member.isField) {
708 Map<Selector, SelectorConstraints> selectors = 710 Map<Selector, SelectorConstraints> selectors =
709 _worldBuilder.invocationsByName(member.name); 711 _worldBuilder.invocationsByName(member.name);
710 if (selectors != null && !selectors.isEmpty) { 712 if (selectors != null && !selectors.isEmpty) {
711 Map<js.Name, js.Expression> callStubsForMember = 713 Map<js.Name, js.Expression> callStubsForMember =
712 classStubGenerator.generateCallStubsForGetter(member, selectors); 714 classStubGenerator.generateCallStubsForGetter(member, selectors);
713 callStubsForMember.forEach((js.Name name, js.Expression code) { 715 callStubsForMember.forEach((js.Name name, js.Expression code) {
714 callStubs.add(_buildStubMethod(name, code, element: member)); 716 callStubs.add(_buildStubMethod(name, code, element: member));
715 }); 717 });
716 } 718 }
717 } 719 }
718 } 720 }
719 721
720 List<StubMethod> noSuchMethodStubs = <StubMethod>[]; 722 List<StubMethod> noSuchMethodStubs = <StubMethod>[];
721 723
722 if (_backendUsage.isNoSuchMethodUsed && element.isObject) { 724 if (_backendUsage.isNoSuchMethodUsed &&
725 cls == _commonElements.objectClass) {
723 Map<js.Name, Selector> selectors = 726 Map<js.Name, Selector> selectors =
724 classStubGenerator.computeSelectorsForNsmHandlers(); 727 classStubGenerator.computeSelectorsForNsmHandlers();
725 selectors.forEach((js.Name name, Selector selector) { 728 selectors.forEach((js.Name name, Selector selector) {
726 // If the program contains `const Symbol` names we have to retain them. 729 // If the program contains `const Symbol` names we have to retain them.
727 String selectorName = selector.name; 730 String selectorName = selector.name;
728 if (selector.isSetter) selectorName = "$selectorName="; 731 if (selector.isSetter) selectorName = "$selectorName=";
729 if (_mirrorsData.symbolsUsed.contains(selectorName)) { 732 if (_mirrorsData.symbolsUsed.contains(selectorName)) {
730 _symbolsMap[name] = selectorName; 733 _symbolsMap[name] = selectorName;
731 } 734 }
732 noSuchMethodStubs.add( 735 noSuchMethodStubs.add(
733 classStubGenerator.generateStubForNoSuchMethod(name, selector)); 736 classStubGenerator.generateStubForNoSuchMethod(name, selector));
734 }); 737 });
735 } 738 }
736 739
737 if (isClosureBaseClass) { 740 if (isClosureBaseClass) {
738 // We add a special getter to allow for tearing off a closure from itself. 741 // We add a special getter to allow for tearing off a closure from itself.
739 js.Name name = _namer.getterForMember(Names.call); 742 js.Name name = _namer.getterForMember(Names.call);
740 js.Fun function = js.js('function() { return this; }'); 743 js.Fun function = js.js('function() { return this; }');
741 callStubs.add(_buildStubMethod(name, function)); 744 callStubs.add(_buildStubMethod(name, function));
742 } 745 }
743 746
744 ClassElement implementation = element.implementation;
745
746 // MixinApplications run through the members of their mixin. Here, we are 747 // MixinApplications run through the members of their mixin. Here, we are
747 // only interested in direct members. 748 // only interested in direct members.
748 if (!onlyForRti && !element.isMixinApplication) { 749 if (!onlyForRti && !_elementEnvironment.isUnnamedMixinApplication(cls)) {
749 implementation.forEachMember(visitMember, includeBackendMembers: true); 750 _elementEnvironment.forEachClassMember(cls, visitMember);
751 if (cls is ClassElement) {
752 // TODO(johnniwinther): Support constructor bodies for entities.
753 cls.forEachBackendMember((ConstructorBodyElement constructorBody) =>
754 visitMember(cls, constructorBody));
755 }
750 } 756 }
751 bool isInterceptedClass = _interceptorData.isInterceptedClass(element); 757 bool isInterceptedClass = _interceptorData.isInterceptedClass(cls);
752 List<Field> instanceFields = onlyForRti 758 List<Field> instanceFields = onlyForRti
753 ? const <Field>[] 759 ? const <Field>[]
754 : _buildFields( 760 : _buildFields(
755 cls: element, 761 cls: cls,
756 visitStatics: false, 762 visitStatics: false,
757 isHolderInterceptedClass: isInterceptedClass); 763 isHolderInterceptedClass: isInterceptedClass);
758 List<Field> staticFieldsForReflection = onlyForRti 764 List<Field> staticFieldsForReflection = onlyForRti
759 ? const <Field>[] 765 ? const <Field>[]
760 : _buildFields( 766 : _buildFields(
761 cls: element, 767 cls: cls,
762 visitStatics: true, 768 visitStatics: true,
763 isHolderInterceptedClass: isInterceptedClass); 769 isHolderInterceptedClass: isInterceptedClass);
764 770
765 TypeTestProperties typeTests = runtimeTypeGenerator.generateIsTests(element, 771 TypeTestProperties typeTests = runtimeTypeGenerator.generateIsTests(cls,
766 storeFunctionTypeInMetadata: _storeFunctionTypesInMetadata); 772 storeFunctionTypeInMetadata: _storeFunctionTypesInMetadata);
767 773
768 List<StubMethod> checkedSetters = <StubMethod>[]; 774 List<StubMethod> checkedSetters = <StubMethod>[];
769 List<StubMethod> isChecks = <StubMethod>[]; 775 List<StubMethod> isChecks = <StubMethod>[];
770 if (_nativeData.isJsInteropClass(element)) { 776 if (_nativeData.isJsInteropClass(cls)) {
771 typeTests.properties.forEach((js.Name name, js.Node code) { 777 typeTests.properties.forEach((js.Name name, js.Node code) {
772 _classes[_commonElements.jsInterceptorClass] 778 _classes[_commonElements.jsInterceptorClass]
773 .isChecks 779 .isChecks
774 .add(_buildStubMethod(name, code)); 780 .add(_buildStubMethod(name, code));
775 }); 781 });
776 } else { 782 } else {
777 for (Field field in instanceFields) { 783 for (Field field in instanceFields) {
778 if (field.needsCheckedSetter) { 784 if (field.needsCheckedSetter) {
779 assert(!field.needsUncheckedSetter); 785 assert(!field.needsUncheckedSetter);
780 FieldElement element = field.element; 786 FieldElement element = field.element;
781 js.Expression code = _generatedCode[element]; 787 js.Expression code = _generatedCode[element];
782 assert(code != null); 788 assert(code != null);
783 js.Name name = _namer.deriveSetterName(field.accessorName); 789 js.Name name = _namer.deriveSetterName(field.accessorName);
784 checkedSetters.add(_buildStubMethod(name, code, element: element)); 790 checkedSetters.add(_buildStubMethod(name, code, element: element));
785 } 791 }
786 } 792 }
787 793
788 typeTests.properties.forEach((js.Name name, js.Node code) { 794 typeTests.properties.forEach((js.Name name, js.Node code) {
789 isChecks.add(_buildStubMethod(name, code)); 795 isChecks.add(_buildStubMethod(name, code));
790 }); 796 });
791 } 797 }
792 798
793 js.Name name = _namer.className(element); 799 js.Name name = _namer.className(cls);
794 String holderName = _namer.globalObjectForClass(element); 800 String holderName = _namer.globalObjectForClass(cls);
795 // TODO(floitsch): we shouldn't update the registry in the middle of 801 // TODO(floitsch): we shouldn't update the registry in the middle of
796 // building a class. 802 // building a class.
797 Holder holder = _registry.registerHolder(holderName); 803 Holder holder = _registry.registerHolder(holderName);
798 bool isInstantiated = !_nativeData.isJsInteropClass(element) && 804 bool isInstantiated = !_nativeData.isJsInteropClass(cls) &&
799 _worldBuilder.directlyInstantiatedClasses.contains(element); 805 _worldBuilder.directlyInstantiatedClasses.contains(cls);
800 806
801 Class result; 807 Class result;
802 if (element.isMixinApplication && !onlyForRti) { 808 if (_elementEnvironment.isUnnamedMixinApplication(cls) && !onlyForRti) {
803 assert(!_nativeData.isNativeClass(element)); 809 assert(!_nativeData.isNativeClass(cls));
804 assert(methods.isEmpty); 810 assert(methods.isEmpty);
805 assert(!isClosureBaseClass); 811 assert(!isClosureBaseClass);
806 812
807 result = new MixinApplication( 813 result = new MixinApplication(
808 element, 814 cls,
809 name, 815 name,
810 holder, 816 holder,
811 instanceFields, 817 instanceFields,
812 staticFieldsForReflection, 818 staticFieldsForReflection,
813 callStubs, 819 callStubs,
814 checkedSetters, 820 checkedSetters,
815 isChecks, 821 isChecks,
816 typeTests.functionTypeIndex, 822 typeTests.functionTypeIndex,
817 isDirectlyInstantiated: isInstantiated, 823 isDirectlyInstantiated: isInstantiated,
818 hasRtiField: hasRtiField, 824 hasRtiField: hasRtiField,
819 onlyForRti: onlyForRti); 825 onlyForRti: onlyForRti);
820 } else { 826 } else {
821 result = new Class( 827 result = new Class(
822 element, 828 cls,
823 name, 829 name,
824 holder, 830 holder,
825 methods, 831 methods,
826 instanceFields, 832 instanceFields,
827 staticFieldsForReflection, 833 staticFieldsForReflection,
828 callStubs, 834 callStubs,
829 noSuchMethodStubs, 835 noSuchMethodStubs,
830 checkedSetters, 836 checkedSetters,
831 isChecks, 837 isChecks,
832 typeTests.functionTypeIndex, 838 typeTests.functionTypeIndex,
833 isDirectlyInstantiated: isInstantiated, 839 isDirectlyInstantiated: isInstantiated,
834 hasRtiField: hasRtiField, 840 hasRtiField: hasRtiField,
835 onlyForRti: onlyForRti, 841 onlyForRti: onlyForRti,
836 isNative: _nativeData.isNativeClass(element), 842 isNative: _nativeData.isNativeClass(cls),
837 isClosureBaseClass: isClosureBaseClass, 843 isClosureBaseClass: isClosureBaseClass,
838 isSoftDeferred: _isSoftDeferred(element)); 844 isSoftDeferred: _isSoftDeferred(cls));
839 } 845 }
840 _classes[element] = result; 846 _classes[cls] = result;
841 return result; 847 return result;
842 } 848 }
843 849
844 bool _methodNeedsStubs(FunctionEntity method) { 850 bool _methodNeedsStubs(FunctionEntity method) {
845 return method.parameterStructure.optionalParameters != 0; 851 return method.parameterStructure.optionalParameters != 0;
846 } 852 }
847 853
848 bool _methodCanBeReflected(FunctionEntity method) { 854 bool _methodCanBeReflected(FunctionEntity method) {
849 return _mirrorsData.isMemberAccessibleByReflection(method); 855 return _mirrorsData.isMemberAccessibleByReflection(method);
850 } 856 }
(...skipping 16 matching lines...) Expand all
867 optionalParameterDefaultValues = <ConstantValue>[]; 873 optionalParameterDefaultValues = <ConstantValue>[];
868 signature.forEachOptionalParameter((ParameterElement parameter) { 874 signature.forEachOptionalParameter((ParameterElement parameter) {
869 ConstantValue def = 875 ConstantValue def =
870 _constantHandler.getConstantValue(parameter.constant); 876 _constantHandler.getConstantValue(parameter.constant);
871 optionalParameterDefaultValues.add(def); 877 optionalParameterDefaultValues.add(def);
872 }); 878 });
873 } 879 }
874 return optionalParameterDefaultValues; 880 return optionalParameterDefaultValues;
875 } 881 }
876 882
877 DartMethod _buildMethod(MethodElement element) { 883 DartMethod _buildMethod(FunctionEntity element) {
878 assert(element.isDeclaration); 884 assert(!(element is MethodElement && !element.isDeclaration));
879 js.Name name = _namer.methodPropertyName(element); 885 js.Name name = _namer.methodPropertyName(element);
880 js.Expression code = _generatedCode[element]; 886 js.Expression code = _generatedCode[element];
881 887
882 // TODO(kasperl): Figure out under which conditions code is null. 888 // TODO(kasperl): Figure out under which conditions code is null.
883 if (code == null) return null; 889 if (code == null) return null;
884 890
885 bool canTearOff = false; 891 bool canTearOff = false;
886 js.Name tearOffName; 892 js.Name tearOffName;
887 bool isClosureCallMethod = false; 893 bool isClosureCallMethod = false;
888 bool isNotApplyTarget = !element.isFunction || element.isAccessor; 894 bool isNotApplyTarget =
895 !element.isFunction || element.isGetter || element.isSetter;
889 896
890 bool canBeReflected = _methodCanBeReflected(element); 897 bool canBeReflected = _methodCanBeReflected(element);
891 bool canBeApplied = _methodCanBeApplied(element); 898 bool canBeApplied = _methodCanBeApplied(element);
892 899
893 js.Name aliasName = _superMemberData.isAliasedSuperMember(element) 900 js.Name aliasName = _superMemberData.isAliasedSuperMember(element)
894 ? _namer.aliasedSuperMemberPropertyName(element) 901 ? _namer.aliasedSuperMemberPropertyName(element)
895 : null; 902 : null;
896 903
897 if (isNotApplyTarget) { 904 if (isNotApplyTarget) {
898 canTearOff = false; 905 canTearOff = false;
899 } else { 906 } else {
900 if (element.enclosingClass.isClosure) { 907 if (element.enclosingClass.isClosure) {
901 canTearOff = false; 908 canTearOff = false;
902 isClosureCallMethod = true; 909 isClosureCallMethod = true;
903 } else { 910 } else {
904 // Careful with operators. 911 // Careful with operators.
905 canTearOff = _worldBuilder.hasInvokedGetter(element, _closedWorld) || 912 canTearOff = _worldBuilder.hasInvokedGetter(element, _closedWorld) ||
906 (canBeReflected && !element.isOperator); 913 (canBeReflected && !Selector.isOperatorName(element.name));
907 assert(canTearOff || 914 assert(canTearOff ||
908 !_worldBuilder.methodsNeedingSuperGetter.contains(element)); 915 !_worldBuilder.methodsNeedingSuperGetter.contains(element));
909 tearOffName = _namer.getterForElement(element); 916 tearOffName = _namer.getterForElement(element);
910 } 917 }
911 } 918 }
912 919
913 if (canTearOff) { 920 if (canTearOff) {
914 assert(!element.isGenerativeConstructor, failedAt(element)); 921 assert(element is! ConstructorEntity, failedAt(element));
915 assert(!element.isGenerativeConstructorBody, failedAt(element)); 922 assert(element is! ConstructorBodyElement, failedAt(element));
916 assert(!element.isConstructor, failedAt(element));
917 } 923 }
918 924
919 js.Name callName = null; 925 js.Name callName = null;
920 if (canTearOff) { 926 if (canTearOff) {
921 Selector callSelector = 927 Selector callSelector =
922 new Selector.fromElement(element).toCallSelector(); 928 new Selector.fromElement(element).toCallSelector();
923 callName = _namer.invocationName(callSelector); 929 callName = _namer.invocationName(callSelector);
924 } 930 }
925 931
926 ResolutionDartType memberType; 932 DartType memberType = _elementEnvironment.getFunctionType(element);
927 if (element.isGenerativeConstructorBody) {
928 // TODO(herhut): Why does this need to be normalized away? We never need
929 // this information anyway as they cannot be torn off or
930 // reflected.
931 var body = element;
932 memberType = body.constructor.type;
933 } else {
934 memberType = element.type;
935 }
936
937 js.Expression functionType; 933 js.Expression functionType;
938 if (canTearOff || canBeReflected) { 934 if (canTearOff || canBeReflected) {
939 OutputUnit outputUnit = _deferredLoadTask.outputUnitForElement(element); 935 OutputUnit outputUnit = _deferredLoadTask.outputUnitForMember(element);
940 functionType = _generateFunctionType(memberType, outputUnit); 936 functionType = _generateFunctionType(memberType, outputUnit);
941 } 937 }
942 938
943 int requiredParameterCount; 939 int requiredParameterCount;
944 var /* List | Map */ optionalParameterDefaultValues; 940 var /* List | Map */ optionalParameterDefaultValues;
945 if (canBeApplied || canBeReflected) { 941 if (canBeApplied || canBeReflected) {
946 FunctionSignature signature = element.functionSignature; 942 // TODO(johnniwinther): Handle function entities.
943 MethodElement method = element;
944 FunctionSignature signature = method.functionSignature;
947 requiredParameterCount = signature.requiredParameterCount; 945 requiredParameterCount = signature.requiredParameterCount;
948 optionalParameterDefaultValues = 946 optionalParameterDefaultValues =
949 _computeParameterDefaultValues(signature); 947 _computeParameterDefaultValues(signature);
950 } 948 }
951 949
952 return new InstanceMethod(element, name, code, 950 return new InstanceMethod(element, name, code,
953 _generateParameterStubs(element, canTearOff), callName, 951 _generateParameterStubs(element, canTearOff), callName,
954 needsTearOff: canTearOff, 952 needsTearOff: canTearOff,
955 tearOffName: tearOffName, 953 tearOffName: tearOffName,
956 isClosureCallMethod: isClosureCallMethod, 954 isClosureCallMethod: isClosureCallMethod,
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
1185 Constant constant = new Constant(name, holder, constantValue); 1183 Constant constant = new Constant(name, holder, constantValue);
1186 _constants[constantValue] = constant; 1184 _constants[constantValue] = constant;
1187 } 1185 }
1188 } 1186 }
1189 1187
1190 Holder _registerStaticStateHolder() { 1188 Holder _registerStaticStateHolder() {
1191 return _registry.registerHolder(_namer.staticStateHolder, 1189 return _registry.registerHolder(_namer.staticStateHolder,
1192 isStaticStateHolder: true); 1190 isStaticStateHolder: true);
1193 } 1191 }
1194 } 1192 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698