| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 * Support for interoperating with JavaScript. | 6 * Support for interoperating with JavaScript. |
| 7 * | 7 * |
| 8 * This library provides access to JavaScript objects from Dart, allowing | 8 * This library provides access to JavaScript objects from Dart, allowing |
| 9 * Dart code to get and set properties, and call methods of JavaScript objects | 9 * Dart code to get and set properties, and call methods of JavaScript objects |
| 10 * and invoke JavaScript functions. The library takes care of converting | 10 * and invoke JavaScript functions. The library takes care of converting |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 import 'dart:typed_data'; | 97 import 'dart:typed_data'; |
| 98 | 98 |
| 99 // Pretend we are always in checked mode as we aren't interested in users | 99 // Pretend we are always in checked mode as we aren't interested in users |
| 100 // running Dartium code outside of checked mode. | 100 // running Dartium code outside of checked mode. |
| 101 final bool CHECK_JS_INVOCATIONS = true; | 101 final bool CHECK_JS_INVOCATIONS = true; |
| 102 | 102 |
| 103 final _allowedMethods = new Map<Symbol, _DeclarationSet>(); | 103 final _allowedMethods = new Map<Symbol, _DeclarationSet>(); |
| 104 final _allowedGetters = new Map<Symbol, _DeclarationSet>(); | 104 final _allowedGetters = new Map<Symbol, _DeclarationSet>(); |
| 105 final _allowedSetters = new Map<Symbol, _DeclarationSet>(); | 105 final _allowedSetters = new Map<Symbol, _DeclarationSet>(); |
| 106 | 106 |
| 107 final _jsInterfaceTypes = new Set<Type>(); | 107 final _jsInterfaceTypes = new Set<mirrors.ClassMirror>(); |
| 108 Iterable<Type> get jsInterfaceTypes => _jsInterfaceTypes; | 108 Iterable<mirrors.ClassMirror> get jsInterfaceTypes => _jsInterfaceTypes; |
| 109 | 109 |
| 110 /// A collection of methods where all methods have the same name. | 110 /// A collection of methods where all methods have the same name. |
| 111 /// This class is intended to optimize whether a specific invocation is | 111 /// This class is intended to optimize whether a specific invocation is |
| 112 /// appropritate for at least some of the methods in the collection. | 112 /// appropritate for at least some of the methods in the collection. |
| 113 class _DeclarationSet { | 113 class _DeclarationSet { |
| 114 _DeclarationSet() : _members = <mirrors.DeclarationMirror>[]; | 114 _DeclarationSet() : _members = <mirrors.DeclarationMirror>[]; |
| 115 | 115 |
| 116 static bool _checkType(obj, mirrors.TypeMirror type) { | 116 static bool _checkType(obj, mirrors.TypeMirror type) { |
| 117 if (obj == null) return true; | 117 if (obj == null) return true; |
| 118 return mirrors.reflectType(obj.runtimeType).isSubtypeOf(type); | 118 return mirrors.reflectType(obj.runtimeType).isSubtypeOf(type); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 206 /** | 206 /** |
| 207 * Temporary method that we hope to remove at some point. This method should | 207 * Temporary method that we hope to remove at some point. This method should |
| 208 * generally only be called by machine generated code. | 208 * generally only be called by machine generated code. |
| 209 */ | 209 */ |
| 210 void registerJsInterfaces([List<Type> classes]) { | 210 void registerJsInterfaces([List<Type> classes]) { |
| 211 // This method is now obsolete in Dartium. | 211 // This method is now obsolete in Dartium. |
| 212 } | 212 } |
| 213 | 213 |
| 214 void _registerJsInterfaces(List<Type> classes) { | 214 void _registerJsInterfaces(List<Type> classes) { |
| 215 for (Type type in classes) { | 215 for (Type type in classes) { |
| 216 if (!_jsInterfaceTypes.add(type)) continue; // Already registered. | |
| 217 mirrors.ClassMirror typeMirror = mirrors.reflectType(type); | 216 mirrors.ClassMirror typeMirror = mirrors.reflectType(type); |
| 218 typeMirror.declarations.forEach((symbol, declaration) { | 217 typeMirror.declarations.forEach((symbol, declaration) { |
| 219 if (declaration is mirrors.MethodMirror || | 218 if (declaration is mirrors.MethodMirror || |
| 220 declaration is mirrors.VariableMirror && !declaration.isStatic) { | 219 declaration is mirrors.VariableMirror && !declaration.isStatic) { |
| 221 bool treatAsGetter = false; | 220 bool treatAsGetter = false; |
| 222 bool treatAsSetter = false; | 221 bool treatAsSetter = false; |
| 223 if (declaration is mirrors.VariableMirror) { | 222 if (declaration is mirrors.VariableMirror) { |
| 224 treatAsGetter = true; | 223 treatAsGetter = true; |
| 225 if (!declaration.isConst && !declaration.isFinal) { | 224 if (!declaration.isConst && !declaration.isFinal) { |
| 226 treatAsSetter = true; | 225 treatAsSetter = true; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 String _getJsName(mirrors.DeclarationMirror mirror) { | 258 String _getJsName(mirrors.DeclarationMirror mirror) { |
| 260 for (var annotation in mirror.metadata) { | 259 for (var annotation in mirror.metadata) { |
| 261 if (mirrors.MirrorSystem.getName(annotation.type.simpleName) == "JS") { | 260 if (mirrors.MirrorSystem.getName(annotation.type.simpleName) == "JS") { |
| 262 mirrors.LibraryMirror library = annotation.type.owner; | 261 mirrors.LibraryMirror library = annotation.type.owner; |
| 263 var uri = library.uri; | 262 var uri = library.uri; |
| 264 // make sure the annotation is from package://js | 263 // make sure the annotation is from package://js |
| 265 if (uri.scheme == 'package' && uri.path == 'js/js.dart') { | 264 if (uri.scheme == 'package' && uri.path == 'js/js.dart') { |
| 266 try { | 265 try { |
| 267 var name = annotation.reflectee.name; | 266 var name = annotation.reflectee.name; |
| 268 return name != null ? name : ""; | 267 return name != null ? name : ""; |
| 269 } catch (e) { | 268 } catch (e) {} |
| 270 } | |
| 271 } | 269 } |
| 272 } | 270 } |
| 273 } | 271 } |
| 274 return null; | 272 return null; |
| 275 } | 273 } |
| 276 | 274 |
| 277 bool _hasJsName(mirrors.DeclarationMirror mirror) => | 275 bool _isAnonymousClass(mirrors.ClassMirror mirror) { |
| 278 _getJsName(mirror) != null; | 276 for (var annotation in mirror.metadata) { |
| 277 if (mirrors.MirrorSystem.getName(annotation.type.simpleName) == |
| 278 "_Anonymous") { |
| 279 mirrors.LibraryMirror library = annotation.type.owner; |
| 280 var uri = library.uri; |
| 281 // make sure the annotation is from package://js |
| 282 if (uri.scheme == 'package' && uri.path == 'js/js.dart') { |
| 283 return true; |
| 284 } |
| 285 } |
| 286 } |
| 287 return false; |
| 288 } |
| 279 | 289 |
| 290 bool _hasJsName(mirrors.DeclarationMirror mirror) => _getJsName(mirror) != null; |
| 280 | 291 |
| 281 _getJsMemberName(mirrors.DeclarationMirror mirror) { | 292 _getJsMemberName(mirrors.DeclarationMirror mirror) { |
| 282 var name = _getJsName(mirror); | 293 var name = _getJsName(mirror); |
| 283 return name == null || name.isEmpty ? _getDeclarationName(mirror) : | 294 return name == null || name.isEmpty ? _getDeclarationName(mirror) : name; |
| 284 name; | |
| 285 } | 295 } |
| 286 | 296 |
| 287 // TODO(jacobr): handle setters correctyl. | 297 // TODO(jacobr): handle setters correctyl. |
| 288 String _getDeclarationName(mirrors.DeclarationMirror declaration) { | 298 String _getDeclarationName(mirrors.DeclarationMirror declaration) { |
| 289 var name = mirrors.MirrorSystem.getName(declaration.simpleName); | 299 var name = mirrors.MirrorSystem.getName(declaration.simpleName); |
| 290 if (declaration is mirrors.MethodMirror && declaration.isSetter) { | 300 if (declaration is mirrors.MethodMirror && declaration.isSetter) { |
| 291 assert(name.endsWith("=")); | 301 assert(name.endsWith("=")); |
| 292 name = name.substring(0, name.length - 1); | 302 name = name.substring(0, name.length - 1); |
| 293 } | 303 } |
| 294 return name; | 304 return name; |
| 295 } | 305 } |
| 296 | 306 |
| 297 final _JS_LIBRARY_PREFIX = "js_library"; | 307 final _JS_LIBRARY_PREFIX = "js_library"; |
| 298 final _UNDEFINED_VAR = "_UNDEFINED_JS_CONST"; | 308 final _UNDEFINED_VAR = "_UNDEFINED_JS_CONST"; |
| 299 | 309 |
| 300 String _accessJsPath(String path) => | 310 String _accessJsPath(String path) => |
| 301 "${_JS_LIBRARY_PREFIX}.context${path.split(".").map((p) => "['$p']").join(''
)}"; | 311 "${_JS_LIBRARY_PREFIX}.context${path.split(".").map((p) => "['$p']").join(''
)}"; |
| 302 | 312 |
| 303 @Deprecated("Internal Use Only") | 313 @Deprecated("Internal Use Only") |
| 304 void addMemberHelper(mirrors.MethodMirror declaration, String path, StringBuffer
sb, {bool isStatic: false, String memberName}) { | 314 void addMemberHelper( |
| 305 var jsName = _getJsMemberName(declaration); | 315 mirrors.MethodMirror declaration, String path, StringBuffer sb, |
| 306 path = (path != null && path.isNotEmpty) ? "${path}.${jsName}" : jsName; | 316 {bool isStatic: false, String memberName}) { |
| 317 if (!declaration.isConstructor) { |
| 318 var jsName = _getJsMemberName(declaration); |
| 319 path = (path != null && path.isNotEmpty) ? "${path}.${jsName}" : jsName; |
| 320 } |
| 307 var name = memberName != null ? memberName : _getDeclarationName(declaration); | 321 var name = memberName != null ? memberName : _getDeclarationName(declaration); |
| 308 if (declaration.isConstructor) { | 322 if (declaration.isConstructor) { |
| 309 sb.write("factory"); | 323 sb.write("factory"); |
| 310 } else if (isStatic) { | 324 } else if (isStatic) { |
| 311 sb.write("static"); | 325 sb.write("static"); |
| 312 } else { | 326 } else { |
| 313 sb.write("patch"); | 327 sb.write("patch"); |
| 314 } | 328 } |
| 315 sb.write(" "); | 329 sb.write(" "); |
| 316 if (declaration.isGetter) { | 330 if (declaration.isGetter) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 339 sb.write("=${_UNDEFINED_VAR}"); | 353 sb.write("=${_UNDEFINED_VAR}"); |
| 340 } | 354 } |
| 341 i++; | 355 i++; |
| 342 } | 356 } |
| 343 if (hasOptional) { | 357 if (hasOptional) { |
| 344 sb.write("]"); | 358 sb.write("]"); |
| 345 } | 359 } |
| 346 // TODO(jacobr): | 360 // TODO(jacobr): |
| 347 sb.write(") => "); | 361 sb.write(") => "); |
| 348 if (declaration.isConstructor) { | 362 if (declaration.isConstructor) { |
| 349 sb.write("new ${_JS_LIBRARY_PREFIX}.JsObject("); | 363 sb.write("new ${_JS_LIBRARY_PREFIX}.JsObject("); |
| 350 } | 364 } |
| 351 sb | 365 sb |
| 352 ..write(_accessJsPath(path)) | 366 ..write(_accessJsPath(path)) |
| 353 ..write(declaration.isConstructor ? "," : ".apply(") | 367 ..write(declaration.isConstructor ? "," : ".apply(") |
| 354 ..write("[${args.join(",")}]"); | 368 ..write("[${args.join(",")}]"); |
| 355 | 369 |
| 356 if (hasOptional) { | 370 if (hasOptional) { |
| 357 sb.write(".takeWhile((i) => i != ${_UNDEFINED_VAR}).toList()"); | 371 sb.write(".takeWhile((i) => i != ${_UNDEFINED_VAR}).toList()"); |
| 358 } | 372 } |
| 359 sb.write(");"); | 373 sb.write(");"); |
| 360 } | 374 } |
| 361 sb.write("\n"); | 375 sb.write("\n"); |
| 362 } | 376 } |
| 363 | 377 |
| 364 // TODO(jacobr): make this check more robust. | 378 // TODO(jacobr): make this check more robust. |
| 365 bool _isExternal(mirrors.MethodMirror mirror) => | 379 bool _isExternal(mirrors.Mirror mirror) { |
| 366 mirror.source != null && mirror.source.startsWith("external "); | 380 /* |
| 381 var source = mirror.source; |
| 382 return source != null && source.startsWith("external "); |
| 383 */ |
| 384 return mirror.isExternal; |
| 385 } |
| 367 | 386 |
| 368 List<String> _generateExternalMethods() { | 387 List<String> _generateExternalMethods() { |
| 369 var staticCodegen = <String>[]; | 388 var staticCodegen = <String>[]; |
| 370 mirrors.currentMirrorSystem().libraries.forEach((uri, library) { | 389 mirrors.currentMirrorSystem().libraries.forEach((uri, library) { |
| 371 var sb = new StringBuffer(); | 390 var sb = new StringBuffer(); |
| 372 String jsLibraryName = _getJsName(library); | 391 String jsLibraryName = _getJsName(library); |
| 373 library.declarations.forEach((name, declaration) { | 392 library.declarations.forEach((name, declaration) { |
| 374 if (declaration is mirrors.MethodMirror) { | 393 if (declaration is mirrors.MethodMirror) { |
| 375 if (_isExternal(declaration) && (_hasJsName(declaration) || jsLibraryNam
e != null)) { | 394 if ((_hasJsName(declaration) || jsLibraryName != null) && |
| 395 _isExternal(declaration)) { |
| 376 addMemberHelper(declaration, jsLibraryName, sb); | 396 addMemberHelper(declaration, jsLibraryName, sb); |
| 377 } | 397 } |
| 378 } else if (declaration is mirrors.ClassMirror) { | 398 } else if (declaration is mirrors.ClassMirror) { |
| 379 mirrors.ClassMirror clazz = declaration; | 399 mirrors.ClassMirror clazz = declaration; |
| 380 if (_hasJsName(clazz)) { | 400 if (_hasJsName(clazz)) { |
| 381 // TODO(jacobr): verify class implements JavaScriptObject. | 401 // TODO(jacobr): verify class implements JavaScriptObject. |
| 382 assert(clazz.hasReflectedType); | |
| 383 jsInterfaceTypes.add(clazz.reflectedType); | |
| 384 String jsClassName = _getJsMemberName(clazz); | 402 String jsClassName = _getJsMemberName(clazz); |
| 385 var className = mirrors.MirrorSystem.getName(clazz.simpleName); | 403 var className = mirrors.MirrorSystem.getName(clazz.simpleName); |
| 386 var sbPatch = new StringBuffer(); | 404 var sbPatch = new StringBuffer(); |
| 405 jsInterfaceTypes.add(clazz); |
| 387 clazz.declarations.forEach((name, declaration) { | 406 clazz.declarations.forEach((name, declaration) { |
| 388 if (declaration is! mirrors.MethodMirror || !_isExternal(declaration
)) return; | 407 if (declaration is! mirrors.MethodMirror || |
| 389 if (declaration.isFactoryConstructor) { | 408 !_isExternal(declaration)) return; |
| 409 if (declaration.isFactoryConstructor && _isAnonymousClass(clazz)) { |
| 390 sbPatch.write(" factory ${className}({"); | 410 sbPatch.write(" factory ${className}({"); |
| 391 int i = 0; | 411 int i = 0; |
| 392 var args = <String>[]; | 412 var args = <String>[]; |
| 413 for (var p in declaration.parameters) { |
| 414 args.add(mirrors.MirrorSystem.getName(p.simpleName)); |
| 415 i++; |
| 416 } |
| 417 sbPatch |
| 418 ..write( |
| 419 args.map((name) => '$name:${_UNDEFINED_VAR}').join(", ")) |
| 420 ..write("}) {\n" |
| 421 " var ret = new ${_JS_LIBRARY_PREFIX}.JsObject.jsify({});
\n"); |
| 422 i = 0; |
| 423 for (var p in declaration.parameters) { |
| 424 assert(p.isNamed); // XXX throw |
| 425 var name = args[i]; |
| 426 var jsName = mirrors.MirrorSystem.getName(p.simpleName); |
| 427 // XXX apply name conversion rules. |
| 428 sbPatch.write( |
| 429 " if($name != ${_UNDEFINED_VAR}) ret['$jsName'] = $name;\
n"); |
| 430 i++; |
| 431 } |
| 432 |
| 433 sbPatch.write(" return ret;\n" |
| 434 " }\n"); |
| 435 } else if (declaration.isConstructor || |
| 436 declaration.isFactoryConstructor) { |
| 437 sbPatch.write(" "); |
| 438 addMemberHelper( |
| 439 declaration, |
| 440 (jsLibraryName != null && jsLibraryName.isNotEmpty) |
| 441 ? "${jsLibraryName}.${jsClassName}" |
| 442 : jsClassName, |
| 443 sbPatch, |
| 444 isStatic: true, |
| 445 memberName: className); |
| 446 } |
| 447 }); |
| 448 |
| 449 clazz.staticMembers.forEach((memberName, member) { |
| 450 if (_isExternal(member)) { |
| 451 sbPatch.write(" "); |
| 452 addMemberHelper( |
| 453 member, |
| 454 (jsLibraryName != null && jsLibraryName.isNotEmpty) |
| 455 ? "${jsLibraryName}.${jsClassName}" |
| 456 : jsClassName, |
| 457 sbPatch, |
| 458 isStatic: true); |
| 459 } |
| 460 }); |
| 461 var typeVariablesClause = ''; |
| 462 if (!clazz.typeVariables.isEmpty) { |
| 463 typeVariablesClause = |
| 464 '<${clazz.typeVariables.map((m) => mirrors.MirrorSystem.getName(
m.simpleName)).join(',')}>'; |
| 465 } |
| 466 if (sbPatch.isNotEmpty) { |
| 467 sb.write(""" |
| 468 patch class $className$typeVariablesClause { |
| 469 $sbPatch |
| 470 } |
| 471 """); |
| 472 } |
| 473 } |
| 474 } |
| 475 }); |
| 476 if (sb.isNotEmpty) { |
| 477 staticCodegen |
| 478 ..add(uri.toString()) |
| 479 ..add("${uri}_js_interop_patch.dart") |
| 480 ..add(""" |
| 481 import 'dart:js' as ${_JS_LIBRARY_PREFIX}; |
| 482 |
| 483 /** |
| 484 * Placeholder object for cases where we need to determine exactly how many |
| 485 * args were passed to a function. |
| 486 */ |
| 487 const ${_UNDEFINED_VAR} = const Object(); |
| 488 |
| 489 ${sb} |
| 490 """); |
| 491 } |
| 492 }); |
| 493 |
| 494 return staticCodegen; |
| 495 } |
| 496 |
| 497 List<String> _generateExternalMethods2() { |
| 498 var staticCodegen = <String>[]; |
| 499 mirrors.currentMirrorSystem().libraries.forEach((uri, library) { |
| 500 var sb = new StringBuffer(); |
| 501 String jsLibraryName = _getJsName(library); |
| 502 library.declarations.forEach((name, declaration) { |
| 503 var isExternal = _isExternal(declaration); |
| 504 if (declaration is mirrors.MethodMirror) { |
| 505 if (isExternal && (_hasJsName(declaration) || jsLibraryName != null)) { |
| 506 addMemberHelper(declaration, jsLibraryName, sb); |
| 507 } |
| 508 } else if (declaration is mirrors.ClassMirror) { |
| 509 mirrors.ClassMirror clazz = declaration; |
| 510 if (_hasJsName(clazz)) { |
| 511 // TODO(jacobr): verify class implements JavaScriptObject. |
| 512 String jsClassName = _getJsMemberName(clazz); |
| 513 var className = mirrors.MirrorSystem.getName(clazz.simpleName); |
| 514 var sbPatch = new StringBuffer(); |
| 515 jsInterfaceTypes.add(clazz); |
| 516 clazz.declarations.forEach((name, declaration) { |
| 517 if (declaration is! mirrors.MethodMirror || |
| 518 !declaration.isAbstract || |
| 519 !isExternal) return; |
| 520 if (_hasLiteralAnnotation(declaration) && |
| 521 declaration.isFactoryConstructor) { |
| 522 sbPatch.write(" factory ${className}({"); |
| 523 int i = 0; |
| 524 var args = <String>[]; |
| 393 for (var p in declaration.parameters) { | 525 for (var p in declaration.parameters) { |
| 394 assert(p.isNamed); // XXX throw | 526 assert(p.isNamed); // XXX throw |
| 395 args.add(mirrors.MirrorSystem.getName(p.simpleName)); | 527 args.add(mirrors.MirrorSystem.getName(p.simpleName)); |
| 396 i++; | 528 i++; |
| 397 } | 529 } |
| 398 sbPatch | 530 sbPatch |
| 399 ..write(args.map((name) => '$name:${_UNDEFINED_VAR}').join(", ")
) | 531 ..write( |
| 532 args.map((name) => '$name:${_UNDEFINED_VAR}').join(", ")) |
| 400 ..write("}) {\n" | 533 ..write("}) {\n" |
| 401 " var ret = new ${_JS_LIBRARY_PREFIX}.JsObject.jsify(
{});\n"); | 534 " var ret = new ${_JS_LIBRARY_PREFIX}.JsObject.jsify({});
\n"); |
| 402 i = 0; | 535 i = 0; |
| 403 for (var p in declaration.parameters) { | 536 for (var p in declaration.parameters) { |
| 404 assert(p.isNamed); // XXX throw | 537 assert(p.isNamed); // XXX throw |
| 405 var name = args[i]; | 538 var name = args[i]; |
| 406 var jsName = mirrors.MirrorSystem.getName(p.simpleName); | 539 var jsName = mirrors.MirrorSystem.getName(p.simpleName); |
| 407 // XXX apply name conversion rules. | 540 // XXX apply name conversion rules. |
| 408 sbPatch.write(" if($name != ${_UNDEFINED_VAR}) ret['$jsName']
= $name;\n"); | 541 sbPatch.write( |
| 542 " if($name != ${_UNDEFINED_VAR}) ret['$jsName'] = $name;\
n"); |
| 409 i++; | 543 i++; |
| 410 } | 544 } |
| 411 | 545 |
| 412 sbPatch.write(" return ret;\n" | 546 sbPatch.write(" return ret;\n" |
| 413 " }\n"); | 547 " }\n"); |
| 414 } else if (declaration.isConstructor) { | 548 } else if (declaration.isConstructor || |
| 549 declaration.isFactoryConstructor) { |
| 415 sbPatch.write(" "); | 550 sbPatch.write(" "); |
| 416 addMemberHelper(declaration, | 551 addMemberHelper( |
| 417 (jsLibraryName != null && jsLibraryName.isNotEmpty) ? "${jsLib
raryName}" : "", | 552 declaration, |
| 553 (jsLibraryName != null && jsLibraryName.isNotEmpty) |
| 554 ? "${jsLibraryName}.${jsClassName}" |
| 555 : jsClassName, |
| 418 sbPatch, | 556 sbPatch, |
| 419 isStatic: true, | 557 isStatic: true, |
| 420 memberName: className); | 558 memberName: className); |
| 421 } | 559 } |
| 422 }); | 560 }); |
| 423 | 561 |
| 424 clazz.staticMembers.forEach((memberName, member) { | 562 clazz.staticMembers.forEach((memberName, member) { |
| 425 if (_isExternal(member)) { | 563 if (_isExternal(member)) { |
| 426 sbPatch.write(" "); | 564 sbPatch.write(" "); |
| 427 addMemberHelper(member, | 565 addMemberHelper( |
| 428 (jsLibraryName != null && jsLibraryName.isNotEmpty) ? "${jsLib
raryName}.${jsClassName}" : jsClassName, | 566 member, |
| 567 (jsLibraryName != null && jsLibraryName.isNotEmpty) |
| 568 ? "${jsLibraryName}.${jsClassName}" |
| 569 : jsClassName, |
| 429 sbPatch, | 570 sbPatch, |
| 430 isStatic: true); | 571 isStatic: true); |
| 431 } | 572 } |
| 432 }); | 573 }); |
| 574 var typeVariablesClause = ''; |
| 575 if (!clazz.typeVariables.isEmpty) { |
| 576 typeVariablesClause = |
| 577 '<${clazz.typeVariables.map((m) => mirrors.MirrorSystem.getName(
m.simpleName)).join(',')}>'; |
| 578 } |
| 433 if (sbPatch.isNotEmpty) { | 579 if (sbPatch.isNotEmpty) { |
| 434 sb.write(""" | 580 sb.write(""" |
| 435 patch class $className { | 581 patch class $className$typeVariablesClause { |
| 436 $sbPatch | 582 $sbPatch |
| 437 } | 583 } |
| 438 """); | 584 """); |
| 439 } | 585 } |
| 440 } | 586 } |
| 441 } | 587 } |
| 442 }); | 588 }); |
| 443 if (sb.isNotEmpty) { | 589 if (sb.isNotEmpty) { |
| 444 staticCodegen | 590 staticCodegen |
| 445 ..add(uri.toString()) | 591 ..add(uri.toString()) |
| (...skipping 23 matching lines...) Expand all Loading... |
| 469 List<String> _generateInteropPatchFiles() { | 615 List<String> _generateInteropPatchFiles() { |
| 470 var ret = _generateExternalMethods(); | 616 var ret = _generateExternalMethods(); |
| 471 var libraryPrefixes = new Map<mirrors.LibraryMirror, String>(); | 617 var libraryPrefixes = new Map<mirrors.LibraryMirror, String>(); |
| 472 var prefixNames = new Set<String>(); | 618 var prefixNames = new Set<String>(); |
| 473 var sb = new StringBuffer(); | 619 var sb = new StringBuffer(); |
| 474 | 620 |
| 475 var implements = <String>[]; | 621 var implements = <String>[]; |
| 476 var implementsArray = <String>[]; | 622 var implementsArray = <String>[]; |
| 477 var listMirror = mirrors.reflectType(List); | 623 var listMirror = mirrors.reflectType(List); |
| 478 | 624 |
| 479 for (var type in jsInterfaceTypes) { | 625 for (var typeMirror in jsInterfaceTypes) { |
| 480 mirrors.ClassMirror typeMirror = mirrors.reflectType(type); | |
| 481 mirrors.LibraryMirror libraryMirror = typeMirror.owner; | 626 mirrors.LibraryMirror libraryMirror = typeMirror.owner; |
| 482 var prefixName; | 627 var prefixName; |
| 483 if (libraryPrefixes.containsKey(libraryMirror)) { | 628 if (libraryPrefixes.containsKey(libraryMirror)) { |
| 484 prefixName = libraryPrefixes[libraryMirror]; | 629 prefixName = libraryPrefixes[libraryMirror]; |
| 485 } else { | 630 } else { |
| 486 var basePrefixName = | 631 var basePrefixName = |
| 487 mirrors.MirrorSystem.getName(libraryMirror.simpleName); | 632 mirrors.MirrorSystem.getName(libraryMirror.simpleName); |
| 488 basePrefixName = basePrefixName.replaceAll('.', '_'); | 633 basePrefixName = basePrefixName.replaceAll('.', '_'); |
| 489 if (basePrefixName.isEmpty) basePrefixName = "lib"; | 634 if (basePrefixName.isEmpty) basePrefixName = "lib"; |
| 490 prefixName = basePrefixName; | 635 prefixName = basePrefixName; |
| 491 var i = 1; | 636 var i = 1; |
| 492 while (prefixNames.contains(prefixName)) { | 637 while (prefixNames.contains(prefixName)) { |
| 493 prefixName = '$basePrefixName$i'; | 638 prefixName = '$basePrefixName$i'; |
| 494 i++; | 639 i++; |
| 495 } | 640 } |
| 496 prefixNames.add(prefixName); | 641 prefixNames.add(prefixName); |
| 497 libraryPrefixes[libraryMirror] = prefixName; | 642 libraryPrefixes[libraryMirror] = prefixName; |
| 498 } | 643 } |
| 499 var isArray = typeMirror.isSubtypeOf(listMirror); | 644 var isArray = typeMirror.isSubtypeOf(listMirror); |
| 500 (isArray ? implementsArray : implements).add( | 645 (isArray ? implementsArray : implements).add( |
| 501 '${prefixName}.${mirrors.MirrorSystem.getName(typeMirror.simpleName)}'); | 646 '${prefixName}.${mirrors.MirrorSystem.getName(typeMirror.simpleName)}'); |
| 502 } | 647 } |
| 503 libraryPrefixes.forEach((libraryMirror, prefix) { | 648 libraryPrefixes.forEach((libraryMirror, prefix) { |
| 504 sb.writeln('import "${libraryMirror.uri}" as $prefix;'); | 649 sb.writeln('import "${libraryMirror.uri}" as $prefix;'); |
| 505 }); | 650 }); |
| 506 buildImplementsClause(classes) => | 651 buildImplementsClause(classes) => |
| 507 classes.isEmpty ? "" : "implements ${classes.join(', ')}" | 652 classes.isEmpty ? "" : "implements ${classes.join(', ')}"; |
| 508 var implementsClause = buildImplementsClause(implements); | 653 var implementsClause = buildImplementsClause(implements); |
| 509 // TODO(jacobr): only certain classes need to be implemented by | 654 // TODO(jacobr): only certain classes need to be implemented by |
| 510 // JsFunctionImpl. | 655 // JsFunctionImpl. |
| 511 var allTypes = []..addAll(implements)..addAll(implementsArray); | 656 var allTypes = []..addAll(implements)..addAll(implementsArray); |
| 512 sb.write(''' | 657 sb.write(''' |
| 513 class JsObjectImpl extends JsObject $implementsClause { | 658 class JsObjectImpl extends JsObject $implementsClause { |
| 514 JsObjectImpl.internal() : super.internal(); | 659 JsObjectImpl.internal() : super.internal(); |
| 515 } | 660 } |
| 516 | 661 |
| 517 class JsFunctionImpl extends JsFunction $implementsClause { | 662 class JsFunctionImpl extends JsFunction $implementsClause { |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 572 sep = ","; | 717 sep = ","; |
| 573 } | 718 } |
| 574 return list.map((e) => e == null ? "" : e.toString()).join(sep.toString()); | 719 return list.map((e) => e == null ? "" : e.toString()).join(sep.toString()); |
| 575 } | 720 } |
| 576 | 721 |
| 577 // TODO(jacobr): should we really bother with this method instead of just | 722 // TODO(jacobr): should we really bother with this method instead of just |
| 578 // shallow copying to a JS array and using the toString method? | 723 // shallow copying to a JS array and using the toString method? |
| 579 String _arrayToString(List list) => _arrayJoin(list, ","); | 724 String _arrayToString(List list) => _arrayJoin(list, ","); |
| 580 | 725 |
| 581 int _arrayPush(List list, List args) { | 726 int _arrayPush(List list, List args) { |
| 582 for(var e in args) { | 727 for (var e in args) { |
| 583 list.add(e); | 728 list.add(e); |
| 584 } | 729 } |
| 585 return list.length; | 730 return list.length; |
| 586 } | 731 } |
| 587 | 732 |
| 588 _arrayPop(List list) { | 733 _arrayPop(List list) { |
| 589 if (list.length > 0) return list.removeLast(); | 734 if (list.length > 0) return list.removeLast(); |
| 590 } | 735 } |
| 591 | 736 |
| 592 // TODO(jacobr): would it be better to just copy input to a JS List | 737 // TODO(jacobr): would it be better to just copy input to a JS List |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 696 JsObject get context { | 841 JsObject get context { |
| 697 if (_cachedContext == null) { | 842 if (_cachedContext == null) { |
| 698 _cachedContext = _context; | 843 _cachedContext = _context; |
| 699 } | 844 } |
| 700 return _cachedContext; | 845 return _cachedContext; |
| 701 } | 846 } |
| 702 | 847 |
| 703 _maybeWrap(o) { | 848 _maybeWrap(o) { |
| 704 var wrapped = html_common.wrap_jso_no_SerializedScriptvalue(o); | 849 var wrapped = html_common.wrap_jso_no_SerializedScriptvalue(o); |
| 705 if (identical(wrapped, o)) return o; | 850 if (identical(wrapped, o)) return o; |
| 706 return (wrapped is html.Blob | 851 return (wrapped is html.Blob || |
| 707 || wrapped is html.Event | 852 wrapped is html.Event || |
| 708 || wrapped is indexed_db.KeyRange | 853 wrapped is indexed_db.KeyRange || |
| 709 || wrapped is html.ImageData | 854 wrapped is html.ImageData || |
| 710 || wrapped is html.Node | 855 wrapped is html.Node || |
| 711 || wrapped is TypedData | 856 wrapped is TypedData || |
| 712 || wrapped is html.Window) ? wrapped : o; | 857 wrapped is html.Window) ? wrapped : o; |
| 713 } | 858 } |
| 714 | 859 |
| 715 /** | 860 /** |
| 716 * Get the dart wrapper object for object. Top-level so we | 861 * Get the dart wrapper object for object. Top-level so we |
| 717 * we can access it from other libraries without it being | 862 * we can access it from other libraries without it being |
| 718 * a public instance field on JsObject. | 863 * a public instance field on JsObject. |
| 719 */ | 864 */ |
| 720 @Deprecated("Internal Use Only") | 865 @Deprecated("Internal Use Only") |
| 721 getDartHtmlWrapperFor(JsObject object) => object._dartHtmlWrapper; | 866 getDartHtmlWrapperFor(JsObject object) => object._dartHtmlWrapper; |
| 722 | 867 |
| 723 /** | 868 /** |
| 724 * Set the dart wrapper object for object. Top-level so we | 869 * Set the dart wrapper object for object. Top-level so we |
| 725 * we can access it from other libraries without it being | 870 * we can access it from other libraries without it being |
| 726 * a public instance field on JsObject. | 871 * a public instance field on JsObject. |
| 727 */ | 872 */ |
| 728 @Deprecated("Internal Use Only") | 873 @Deprecated("Internal Use Only") |
| 729 void setDartHtmlWrapperFor(JsObject object, wrapper) { | 874 void setDartHtmlWrapperFor(JsObject object, wrapper) { |
| 730 object._dartHtmlWrapper = wrapper; | 875 object._dartHtmlWrapper = wrapper; |
| 731 } | 876 } |
| 732 | 877 |
| 733 /** | 878 /** |
| 734 * Used by callMethod to get the JS object for each argument passed if the | 879 * Used by callMethod to get the JS object for each argument passed if the |
| 735 * argument is a Dart class instance that delegates to a DOM object. See | 880 * argument is a Dart class instance that delegates to a DOM object. See |
| 736 * wrap_jso defined in dart:html. | 881 * wrap_jso defined in dart:html. |
| 737 */ | 882 */ |
| 738 @Deprecated("Internal Use Only") | 883 @Deprecated("Internal Use Only") |
| 739 unwrap_jso(dartClass_instance) { | 884 unwrap_jso(dartClass_instance) { |
| 740 if (dartClass_instance is html.DartHtmlDomObject) | 885 if (dartClass_instance is html.DartHtmlDomObject && |
| 741 return dartClass_instance.blink_jsObject; | 886 dartClass_instance is! JsObject) return dartClass_instance.blink_jsObject; |
| 742 else | 887 else return dartClass_instance; |
| 743 return dartClass_instance; | |
| 744 } | 888 } |
| 745 | 889 |
| 746 /** | 890 /** |
| 747 * Proxies a JavaScript object to Dart. | 891 * Proxies a JavaScript object to Dart. |
| 748 * | 892 * |
| 749 * The properties of the JavaScript object are accessible via the `[]` and | 893 * The properties of the JavaScript object are accessible via the `[]` and |
| 750 * `[]=` operators. Methods are callable via [callMethod]. | 894 * `[]=` operators. Methods are callable via [callMethod]. |
| 751 */ | 895 */ |
| 752 class JsObject extends NativeFieldWrapperClass2 { | 896 class JsObject extends NativeFieldWrapperClass2 { |
| 753 JsObject.internal(); | 897 JsObject.internal(); |
| 754 | 898 |
| 755 /** | 899 /** |
| 756 * If this JsObject is wrapped, e.g. DOM objects, then we can save the | 900 * If this JsObject is wrapped, e.g. DOM objects, then we can save the |
| 757 * wrapper here and preserve its identity. | 901 * wrapper here and preserve its identity. |
| 758 */ | 902 */ |
| 759 var _dartHtmlWrapper; | 903 var _dartHtmlWrapper; |
| 760 | 904 |
| 761 /** | 905 /** |
| 762 * Constructs a new JavaScript object from [constructor] and returns a proxy | 906 * Constructs a new JavaScript object from [constructor] and returns a proxy |
| 763 * to it. | 907 * to it. |
| 764 */ | 908 */ |
| 765 factory JsObject(JsFunction constructor, [List arguments]) { | 909 factory JsObject(JsFunction constructor, [List arguments]) { |
| 766 try { | 910 try { |
| 767 return _create(constructor, arguments); | 911 return html_common.unwrap_jso(_create(constructor, arguments)); |
| 768 } catch (e) { | 912 } catch (e) { |
| 769 // Re-throw any errors (returned as a string) as a DomException. | 913 // Re-throw any errors (returned as a string) as a DomException. |
| 770 throw new html.DomException.jsInterop(e); | 914 throw new html.DomException.jsInterop(e); |
| 771 } | 915 } |
| 772 } | 916 } |
| 773 | 917 |
| 774 static JsObject _create( | 918 static JsObject _create(JsFunction constructor, arguments) |
| 775 JsFunction constructor, arguments) native "JsObject_constructorCallback"; | 919 native "JsObject_constructorCallback"; |
| 776 | 920 |
| 777 _buildArgs(Invocation invocation) { | 921 _buildArgs(Invocation invocation) { |
| 778 if (invocation.namedArguments.isEmpty) { | 922 if (invocation.namedArguments.isEmpty) { |
| 779 return invocation.positionalArguments; | 923 return invocation.positionalArguments; |
| 780 } else { | 924 } else { |
| 781 var varArgs = new Map<String, Object>(); | 925 var varArgs = new Map<String, Object>(); |
| 782 invocation.namedArguments.forEach((symbol, val) { | 926 invocation.namedArguments.forEach((symbol, val) { |
| 783 varArgs[mirrors.MirrorSystem.getName(symbol)] = val; | 927 varArgs[mirrors.MirrorSystem.getName(symbol)] = val; |
| 784 }); | 928 }); |
| 785 return invocation.positionalArguments.toList() | 929 return invocation.positionalArguments.toList() |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 832 * The type of [property] must be either [String] or [num]. | 976 * The type of [property] must be either [String] or [num]. |
| 833 */ | 977 */ |
| 834 operator [](property) { | 978 operator [](property) { |
| 835 try { | 979 try { |
| 836 return _maybeWrap(_operator_getter(property)); | 980 return _maybeWrap(_operator_getter(property)); |
| 837 } catch (e) { | 981 } catch (e) { |
| 838 // Re-throw any errors (returned as a string) as a DomException. | 982 // Re-throw any errors (returned as a string) as a DomException. |
| 839 throw new html.DomException.jsInterop(e); | 983 throw new html.DomException.jsInterop(e); |
| 840 } | 984 } |
| 841 } | 985 } |
| 986 |
| 842 _operator_getter(property) native "JsObject_[]"; | 987 _operator_getter(property) native "JsObject_[]"; |
| 843 | 988 |
| 844 /** | 989 /** |
| 845 * Sets the value associated with [property] on the proxied JavaScript | 990 * Sets the value associated with [property] on the proxied JavaScript |
| 846 * object. | 991 * object. |
| 847 * | 992 * |
| 848 * The type of [property] must be either [String] or [num]. | 993 * The type of [property] must be either [String] or [num]. |
| 849 */ | 994 */ |
| 850 operator []=(property, value) { | 995 operator []=(property, value) { |
| 851 try { | 996 try { |
| 852 _operator_setter(property, value); | 997 _operator_setter(property, value); |
| 853 } catch (e) { | 998 } catch (e) { |
| 854 // Re-throw any errors (returned as a string) as a DomException. | 999 // Re-throw any errors (returned as a string) as a DomException. |
| 855 throw new html.DomException.jsInterop(e); | 1000 throw new html.DomException.jsInterop(e); |
| 856 } | 1001 } |
| 857 } | 1002 } |
| 1003 |
| 858 _operator_setter(property, value) native "JsObject_[]="; | 1004 _operator_setter(property, value) native "JsObject_[]="; |
| 859 | 1005 |
| 860 int get hashCode native "JsObject_hashCode"; | 1006 int get hashCode native "JsObject_hashCode"; |
| 861 | 1007 |
| 862 operator ==(other) { | 1008 operator ==(other) { |
| 863 var is_JsObject = other is JsObject; | 1009 var is_JsObject = other is JsObject; |
| 864 if (!is_JsObject) { | 1010 if (!is_JsObject) { |
| 865 other = html_common.unwrap_jso(other); | 1011 other = html_common.unwrap_jso(other); |
| 866 is_JsObject = other is JsObject; | 1012 is_JsObject = other is JsObject; |
| 867 } | 1013 } |
| 868 return is_JsObject && _identityEquality(this, other); | 1014 return is_JsObject && _identityEquality(this, other); |
| 869 } | 1015 } |
| 870 | 1016 |
| 871 static bool _identityEquality( | 1017 static bool _identityEquality(JsObject a, JsObject b) |
| 872 JsObject a, JsObject b) native "JsObject_identityEquality"; | 1018 native "JsObject_identityEquality"; |
| 873 | 1019 |
| 874 /** | 1020 /** |
| 875 * Returns `true` if the JavaScript object contains the specified property | 1021 * Returns `true` if the JavaScript object contains the specified property |
| 876 * either directly or though its prototype chain. | 1022 * either directly or though its prototype chain. |
| 877 * | 1023 * |
| 878 * This is the equivalent of the `in` operator in JavaScript. | 1024 * This is the equivalent of the `in` operator in JavaScript. |
| 879 */ | 1025 */ |
| 880 bool hasProperty(String property) native "JsObject_hasProperty"; | 1026 bool hasProperty(String property) native "JsObject_hasProperty"; |
| 881 | 1027 |
| 882 /** | 1028 /** |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1012 * Returns a [JsFunction] that captures its 'this' binding and calls [f] | 1158 * Returns a [JsFunction] that captures its 'this' binding and calls [f] |
| 1013 * with the value of this passed as the first argument. | 1159 * with the value of this passed as the first argument. |
| 1014 */ | 1160 */ |
| 1015 factory JsFunction.withThis(Function f) => _withThis(f); | 1161 factory JsFunction.withThis(Function f) => _withThis(f); |
| 1016 | 1162 |
| 1017 /** | 1163 /** |
| 1018 * Invokes the JavaScript function with arguments [args]. If [thisArg] is | 1164 * Invokes the JavaScript function with arguments [args]. If [thisArg] is |
| 1019 * supplied it is the value of `this` for the invocation. | 1165 * supplied it is the value of `this` for the invocation. |
| 1020 */ | 1166 */ |
| 1021 dynamic apply(List args, {thisArg}) => | 1167 dynamic apply(List args, {thisArg}) => |
| 1022 _maybeWrap(_apply(args, thisArg: thisArg)); | 1168 _maybeWrap(_apply(args, thisArg: thisArg)); |
| 1023 | 1169 |
| 1024 dynamic _apply(List args, {thisArg}) native "JsFunction_apply"; | 1170 dynamic _apply(List args, {thisArg}) native "JsFunction_apply"; |
| 1025 | 1171 |
| 1026 noSuchMethod(Invocation invocation) { | 1172 noSuchMethod(Invocation invocation) { |
| 1027 if (invocation.isMethod && invocation.memberName == #call) { | 1173 if (invocation.isMethod && invocation.memberName == #call) { |
| 1028 return apply(_buildArgs(invocation)); | 1174 return apply(_buildArgs(invocation)); |
| 1029 } | 1175 } |
| 1030 return super.noSuchMethod(invocation); | 1176 return super.noSuchMethod(invocation); |
| 1031 } | 1177 } |
| 1032 | 1178 |
| 1033 /** | 1179 /** |
| 1034 * Internal only version of apply which uses debugger proxies of Dart objects | 1180 * Internal only version of apply which uses debugger proxies of Dart objects |
| 1035 * rather than opaque handles. This method is private because it cannot be | 1181 * rather than opaque handles. This method is private because it cannot be |
| 1036 * efficiently implemented in Dart2Js so should only be used by internal | 1182 * efficiently implemented in Dart2Js so should only be used by internal |
| 1037 * tools. | 1183 * tools. |
| 1038 */ | 1184 */ |
| 1039 _applyDebuggerOnly(List args, | 1185 _applyDebuggerOnly(List args, {thisArg}) |
| 1040 {thisArg}) native "JsFunction_applyDebuggerOnly"; | 1186 native "JsFunction_applyDebuggerOnly"; |
| 1041 | 1187 |
| 1042 static JsFunction _withThis(Function f) native "JsFunction_withThis"; | 1188 static JsFunction _withThis(Function f) native "JsFunction_withThis"; |
| 1043 } | 1189 } |
| 1044 | 1190 |
| 1045 /** | 1191 /** |
| 1046 * A [List] proxying a JavaScript Array. | 1192 * A [List] proxying a JavaScript Array. |
| 1047 */ | 1193 */ |
| 1048 class JsArray<E> extends JsObject with ListMixin<E> { | 1194 class JsArray<E> extends JsObject with ListMixin<E> { |
| 1049 JsArray.internal() : super.internal(); | 1195 JsArray.internal() : super.internal(); |
| 1050 | 1196 |
| 1051 factory JsArray() => _newJsArray(); | 1197 factory JsArray() => _newJsArray(); |
| 1052 | 1198 |
| 1053 static JsArray _newJsArray() native "JsArray_newJsArray"; | 1199 static JsArray _newJsArray() native "JsArray_newJsArray"; |
| 1054 | 1200 |
| 1055 factory JsArray.from(Iterable<E> other) => | 1201 factory JsArray.from(Iterable<E> other) => |
| 1056 _newJsArrayFromSafeList(new List.from(other)); | 1202 _newJsArrayFromSafeList(new List.from(other)); |
| 1057 | 1203 |
| 1058 static JsArray _newJsArrayFromSafeList( | 1204 static JsArray _newJsArrayFromSafeList(List list) |
| 1059 List list) native "JsArray_newJsArrayFromSafeList"; | 1205 native "JsArray_newJsArrayFromSafeList"; |
| 1060 | 1206 |
| 1061 _checkIndex(int index, {bool insert: false}) { | 1207 _checkIndex(int index, {bool insert: false}) { |
| 1062 int length = insert ? this.length + 1 : this.length; | 1208 int length = insert ? this.length + 1 : this.length; |
| 1063 if (index is int && (index < 0 || index >= length)) { | 1209 if (index is int && (index < 0 || index >= length)) { |
| 1064 throw new RangeError.range(index, 0, length); | 1210 throw new RangeError.range(index, 0, length); |
| 1065 } | 1211 } |
| 1066 } | 1212 } |
| 1067 | 1213 |
| 1068 _checkRange(int start, int end) { | 1214 _checkRange(int start, int end) { |
| 1069 int cachedLength = this.length; | 1215 int cachedLength = this.length; |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1151 | 1297 |
| 1152 // TODO(jacobr): this method is a hack to work around the lack of proper dart | 1298 // TODO(jacobr): this method is a hack to work around the lack of proper dart |
| 1153 // support for varargs methods. | 1299 // support for varargs methods. |
| 1154 List _stripUndefinedArgs(List args) => | 1300 List _stripUndefinedArgs(List args) => |
| 1155 args.takeWhile((i) => i != _UNDEFINED).toList(); | 1301 args.takeWhile((i) => i != _UNDEFINED).toList(); |
| 1156 | 1302 |
| 1157 /** | 1303 /** |
| 1158 * Returns a method that can be called with an arbitrary number (for n less | 1304 * Returns a method that can be called with an arbitrary number (for n less |
| 1159 * than 11) of arguments without violating Dart type checks. | 1305 * than 11) of arguments without violating Dart type checks. |
| 1160 */ | 1306 */ |
| 1161 Function _wrapAsDebuggerVarArgsFunction(JsFunction jsFunction) => | 1307 Function _wrapAsDebuggerVarArgsFunction(JsFunction jsFunction) => ( |
| 1162 ([a1 = _UNDEFINED, a2 = _UNDEFINED, a3 = _UNDEFINED, a4 = _UNDEFINED, | 1308 [a1 = _UNDEFINED, |
| 1163 a5 = _UNDEFINED, a6 = _UNDEFINED, a7 = _UNDEFINED, a8 = _UNDEFINED, | 1309 a2 = _UNDEFINED, |
| 1164 a9 = _UNDEFINED, a10 = _UNDEFINED]) => jsFunction._applyDebuggerOnly( | 1310 a3 = _UNDEFINED, |
| 1165 _stripUndefinedArgs([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10])); | 1311 a4 = _UNDEFINED, |
| 1312 a5 = _UNDEFINED, |
| 1313 a6 = _UNDEFINED, |
| 1314 a7 = _UNDEFINED, |
| 1315 a8 = _UNDEFINED, |
| 1316 a9 = _UNDEFINED, |
| 1317 a10 = _UNDEFINED]) => |
| 1318 jsFunction._applyDebuggerOnly( |
| 1319 _stripUndefinedArgs([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10])); |
| 1166 | 1320 |
| 1167 // The allowInterop method is a no-op in Dartium. | 1321 // The allowInterop method is a no-op in Dartium. |
| 1168 // TODO(jacobr): tag methods so we can throw if a Dart method is passed to | 1322 // TODO(jacobr): tag methods so we can throw if a Dart method is passed to |
| 1169 // JavaScript using the new interop without calling allowInterop. | 1323 // JavaScript using the new interop without calling allowInterop. |
| 1170 | 1324 |
| 1171 /// Returns a wrapper around function [f] that can be called from JavaScript | 1325 /// Returns a wrapper around function [f] that can be called from JavaScript |
| 1172 /// using the package:js Dart-JavaScript interop. | 1326 /// using the package:js Dart-JavaScript interop. |
| 1173 /// | 1327 /// |
| 1174 /// For performance reasons in Dart2Js, by default Dart functions cannot be | 1328 /// For performance reasons in Dart2Js, by default Dart functions cannot be |
| 1175 /// passed directly to JavaScript unless this method is called to create | 1329 /// passed directly to JavaScript unless this method is called to create |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1197 return f; | 1351 return f; |
| 1198 } else { | 1352 } else { |
| 1199 var ret = _interopCaptureThisExpando[f]; | 1353 var ret = _interopCaptureThisExpando[f]; |
| 1200 if (ret == null) { | 1354 if (ret == null) { |
| 1201 ret = new JsFunction.withThis(f); | 1355 ret = new JsFunction.withThis(f); |
| 1202 _interopCaptureThisExpando[f] = ret; | 1356 _interopCaptureThisExpando[f] = ret; |
| 1203 } | 1357 } |
| 1204 return ret; | 1358 return ret; |
| 1205 } | 1359 } |
| 1206 } | 1360 } |
| OLD | NEW |