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 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 // symbol name. | 328 // symbol name. |
329 var names = getOwnPropertyNames(coreObjProto); | 329 var names = getOwnPropertyNames(coreObjProto); |
330 for (int i = 0; i < JS('int', '#.length', names); ++i) { | 330 for (int i = 0; i < JS('int', '#.length', names); ++i) { |
331 var name = JS('', '#[#]', names, i); | 331 var name = JS('', '#[#]', names, i); |
332 var desc = getOwnPropertyDescriptor(coreObjProto, name); | 332 var desc = getOwnPropertyDescriptor(coreObjProto, name); |
333 defineProperty(jsProto, getExtensionSymbol(name), desc); | 333 defineProperty(jsProto, getExtensionSymbol(name), desc); |
334 } | 334 } |
335 return; | 335 return; |
336 } | 336 } |
337 | 337 |
338 | |
339 /// | |
340 /// Copy symbols from the prototype of the source to destination. | 338 /// Copy symbols from the prototype of the source to destination. |
341 /// These are the only properties safe to copy onto an existing public | 339 /// These are the only properties safe to copy onto an existing public |
342 /// JavaScript class. | 340 /// JavaScript class. |
343 /// | |
344 registerExtension(jsType, dartExtType) => JS('', '''(() => { | 341 registerExtension(jsType, dartExtType) => JS('', '''(() => { |
345 // TODO(vsm): Not all registered js types are real. | 342 // TODO(vsm): Not all registered js types are real. |
346 if (!jsType) return; | 343 if (!jsType) return; |
347 | 344 |
348 let extProto = $dartExtType.prototype; | 345 let extProto = $dartExtType.prototype; |
349 let jsProto = $jsType.prototype; | 346 let jsProto = $jsType.prototype; |
350 | 347 |
351 // Mark the JS type's instances so we can easily check for extensions. | 348 // Mark the JS type's instances so we can easily check for extensions. |
352 jsProto[$_extensionType] = $dartExtType; | 349 jsProto[$_extensionType] = $dartExtType; |
353 $_installProperties(jsProto, extProto); | 350 $_installProperties(jsProto, extProto); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 let originalSigFn = $getOwnPropertyDescriptor($type, $_methodSig).get; | 392 let originalSigFn = $getOwnPropertyDescriptor($type, $_methodSig).get; |
396 $defineMemoizedGetter(type, $_methodSig, function() { | 393 $defineMemoizedGetter(type, $_methodSig, function() { |
397 let sig = originalSigFn(); | 394 let sig = originalSigFn(); |
398 for (let name of $methodNames) { | 395 for (let name of $methodNames) { |
399 sig[$getExtensionSymbol(name)] = sig[name]; | 396 sig[$getExtensionSymbol(name)] = sig[name]; |
400 } | 397 } |
401 return sig; | 398 return sig; |
402 }); | 399 }); |
403 })()'''); | 400 })()'''); |
404 | 401 |
405 canonicalMember(obj, name) => JS('', '''(() => { | |
406 // Private names are symbols and are already canonical. | |
407 if (typeof name === 'symbol') return name; | |
408 | |
409 if ($obj != null && $obj[$_extensionType]) return $dartx[$name]; | |
410 // Check for certain names that we can't use in JS | |
411 if ($name == 'constructor' || $name == 'prototype') { | |
412 $name = '+' + $name; | |
413 } | |
414 return $name; | |
415 })()'''); | |
416 | |
417 /// Sets the type of `obj` to be `type` | 402 /// Sets the type of `obj` to be `type` |
418 setType(obj, type) { | 403 setType(obj, type) { |
419 JS('', '#.__proto__ = #.prototype', obj, type); | 404 JS('', '#.__proto__ = #.prototype', obj, type); |
420 return obj; | 405 return obj; |
421 } | 406 } |
422 | 407 |
423 /// Sets the element type of a list literal. | 408 /// Sets the element type of a list literal. |
424 list(obj, elementType) => | 409 list(obj, elementType) => |
425 JS('', '$setType($obj, ${getGenericClass(JSArray)}($elementType))'); | 410 JS('', '$setType($obj, ${getGenericClass(JSArray)}($elementType))'); |
426 | 411 |
427 /// Link the extension to the type it's extending as a base class. | 412 /// Link the extension to the type it's extending as a base class. |
428 setBaseClass(derived, base) { | 413 setBaseClass(derived, base) { |
429 JS('', '#.prototype.__proto__ = #.prototype', derived, base); | 414 JS('', '#.prototype.__proto__ = #.prototype', derived, base); |
430 // We use __proto__ to track the superclass hierarchy (see isSubtype). | 415 // We use __proto__ to track the superclass hierarchy (see isSubtype). |
431 JS('', '#.__proto__ = #', derived, base); | 416 JS('', '#.__proto__ = #', derived, base); |
432 } | 417 } |
433 | 418 |
434 /// Like [setBaseClass] but for generic extension types, e.g. `JSArray<E>` | 419 /// Like [setBaseClass] but for generic extension types, e.g. `JSArray<E>` |
435 setExtensionBaseClass(derived, base) { | 420 setExtensionBaseClass(derived, base) { |
436 // Mark the generic type as an extension type. | 421 // Mark the generic type as an extension type. |
437 JS('', '#.prototype[#] = #', derived, _extensionType, derived); | 422 JS('', '#.prototype[#] = #', derived, _extensionType, derived); |
438 // Link the prototype objects | 423 // Link the prototype objects |
439 JS('', '#.prototype.__proto__ = #.prototype', derived, base); | 424 JS('', '#.prototype.__proto__ = #.prototype', derived, base); |
440 } | 425 } |
OLD | NEW |