1 package goja
2
3 type weakSetObject struct {
4 baseObject
5 s weakMap
6 }
7
8 func (ws *weakSetObject) init() {
9 ws.baseObject.init()
10 ws.s = weakMap(ws.val.runtime.genId())
11 }
12
13 func (r *Runtime) weakSetProto_add(call FunctionCall) Value {
14 thisObj := r.toObject(call.This)
15 wso, ok := thisObj.self.(*weakSetObject)
16 if !ok {
17 panic(r.NewTypeError("Method WeakSet.prototype.add called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj})))
18 }
19 wso.s.set(r.toObject(call.Argument(0)), nil)
20 return call.This
21 }
22
23 func (r *Runtime) weakSetProto_delete(call FunctionCall) Value {
24 thisObj := r.toObject(call.This)
25 wso, ok := thisObj.self.(*weakSetObject)
26 if !ok {
27 panic(r.NewTypeError("Method WeakSet.prototype.delete called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj})))
28 }
29 obj, ok := call.Argument(0).(*Object)
30 if ok && wso.s.remove(obj) {
31 return valueTrue
32 }
33 return valueFalse
34 }
35
36 func (r *Runtime) weakSetProto_has(call FunctionCall) Value {
37 thisObj := r.toObject(call.This)
38 wso, ok := thisObj.self.(*weakSetObject)
39 if !ok {
40 panic(r.NewTypeError("Method WeakSet.prototype.has called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj})))
41 }
42 obj, ok := call.Argument(0).(*Object)
43 if ok && wso.s.has(obj) {
44 return valueTrue
45 }
46 return valueFalse
47 }
48
49 func (r *Runtime) builtin_newWeakSet(args []Value, newTarget *Object) *Object {
50 if newTarget == nil {
51 panic(r.needNew("WeakSet"))
52 }
53 proto := r.getPrototypeFromCtor(newTarget, r.global.WeakSet, r.global.WeakSetPrototype)
54 o := &Object{runtime: r}
55
56 wso := &weakSetObject{}
57 wso.class = classObject
58 wso.val = o
59 wso.extensible = true
60 o.self = wso
61 wso.prototype = proto
62 wso.init()
63 if len(args) > 0 {
64 if arg := args[0]; arg != nil && arg != _undefined && arg != _null {
65 adder := wso.getStr("add", nil)
66 stdArr := r.checkStdArrayIter(arg)
67 if adder == r.global.weakSetAdder {
68 if stdArr != nil {
69 for _, v := range stdArr.values {
70 wso.s.set(r.toObject(v), nil)
71 }
72 } else {
73 r.getIterator(arg, nil).iterate(func(item Value) {
74 wso.s.set(r.toObject(item), nil)
75 })
76 }
77 } else {
78 adderFn := toMethod(adder)
79 if adderFn == nil {
80 panic(r.NewTypeError("WeakSet.add in missing"))
81 }
82 if stdArr != nil {
83 for _, item := range stdArr.values {
84 adderFn(FunctionCall{This: o, Arguments: []Value{item}})
85 }
86 } else {
87 r.getIterator(arg, nil).iterate(func(item Value) {
88 adderFn(FunctionCall{This: o, Arguments: []Value{item}})
89 })
90 }
91 }
92 }
93 }
94 return o
95 }
96
97 func (r *Runtime) createWeakSetProto(val *Object) objectImpl {
98 o := newBaseObjectObj(val, r.global.ObjectPrototype, classObject)
99
100 o._putProp("constructor", r.global.WeakSet, true, false, true)
101 r.global.weakSetAdder = r.newNativeFunc(r.weakSetProto_add, "add", 1)
102 o._putProp("add", r.global.weakSetAdder, true, false, true)
103 o._putProp("delete", r.newNativeFunc(r.weakSetProto_delete, "delete", 1), true, false, true)
104 o._putProp("has", r.newNativeFunc(r.weakSetProto_has, "has", 1), true, false, true)
105
106 o._putSym(SymToStringTag, valueProp(asciiString(classWeakSet), false, false, true))
107
108 return o
109 }
110
111 func (r *Runtime) createWeakSet(val *Object) objectImpl {
112 o := r.newNativeConstructOnly(val, r.builtin_newWeakSet, r.getWeakSetPrototype(), "WeakSet", 0)
113
114 return o
115 }
116
117 func (r *Runtime) getWeakSetPrototype() *Object {
118 ret := r.global.WeakSetPrototype
119 if ret == nil {
120 ret = &Object{runtime: r}
121 r.global.WeakSetPrototype = ret
122 ret.self = r.createWeakSetProto(ret)
123 }
124 return ret
125 }
126
127 func (r *Runtime) getWeakSet() *Object {
128 ret := r.global.WeakSet
129 if ret == nil {
130 ret = &Object{runtime: r}
131 r.global.WeakSet = ret
132 ret.self = r.createWeakSet(ret)
133 }
134 return ret
135 }
136
View as plain text