Chromium Code Reviews| 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 63c95c4272f16297b2e622c1bb93a5278e981f17..11d7a276139a7676d4bf41a287c411ee72dbd6fc 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,34 @@ 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); |
| - } |
| + var dartProto = JS('', '#.prototype', dartType); |
| + 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
|
| + |
| + // 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)); |
| + |
| + 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 +448,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 +535,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 +544,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) { |