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 #library('native'); | 5 #library('native'); |
6 #import('dart:uri'); | 6 #import('dart:uri'); |
7 #import('leg.dart'); | 7 #import('leg.dart'); |
8 #import('elements/elements.dart'); | 8 #import('elements/elements.dart'); |
9 #import('js_backend/js_backend.dart'); | 9 #import('js_backend/js_backend.dart'); |
10 #import('scanner/scannerlib.dart'); | 10 #import('scanner/scannerlib.dart'); |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
235 FunctionSignature parameters = element.computeSignature(builder.compiler); | 235 FunctionSignature parameters = element.computeSignature(builder.compiler); |
236 if (!hasBody) { | 236 if (!hasBody) { |
237 List<String> arguments = <String>[]; | 237 List<String> arguments = <String>[]; |
238 List<HInstruction> inputs = <HInstruction>[]; | 238 List<HInstruction> inputs = <HInstruction>[]; |
239 String receiver = ''; | 239 String receiver = ''; |
240 if (element.isInstanceMember()) { | 240 if (element.isInstanceMember()) { |
241 receiver = '#.'; | 241 receiver = '#.'; |
242 inputs.add(builder.localsHandler.readThis()); | 242 inputs.add(builder.localsHandler.readThis()); |
243 } | 243 } |
244 parameters.forEachParameter((Element parameter) { | 244 parameters.forEachParameter((Element parameter) { |
245 Type type = parameter.computeType(compiler); | 245 Type type = parameter.computeType(compiler).unalias(compiler); |
246 HInstruction input = builder.localsHandler.readLocal(parameter); | 246 HInstruction input = builder.localsHandler.readLocal(parameter); |
247 if (type is FunctionType) input = convertDartClosure(parameter, type); | 247 if (type is FunctionType) { |
| 248 // The parameter type is a function type either directly or through |
| 249 // typedef(s). |
| 250 input = convertDartClosure(parameter, type); |
| 251 } |
248 inputs.add(input); | 252 inputs.add(input); |
249 arguments.add('#'); | 253 arguments.add('#'); |
250 }); | 254 }); |
251 | 255 |
252 String foreignParameters = Strings.join(arguments, ','); | 256 String foreignParameters = Strings.join(arguments, ','); |
253 String nativeMethodCall; | 257 String nativeMethodCall; |
254 if (element.kind == ElementKind.FUNCTION) { | 258 if (element.kind == ElementKind.FUNCTION) { |
255 nativeMethodCall = '$receiver$nativeMethodName($foreignParameters)'; | 259 nativeMethodCall = '$receiver$nativeMethodName($foreignParameters)'; |
256 } else if (element.kind == ElementKind.GETTER) { | 260 } else if (element.kind == ElementKind.GETTER) { |
257 nativeMethodCall = '$receiver$nativeMethodName'; | 261 nativeMethodCall = '$receiver$nativeMethodName'; |
258 } else if (element.kind == ElementKind.SETTER) { | 262 } else if (element.kind == ElementKind.SETTER) { |
259 nativeMethodCall = '$receiver$nativeMethodName = $foreignParameters'; | 263 nativeMethodCall = '$receiver$nativeMethodName = $foreignParameters'; |
260 } else { | 264 } else { |
261 builder.compiler.internalError('unexpected kind: "${element.kind}"', | 265 builder.compiler.internalError('unexpected kind: "${element.kind}"', |
262 element: element); | 266 element: element); |
263 } | 267 } |
264 | 268 |
265 DartString jsCode = new DartString.literal(nativeMethodCall); | 269 DartString jsCode = new DartString.literal(nativeMethodCall); |
266 builder.push( | 270 builder.push( |
267 new HForeign(jsCode, const LiteralDartString('Object'), inputs)); | 271 new HForeign(jsCode, const LiteralDartString('Object'), inputs)); |
268 builder.close(new HReturn(builder.pop())).addSuccessor(builder.graph.exit); | 272 builder.close(new HReturn(builder.pop())).addSuccessor(builder.graph.exit); |
269 } else { | 273 } else { |
270 // This is JS code written in a Dart file with the construct | 274 // This is JS code written in a Dart file with the construct |
271 // native """ ... """;. It does not work well with mangling, | 275 // native """ ... """;. It does not work well with mangling, |
272 // but there should currently be no clash between leg mangling | 276 // but there should currently be no clash between leg mangling |
273 // and the library where this construct is being used. This | 277 // and the library where this construct is being used. This |
274 // mangling problem will go away once we switch these libraries | 278 // mangling problem will go away once we switch these libraries |
275 // to use Leg's 'JS' function. | 279 // to use Leg's 'JS' function. |
276 parameters.forEachParameter((Element parameter) { | 280 parameters.forEachParameter((Element parameter) { |
277 Type type = parameter.computeType(compiler); | 281 Type type = parameter.computeType(compiler).unalias(compiler); |
278 if (type is FunctionType) { | 282 if (type is FunctionType) { |
| 283 // The parameter type is a function type either directly or through |
| 284 // typedef(s). |
279 HInstruction jsClosure = convertDartClosure(parameter, type); | 285 HInstruction jsClosure = convertDartClosure(parameter, type); |
280 // Because the JS code references the argument name directly, | 286 // Because the JS code references the argument name directly, |
281 // we must keep the name and assign the JS closure to it. | 287 // we must keep the name and assign the JS closure to it. |
282 builder.add(new HForeign( | 288 builder.add(new HForeign( |
283 new DartString.literal('${parameter.name.slowToString()} = #'), | 289 new DartString.literal('${parameter.name.slowToString()} = #'), |
284 const LiteralDartString('void'), | 290 const LiteralDartString('void'), |
285 <HInstruction>[jsClosure])); | 291 <HInstruction>[jsClosure])); |
286 } | 292 } |
287 }); | 293 }); |
288 LiteralString jsCode = nativeBody.asLiteralString(); | 294 LiteralString jsCode = nativeBody.asLiteralString(); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
327 String parameters) { | 333 String parameters) { |
328 buffer.add(" if (Object.getPrototypeOf(this).hasOwnProperty"); | 334 buffer.add(" if (Object.getPrototypeOf(this).hasOwnProperty"); |
329 buffer.add("('$methodName')) {\n"); | 335 buffer.add("('$methodName')) {\n"); |
330 buffer.add(" $code"); | 336 buffer.add(" $code"); |
331 buffer.add(" } else {\n"); | 337 buffer.add(" } else {\n"); |
332 buffer.add(" return Object.prototype.$methodName.call(this"); | 338 buffer.add(" return Object.prototype.$methodName.call(this"); |
333 buffer.add(parameters == '' ? '' : ', $parameters'); | 339 buffer.add(parameters == '' ? '' : ', $parameters'); |
334 buffer.add(");\n"); | 340 buffer.add(");\n"); |
335 buffer.add(" }\n"); | 341 buffer.add(" }\n"); |
336 } | 342 } |
OLD | NEW |