SymbolPrototype.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. #pragma warning disable CA1859 // Use concrete types when possible for improved performance -- most of prototype methods return JsValue
  2. using Jint.Collections;
  3. using Jint.Native.Object;
  4. using Jint.Runtime;
  5. using Jint.Runtime.Descriptors;
  6. using Jint.Runtime.Interop;
  7. namespace Jint.Native.Symbol
  8. {
  9. /// <summary>
  10. /// https://tc39.es/ecma262/#sec-properties-of-the-symbol-prototype-object
  11. /// </summary>
  12. internal sealed class SymbolPrototype : Prototype
  13. {
  14. private readonly SymbolConstructor _constructor;
  15. internal SymbolPrototype(
  16. Engine engine,
  17. Realm realm,
  18. SymbolConstructor symbolConstructor,
  19. ObjectPrototype objectPrototype)
  20. : base(engine, realm)
  21. {
  22. _prototype = objectPrototype;
  23. _constructor = symbolConstructor;
  24. }
  25. protected override void Initialize()
  26. {
  27. const PropertyFlag lengthFlags = PropertyFlag.Configurable;
  28. const PropertyFlag propertyFlags = PropertyFlag.Configurable;
  29. SetProperties(new PropertyDictionary(5, checkExistingKeys: false)
  30. {
  31. ["length"] = new PropertyDescriptor(JsNumber.PositiveZero, propertyFlags),
  32. ["constructor"] = new PropertyDescriptor(_constructor, PropertyFlag.Configurable | PropertyFlag.Writable),
  33. ["description"] = new GetSetPropertyDescriptor(new ClrFunction(Engine, "description", Description, 0, lengthFlags), Undefined, propertyFlags),
  34. ["toString"] = new PropertyDescriptor(new ClrFunction(Engine, "toString", ToSymbolString, 0, lengthFlags), PropertyFlag.Configurable | PropertyFlag.Writable),
  35. ["valueOf"] = new PropertyDescriptor(new ClrFunction(Engine, "valueOf", ValueOf, 0, lengthFlags), PropertyFlag.Configurable | PropertyFlag.Writable)
  36. });
  37. SetSymbols(new SymbolDictionary(1)
  38. {
  39. [GlobalSymbolRegistry.ToPrimitive] = new PropertyDescriptor(new ClrFunction(Engine, "[Symbol.toPrimitive]", ToPrimitive, 1, lengthFlags), propertyFlags), [GlobalSymbolRegistry.ToStringTag] = new PropertyDescriptor(new JsString("Symbol"), propertyFlags)
  40. }
  41. );
  42. }
  43. /// <summary>
  44. /// https://tc39.es/ecma262/#sec-symbol.prototype.description
  45. /// </summary>
  46. private JsValue Description(JsValue thisObject, JsValue[] arguments)
  47. {
  48. var sym = ThisSymbolValue(thisObject);
  49. return sym._value;
  50. }
  51. /// <summary>
  52. /// https://tc39.es/ecma262/#sec-symbol.prototype.tostring
  53. /// </summary>
  54. private JsValue ToSymbolString(JsValue thisObject, JsValue[] arguments)
  55. {
  56. var sym = ThisSymbolValue(thisObject);
  57. return new JsString(sym.ToString());
  58. }
  59. /// <summary>
  60. /// https://tc39.es/ecma262/#sec-symbol.prototype.valueof
  61. /// </summary>
  62. private JsValue ValueOf(JsValue thisObject, JsValue[] arguments)
  63. {
  64. return ThisSymbolValue(thisObject);
  65. }
  66. /// <summary>
  67. /// https://tc39.es/ecma262/#sec-symbol.prototype-@@toprimitive
  68. /// </summary>
  69. private JsValue ToPrimitive(JsValue thisObject, JsValue[] arguments)
  70. {
  71. return ThisSymbolValue(thisObject);
  72. }
  73. private JsSymbol ThisSymbolValue(JsValue thisObject)
  74. {
  75. if (thisObject is JsSymbol s)
  76. {
  77. return s;
  78. }
  79. if (thisObject is SymbolInstance instance)
  80. {
  81. return instance.SymbolData;
  82. }
  83. ExceptionHelper.ThrowTypeError(_realm);
  84. return null;
  85. }
  86. }
  87. }