SetInstance.cs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. using Jint.Native.Object;
  2. using Jint.Runtime;
  3. using Jint.Runtime.Descriptors;
  4. namespace Jint.Native.Set
  5. {
  6. public class SetInstance : ObjectInstance
  7. {
  8. internal readonly OrderedSet<JsValue> _set;
  9. public SetInstance(Engine engine)
  10. : base(engine, objectClass: "Map")
  11. {
  12. _set = new OrderedSet<JsValue>();
  13. }
  14. /// Implementation from ObjectInstance official specs as the one
  15. /// in ObjectInstance is optimized for the general case and wouldn't work
  16. /// for arrays
  17. public override void Put(in Key propertyName, JsValue value, bool throwOnError)
  18. {
  19. if (!CanPut(propertyName))
  20. {
  21. if (throwOnError)
  22. {
  23. ExceptionHelper.ThrowTypeError(Engine);
  24. }
  25. return;
  26. }
  27. var ownDesc = GetOwnProperty(propertyName);
  28. if (ownDesc.IsDataDescriptor())
  29. {
  30. var valueDesc = new PropertyDescriptor(value, PropertyFlag.None);
  31. DefineOwnProperty(propertyName, valueDesc, throwOnError);
  32. return;
  33. }
  34. // property is an accessor or inherited
  35. var desc = GetProperty(propertyName);
  36. if (desc.IsAccessorDescriptor())
  37. {
  38. var setter = desc.Set.TryCast<ICallable>();
  39. setter.Call(this, new[] {value});
  40. }
  41. else
  42. {
  43. var newDesc = new PropertyDescriptor(value, PropertyFlag.ConfigurableEnumerableWritable);
  44. DefineOwnProperty(propertyName, newDesc, throwOnError);
  45. }
  46. }
  47. public override PropertyDescriptor GetOwnProperty(in Key propertyName)
  48. {
  49. if (propertyName == KnownKeys.Size)
  50. {
  51. return new PropertyDescriptor(_set.Count, PropertyFlag.None);
  52. }
  53. return base.GetOwnProperty(propertyName);
  54. }
  55. protected override bool TryGetProperty(in Key propertyName, out PropertyDescriptor descriptor)
  56. {
  57. if (propertyName == KnownKeys.Size)
  58. {
  59. descriptor = new PropertyDescriptor(_set.Count, PropertyFlag.None);
  60. return true;
  61. }
  62. return base.TryGetProperty(propertyName, out descriptor);
  63. }
  64. public void Add(JsValue value)
  65. {
  66. _set.Add(value);
  67. }
  68. public void Clear()
  69. {
  70. _set.Clear();
  71. }
  72. public bool Has(JsValue key)
  73. {
  74. return _set.Contains(key);
  75. }
  76. public bool Delete(JsValue key)
  77. {
  78. return _set.Remove(key);
  79. }
  80. public void ForEach(ICallable callable, JsValue thisArg)
  81. {
  82. var args = _engine._jsValueArrayPool.RentArray(3);
  83. args[2] = this;
  84. for (var i = 0; i < _set._list.Count; i++)
  85. {
  86. var value = _set._list[i];
  87. args[0] = value;
  88. args[1] = value;
  89. callable.Call(thisArg, args);
  90. }
  91. _engine._jsValueArrayPool.ReturnArray(args);
  92. }
  93. public ObjectInstance Entries()
  94. {
  95. return _engine.Iterator.ConstructEntryIterator(this);
  96. }
  97. public ObjectInstance Values()
  98. {
  99. return _engine.Iterator.Construct(_set._list);
  100. }
  101. }
  102. }