Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(151)

Side by Side Diff: pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart

Issue 2982723002: Name-based approach to cross frame support.
Patch Set: Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 /// This library defines the operations that define and manipulate Dart 5 /// This library defines the operations that define and manipulate Dart
6 /// classes. Included in this are: 6 /// classes. Included in this are:
7 /// - Generics 7 /// - Generics
8 /// - Class metadata 8 /// - Class metadata
9 /// - Extension methods 9 /// - Extension methods
10 /// 10 ///
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 return $name in sigObj; 384 return $name in sigObj;
385 })()'''); 385 })()''');
386 386
387 bool hasMethod(type, name) => _hasSigEntry(type, _methodSig, name); 387 bool hasMethod(type, name) => _hasSigEntry(type, _methodSig, name);
388 bool hasGetter(type, name) => _hasSigEntry(type, _getterSig, name); 388 bool hasGetter(type, name) => _hasSigEntry(type, _getterSig, name);
389 bool hasSetter(type, name) => _hasSigEntry(type, _setterSig, name); 389 bool hasSetter(type, name) => _hasSigEntry(type, _setterSig, name);
390 bool hasField(type, name) => _hasSigEntry(type, _fieldSig, name); 390 bool hasField(type, name) => _hasSigEntry(type, _fieldSig, name);
391 391
392 final _extensionType = JS('', 'Symbol("extensionType")'); 392 final _extensionType = JS('', 'Symbol("extensionType")');
393 393
394 getExtensionType(obj) => JS('', '#[#]', obj, _extensionType); 394 getExtensionType(obj) {
395 var result = JS('', '#[#]', obj, _extensionType);
396 if (result != null) return result;
397
398 if (JS('bool', 'typeof # != "object" || # instanceof #.Object', obj, obj,
399 global_)) {
400 return null;
401 }
402
403 // This is an object from another frame. Check to see if we have registered
404 // an extension in case this is a DOM/native type.
405 var jsType = JS('', '#.constructor', obj);
406 var tag = JS('', '#.name', jsType);
407 if (JS('bool', '#.has(#)', _extMap, tag)) {
408 var jsProto = JS('', '#.__proto__', obj);
409 var dartType = JS('', '#.get(#)', _extMap, tag);
410 _installExtension(jsType, jsProto, dartType);
411 return dartType;
412 }
413
414 return null;
415 }
395 416
396 final dartx = JS('', 'dartx'); 417 final dartx = JS('', 'dartx');
397 418
398 getExtensionSymbol(name) { 419 getExtensionSymbol(name) {
399 var sym = JS('', 'dartx[#]', name); 420 var sym = JS('', 'dartx[#]', name);
400 if (sym == null) { 421 if (sym == null) {
401 sym = JS('', 'Symbol("dartx." + #.toString())', name); 422 sym = JS('', 'Symbol("dartx." + #.toString())', name);
402 JS('', 'dartx[#] = #', name, sym); 423 JS('', 'dartx[#] = #', name, sym);
403 } 424 }
404 return sym; 425 return sym;
(...skipping 25 matching lines...) Expand all
430 // symbol name. 451 // symbol name.
431 var coreObjProto = JS('', '#.prototype', Object); 452 var coreObjProto = JS('', '#.prototype', Object);
432 var names = getOwnPropertyNames(coreObjProto); 453 var names = getOwnPropertyNames(coreObjProto);
433 for (int i = 0; i < JS('int', '#.length', names); ++i) { 454 for (int i = 0; i < JS('int', '#.length', names); ++i) {
434 var name = JS('', '#[#]', names, i); 455 var name = JS('', '#[#]', names, i);
435 var desc = getOwnPropertyDescriptor(coreObjProto, name); 456 var desc = getOwnPropertyDescriptor(coreObjProto, name);
436 defineProperty(jsProto, getExtensionSymbol(name), desc); 457 defineProperty(jsProto, getExtensionSymbol(name), desc);
437 } 458 }
438 } 459 }
439 460
461 var _extMap;
462
463 _cacheExtension(jsProto, dartType) {
464 if (_extMap == null) _extMap = JS('', 'new Map()');
465 // TODO(vsm): Make this work on non-Chrome browsers.
466 var tag = JS('', '#.constructor.name', jsProto);
467 JS('', '#.set(#, #)', _extMap, tag, dartType);
468 }
469
440 /// Copy symbols from the prototype of the source to destination. 470 /// Copy symbols from the prototype of the source to destination.
441 /// These are the only properties safe to copy onto an existing public 471 /// These are the only properties safe to copy onto an existing public
442 /// JavaScript class. 472 /// JavaScript class.
443 registerExtension(jsType, dartExtType) => JS( 473 registerExtension(jsType, dartExtType) => JS(
444 '', 474 '',
445 '''(() => { 475 '''(() => {
446 // TODO(vsm): Not all registered js types are real. 476 // TODO(vsm): Not all registered js types are real.
447 if (!jsType) return; 477 if (!jsType) return;
448 478
449 let jsProto = $jsType.prototype; 479 let jsProto = $jsType.prototype;
450 480
451 // TODO(vsm): This sometimes doesn't exist on FF. These types will be 481 // TODO(vsm): This sometimes doesn't exist on FF. These types will be
452 // broken. 482 // broken.
453 if (!jsProto) return; 483 if (!jsProto) return;
454 484
455 $_installProperties(jsProto, $dartExtType, jsProto[$_extensionType]); 485 $_cacheExtension(jsProto, $dartExtType);
456 486
457 // Mark the JS type's instances so we can easily check for extensions. 487 // Mark the JS type's instances so we can easily check for extensions.
458 jsProto[$_extensionType] = $dartExtType; 488 $_installExtension(jsType, jsProto, dartExtType);
489 })()''');
459 490
491 _installExtension(jsType, jsProto, dartType) => JS(
492 '',
493 '''(() => {
494 $_installProperties(jsProto, $dartType, jsProto[$_extensionType]);
495
496 // Mark the JS type's instances so we can easily check for extensions.
497 jsProto[$_extensionType] = $dartType;
460 function updateSig(sigF) { 498 function updateSig(sigF) {
461 let originalDesc = $getOwnPropertyDescriptor($dartExtType, sigF); 499 let originalDesc = $getOwnPropertyDescriptor($dartType, sigF);
462 if (originalDesc === void 0) return; 500 if (originalDesc === void 0) return;
463 let originalSigFn = originalDesc.get; 501 let originalSigFn = originalDesc.get;
464 $assert_(originalSigFn); 502 $assert_(originalSigFn);
465 $defineMemoizedGetter($jsType, sigF, originalSigFn); 503 $defineMemoizedGetter($jsType, sigF, originalSigFn);
466 } 504 }
467 updateSig($_methodSig); 505 updateSig($_methodSig);
468 updateSig($_fieldSig); 506 updateSig($_fieldSig);
469 updateSig($_getterSig); 507 updateSig($_getterSig);
470 updateSig($_setterSig); 508 updateSig($_setterSig);
471 })()'''); 509 })()''');
472 510
473 /// 511 ///
474 /// Mark a concrete type as implementing extension methods. 512 /// Mark a concrete type as implementing extension methods.
475 /// For example: `class MyIter implements Iterable`. 513 /// For example: `class MyIter implements Iterable`.
476 /// 514 ///
477 /// This takes a list of names, which are the extension methods implemented. 515 /// This takes a list of names, which are the extension methods implemented.
478 /// It will add a forwarder, so the extension method name redirects to the 516 /// It will add a forwarder, so the extension method name redirects to the
479 /// normal Dart method name. For example: 517 /// normal Dart method name. For example:
480 /// 518 ///
481 /// defineExtensionMembers(MyType, ['add', 'remove']); 519 /// defineExtensionMembers(MyType, ['add', 'remove']);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 590
553 defineEnumValues(enumClass, names) { 591 defineEnumValues(enumClass, names) {
554 var values = []; 592 var values = [];
555 for (var i = 0; i < JS('int', '#.length', names); i++) { 593 for (var i = 0; i < JS('int', '#.length', names); i++) {
556 var value = const_(JS('', 'new #.new(#)', enumClass, i)); 594 var value = const_(JS('', 'new #.new(#)', enumClass, i));
557 JS('', '#.push(#)', values, value); 595 JS('', '#.push(#)', values, value);
558 defineValue(enumClass, JS('', '#[#]', names, i), value); 596 defineValue(enumClass, JS('', '#[#]', names, i), value);
559 } 597 }
560 JS('', '#.values = #', enumClass, constList(values, enumClass)); 598 JS('', '#.values = #', enumClass, constList(values, enumClass));
561 } 599 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698