Index: pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart |
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart |
index 779eb3979ab16f886583d18c2754f8a37b17e626..4a8670bd65178dbd7914982df4ac822520dfaddc 100644 |
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart |
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart |
@@ -409,46 +409,32 @@ defineExtensionNames(names) => |
/// Install properties in prototype-first order. Properties / descriptors from |
/// more specific types should overwrite ones from less specific types. |
-void _installProperties(jsProto, extProto) { |
- // This relies on the Dart type literal evaluating to the JavaScript |
- // constructor. |
- var coreObjProto = JS('', '#.prototype', Object); |
- |
- var parentsExtension = JS('', '(#.__proto__)[#]', jsProto, _extensionType); |
- var installedParent = |
- JS('', '# && #.prototype', parentsExtension, parentsExtension); |
- |
- _installProperties2(jsProto, extProto, coreObjProto, installedParent); |
-} |
- |
-void _installProperties2(jsProto, extProto, coreObjProto, installedParent) { |
- if (JS('bool', '# === #', extProto, coreObjProto)) { |
- _installPropertiesForObject(jsProto, coreObjProto); |
+void _installProperties(jsProto, dartType, installedParent) { |
+ if (JS('bool', '# === #', dartType, Object)) { |
+ _installPropertiesForObject(jsProto); |
return; |
} |
- if (JS('bool', '# !== #', jsProto, extProto)) { |
- var extParent = JS('', '#.__proto__', extProto); |
- |
- // If the extension methods of the parent have been installed on the parent |
- // of [jsProto], the methods will be available via prototype inheritance. |
- |
- if (JS('bool', '# !== #', installedParent, extParent)) { |
- _installProperties2(jsProto, extParent, coreObjProto, installedParent); |
- } |
+ // If the extension methods of the parent have been installed on the parent |
+ // of [jsProto], the methods will be available via prototype inheritance. |
+ var dartSupertype = JS('', '#.__proto__', dartType); |
+ if (JS('bool', '# !== #', dartSupertype, installedParent)) { |
+ _installProperties(jsProto, dartSupertype, installedParent); |
} |
- copyTheseProperties(jsProto, extProto, getOwnPropertySymbols(extProto)); |
+ |
+ var dartProto = JS('', '#.prototype', dartType); |
+ copyTheseProperties(jsProto, dartProto, getOwnPropertySymbols(dartProto)); |
} |
-void _installPropertiesForObject(jsProto, coreObjProto) { |
+void _installPropertiesForObject(jsProto) { |
// core.Object members need to be copied from the non-symbol name to the |
// symbol name. |
+ var coreObjProto = JS('', '#.prototype', Object); |
var names = getOwnPropertyNames(coreObjProto); |
for (int i = 0; i < JS('int', '#.length', names); ++i) { |
var name = JS('', '#[#]', names, i); |
var desc = getOwnPropertyDescriptor(coreObjProto, name); |
defineProperty(jsProto, getExtensionSymbol(name), desc); |
} |
- return; |
} |
/// Copy symbols from the prototype of the source to destination. |
@@ -460,16 +446,17 @@ registerExtension(jsType, dartExtType) => JS( |
// TODO(vsm): Not all registered js types are real. |
if (!jsType) return; |
- let extProto = $dartExtType.prototype; |
let jsProto = $jsType.prototype; |
// TODO(vsm): This sometimes doesn't exist on FF. These types will be |
// broken. |
if (!jsProto) return; |
+ $_installProperties(jsProto, $dartExtType, jsProto[$_extensionType]); |
+ |
// Mark the JS type's instances so we can easily check for extensions. |
jsProto[$_extensionType] = $dartExtType; |
- $_installProperties(jsProto, extProto); |
+ |
function updateSig(sigF) { |
let originalDesc = $getOwnPropertyDescriptor($dartExtType, sigF); |
if (originalDesc === void 0) return; |
@@ -546,7 +533,7 @@ setType(obj, type) { |
/// Sets the element type of a list literal. |
list(obj, elementType) => |
- JS('', '$setType($obj, ${getGenericClass(JSArray)}($elementType))'); |
+ setType(obj, JS('', '#(#)', getGenericClass(JSArray), elementType)); |
/// Link the extension to the type it's extending as a base class. |
setBaseClass(derived, base) { |
@@ -555,17 +542,12 @@ setBaseClass(derived, base) { |
JS('', '#.__proto__ = #', derived, base); |
} |
-/// Like [setBaseClass] but for generic extension types, e.g. `JSArray<E>` |
-setExtensionBaseClass(derived, base) { |
- // Mark the generic type as an extension type and link the prototype objects |
- return JS( |
- '', |
- '''(() => { |
- if ($base) { |
- $derived.prototype[$_extensionType] = $derived; |
- $derived.prototype.__proto__ = $base.prototype |
- } |
-})()'''); |
+/// Like [setBaseClass], but for generic extension types such as `JSArray<E>`. |
+setExtensionBaseClass(dartType, jsType) { |
+ // Mark the generic type as an extension type and link the prototype objects. |
+ var dartProto = JS('', '#.prototype', dartType); |
+ JS('', '#[#] = #', dartProto, _extensionType, dartType); |
+ JS('', '#.__proto__ = #.prototype', dartProto, jsType); |
} |
defineEnumValues(enumClass, names) { |