| 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 |