builtin_weakset.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  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", r.objectproto_toString(FunctionCall{This: thisObj})))
  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", r.objectproto_toString(FunctionCall{This: thisObj})))
  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", r.objectproto_toString(FunctionCall{This: thisObj})))
  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) builtin_newWeakSet(args []Value, newTarget *Object) *Object {
  44. if newTarget == nil {
  45. panic(r.needNew("WeakSet"))
  46. }
  47. proto := r.getPrototypeFromCtor(newTarget, r.global.WeakSet, r.global.WeakSetPrototype)
  48. o := &Object{runtime: r}
  49. wso := &weakSetObject{}
  50. wso.class = classObject
  51. wso.val = o
  52. wso.extensible = true
  53. o.self = wso
  54. wso.prototype = proto
  55. wso.init()
  56. if len(args) > 0 {
  57. if arg := args[0]; arg != nil && arg != _undefined && arg != _null {
  58. adder := wso.getStr("add", nil)
  59. stdArr := r.checkStdArrayIter(arg)
  60. if adder == r.global.weakSetAdder {
  61. if stdArr != nil {
  62. for _, v := range stdArr.values {
  63. wso.s.set(r.toObject(v), nil)
  64. }
  65. } else {
  66. r.getIterator(arg, nil).iterate(func(item Value) {
  67. wso.s.set(r.toObject(item), nil)
  68. })
  69. }
  70. } else {
  71. adderFn := toMethod(adder)
  72. if adderFn == nil {
  73. panic(r.NewTypeError("WeakSet.add in missing"))
  74. }
  75. if stdArr != nil {
  76. for _, item := range stdArr.values {
  77. adderFn(FunctionCall{This: o, Arguments: []Value{item}})
  78. }
  79. } else {
  80. r.getIterator(arg, nil).iterate(func(item Value) {
  81. adderFn(FunctionCall{This: o, Arguments: []Value{item}})
  82. })
  83. }
  84. }
  85. }
  86. }
  87. return o
  88. }
  89. func (r *Runtime) createWeakSetProto(val *Object) objectImpl {
  90. o := newBaseObjectObj(val, r.global.ObjectPrototype, classObject)
  91. o._putProp("constructor", r.global.WeakSet, true, false, true)
  92. r.global.weakSetAdder = r.newNativeFunc(r.weakSetProto_add, "add", 1)
  93. o._putProp("add", r.global.weakSetAdder, true, false, true)
  94. o._putProp("delete", r.newNativeFunc(r.weakSetProto_delete, "delete", 1), true, false, true)
  95. o._putProp("has", r.newNativeFunc(r.weakSetProto_has, "has", 1), true, false, true)
  96. o._putSym(SymToStringTag, valueProp(asciiString(classWeakSet), false, false, true))
  97. return o
  98. }
  99. func (r *Runtime) createWeakSet(val *Object) objectImpl {
  100. o := r.newNativeConstructOnly(val, r.builtin_newWeakSet, r.getWeakSetPrototype(), "WeakSet", 0)
  101. return o
  102. }
  103. func (r *Runtime) getWeakSetPrototype() *Object {
  104. ret := r.global.WeakSetPrototype
  105. if ret == nil {
  106. ret = &Object{runtime: r}
  107. r.global.WeakSetPrototype = ret
  108. ret.self = r.createWeakSetProto(ret)
  109. }
  110. return ret
  111. }
  112. func (r *Runtime) getWeakSet() *Object {
  113. ret := r.global.WeakSet
  114. if ret == nil {
  115. ret = &Object{runtime: r}
  116. r.global.WeakSet = ret
  117. ret.self = r.createWeakSet(ret)
  118. }
  119. return ret
  120. }