Chromium Code Reviews| 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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 } | 269 } |
| 271 } | 270 } |
| 272 } | 271 } |
| 273 } | 272 } |
| 274 return null; | 273 return null; |
| 275 } | 274 } |
| 276 | 275 |
| 276 bool _isAnonymousClass(mirrors.ClassMirror mirror) { | |
| 277 for (var annotation in mirror.metadata) { | |
| 278 if (mirrors.MirrorSystem.getName(annotation.type.simpleName) == "_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 } | |
| 289 | |
| 277 bool _hasJsName(mirrors.DeclarationMirror mirror) => | 290 bool _hasJsName(mirrors.DeclarationMirror mirror) => |
| 278 _getJsName(mirror) != null; | 291 _getJsName(mirror) != null; |
| 279 | 292 |
| 280 | 293 |
| 281 _getJsMemberName(mirrors.DeclarationMirror mirror) { | 294 _getJsMemberName(mirrors.DeclarationMirror mirror) { |
| 282 var name = _getJsName(mirror); | 295 var name = _getJsName(mirror); |
| 283 return name == null || name.isEmpty ? _getDeclarationName(mirror) : | 296 return name == null || name.isEmpty ? _getDeclarationName(mirror) : |
| 284 name; | 297 name; |
| 285 } | 298 } |
| 286 | 299 |
| 287 // TODO(jacobr): handle setters correctyl. | 300 // TODO(jacobr): handle setters correctyl. |
| 288 String _getDeclarationName(mirrors.DeclarationMirror declaration) { | 301 String _getDeclarationName(mirrors.DeclarationMirror declaration) { |
| 289 var name = mirrors.MirrorSystem.getName(declaration.simpleName); | 302 var name = mirrors.MirrorSystem.getName(declaration.simpleName); |
| 290 if (declaration is mirrors.MethodMirror && declaration.isSetter) { | 303 if (declaration is mirrors.MethodMirror && declaration.isSetter) { |
| 291 assert(name.endsWith("=")); | 304 assert(name.endsWith("=")); |
| 292 name = name.substring(0, name.length - 1); | 305 name = name.substring(0, name.length - 1); |
| 293 } | 306 } |
| 294 return name; | 307 return name; |
| 295 } | 308 } |
| 296 | 309 |
| 297 final _JS_LIBRARY_PREFIX = "js_library"; | 310 final _JS_LIBRARY_PREFIX = "js_library"; |
| 298 final _UNDEFINED_VAR = "_UNDEFINED_JS_CONST"; | 311 final _UNDEFINED_VAR = "_UNDEFINED_JS_CONST"; |
| 299 | 312 |
| 300 String _accessJsPath(String path) => | 313 String _accessJsPath(String path) => |
| 301 "${_JS_LIBRARY_PREFIX}.context${path.split(".").map((p) => "['$p']").join('' )}"; | 314 "${_JS_LIBRARY_PREFIX}.context${path.split(".").map((p) => "['$p']").join('' )}"; |
| 302 | 315 |
| 303 @Deprecated("Internal Use Only") | 316 @Deprecated("Internal Use Only") |
| 304 void addMemberHelper(mirrors.MethodMirror declaration, String path, StringBuffer sb, {bool isStatic: false, String memberName}) { | 317 void addMemberHelper(mirrors.MethodMirror declaration, String path, StringBuffer sb, {bool isStatic: false, String memberName}) { |
| 305 var jsName = _getJsMemberName(declaration); | 318 if (!declaration.isConstructor) { |
| 306 path = (path != null && path.isNotEmpty) ? "${path}.${jsName}" : jsName; | 319 var jsName = _getJsMemberName(declaration); |
| 320 path = (path != null && path.isNotEmpty) ? "${path}.${jsName}" : jsName; | |
| 321 } | |
| 307 var name = memberName != null ? memberName : _getDeclarationName(declaration); | 322 var name = memberName != null ? memberName : _getDeclarationName(declaration); |
| 308 if (declaration.isConstructor) { | 323 if (declaration.isConstructor) { |
| 309 sb.write("factory"); | 324 sb.write("factory"); |
| 310 } else if (isStatic) { | 325 } else if (isStatic) { |
| 311 sb.write("static"); | 326 sb.write("static"); |
| 312 } else { | 327 } else { |
| 313 sb.write("patch"); | 328 sb.write("patch"); |
| 314 } | 329 } |
| 315 sb.write(" "); | 330 sb.write(" "); |
| 316 if (declaration.isGetter) { | 331 if (declaration.isGetter) { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 355 | 370 |
| 356 if (hasOptional) { | 371 if (hasOptional) { |
| 357 sb.write(".takeWhile((i) => i != ${_UNDEFINED_VAR}).toList()"); | 372 sb.write(".takeWhile((i) => i != ${_UNDEFINED_VAR}).toList()"); |
| 358 } | 373 } |
| 359 sb.write(");"); | 374 sb.write(");"); |
| 360 } | 375 } |
| 361 sb.write("\n"); | 376 sb.write("\n"); |
| 362 } | 377 } |
| 363 | 378 |
| 364 // TODO(jacobr): make this check more robust. | 379 // TODO(jacobr): make this check more robust. |
| 365 bool _isExternal(mirrors.MethodMirror mirror) => | 380 bool _isExternal(mirrors.Mirror mirror) { |
| 366 mirror.source != null && mirror.source.startsWith("external "); | 381 /* |
| 382 var source = mirror.source; | |
| 383 return source != null && source.startsWith("external "); | |
| 384 */ | |
| 385 return mirror.isExternal; | |
| 386 } | |
| 367 | 387 |
| 368 List<String> _generateExternalMethods() { | 388 List<String> _generateExternalMethods() { |
| 369 var staticCodegen = <String>[]; | 389 var staticCodegen = <String>[]; |
| 370 mirrors.currentMirrorSystem().libraries.forEach((uri, library) { | 390 mirrors.currentMirrorSystem().libraries.forEach((uri, library) { |
| 371 var sb = new StringBuffer(); | 391 var sb = new StringBuffer(); |
| 372 String jsLibraryName = _getJsName(library); | 392 String jsLibraryName = _getJsName(library); |
| 373 library.declarations.forEach((name, declaration) { | 393 library.declarations.forEach((name, declaration) { |
| 374 if (declaration is mirrors.MethodMirror) { | 394 if (declaration is mirrors.MethodMirror) { |
| 375 if (_isExternal(declaration) && (_hasJsName(declaration) || jsLibraryNam e != null)) { | 395 if ((_hasJsName(declaration) || jsLibraryName != null) && _isExternal(de claration)) { |
| 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 || !_isExternal(declaration )) return; |
| 389 if (declaration.isFactoryConstructor) { | 408 if (declaration.isFactoryConstructor && _isAnonymousClass(clazz)) { |
| 390 sbPatch.write(" factory ${className}({"); | 409 sbPatch.write(" factory ${className}({"); |
| 391 int i = 0; | 410 int i = 0; |
| 392 var args = <String>[]; | 411 var args = <String>[]; |
| 412 for (var p in declaration.parameters) { | |
| 413 args.add(mirrors.MirrorSystem.getName(p.simpleName)); | |
| 414 i++; | |
| 415 } | |
| 416 sbPatch | |
| 417 ..write(args.map((name) => '$name:${_UNDEFINED_VAR}').join(", ") ) | |
| 418 ..write("}) {\n" | |
| 419 " var ret = new ${_JS_LIBRARY_PREFIX}.JsObject.jsify( {});\n"); | |
| 420 i = 0; | |
| 421 for (var p in declaration.parameters) { | |
| 422 assert(p.isNamed); // XXX throw | |
| 423 var name = args[i]; | |
| 424 var jsName = mirrors.MirrorSystem.getName(p.simpleName); | |
| 425 // XXX apply name conversion rules. | |
| 426 sbPatch.write(" if($name != ${_UNDEFINED_VAR}) ret['$jsName'] = $name;\n"); | |
| 427 i++; | |
| 428 } | |
| 429 | |
| 430 sbPatch.write(" return ret;\n" | |
| 431 " }\n"); | |
| 432 } else if (declaration.isConstructor || declaration.isFactoryConstru ctor) { | |
| 433 sbPatch.write(" "); | |
| 434 addMemberHelper(declaration, | |
| 435 (jsLibraryName != null && jsLibraryName.isNotEmpty) ? "${jsLib raryName}.${jsClassName}" : jsClassName, | |
| 436 sbPatch, | |
| 437 isStatic: true, | |
| 438 memberName: className); | |
| 439 } | |
| 440 }); | |
| 441 | |
| 442 clazz.staticMembers.forEach((memberName, member) { | |
| 443 if (_isExternal(member)) { | |
| 444 sbPatch.write(" "); | |
| 445 addMemberHelper(member, | |
| 446 (jsLibraryName != null && jsLibraryName.isNotEmpty) ? "${jsLib raryName}.${jsClassName}" : jsClassName, | |
| 447 sbPatch, | |
| 448 isStatic: true); | |
| 449 } | |
| 450 }); | |
| 451 var typeVariablesClause = ''; | |
| 452 if (!clazz.typeVariables.isEmpty) { | |
| 453 typeVariablesClause = '<${clazz.typeVariables.map((m) => mirrors.Mir rorSystem.getName(m.simpleName)).join(',')}>'; | |
| 454 } | |
| 455 if (sbPatch.isNotEmpty) { | |
| 456 sb.write(""" | |
| 457 patch class $className$typeVariablesClause { | |
| 458 $sbPatch | |
| 459 } | |
| 460 """); | |
| 461 } | |
| 462 } | |
| 463 } | |
| 464 }); | |
| 465 if (sb.isNotEmpty) { | |
| 466 staticCodegen | |
| 467 ..add(uri.toString()) | |
| 468 ..add("${uri}_js_interop_patch.dart") | |
| 469 ..add(""" | |
| 470 import 'dart:js' as ${_JS_LIBRARY_PREFIX}; | |
| 471 | |
| 472 /** | |
| 473 * Placeholder object for cases where we need to determine exactly how many | |
| 474 * args were passed to a function. | |
| 475 */ | |
| 476 const ${_UNDEFINED_VAR} = const Object(); | |
| 477 | |
| 478 ${sb} | |
| 479 """); | |
| 480 } | |
| 481 }); | |
| 482 | |
| 483 return staticCodegen; | |
| 484 } | |
| 485 | |
| 486 List<String> _generateExternalMethods2() { | |
| 487 var staticCodegen = <String>[]; | |
| 488 mirrors.currentMirrorSystem().libraries.forEach((uri, library) { | |
| 489 var sb = new StringBuffer(); | |
| 490 String jsLibraryName = _getJsName(library); | |
| 491 library.declarations.forEach((name, declaration) { | |
| 492 var isExternal = _isExternal(declaration); | |
| 493 if (declaration is mirrors.MethodMirror) { | |
| 494 if (isExternal && (_hasJsName(declaration) || jsLibraryName != null)) { | |
| 495 addMemberHelper(declaration, jsLibraryName, sb); | |
| 496 } | |
| 497 } else if (declaration is mirrors.ClassMirror) { | |
| 498 mirrors.ClassMirror clazz = declaration; | |
| 499 if (_hasJsName(clazz)) { | |
| 500 // TODO(jacobr): verify class implements JavaScriptObject. | |
| 501 String jsClassName = _getJsMemberName(clazz); | |
| 502 var className = mirrors.MirrorSystem.getName(clazz.simpleName); | |
| 503 var sbPatch = new StringBuffer(); | |
| 504 jsInterfaceTypes.add(clazz); | |
| 505 clazz.declarations.forEach((name, declaration) { | |
| 506 if (declaration is! mirrors.MethodMirror || !declaration.isAbstract || !isExternal) return; | |
| 507 if (_hasLiteralAnnotation(declaration) && declaration.isFactoryConst ructor) { | |
| 508 sbPatch.write(" factory ${className}({"); | |
| 509 int i = 0; | |
| 510 var args = <String>[]; | |
| 393 for (var p in declaration.parameters) { | 511 for (var p in declaration.parameters) { |
| 394 assert(p.isNamed); // XXX throw | 512 assert(p.isNamed); // XXX throw |
| 395 args.add(mirrors.MirrorSystem.getName(p.simpleName)); | 513 args.add(mirrors.MirrorSystem.getName(p.simpleName)); |
| 396 i++; | 514 i++; |
| 397 } | 515 } |
| 398 sbPatch | 516 sbPatch |
| 399 ..write(args.map((name) => '$name:${_UNDEFINED_VAR}').join(", ") ) | 517 ..write(args.map((name) => '$name:${_UNDEFINED_VAR}').join(", ") ) |
| 400 ..write("}) {\n" | 518 ..write("}) {\n" |
| 401 " var ret = new ${_JS_LIBRARY_PREFIX}.JsObject.jsify( {});\n"); | 519 " var ret = new ${_JS_LIBRARY_PREFIX}.JsObject.jsify( {});\n"); |
| 402 i = 0; | 520 i = 0; |
| 403 for (var p in declaration.parameters) { | 521 for (var p in declaration.parameters) { |
| 404 assert(p.isNamed); // XXX throw | 522 assert(p.isNamed); // XXX throw |
| 405 var name = args[i]; | 523 var name = args[i]; |
| 406 var jsName = mirrors.MirrorSystem.getName(p.simpleName); | 524 var jsName = mirrors.MirrorSystem.getName(p.simpleName); |
| 407 // XXX apply name conversion rules. | 525 // XXX apply name conversion rules. |
| 408 sbPatch.write(" if($name != ${_UNDEFINED_VAR}) ret['$jsName'] = $name;\n"); | 526 sbPatch.write(" if($name != ${_UNDEFINED_VAR}) ret['$jsName'] = $name;\n"); |
| 409 i++; | 527 i++; |
| 410 } | 528 } |
| 411 | 529 |
| 412 sbPatch.write(" return ret;\n" | 530 sbPatch.write(" return ret;\n" |
| 413 " }\n"); | 531 " }\n"); |
| 414 } else if (declaration.isConstructor) { | 532 } else if (declaration.isConstructor || declaration.isFactoryConstru ctor) { |
| 415 sbPatch.write(" "); | 533 sbPatch.write(" "); |
| 416 addMemberHelper(declaration, | 534 addMemberHelper(declaration, |
| 417 (jsLibraryName != null && jsLibraryName.isNotEmpty) ? "${jsLib raryName}" : "", | 535 (jsLibraryName != null && jsLibraryName.isNotEmpty) ? "${jsLib raryName}.${jsClassName}" : jsClassName, |
| 418 sbPatch, | 536 sbPatch, |
| 419 isStatic: true, | 537 isStatic: true, |
| 420 memberName: className); | 538 memberName: className); |
| 421 } | 539 } |
| 422 }); | 540 }); |
| 423 | 541 |
| 424 clazz.staticMembers.forEach((memberName, member) { | 542 clazz.staticMembers.forEach((memberName, member) { |
| 425 if (_isExternal(member)) { | 543 if (_isExternal(member)) { |
| 426 sbPatch.write(" "); | 544 sbPatch.write(" "); |
| 427 addMemberHelper(member, | 545 addMemberHelper(member, |
| 428 (jsLibraryName != null && jsLibraryName.isNotEmpty) ? "${jsLib raryName}.${jsClassName}" : jsClassName, | 546 (jsLibraryName != null && jsLibraryName.isNotEmpty) ? "${jsLib raryName}.${jsClassName}" : jsClassName, |
| 429 sbPatch, | 547 sbPatch, |
| 430 isStatic: true); | 548 isStatic: true); |
| 431 } | 549 } |
| 432 }); | 550 }); |
| 551 var typeVariablesClause = ''; | |
| 552 if (!clazz.typeVariables.isEmpty) { | |
| 553 typeVariablesClause = '<${clazz.typeVariables.map((m) => mirrors.Mir rorSystem.getName(m.simpleName)).join(',')}>'; | |
| 554 } | |
| 433 if (sbPatch.isNotEmpty) { | 555 if (sbPatch.isNotEmpty) { |
| 434 sb.write(""" | 556 sb.write(""" |
| 435 patch class $className { | 557 patch class $className$typeVariablesClause { |
| 436 $sbPatch | 558 $sbPatch |
| 437 } | 559 } |
| 438 """); | 560 """); |
| 439 } | 561 } |
| 440 } | 562 } |
| 441 } | 563 } |
| 442 }); | 564 }); |
| 443 if (sb.isNotEmpty) { | 565 if (sb.isNotEmpty) { |
| 444 staticCodegen | 566 staticCodegen |
| 445 ..add(uri.toString()) | 567 ..add(uri.toString()) |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 469 List<String> _generateInteropPatchFiles() { | 591 List<String> _generateInteropPatchFiles() { |
| 470 var ret = _generateExternalMethods(); | 592 var ret = _generateExternalMethods(); |
| 471 var libraryPrefixes = new Map<mirrors.LibraryMirror, String>(); | 593 var libraryPrefixes = new Map<mirrors.LibraryMirror, String>(); |
| 472 var prefixNames = new Set<String>(); | 594 var prefixNames = new Set<String>(); |
| 473 var sb = new StringBuffer(); | 595 var sb = new StringBuffer(); |
| 474 | 596 |
| 475 var implements = <String>[]; | 597 var implements = <String>[]; |
| 476 var implementsArray = <String>[]; | 598 var implementsArray = <String>[]; |
| 477 var listMirror = mirrors.reflectType(List); | 599 var listMirror = mirrors.reflectType(List); |
| 478 | 600 |
| 479 for (var type in jsInterfaceTypes) { | 601 for (var typeMirror in jsInterfaceTypes) { |
| 480 mirrors.ClassMirror typeMirror = mirrors.reflectType(type); | |
| 481 mirrors.LibraryMirror libraryMirror = typeMirror.owner; | 602 mirrors.LibraryMirror libraryMirror = typeMirror.owner; |
| 482 var prefixName; | 603 var prefixName; |
| 483 if (libraryPrefixes.containsKey(libraryMirror)) { | 604 if (libraryPrefixes.containsKey(libraryMirror)) { |
| 484 prefixName = libraryPrefixes[libraryMirror]; | 605 prefixName = libraryPrefixes[libraryMirror]; |
| 485 } else { | 606 } else { |
| 486 var basePrefixName = | 607 var basePrefixName = |
| 487 mirrors.MirrorSystem.getName(libraryMirror.simpleName); | 608 mirrors.MirrorSystem.getName(libraryMirror.simpleName); |
| 488 basePrefixName = basePrefixName.replaceAll('.', '_'); | 609 basePrefixName = basePrefixName.replaceAll('.', '_'); |
| 489 if (basePrefixName.isEmpty) basePrefixName = "lib"; | 610 if (basePrefixName.isEmpty) basePrefixName = "lib"; |
| 490 prefixName = basePrefixName; | 611 prefixName = basePrefixName; |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 730 object._dartHtmlWrapper = wrapper; | 851 object._dartHtmlWrapper = wrapper; |
| 731 } | 852 } |
| 732 | 853 |
| 733 /** | 854 /** |
| 734 * Used by callMethod to get the JS object for each argument passed if the | 855 * 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 | 856 * argument is a Dart class instance that delegates to a DOM object. See |
| 736 * wrap_jso defined in dart:html. | 857 * wrap_jso defined in dart:html. |
| 737 */ | 858 */ |
| 738 @Deprecated("Internal Use Only") | 859 @Deprecated("Internal Use Only") |
| 739 unwrap_jso(dartClass_instance) { | 860 unwrap_jso(dartClass_instance) { |
| 740 if (dartClass_instance is html.DartHtmlDomObject) | 861 if (dartClass_instance is html.DartHtmlDomObject && dartClass_instance is! JsO bject) |
|
Alan Knight
2015/10/30 00:38:58
There's a way it can be both?
Jacob
2015/10/30 00:41:24
yep... and not just by accident.
@JS
class MyPoly
| |
| 741 return dartClass_instance.blink_jsObject; | 862 return dartClass_instance.blink_jsObject; |
| 742 else | 863 else |
| 743 return dartClass_instance; | 864 return dartClass_instance; |
| 744 } | 865 } |
| 745 | 866 |
| 746 /** | 867 /** |
| 747 * Proxies a JavaScript object to Dart. | 868 * Proxies a JavaScript object to Dart. |
| 748 * | 869 * |
| 749 * The properties of the JavaScript object are accessible via the `[]` and | 870 * The properties of the JavaScript object are accessible via the `[]` and |
| 750 * `[]=` operators. Methods are callable via [callMethod]. | 871 * `[]=` operators. Methods are callable via [callMethod]. |
| 751 */ | 872 */ |
| 752 class JsObject extends NativeFieldWrapperClass2 { | 873 class JsObject extends NativeFieldWrapperClass2 { |
| 753 JsObject.internal(); | 874 JsObject.internal(); |
| 754 | 875 |
| 755 /** | 876 /** |
| 756 * If this JsObject is wrapped, e.g. DOM objects, then we can save the | 877 * If this JsObject is wrapped, e.g. DOM objects, then we can save the |
| 757 * wrapper here and preserve its identity. | 878 * wrapper here and preserve its identity. |
| 758 */ | 879 */ |
| 759 var _dartHtmlWrapper; | 880 var _dartHtmlWrapper; |
| 760 | 881 |
| 761 /** | 882 /** |
| 762 * Constructs a new JavaScript object from [constructor] and returns a proxy | 883 * Constructs a new JavaScript object from [constructor] and returns a proxy |
| 763 * to it. | 884 * to it. |
| 764 */ | 885 */ |
| 765 factory JsObject(JsFunction constructor, [List arguments]) { | 886 factory JsObject(JsFunction constructor, [List arguments]) { |
| 766 try { | 887 try { |
| 767 return _create(constructor, arguments); | 888 return html_common.unwrap_jso(_create(constructor, arguments)); |
| 768 } catch (e) { | 889 } catch (e) { |
| 769 // Re-throw any errors (returned as a string) as a DomException. | 890 // Re-throw any errors (returned as a string) as a DomException. |
| 770 throw new html.DomException.jsInterop(e); | 891 throw new html.DomException.jsInterop(e); |
| 771 } | 892 } |
| 772 } | 893 } |
| 773 | 894 |
| 774 static JsObject _create( | 895 static JsObject _create( |
| 775 JsFunction constructor, arguments) native "JsObject_constructorCallback"; | 896 JsFunction constructor, arguments) native "JsObject_constructorCallback"; |
| 776 | 897 |
| 777 _buildArgs(Invocation invocation) { | 898 _buildArgs(Invocation invocation) { |
| (...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1197 return f; | 1318 return f; |
| 1198 } else { | 1319 } else { |
| 1199 var ret = _interopCaptureThisExpando[f]; | 1320 var ret = _interopCaptureThisExpando[f]; |
| 1200 if (ret == null) { | 1321 if (ret == null) { |
| 1201 ret = new JsFunction.withThis(f); | 1322 ret = new JsFunction.withThis(f); |
| 1202 _interopCaptureThisExpando[f] = ret; | 1323 _interopCaptureThisExpando[f] = ret; |
| 1203 } | 1324 } |
| 1204 return ret; | 1325 return ret; |
| 1205 } | 1326 } |
| 1206 } | 1327 } |
| OLD | NEW |