136 lines
3.7 KiB
Go
136 lines
3.7 KiB
Go
|
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
|
||
|
}
|