SetPrototype.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. using Jint.Collections;
  2. using Jint.Native.Object;
  3. using Jint.Native.Symbol;
  4. using Jint.Runtime;
  5. using Jint.Runtime.Descriptors;
  6. using Jint.Runtime.Interop;
  7. namespace Jint.Native.Set;
  8. /// <summary>
  9. /// https://www.ecma-international.org/ecma-262/6.0/#sec-set-objects
  10. /// </summary>
  11. internal sealed class SetPrototype : Prototype
  12. {
  13. private readonly SetConstructor _constructor;
  14. internal SetPrototype(
  15. Engine engine,
  16. Realm realm,
  17. SetConstructor setConstructor,
  18. ObjectPrototype objectPrototype) : base(engine, realm)
  19. {
  20. _prototype = objectPrototype;
  21. _constructor = setConstructor;
  22. }
  23. protected override void Initialize()
  24. {
  25. var properties = new PropertyDictionary(12, checkExistingKeys: false)
  26. {
  27. ["length"] = new PropertyDescriptor(0, PropertyFlag.Configurable),
  28. ["constructor"] = new PropertyDescriptor(_constructor, PropertyFlag.NonEnumerable),
  29. ["add"] = new PropertyDescriptor(new ClrFunctionInstance(Engine, "add", Add, 1, PropertyFlag.Configurable), true, false, true),
  30. ["clear"] = new PropertyDescriptor(new ClrFunctionInstance(Engine, "clear", Clear, 0, PropertyFlag.Configurable), true, false, true),
  31. ["delete"] = new PropertyDescriptor(new ClrFunctionInstance(Engine, "delete", Delete, 1, PropertyFlag.Configurable), true, false, true),
  32. ["entries"] = new PropertyDescriptor(new ClrFunctionInstance(Engine, "entries", Entries, 0, PropertyFlag.Configurable), true, false, true),
  33. ["forEach"] = new PropertyDescriptor(new ClrFunctionInstance(Engine, "forEach", ForEach, 1, PropertyFlag.Configurable), true, false, true),
  34. ["has"] = new PropertyDescriptor(new ClrFunctionInstance(Engine, "has", Has, 1, PropertyFlag.Configurable), true, false, true),
  35. ["keys"] = new PropertyDescriptor(new ClrFunctionInstance(Engine, "keys", Values, 0, PropertyFlag.Configurable), true, false, true),
  36. ["values"] = new PropertyDescriptor(new ClrFunctionInstance(Engine, "values", Values, 0, PropertyFlag.Configurable), true, false, true),
  37. ["size"] = new GetSetPropertyDescriptor(get: new ClrFunctionInstance(Engine, "get size", Size, 0, PropertyFlag.Configurable), set: null, PropertyFlag.Configurable)
  38. };
  39. SetProperties(properties);
  40. var symbols = new SymbolDictionary(2)
  41. {
  42. [GlobalSymbolRegistry.Iterator] = new PropertyDescriptor(new ClrFunctionInstance(Engine, "iterator", Values, 1, PropertyFlag.Configurable), true, false, true),
  43. [GlobalSymbolRegistry.ToStringTag] = new PropertyDescriptor("Set", false, false, true)
  44. };
  45. SetSymbols(symbols);
  46. }
  47. private JsValue Size(JsValue thisObject, JsValue[] arguments)
  48. {
  49. AssertSetInstance(thisObject);
  50. return JsNumber.Create(0);
  51. }
  52. private JsValue Add(JsValue thisObject, JsValue[] arguments)
  53. {
  54. var set = AssertSetInstance(thisObject);
  55. var value = arguments.At(0);
  56. if (value is JsNumber number && number.IsNegativeZero())
  57. {
  58. value = JsNumber.PositiveZero;
  59. }
  60. set.Add(value);
  61. return thisObject;
  62. }
  63. private JsValue Clear(JsValue thisObject, JsValue[] arguments)
  64. {
  65. var set = AssertSetInstance(thisObject);
  66. set.Clear();
  67. return Undefined;
  68. }
  69. private JsValue Delete(JsValue thisObject, JsValue[] arguments)
  70. {
  71. var set = AssertSetInstance(thisObject);
  72. return set.SetDelete(arguments.At(0))
  73. ? JsBoolean.True
  74. : JsBoolean.False;
  75. }
  76. private JsValue Has(JsValue thisObject, JsValue[] arguments)
  77. {
  78. var set = AssertSetInstance(thisObject);
  79. return set.Has(arguments.At(0))
  80. ? JsBoolean.True
  81. : JsBoolean.False;
  82. }
  83. private JsValue Entries(JsValue thisObject, JsValue[] arguments)
  84. {
  85. var set = AssertSetInstance(thisObject);
  86. return set.Entries();
  87. }
  88. private JsValue ForEach(JsValue thisObject, JsValue[] arguments)
  89. {
  90. var callbackfn = arguments.At(0);
  91. var thisArg = arguments.At(1);
  92. var set = AssertSetInstance(thisObject);
  93. var callable = GetCallable(callbackfn);
  94. set.ForEach(callable, thisArg);
  95. return Undefined;
  96. }
  97. private ObjectInstance Values(JsValue thisObject, JsValue[] arguments)
  98. {
  99. var set = AssertSetInstance(thisObject);
  100. return set.Values();
  101. }
  102. private JsSet AssertSetInstance(JsValue thisObject)
  103. {
  104. if (thisObject is JsSet set)
  105. {
  106. return set;
  107. }
  108. ExceptionHelper.ThrowTypeError(_realm, "object must be a Set");
  109. return default;
  110. }
  111. }