OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 /** | 5 /** |
6 * A function element that represents a closure call. The signature is copied | 6 * A function element that represents a closure call. The signature is copied |
7 * from the given element. | 7 * from the given element. |
8 */ | 8 */ |
9 class ClosureInvocationElement extends FunctionElement { | 9 class ClosureInvocationElement extends FunctionElement { |
10 ClosureInvocationElement(SourceString name, | 10 ClosureInvocationElement(SourceString name, |
(...skipping 565 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
576 void generateTypeTest(ClassElement element)) { | 576 void generateTypeTest(ClassElement element)) { |
577 if (compiler.codegenWorld.isChecks.contains(cls)) { | 577 if (compiler.codegenWorld.isChecks.contains(cls)) { |
578 generateTypeTest(cls); | 578 generateTypeTest(cls); |
579 } | 579 } |
580 generateInterfacesIsTests(cls, generateTypeTest, new Set<Element>()); | 580 generateInterfacesIsTests(cls, generateTypeTest, new Set<Element>()); |
581 } | 581 } |
582 | 582 |
583 void generateInterfacesIsTests(ClassElement cls, | 583 void generateInterfacesIsTests(ClassElement cls, |
584 void generateTypeTest(ClassElement element), | 584 void generateTypeTest(ClassElement element), |
585 Set<Element> alreadyGenerated) { | 585 Set<Element> alreadyGenerated) { |
586 for (Type interfaceType in cls.interfaces) { | 586 for (DartType interfaceType in cls.interfaces) { |
587 Element element = interfaceType.element; | 587 Element element = interfaceType.element; |
588 if (!alreadyGenerated.contains(element) && | 588 if (!alreadyGenerated.contains(element) && |
589 compiler.codegenWorld.isChecks.contains(element)) { | 589 compiler.codegenWorld.isChecks.contains(element)) { |
590 alreadyGenerated.add(element); | 590 alreadyGenerated.add(element); |
591 generateTypeTest(element); | 591 generateTypeTest(element); |
592 } | 592 } |
593 generateInterfacesIsTests(element, generateTypeTest, alreadyGenerated); | 593 generateInterfacesIsTests(element, generateTypeTest, alreadyGenerated); |
594 } | 594 } |
595 } | 595 } |
596 | 596 |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
887 namer.instanceMethodName(null, Compiler.NO_SUCH_METHOD, 2); | 887 namer.instanceMethodName(null, Compiler.NO_SUCH_METHOD, 2); |
888 | 888 |
889 // Keep track of the JavaScript names we've already added so we | 889 // Keep track of the JavaScript names we've already added so we |
890 // do not introduce duplicates (bad for code size). | 890 // do not introduce duplicates (bad for code size). |
891 Set<String> addedJsNames = new Set<String>(); | 891 Set<String> addedJsNames = new Set<String>(); |
892 | 892 |
893 // Keep track of the noSuchMethod holders for each possible | 893 // Keep track of the noSuchMethod holders for each possible |
894 // receiver type. | 894 // receiver type. |
895 Map<ClassElement, Set<ClassElement>> noSuchMethodHolders = | 895 Map<ClassElement, Set<ClassElement>> noSuchMethodHolders = |
896 new Map<ClassElement, Set<ClassElement>>(); | 896 new Map<ClassElement, Set<ClassElement>>(); |
897 Set<ClassElement> noSuchMethodHoldersFor(Type type) { | 897 Set<ClassElement> noSuchMethodHoldersFor(DartType type) { |
898 ClassElement element = type.element; | 898 ClassElement element = type.element; |
899 Set<ClassElement> result = noSuchMethodHolders[element]; | 899 Set<ClassElement> result = noSuchMethodHolders[element]; |
900 if (result === null) { | 900 if (result === null) { |
901 // For now, we check the entire world to see if an object of | 901 // For now, we check the entire world to see if an object of |
902 // the given type may have a user-defined noSuchMethod | 902 // the given type may have a user-defined noSuchMethod |
903 // implementation. We could do better by only looking at | 903 // implementation. We could do better by only looking at |
904 // instantiated (or otherwise needed) classes. | 904 // instantiated (or otherwise needed) classes. |
905 result = compiler.world.findNoSuchMethodHolders(type); | 905 result = compiler.world.findNoSuchMethodHolders(type); |
906 noSuchMethodHolders[element] = result; | 906 noSuchMethodHolders[element] = result; |
907 } | 907 } |
908 return result; | 908 return result; |
909 } | 909 } |
910 | 910 |
911 CodeBuffer generateMethod(String methodName, Selector selector) { | 911 CodeBuffer generateMethod(String methodName, Selector selector) { |
912 CodeBuffer args = new CodeBuffer(); | 912 CodeBuffer args = new CodeBuffer(); |
913 for (int i = 0; i < selector.argumentCount; i++) { | 913 for (int i = 0; i < selector.argumentCount; i++) { |
914 if (i != 0) args.add(', '); | 914 if (i != 0) args.add(', '); |
915 args.add('\$$i'); | 915 args.add('\$$i'); |
916 } | 916 } |
917 CodeBuffer buffer = new CodeBuffer(); | 917 CodeBuffer buffer = new CodeBuffer(); |
918 buffer.add('function($args) {\n'); | 918 buffer.add('function($args) {\n'); |
919 buffer.add(' return this.$noSuchMethodName("$methodName", [$args]);\n'); | 919 buffer.add(' return this.$noSuchMethodName("$methodName", [$args]);\n'); |
920 buffer.add(' }'); | 920 buffer.add(' }'); |
921 return buffer; | 921 return buffer; |
922 } | 922 } |
923 | 923 |
924 void addNoSuchMethodHandlers(SourceString ignore, Set<Selector> selectors) { | 924 void addNoSuchMethodHandlers(SourceString ignore, Set<Selector> selectors) { |
925 // Cache the object class and type. | 925 // Cache the object class and type. |
926 ClassElement objectClass = compiler.objectClass; | 926 ClassElement objectClass = compiler.objectClass; |
927 Type objectType = objectClass.computeType(compiler); | 927 DartType objectType = objectClass.computeType(compiler); |
928 | 928 |
929 for (Selector selector in selectors) { | 929 for (Selector selector in selectors) { |
930 // Introduce a helper function that determines if the given | 930 // Introduce a helper function that determines if the given |
931 // class has a member that matches the current name and | 931 // class has a member that matches the current name and |
932 // selector (grabbed from the scope). | 932 // selector (grabbed from the scope). |
933 bool hasMatchingMember(ClassElement holder) { | 933 bool hasMatchingMember(ClassElement holder) { |
934 Element element = holder.lookupMember(selector.name); | 934 Element element = holder.lookupMember(selector.name); |
935 if (element === null) return false; | 935 if (element === null) return false; |
936 | 936 |
937 // TODO(kasperl): Consider folding this logic into the | 937 // TODO(kasperl): Consider folding this logic into the |
938 // Selector.applies() method. | 938 // Selector.applies() method. |
939 if (element is AbstractFieldElement) { | 939 if (element is AbstractFieldElement) { |
940 AbstractFieldElement field = element; | 940 AbstractFieldElement field = element; |
941 if (selector.kind === SelectorKind.GETTER) { | 941 if (selector.kind === SelectorKind.GETTER) { |
942 return field.getter !== null; | 942 return field.getter !== null; |
943 } else if (selector.kind === SelectorKind.SETTER) { | 943 } else if (selector.kind === SelectorKind.SETTER) { |
944 return field.setter !== null; | 944 return field.setter !== null; |
945 } else { | 945 } else { |
946 return false; | 946 return false; |
947 } | 947 } |
948 } | 948 } |
949 return selector.applies(element, compiler); | 949 return selector.applies(element, compiler); |
950 } | 950 } |
951 | 951 |
952 // If the selector is typed, we check to see if that type may | 952 // If the selector is typed, we check to see if that type may |
953 // have a user-defined noSuchMethod implementation. If not, we | 953 // have a user-defined noSuchMethod implementation. If not, we |
954 // skip the selector altogether. | 954 // skip the selector altogether. |
955 Type receiverType = objectType; | 955 DartType receiverType = objectType; |
956 ClassElement receiverClass = objectClass; | 956 ClassElement receiverClass = objectClass; |
957 if (selector is TypedSelector) { | 957 if (selector is TypedSelector) { |
958 TypedSelector typedSelector = selector; | 958 TypedSelector typedSelector = selector; |
959 receiverType = typedSelector.receiverType; | 959 receiverType = typedSelector.receiverType; |
960 receiverClass = receiverType.element; | 960 receiverClass = receiverType.element; |
961 } | 961 } |
962 | 962 |
963 // If the receiver class is guaranteed to have a member that | 963 // If the receiver class is guaranteed to have a member that |
964 // matches what we're looking for, there's no need to | 964 // matches what we're looking for, there's no need to |
965 // introduce a noSuchMethod handler. It will never be called. | 965 // introduce a noSuchMethod handler. It will never be called. |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1167 sourceName = token.slowToString(); | 1167 sourceName = token.slowToString(); |
1168 } | 1168 } |
1169 int totalOffset = bufferOffset + offset; | 1169 int totalOffset = bufferOffset + offset; |
1170 sourceMapBuilder.addMapping( | 1170 sourceMapBuilder.addMapping( |
1171 sourceFile, token.charOffset, sourceName, totalOffset); | 1171 sourceFile, token.charOffset, sourceName, totalOffset); |
1172 }); | 1172 }); |
1173 } | 1173 } |
1174 } | 1174 } |
1175 | 1175 |
1176 typedef void DefineMemberFunction(String invocationName, CodeBuffer definition); | 1176 typedef void DefineMemberFunction(String invocationName, CodeBuffer definition); |
OLD | NEW |