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 1246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1257 if (compiler.codegenWorld.hasInvokedGetter(member, compiler)) { | 1257 if (compiler.codegenWorld.hasInvokedGetter(member, compiler)) { |
1258 emitDynamicFunctionGetter(member, defineInstanceMember); | 1258 emitDynamicFunctionGetter(member, defineInstanceMember); |
1259 } | 1259 } |
1260 } | 1260 } |
1261 } | 1261 } |
1262 | 1262 |
1263 void emitNoSuchMethodHandlers(DefineMemberFunction defineInstanceMember) { | 1263 void emitNoSuchMethodHandlers(DefineMemberFunction defineInstanceMember) { |
1264 // Do not generate no such method handlers if there is no class. | 1264 // Do not generate no such method handlers if there is no class. |
1265 if (compiler.codegenWorld.instantiatedClasses.isEmpty()) return; | 1265 if (compiler.codegenWorld.instantiatedClasses.isEmpty()) return; |
1266 | 1266 |
1267 String noSuchMethodName = | 1267 String noSuchMethodName = namer.publicInstanceMethodNameByArity( |
1268 namer.publicInstanceMethodNameByArity(Compiler.NO_SUCH_METHOD, 2); | 1268 Compiler.NO_SUCH_METHOD, Compiler.NO_SUCH_METHOD_ARG_COUNT); |
1269 | 1269 |
1270 // Keep track of the JavaScript names we've already added so we | 1270 // Keep track of the JavaScript names we've already added so we |
1271 // do not introduce duplicates (bad for code size). | 1271 // do not introduce duplicates (bad for code size). |
1272 Set<String> addedJsNames = new Set<String>(); | 1272 Set<String> addedJsNames = new Set<String>(); |
1273 | 1273 |
1274 // Keep track of the noSuchMethod holders for each possible | 1274 // Keep track of the noSuchMethod holders for each possible |
1275 // receiver type. | 1275 // receiver type. |
1276 Map<ClassElement, Set<ClassElement>> noSuchMethodHolders = | 1276 Map<ClassElement, Set<ClassElement>> noSuchMethodHolders = |
1277 new Map<ClassElement, Set<ClassElement>>(); | 1277 new Map<ClassElement, Set<ClassElement>>(); |
1278 Set<ClassElement> noSuchMethodHoldersFor(DartType type) { | 1278 Set<ClassElement> noSuchMethodHoldersFor(DartType type) { |
1279 ClassElement element = type.element; | 1279 ClassElement element = type.element; |
1280 Set<ClassElement> result = noSuchMethodHolders[element]; | 1280 Set<ClassElement> result = noSuchMethodHolders[element]; |
1281 if (result == null) { | 1281 if (result == null) { |
1282 // For now, we check the entire world to see if an object of | 1282 // For now, we check the entire world to see if an object of |
1283 // the given type may have a user-defined noSuchMethod | 1283 // the given type may have a user-defined noSuchMethod |
1284 // implementation. We could do better by only looking at | 1284 // implementation. We could do better by only looking at |
1285 // instantiated (or otherwise needed) classes. | 1285 // instantiated (or otherwise needed) classes. |
1286 result = compiler.world.findNoSuchMethodHolders(type); | 1286 result = compiler.world.findNoSuchMethodHolders(type); |
1287 noSuchMethodHolders[element] = result; | 1287 noSuchMethodHolders[element] = result; |
1288 } | 1288 } |
1289 return result; | 1289 return result; |
1290 } | 1290 } |
1291 | 1291 |
1292 CodeBuffer generateMethod(String methodName, Selector selector) { | 1292 CodeBuffer generateMethod(String methodName, Selector selector) { |
| 1293 // Values match JSInvocationMirror in js-helper library. |
| 1294 const int METHOD = 0; |
| 1295 const int GETTER = 1; |
| 1296 const int SETTER = 2; |
| 1297 int type = METHOD; |
| 1298 if (selector.isGetter()) { |
| 1299 type = GETTER; |
| 1300 } else if (selector.isSetter()) { |
| 1301 type = SETTER; |
| 1302 } |
1293 CodeBuffer args = new CodeBuffer(); | 1303 CodeBuffer args = new CodeBuffer(); |
1294 for (int i = 0; i < selector.argumentCount; i++) { | 1304 for (int i = 0; i < selector.argumentCount; i++) { |
1295 if (i != 0) args.add(', '); | 1305 if (i != 0) args.add(', '); |
1296 args.add('\$$i'); | 1306 args.add('\$$i'); |
1297 } | 1307 } |
| 1308 CodeBuffer argNames = new CodeBuffer(); |
| 1309 List<SourceString> names = selector.getOrderedNamedArguments(); |
| 1310 for (int i = 0; i < names.length; i++) { |
| 1311 if (i != 0) argNames.add(', '); |
| 1312 argNames.add('"'); |
| 1313 argNames.add(names[i].slowToString()); |
| 1314 argNames.add('"'); |
| 1315 } |
| 1316 String internalName = namer.instanceMethodInvocationName( |
| 1317 selector.library, new SourceString(methodName), selector); |
1298 CodeBuffer buffer = new CodeBuffer(); | 1318 CodeBuffer buffer = new CodeBuffer(); |
1299 buffer.add('function($args) {\n'); | 1319 buffer.add('function($args) {\n'); |
1300 buffer.add(' return this.$noSuchMethodName("$methodName", [$args]);\n'); | 1320 buffer.add(' return this.$noSuchMethodName(' |
| 1321 '\$.createInvocationMirror("$methodName", "$internalName",' |
| 1322 ' $type, [$args], [$argNames]));\n'); |
1301 buffer.add(' }'); | 1323 buffer.add(' }'); |
1302 return buffer; | 1324 return buffer; |
1303 } | 1325 } |
1304 | 1326 |
1305 void addNoSuchMethodHandlers(SourceString ignore, Set<Selector> selectors) { | 1327 void addNoSuchMethodHandlers(SourceString ignore, Set<Selector> selectors) { |
1306 // Cache the object class and type. | 1328 // Cache the object class and type. |
1307 ClassElement objectClass = compiler.objectClass; | 1329 ClassElement objectClass = compiler.objectClass; |
1308 DartType objectType = objectClass.computeType(compiler); | 1330 DartType objectType = objectClass.computeType(compiler); |
1309 | 1331 |
1310 for (Selector selector in selectors) { | 1332 for (Selector selector in selectors) { |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1576 const String HOOKS_API_USAGE = """ | 1598 const String HOOKS_API_USAGE = """ |
1577 // Generated by dart2js, the Dart to JavaScript compiler. | 1599 // Generated by dart2js, the Dart to JavaScript compiler. |
1578 // The code supports the following hooks: | 1600 // The code supports the following hooks: |
1579 // dartPrint(message) - if this function is defined it is called | 1601 // dartPrint(message) - if this function is defined it is called |
1580 // instead of the Dart [print] method. | 1602 // instead of the Dart [print] method. |
1581 // dartMainRunner(main) - if this function is defined, the Dart [main] | 1603 // dartMainRunner(main) - if this function is defined, the Dart [main] |
1582 // method will not be invoked directly. | 1604 // method will not be invoked directly. |
1583 // Instead, a closure that will invoke [main] is | 1605 // Instead, a closure that will invoke [main] is |
1584 // passed to [dartMainRunner]. | 1606 // passed to [dartMainRunner]. |
1585 """; | 1607 """; |
OLD | NEW |