Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 272 if (sym == null) { | 272 if (sym == null) { |
| 273 sym = JS('', 'Symbol("dartx." + #.toString())', name); | 273 sym = JS('', 'Symbol("dartx." + #.toString())', name); |
| 274 JS('', 'dartx[#] = #', name, sym); | 274 JS('', 'dartx[#] = #', name, sym); |
| 275 } | 275 } |
| 276 return sym; | 276 return sym; |
| 277 } | 277 } |
| 278 | 278 |
| 279 defineExtensionNames(names) => | 279 defineExtensionNames(names) => |
| 280 JS('', '#.forEach(#)', names, getExtensionSymbol); | 280 JS('', '#.forEach(#)', names, getExtensionSymbol); |
| 281 | 281 |
| 282 // Install properties in prototype order. Properties / descriptors from | 282 |
| 283 // more specific types should overwrite ones from less specific types. | 283 /// A map from peer class prototypes to the Dart class prototype. This is used |
| 284 _installProperties(jsProto, extProto) { | 284 /// to recognize when Dart subclass inheritance corresponds to JavaScript |
| 285 /// prototype inheritance. | |
| 286 final _installedDartPeers = JS('', 'new Map()'); | |
|
Jennifer Messerly
2016/05/17 17:50:51
isn't this identical to _extensionType field?
See
| |
| 287 | |
| 288 /// Install properties in prototype-first order. Properties / descriptors from | |
| 289 /// more specific types should overwrite ones from less specific types. | |
| 290 void _installProperties(jsProto, extProto) { | |
| 291 | |
| 292 // This relies on the Dart type literal evaluating to the JavaScript | |
| 293 // constructor. | |
| 285 var coreObjProto = JS('', '#.prototype', Object); | 294 var coreObjProto = JS('', '#.prototype', Object); |
| 295 | |
| 296 var installedParent = | |
| 297 JS('', '#.get(#.__proto__)', _installedDartPeers, jsProto); | |
| 298 | |
| 299 _installProperties2(jsProto, extProto, coreObjProto, installedParent); | |
| 300 | |
| 301 // Mark this jsProto as being the prototype for the extension class. | |
| 302 JS('', '#.set(#, #)', _installedDartPeers, jsProto, extProto); | |
| 303 } | |
| 304 | |
| 305 void _installProperties2(jsProto, extProto, coreObjProto, installedParent) { | |
| 286 if (JS('bool', '# === #', extProto, coreObjProto)) { | 306 if (JS('bool', '# === #', extProto, coreObjProto)) { |
| 287 // core.Object members need to be copied from the non-symbol name to the | 307 _installPropertiesForObject(jsProto, coreObjProto); |
| 288 // symbol name. | |
| 289 var names = getOwnPropertyNames(coreObjProto); | |
| 290 for (int i = 0; i < JS('int', '#.length', names); ++i) { | |
| 291 var name = JS('', '#[#]', names, i); | |
| 292 var desc = getOwnPropertyDescriptor(coreObjProto, name); | |
| 293 defineProperty(jsProto, getExtensionSymbol(name), desc); | |
| 294 } | |
| 295 return; | 308 return; |
| 296 } | 309 } |
| 297 if (JS('bool', '# !== #', jsProto, extProto)) { | 310 if (JS('bool', '# !== #', jsProto, extProto)) { |
| 298 _installProperties(jsProto, JS('', '#.__proto__', extProto)); | 311 var extParent = JS('', '#.__proto__', extProto); |
| 312 | |
| 313 // If the extension methods of the parent have been installed on the parent | |
| 314 // of [jsProto], the methods will be available via prototype inheritance. | |
| 315 | |
| 316 if(JS('bool', '# !== #', installedParent, extParent)) { | |
| 317 _installProperties2(jsProto, extParent, coreObjProto, installedParent); | |
| 318 } | |
| 299 } | 319 } |
| 300 copyTheseProperties(jsProto, extProto, getOwnPropertySymbols(extProto)); | 320 copyTheseProperties(jsProto, extProto, getOwnPropertySymbols(extProto)); |
| 301 } | 321 } |
| 322 | |
| 323 void _installPropertiesForObject(jsProto, coreObjProto) { | |
| 324 // core.Object members need to be copied from the non-symbol name to the | |
| 325 // symbol name. | |
| 326 var names = getOwnPropertyNames(coreObjProto); | |
| 327 for (int i = 0; i < JS('int', '#.length', names); ++i) { | |
| 328 var name = JS('', '#[#]', names, i); | |
| 329 var desc = getOwnPropertyDescriptor(coreObjProto, name); | |
| 330 defineProperty(jsProto, getExtensionSymbol(name), desc); | |
| 331 } | |
| 332 return; | |
| 333 } | |
| 334 | |
| 335 | |
| 302 /// | 336 /// |
| 303 /// Copy symbols from the prototype of the source to destination. | 337 /// Copy symbols from the prototype of the source to destination. |
| 304 /// These are the only properties safe to copy onto an existing public | 338 /// These are the only properties safe to copy onto an existing public |
| 305 /// JavaScript class. | 339 /// JavaScript class. |
| 306 /// | 340 /// |
| 307 registerExtension(jsType, dartExtType) => JS('', '''(() => { | 341 registerExtension(jsType, dartExtType) => JS('', '''(() => { |
| 308 // TODO(vsm): Not all registered js types are real. | 342 // TODO(vsm): Not all registered js types are real. |
| 309 if (!jsType) return; | 343 if (!jsType) return; |
| 310 | 344 |
| 311 let extProto = $dartExtType.prototype; | 345 let extProto = $dartExtType.prototype; |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 387 })()'''); | 421 })()'''); |
| 388 | 422 |
| 389 /// Sets the element type of a list literal. | 423 /// Sets the element type of a list literal. |
| 390 list(obj, elementType) => | 424 list(obj, elementType) => |
| 391 JS('', '$setType($obj, ${getGenericClass(JSArray)}($elementType))'); | 425 JS('', '$setType($obj, ${getGenericClass(JSArray)}($elementType))'); |
| 392 | 426 |
| 393 setBaseClass(derived, base) => JS('', '''(() => { | 427 setBaseClass(derived, base) => JS('', '''(() => { |
| 394 // Link the extension to the type it's extending as a base class. | 428 // Link the extension to the type it's extending as a base class. |
| 395 $derived.prototype.__proto__ = $base.prototype; | 429 $derived.prototype.__proto__ = $base.prototype; |
| 396 })()'''); | 430 })()'''); |
| OLD | NEW |