builtin_weakset.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. package goja
  2. type weakSetObject struct {
  3. baseObject
  4. s weakMap
  5. }
  6. func (ws *weakSetObject) init() {
  7. ws.baseObject.init()
  8. ws.s = weakMap(ws.val.runtime.genId())
  9. }
  10. func (r *Runtime) weakSetProto_add(call FunctionCall) Value {
  11. thisObj := r.toObject(call.This)
  12. wso, ok := thisObj.self.(*weakSetObject)
  13. if !ok {
  14. panic(r.NewTypeError("Method WeakSet.prototype.add called on incompatible receiver %s", thisObj.String()))
  15. }
  16. wso.s.set(r.toObject(call.Argument(0)), nil)
  17. return call.This
  18. }
  19. func (r *Runtime) weakSetProto_delete(call FunctionCall) Value {
  20. thisObj := r.toObject(call.This)
  21. wso, ok := thisObj.self.(*weakSetObject)
  22. if !ok {
  23. panic(r.NewTypeError("Method WeakSet.prototype.delete called on incompatible receiver %s", thisObj.String()))
  24. }
  25. obj, ok := call.Argument(0).(*Object)
  26. if ok && wso.s.remove(obj) {
  27. return valueTrue
  28. }
  29. return valueFalse
  30. }
  31. func (r *Runtime) weakSetProto_has(call FunctionCall) Value {
  32. thisObj := r.toObject(call.This)
  33. wso, ok := thisObj.self.(*weakSetObject)
  34. if !ok {
  35. panic(r.NewTypeError("Method WeakSet.prototype.has called on incompatible receiver %s", thisObj.String()))
  36. }
  37. obj, ok := call.Argument(0).(*Object)
  38. if ok && wso.s.has(obj) {
  39. return valueTrue
  40. }
  41. return valueFalse
  42. }
  43. func (r *Runtime) populateWeakSetGeneric(s *Object, adderValue Value, iterable Value) {
  44. adder := toMethod(adderValue)
  45. if adder == nil {
  46. panic(r.NewTypeError("WeakSet.add is not set"))
  47. }
  48. iter := r.getIterator(iterable, nil)
  49. iter.iterate(func(val Value) {
  50. adder(FunctionCall{This: s, Arguments: []Value{val}})
  51. })
  52. }
  53. func (r *Runtime) builtin_newWeakSet(args []Value, newTarget *Object) *Object {
  54. if newTarget == nil {
  55. panic(r.needNew("WeakSet"))
  56. }
  57. proto := r.getPrototypeFromCtor(newTarget, r.global.WeakSet, r.global.WeakSetPrototype)
  58. o := &Object{runtime: r}
  59. wso := &weakSetObject{}
  60. wso.class = classWeakSet
  61. wso.val = o
  62. wso.extensible = true
  63. o.self = wso
  64. wso.prototype = proto
  65. wso.init()
  66. if len(args) > 0 {
  67. if arg := args[0]; arg != nil && arg != _undefined && arg != _null {
  68. adder := wso.getStr("add", nil)
  69. if adder == r.global.weakSetAdder {
  70. if arr := r.checkStdArrayIter(arg); arr != nil {
  71. for _, v := range arr.values {
  72. wso.s.set(r.toObject(v), nil)
  73. }
  74. return o
  75. }
  76. }
  77. r.populateWeakSetGeneric(o, adder, arg)
  78. }
  79. }
  80. return o
  81. }
  82. func (r *Runtime) createWeakSetProto(val *Object) objectImpl {
  83. o := newBaseObjectObj(val, r.global.ObjectPrototype, classObject)
  84. o._putProp("constructor", r.global.WeakSet, true, false, true)
  85. r.global.weakSetAdder = r.newNativeFunc(r.weakSetProto_add, nil, "add", nil, 1)
  86. o._putProp("add", r.global.weakSetAdder, true, false, true)
  87. o._putProp("delete", r.newNativeFunc(r.weakSetProto_delete, nil, "delete", nil, 1), true, false, true)
  88. o._putProp("has", r.newNativeFunc(r.weakSetProto_has, nil, "has", nil, 1), true, false, true)
  89. o._putSym(SymToStringTag, valueProp(asciiString(classWeakSet), false, false, true))
  90. return o
  91. }
  92. func (r *Runtime) createWeakSet(val *Object) objectImpl {
  93. o := r.newNativeConstructOnly(val, r.builtin_newWeakSet, r.global.WeakSetPrototype, "WeakSet", 0)
  94. return o
  95. }
  96. func (r *Runtime) initWeakSet() {
  97. r.global.WeakSetPrototype = r.newLazyObject(r.createWeakSetProto)
  98. r.global.WeakSet = r.newLazyObject(r.createWeakSet)
  99. r.addToGlobal("WeakSet", r.global.WeakSet)
  100. }