package goja type weakSetObject struct { baseObject s weakMap } func (ws *weakSetObject) init() { ws.baseObject.init() ws.s = weakMap(ws.val.runtime.genId()) } func (r *Runtime) weakSetProto_add(call FunctionCall) Value { thisObj := r.toObject(call.This) wso, ok := thisObj.self.(*weakSetObject) if !ok { panic(r.NewTypeError("Method WeakSet.prototype.add called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj}))) } wso.s.set(r.toObject(call.Argument(0)), nil) return call.This } func (r *Runtime) weakSetProto_delete(call FunctionCall) Value { thisObj := r.toObject(call.This) wso, ok := thisObj.self.(*weakSetObject) if !ok { panic(r.NewTypeError("Method WeakSet.prototype.delete called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj}))) } obj, ok := call.Argument(0).(*Object) if ok && wso.s.remove(obj) { return valueTrue } return valueFalse } func (r *Runtime) weakSetProto_has(call FunctionCall) Value { thisObj := r.toObject(call.This) wso, ok := thisObj.self.(*weakSetObject) if !ok { panic(r.NewTypeError("Method WeakSet.prototype.has called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj}))) } obj, ok := call.Argument(0).(*Object) if ok && wso.s.has(obj) { return valueTrue } return valueFalse } func (r *Runtime) builtin_newWeakSet(args []Value, newTarget *Object) *Object { if newTarget == nil { panic(r.needNew("WeakSet")) } proto := r.getPrototypeFromCtor(newTarget, r.global.WeakSet, r.global.WeakSetPrototype) o := &Object{runtime: r} wso := &weakSetObject{} wso.class = classObject wso.val = o wso.extensible = true o.self = wso wso.prototype = proto wso.init() if len(args) > 0 { if arg := args[0]; arg != nil && arg != _undefined && arg != _null { adder := wso.getStr("add", nil) stdArr := r.checkStdArrayIter(arg) if adder == r.global.weakSetAdder { if stdArr != nil { for _, v := range stdArr.values { wso.s.set(r.toObject(v), nil) } } else { r.getIterator(arg, nil).iterate(func(item Value) { wso.s.set(r.toObject(item), nil) }) } } else { adderFn := toMethod(adder) if adderFn == nil { panic(r.NewTypeError("WeakSet.add in missing")) } if stdArr != nil { for _, item := range stdArr.values { adderFn(FunctionCall{This: o, Arguments: []Value{item}}) } } else { r.getIterator(arg, nil).iterate(func(item Value) { adderFn(FunctionCall{This: o, Arguments: []Value{item}}) }) } } } } return o } func (r *Runtime) createWeakSetProto(val *Object) objectImpl { o := newBaseObjectObj(val, r.global.ObjectPrototype, classObject) o._putProp("constructor", r.global.WeakSet, true, false, true) r.global.weakSetAdder = r.newNativeFunc(r.weakSetProto_add, "add", 1) o._putProp("add", r.global.weakSetAdder, true, false, true) o._putProp("delete", r.newNativeFunc(r.weakSetProto_delete, "delete", 1), true, false, true) o._putProp("has", r.newNativeFunc(r.weakSetProto_has, "has", 1), true, false, true) o._putSym(SymToStringTag, valueProp(asciiString(classWeakSet), false, false, true)) return o } func (r *Runtime) createWeakSet(val *Object) objectImpl { o := r.newNativeConstructOnly(val, r.builtin_newWeakSet, r.getWeakSetPrototype(), "WeakSet", 0) return o } func (r *Runtime) getWeakSetPrototype() *Object { ret := r.global.WeakSetPrototype if ret == nil { ret = &Object{runtime: r} r.global.WeakSetPrototype = ret ret.self = r.createWeakSetProto(ret) } return ret } func (r *Runtime) getWeakSet() *Object { ret := r.global.WeakSet if ret == nil { ret = &Object{runtime: r} r.global.WeakSet = ret ret.self = r.createWeakSet(ret) } return ret }