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

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

Issue 2980853002: Registration-based approach to cross frame support. (Closed)
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 392 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 } 403 }
404 return sym; 404 return sym;
405 } 405 }
406 406
407 defineExtensionNames(names) => 407 defineExtensionNames(names) =>
408 JS('', '#.forEach(#)', names, getExtensionSymbol); 408 JS('', '#.forEach(#)', names, getExtensionSymbol);
409 409
410 /// Install properties in prototype-first order. Properties / descriptors from 410 /// Install properties in prototype-first order. Properties / descriptors from
411 /// more specific types should overwrite ones from less specific types. 411 /// more specific types should overwrite ones from less specific types.
412 void _installProperties(jsProto, dartType, installedParent) { 412 void _installProperties(jsProto, dartType, installedParent) {
413 if (JS('bool', '# === #', dartType, Object)) { 413 // Extension types should bottom out at core.Object. The one exception
414 // is JSArray, which we rewire to the native Array type.
Jennifer Messerly 2017/07/14 19:38:08 hmmm wait I don't understand the JSArray comment.
415 if (JS('bool', '# === # || # === #.Object', dartType, Object, dartType,
416 global_)) {
414 _installPropertiesForObject(jsProto); 417 _installPropertiesForObject(jsProto);
415 return; 418 return;
416 } 419 }
417 // If the extension methods of the parent have been installed on the parent 420 // If the extension methods of the parent have been installed on the parent
418 // of [jsProto], the methods will be available via prototype inheritance. 421 // of [jsProto], the methods will be available via prototype inheritance.
419 var dartSupertype = JS('', '#.__proto__', dartType); 422 var dartSupertype = JS('', '#.__proto__', dartType);
420 if (JS('bool', '# !== #', dartSupertype, installedParent)) { 423 if (JS('bool', '# !== #', dartSupertype, installedParent)) {
421 _installProperties(jsProto, dartSupertype, installedParent); 424 _installProperties(jsProto, dartSupertype, installedParent);
422 } 425 }
423 426
424 var dartProto = JS('', '#.prototype', dartType); 427 var dartProto = JS('', '#.prototype', dartType);
425 copyTheseProperties(jsProto, dartProto, getOwnPropertySymbols(dartProto)); 428 copyTheseProperties(jsProto, dartProto, getOwnPropertySymbols(dartProto));
426 } 429 }
427 430
428 void _installPropertiesForObject(jsProto) { 431 void _installPropertiesForObject(jsProto) {
429 // core.Object members need to be copied from the non-symbol name to the 432 // core.Object members need to be copied from the non-symbol name to the
430 // symbol name. 433 // symbol name.
431 var coreObjProto = JS('', '#.prototype', Object); 434 var coreObjProto = JS('', '#.prototype', Object);
432 var names = getOwnPropertyNames(coreObjProto); 435 var names = getOwnPropertyNames(coreObjProto);
433 for (int i = 0; i < JS('int', '#.length', names); ++i) { 436 for (int i = 0; i < JS('int', '#.length', names); ++i) {
434 var name = JS('', '#[#]', names, i); 437 var name = JS('', '#[#]', names, i);
435 var desc = getOwnPropertyDescriptor(coreObjProto, name); 438 var desc = getOwnPropertyDescriptor(coreObjProto, name);
436 defineProperty(jsProto, getExtensionSymbol(name), desc); 439 defineProperty(jsProto, getExtensionSymbol(name), desc);
437 } 440 }
438 } 441 }
439 442
440 /// Copy symbols from the prototype of the source to destination. 443 var _extensionMap;
Jennifer Messerly 2017/07/14 19:38:08 this can be eager initialized: final _extensi
vsm 2017/07/19 15:59:02 Done.
441 /// These are the only properties safe to copy onto an existing public 444
442 /// JavaScript class. 445 _cacheExtension(name, dartExtType) {
443 registerExtension(jsType, dartExtType) => JS( 446 if (_extensionMap == null) _extensionMap = JS('', 'new Map()');
447 JS('', '#.set(#, #)', _extensionMap, name, dartExtType);
448 }
449
450 _applyExtension(jsType, dartExtType) => JS(
444 '', 451 '',
445 '''(() => { 452 '''(() => {
446 // TODO(vsm): Not all registered js types are real. 453 // TODO(vsm): Not all registered js types are real.
447 if (!jsType) return; 454 if (!jsType) return;
448 455
456 let extProto = $dartExtType.prototype;
Jennifer Messerly 2017/07/14 19:38:08 this line is unused. I'm guessing it was a merge c
vsm 2017/07/19 15:59:02 Done.
449 let jsProto = $jsType.prototype; 457 let jsProto = $jsType.prototype;
450 458
451 // TODO(vsm): This sometimes doesn't exist on FF. These types will be 459 // TODO(vsm): This sometimes doesn't exist on FF. These types will be
452 // broken. 460 // broken.
453 if (!jsProto) return; 461 if (!jsProto) return;
454 462
455 $_installProperties(jsProto, $dartExtType, jsProto[$_extensionType]); 463 $_installProperties(jsProto, $dartExtType, jsProto[$_extensionType]);
456 464
457 // Mark the JS type's instances so we can easily check for extensions. 465 // Mark the JS type's instances so we can easily check for extensions.
458 jsProto[$_extensionType] = $dartExtType; 466 jsProto[$_extensionType] = $dartExtType;
459 467
460 function updateSig(sigF) { 468 function updateSig(sigF) {
461 let originalDesc = $getOwnPropertyDescriptor($dartExtType, sigF); 469 let originalDesc = $getOwnPropertyDescriptor($dartExtType, sigF);
462 if (originalDesc === void 0) return; 470 if (originalDesc === void 0) return;
463 let originalSigFn = originalDesc.get; 471 let originalSigFn = originalDesc.get;
464 $assert_(originalSigFn); 472 $assert_(originalSigFn);
465 $defineMemoizedGetter($jsType, sigF, originalSigFn); 473 $defineMemoizedGetter(jsType, sigF, originalSigFn);
466 } 474 }
467 updateSig($_methodSig); 475 updateSig($_methodSig);
468 updateSig($_fieldSig); 476 updateSig($_fieldSig);
469 updateSig($_getterSig); 477 updateSig($_getterSig);
470 updateSig($_setterSig); 478 updateSig($_setterSig);
471 })()'''); 479 })()''');
472 480
481 /// Apply all registered extensions to a window. This is intended for
482 /// different frames, where registrations need to be reapplied.
483 applyAllExtensions(global) {
484 JS('', '#.forEach((dartExtType, name) => #(#[name], dartExtType))',
485 _extensionMap, _applyExtension, global);
486 }
487
488 /// Copy symbols from the prototype of the source to destination.
489 /// These are the only properties safe to copy onto an existing public
490 /// JavaScript class.
491 registerExtension(name, dartExtType) {
492 _cacheExtension(name, dartExtType);
Jennifer Messerly 2017/07/14 19:38:08 based on suggestion above this is a 1-liner now an
vsm 2017/07/19 15:59:01 Done.
493 var jsType = JS('', '#[#]', global_, name);
494 _applyExtension(jsType, dartExtType);
495 }
496
473 /// 497 ///
474 /// Mark a concrete type as implementing extension methods. 498 /// Mark a concrete type as implementing extension methods.
475 /// For example: `class MyIter implements Iterable`. 499 /// For example: `class MyIter implements Iterable`.
476 /// 500 ///
477 /// This takes a list of names, which are the extension methods implemented. 501 /// 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 502 /// It will add a forwarder, so the extension method name redirects to the
479 /// normal Dart method name. For example: 503 /// normal Dart method name. For example:
480 /// 504 ///
481 /// defineExtensionMembers(MyType, ['add', 'remove']); 505 /// defineExtensionMembers(MyType, ['add', 'remove']);
482 /// 506 ///
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 576
553 defineEnumValues(enumClass, names) { 577 defineEnumValues(enumClass, names) {
554 var values = []; 578 var values = [];
555 for (var i = 0; i < JS('int', '#.length', names); i++) { 579 for (var i = 0; i < JS('int', '#.length', names); i++) {
556 var value = const_(JS('', 'new #.new(#)', enumClass, i)); 580 var value = const_(JS('', 'new #.new(#)', enumClass, i));
557 JS('', '#.push(#)', values, value); 581 JS('', '#.push(#)', values, value);
558 defineValue(enumClass, JS('', '#[#]', names, i), value); 582 defineValue(enumClass, JS('', '#[#]', names, i), value);
559 } 583 }
560 JS('', '#.values = #', enumClass, constList(values, enumClass)); 584 JS('', '#.values = #', enumClass, constList(values, enumClass));
561 } 585 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698