Chromium Code Reviews| 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 903 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 name, Set<Selector> selectors) { | 924 void addNoSuchMethodHandlers(SourceString ignore, Set<Selector> selectors) { |
|
ngeoffray
2012/08/17 11:56:57
Should you remove the parameter then?
kasperl
2012/08/17 12:08:44
The plan is to have it go away once we change the
| |
| 925 // TODO(kasperl): We should really teach private selectors about | |
| 926 // which libraries they are used from. That way, we wouldn't | |
| 927 // have to conservatively generate versions for all libraries | |
| 928 // the name is used from. | |
| 929 String nameString = name.slowToString(); | |
| 930 Collection<LibraryElement> libraries = name.isPrivate() | |
| 931 ? namer.usedPrivateNames[nameString] | |
| 932 : const [ null ]; | |
| 933 | |
| 934 // Cache the object class and type. | 925 // Cache the object class and type. |
| 935 ClassElement objectClass = compiler.objectClass; | 926 ClassElement objectClass = compiler.objectClass; |
| 936 Type objectType = objectClass.computeType(compiler); | 927 Type objectType = objectClass.computeType(compiler); |
| 937 | 928 |
| 938 for (Selector selector in selectors) { | 929 for (Selector selector in selectors) { |
| 939 // Introduce a helper function that determines if the given | 930 // Introduce a helper function that determines if the given |
| 940 // class has a member that matches the current name and | 931 // class has a member that matches the current name and |
| 941 // selector (grabbed from the scope). | 932 // selector (grabbed from the scope). |
| 942 bool hasMatchingMember(ClassElement holder) { | 933 bool hasMatchingMember(ClassElement holder) { |
| 943 Element element = holder.lookupMember(name); | 934 Element element = holder.lookupMember(selector.name); |
| 944 if (element === null) return false; | 935 if (element === null) return false; |
| 945 | 936 |
| 946 // TODO(kasperl): Consider folding this logic into the | 937 // TODO(kasperl): Consider folding this logic into the |
| 947 // Selector.applies() method. | 938 // Selector.applies() method. |
| 948 if (element is AbstractFieldElement) { | 939 if (element is AbstractFieldElement) { |
| 949 AbstractFieldElement field = element; | 940 AbstractFieldElement field = element; |
| 950 if (selector.kind === SelectorKind.GETTER) { | 941 if (selector.kind === SelectorKind.GETTER) { |
| 951 return field.getter !== null; | 942 return field.getter !== null; |
| 952 } else if (selector.kind === SelectorKind.SETTER) { | 943 } else if (selector.kind === SelectorKind.SETTER) { |
| 953 return field.setter !== null; | 944 return field.setter !== null; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1007 // If we're calling bar on an object of type D, we don't need | 998 // If we're calling bar on an object of type D, we don't need |
| 1008 // the handler either because all objects of type D implement | 999 // the handler either because all objects of type D implement |
| 1009 // bar through inheritance. | 1000 // bar through inheritance. |
| 1010 // | 1001 // |
| 1011 // If we're calling bar on an object of type A we do need the | 1002 // If we're calling bar on an object of type A we do need the |
| 1012 // handler because we may have to call B.noSuchMethod since B | 1003 // handler because we may have to call B.noSuchMethod since B |
| 1013 // does not implement bar. | 1004 // does not implement bar. |
| 1014 Set<ClassElement> holders = noSuchMethodHoldersFor(receiverType); | 1005 Set<ClassElement> holders = noSuchMethodHoldersFor(receiverType); |
| 1015 if (holders.every(hasMatchingMember)) continue; | 1006 if (holders.every(hasMatchingMember)) continue; |
| 1016 | 1007 |
| 1017 for (LibraryElement lib in libraries) { | 1008 String jsName = null; |
| 1018 String jsName = null; | 1009 String methodName = null; |
| 1019 String methodName = null; | 1010 String nameString = selector.name.slowToString(); |
| 1020 if (selector.isGetter()) { | 1011 if (selector.isGetter()) { |
| 1021 jsName = namer.getterName(lib, name); | 1012 jsName = namer.getterName(selector.library, selector.name); |
| 1022 methodName = 'get:$nameString'; | 1013 methodName = 'get:$nameString'; |
| 1023 } else if (selector.isSetter()) { | 1014 } else if (selector.isSetter()) { |
| 1024 jsName = namer.setterName(lib, name); | 1015 jsName = namer.setterName(selector.library, selector.name); |
| 1025 methodName = 'set:$nameString'; | 1016 methodName = 'set:$nameString'; |
| 1026 } else if (selector.isCall()) { | 1017 } else if (selector.isCall()) { |
| 1027 jsName = namer.instanceMethodInvocationName(lib, name, selector); | 1018 jsName = namer.instanceMethodInvocationName( |
| 1028 methodName = nameString; | 1019 selector.library, selector.name, selector); |
| 1029 } else { | 1020 methodName = nameString; |
| 1030 // We simply ignore selectors that do not need | 1021 } else { |
| 1031 // noSuchMethod handlers. | 1022 // We simply ignore selectors that do not need |
| 1032 continue; | 1023 // noSuchMethod handlers. |
| 1033 } | 1024 continue; |
| 1034 if (!addedJsNames.contains(jsName)) { | 1025 } |
| 1035 CodeBuffer jsCode = generateMethod(methodName, selector); | 1026 |
| 1036 defineInstanceMember(jsName, jsCode); | 1027 if (!addedJsNames.contains(jsName)) { |
| 1037 addedJsNames.add(jsName); | 1028 CodeBuffer jsCode = generateMethod(methodName, selector); |
| 1038 } | 1029 defineInstanceMember(jsName, jsCode); |
| 1030 addedJsNames.add(jsName); | |
| 1039 } | 1031 } |
| 1040 } | 1032 } |
| 1041 } | 1033 } |
| 1042 | 1034 |
| 1043 compiler.codegenWorld.invokedNames.forEach(addNoSuchMethodHandlers); | 1035 compiler.codegenWorld.invokedNames.forEach(addNoSuchMethodHandlers); |
| 1044 compiler.codegenWorld.invokedGetters.forEach(addNoSuchMethodHandlers); | 1036 compiler.codegenWorld.invokedGetters.forEach(addNoSuchMethodHandlers); |
| 1045 compiler.codegenWorld.invokedSetters.forEach(addNoSuchMethodHandlers); | 1037 compiler.codegenWorld.invokedSetters.forEach(addNoSuchMethodHandlers); |
| 1046 } | 1038 } |
| 1047 | 1039 |
| 1048 String buildIsolateSetup(CodeBuffer buffer, | 1040 String buildIsolateSetup(CodeBuffer buffer, |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1175 sourceName = token.slowToString(); | 1167 sourceName = token.slowToString(); |
| 1176 } | 1168 } |
| 1177 int totalOffset = bufferOffset + offset; | 1169 int totalOffset = bufferOffset + offset; |
| 1178 sourceMapBuilder.addMapping( | 1170 sourceMapBuilder.addMapping( |
| 1179 sourceFile, token.charOffset, sourceName, totalOffset); | 1171 sourceFile, token.charOffset, sourceName, totalOffset); |
| 1180 }); | 1172 }); |
| 1181 } | 1173 } |
| 1182 } | 1174 } |
| 1183 | 1175 |
| 1184 typedef void DefineMemberFunction(String invocationName, CodeBuffer definition); | 1176 typedef void DefineMemberFunction(String invocationName, CodeBuffer definition); |
| OLD | NEW |