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

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

Issue 2962263002: fix #30030, fix #27327 - fix tearoffs and various Object member bugs (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 391 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 JS('', 'dartx[#] = #', name, sym); 402 JS('', 'dartx[#] = #', name, sym);
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, extProto) { 412 void _installProperties(jsProto, dartType, installedParent) {
413 // This relies on the Dart type literal evaluating to the JavaScript 413 if (JS('bool', '# === #', dartType, Object)) {
414 // constructor. 414 _installPropertiesForObject(jsProto);
415 var coreObjProto = JS('', '#.prototype', Object); 415 return;
416 }
417 var dartProto = JS('', '#.prototype', dartType);
418 if (JS('bool', '# === #', jsProto, dartProto)) return;
vsm 2017/06/30 18:08:47 This was there before, but I'm not sure I understa
Jennifer Messerly 2017/07/05 21:17:16 Yeah, I'm not sure! It might've been a guard again
416 419
417 var parentsExtension = JS('', '(#.__proto__)[#]', jsProto, _extensionType); 420 // If the extension methods of the parent have been installed on the parent
418 var installedParent = 421 // of [jsProto], the methods will be available via prototype inheritance.
419 JS('', '# && #.prototype', parentsExtension, parentsExtension); 422 var dartSupertype = JS('', '#.__proto__', dartType);
423 if (JS('bool', '# !== #', dartSupertype, installedParent)) {
424 _installProperties(jsProto, dartSupertype, installedParent);
425 }
420 426
421 _installProperties2(jsProto, extProto, coreObjProto, installedParent); 427 copyTheseProperties(jsProto, dartProto, getOwnPropertySymbols(dartProto));
422 } 428 }
423 429
424 void _installProperties2(jsProto, extProto, coreObjProto, installedParent) { 430 void _installPropertiesForObject(jsProto) {
425 if (JS('bool', '# === #', extProto, coreObjProto)) {
426 _installPropertiesForObject(jsProto, coreObjProto);
427 return;
428 }
429 if (JS('bool', '# !== #', jsProto, extProto)) {
430 var extParent = JS('', '#.__proto__', extProto);
431
432 // If the extension methods of the parent have been installed on the parent
433 // of [jsProto], the methods will be available via prototype inheritance.
434
435 if (JS('bool', '# !== #', installedParent, extParent)) {
436 _installProperties2(jsProto, extParent, coreObjProto, installedParent);
437 }
438 }
439 copyTheseProperties(jsProto, extProto, getOwnPropertySymbols(extProto));
440 }
441
442 void _installPropertiesForObject(jsProto, coreObjProto) {
443 // core.Object members need to be copied from the non-symbol name to the 431 // core.Object members need to be copied from the non-symbol name to the
444 // symbol name. 432 // symbol name.
433 var coreObjProto = JS('', '#.prototype', Object);
445 var names = getOwnPropertyNames(coreObjProto); 434 var names = getOwnPropertyNames(coreObjProto);
446 for (int i = 0; i < JS('int', '#.length', names); ++i) { 435 for (int i = 0; i < JS('int', '#.length', names); ++i) {
447 var name = JS('', '#[#]', names, i); 436 var name = JS('', '#[#]', names, i);
448 var desc = getOwnPropertyDescriptor(coreObjProto, name); 437 var desc = getOwnPropertyDescriptor(coreObjProto, name);
449 defineProperty(jsProto, getExtensionSymbol(name), desc); 438 defineProperty(jsProto, getExtensionSymbol(name), desc);
450 } 439 }
451 return;
452 } 440 }
453 441
454 /// Copy symbols from the prototype of the source to destination. 442 /// Copy symbols from the prototype of the source to destination.
455 /// These are the only properties safe to copy onto an existing public 443 /// These are the only properties safe to copy onto an existing public
456 /// JavaScript class. 444 /// JavaScript class.
457 registerExtension(jsType, dartExtType) => JS( 445 registerExtension(jsType, dartExtType) => JS(
458 '', 446 '',
459 '''(() => { 447 '''(() => {
460 // TODO(vsm): Not all registered js types are real. 448 // TODO(vsm): Not all registered js types are real.
461 if (!jsType) return; 449 if (!jsType) return;
462 450
463 let extProto = $dartExtType.prototype;
464 let jsProto = $jsType.prototype; 451 let jsProto = $jsType.prototype;
465 452
466 // TODO(vsm): This sometimes doesn't exist on FF. These types will be 453 // TODO(vsm): This sometimes doesn't exist on FF. These types will be
467 // broken. 454 // broken.
468 if (!jsProto) return; 455 if (!jsProto) return;
469 456
457 $_installProperties(jsProto, $dartExtType, jsProto[$_extensionType]);
458
470 // Mark the JS type's instances so we can easily check for extensions. 459 // Mark the JS type's instances so we can easily check for extensions.
471 jsProto[$_extensionType] = $dartExtType; 460 jsProto[$_extensionType] = $dartExtType;
472 $_installProperties(jsProto, extProto); 461
473 function updateSig(sigF) { 462 function updateSig(sigF) {
474 let originalDesc = $getOwnPropertyDescriptor($dartExtType, sigF); 463 let originalDesc = $getOwnPropertyDescriptor($dartExtType, sigF);
475 if (originalDesc === void 0) return; 464 if (originalDesc === void 0) return;
476 let originalSigFn = originalDesc.get; 465 let originalSigFn = originalDesc.get;
477 $assert_(originalSigFn); 466 $assert_(originalSigFn);
478 $defineMemoizedGetter($jsType, sigF, originalSigFn); 467 $defineMemoizedGetter($jsType, sigF, originalSigFn);
479 } 468 }
480 updateSig($_methodSig); 469 updateSig($_methodSig);
481 updateSig($_fieldSig); 470 updateSig($_fieldSig);
482 updateSig($_getterSig); 471 updateSig($_getterSig);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
539 })()'''); 528 })()''');
540 529
541 /// Sets the type of `obj` to be `type` 530 /// Sets the type of `obj` to be `type`
542 setType(obj, type) { 531 setType(obj, type) {
543 JS('', '#.__proto__ = #.prototype', obj, type); 532 JS('', '#.__proto__ = #.prototype', obj, type);
544 return obj; 533 return obj;
545 } 534 }
546 535
547 /// Sets the element type of a list literal. 536 /// Sets the element type of a list literal.
548 list(obj, elementType) => 537 list(obj, elementType) =>
549 JS('', '$setType($obj, ${getGenericClass(JSArray)}($elementType))'); 538 setType(obj, JS('', '#(#)', getGenericClass(JSArray), elementType));
550 539
551 /// Link the extension to the type it's extending as a base class. 540 /// Link the extension to the type it's extending as a base class.
552 setBaseClass(derived, base) { 541 setBaseClass(derived, base) {
553 JS('', '#.prototype.__proto__ = #.prototype', derived, base); 542 JS('', '#.prototype.__proto__ = #.prototype', derived, base);
554 // We use __proto__ to track the superclass hierarchy (see isSubtype). 543 // We use __proto__ to track the superclass hierarchy (see isSubtype).
555 JS('', '#.__proto__ = #', derived, base); 544 JS('', '#.__proto__ = #', derived, base);
556 } 545 }
557 546
558 /// Like [setBaseClass] but for generic extension types, e.g. `JSArray<E>` 547 /// Like [setBaseClass], but for generic extension types such as `JSArray<E>`.
559 setExtensionBaseClass(derived, base) { 548 setExtensionBaseClass(dartType, jsType) {
560 // Mark the generic type as an extension type and link the prototype objects 549 // Mark the generic type as an extension type and link the prototype objects.
561 return JS( 550 var dartProto = JS('', '#.prototype', dartType);
562 '', 551 JS('', '#[#] = #', dartProto, _extensionType, dartType);
563 '''(() => { 552 JS('', '#.__proto__ = #.prototype', dartProto, jsType);
564 if ($base) {
565 $derived.prototype[$_extensionType] = $derived;
566 $derived.prototype.__proto__ = $base.prototype
567 }
568 })()''');
569 } 553 }
570 554
571 defineEnumValues(enumClass, names) { 555 defineEnumValues(enumClass, names) {
572 var values = []; 556 var values = [];
573 for (var i = 0; i < JS('int', '#.length', names); i++) { 557 for (var i = 0; i < JS('int', '#.length', names); i++) {
574 var value = const_(JS('', 'new #.new(#)', enumClass, i)); 558 var value = const_(JS('', 'new #.new(#)', enumClass, i));
575 JS('', '#.push(#)', values, value); 559 JS('', '#.push(#)', values, value);
576 defineValue(enumClass, JS('', '#[#]', names, i), value); 560 defineValue(enumClass, JS('', '#[#]', names, i), value);
577 } 561 }
578 JS('', '#.values = #', enumClass, constList(values, enumClass)); 562 JS('', '#.values = #', enumClass, constList(values, enumClass));
579 } 563 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698