builtin_set.go 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. package goja
  2. import (
  3. "fmt"
  4. "reflect"
  5. )
  6. var setExportType = reflectTypeArray
  7. type setObject struct {
  8. baseObject
  9. m *orderedMap
  10. }
  11. type setIterObject struct {
  12. baseObject
  13. iter *orderedMapIter
  14. kind iterationKind
  15. }
  16. func (o *setIterObject) next() Value {
  17. if o.iter == nil {
  18. return o.val.runtime.createIterResultObject(_undefined, true)
  19. }
  20. entry := o.iter.next()
  21. if entry == nil {
  22. o.iter = nil
  23. return o.val.runtime.createIterResultObject(_undefined, true)
  24. }
  25. var result Value
  26. switch o.kind {
  27. case iterationKindValue:
  28. result = entry.key
  29. default:
  30. result = o.val.runtime.newArrayValues([]Value{entry.key, entry.key})
  31. }
  32. return o.val.runtime.createIterResultObject(result, false)
  33. }
  34. func (so *setObject) init() {
  35. so.baseObject.init()
  36. so.m = newOrderedMap(so.val.runtime.getHash())
  37. }
  38. func (so *setObject) exportType() reflect.Type {
  39. return setExportType
  40. }
  41. func (so *setObject) export(ctx *objectExportCtx) interface{} {
  42. a := make([]interface{}, so.m.size)
  43. ctx.put(so.val, a)
  44. iter := so.m.newIter()
  45. for i := 0; i < len(a); i++ {
  46. entry := iter.next()
  47. if entry == nil {
  48. break
  49. }
  50. a[i] = exportValue(entry.key, ctx)
  51. }
  52. return a
  53. }
  54. func (so *setObject) exportToArrayOrSlice(dst reflect.Value, typ reflect.Type, ctx *objectExportCtx) error {
  55. l := so.m.size
  56. if typ.Kind() == reflect.Array {
  57. if dst.Len() != l {
  58. return fmt.Errorf("cannot convert a Set into an array, lengths mismatch: have %d, need %d)", l, dst.Len())
  59. }
  60. } else {
  61. dst.Set(reflect.MakeSlice(typ, l, l))
  62. }
  63. ctx.putTyped(so.val, typ, dst.Interface())
  64. iter := so.m.newIter()
  65. r := so.val.runtime
  66. for i := 0; i < l; i++ {
  67. entry := iter.next()
  68. if entry == nil {
  69. break
  70. }
  71. err := r.toReflectValue(entry.key, dst.Index(i), ctx)
  72. if err != nil {
  73. return err
  74. }
  75. }
  76. return nil
  77. }
  78. func (so *setObject) exportToMap(dst reflect.Value, typ reflect.Type, ctx *objectExportCtx) error {
  79. dst.Set(reflect.MakeMap(typ))
  80. keyTyp := typ.Key()
  81. elemTyp := typ.Elem()
  82. iter := so.m.newIter()
  83. r := so.val.runtime
  84. for {
  85. entry := iter.next()
  86. if entry == nil {
  87. break
  88. }
  89. keyVal := reflect.New(keyTyp).Elem()
  90. err := r.toReflectValue(entry.key, keyVal, ctx)
  91. if err != nil {
  92. return err
  93. }
  94. dst.SetMapIndex(keyVal, reflect.Zero(elemTyp))
  95. }
  96. return nil
  97. }
  98. func (r *Runtime) setProto_add(call FunctionCall) Value {
  99. thisObj := r.toObject(call.This)
  100. so, ok := thisObj.self.(*setObject)
  101. if !ok {
  102. panic(r.NewTypeError("Method Set.prototype.add called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj})))
  103. }
  104. so.m.set(call.Argument(0), nil)
  105. return call.This
  106. }
  107. func (r *Runtime) setProto_clear(call FunctionCall) Value {
  108. thisObj := r.toObject(call.This)
  109. so, ok := thisObj.self.(*setObject)
  110. if !ok {
  111. panic(r.NewTypeError("Method Set.prototype.clear called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj})))
  112. }
  113. so.m.clear()
  114. return _undefined
  115. }
  116. func (r *Runtime) setProto_delete(call FunctionCall) Value {
  117. thisObj := r.toObject(call.This)
  118. so, ok := thisObj.self.(*setObject)
  119. if !ok {
  120. panic(r.NewTypeError("Method Set.prototype.delete called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj})))
  121. }
  122. return r.toBoolean(so.m.remove(call.Argument(0)))
  123. }
  124. func (r *Runtime) setProto_entries(call FunctionCall) Value {
  125. return r.createSetIterator(call.This, iterationKindKeyValue)
  126. }
  127. func (r *Runtime) setProto_forEach(call FunctionCall) Value {
  128. thisObj := r.toObject(call.This)
  129. so, ok := thisObj.self.(*setObject)
  130. if !ok {
  131. panic(r.NewTypeError("Method Set.prototype.forEach called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj})))
  132. }
  133. callbackFn, ok := r.toObject(call.Argument(0)).self.assertCallable()
  134. if !ok {
  135. panic(r.NewTypeError("object is not a function %s"))
  136. }
  137. t := call.Argument(1)
  138. iter := so.m.newIter()
  139. for {
  140. entry := iter.next()
  141. if entry == nil {
  142. break
  143. }
  144. callbackFn(FunctionCall{This: t, Arguments: []Value{entry.key, entry.key, thisObj}})
  145. }
  146. return _undefined
  147. }
  148. func (r *Runtime) setProto_has(call FunctionCall) Value {
  149. thisObj := r.toObject(call.This)
  150. so, ok := thisObj.self.(*setObject)
  151. if !ok {
  152. panic(r.NewTypeError("Method Set.prototype.has called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj})))
  153. }
  154. return r.toBoolean(so.m.has(call.Argument(0)))
  155. }
  156. func (r *Runtime) setProto_getSize(call FunctionCall) Value {
  157. thisObj := r.toObject(call.This)
  158. so, ok := thisObj.self.(*setObject)
  159. if !ok {
  160. panic(r.NewTypeError("Method get Set.prototype.size called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj})))
  161. }
  162. return intToValue(int64(so.m.size))
  163. }
  164. func (r *Runtime) setProto_values(call FunctionCall) Value {
  165. return r.createSetIterator(call.This, iterationKindValue)
  166. }
  167. func (r *Runtime) builtin_newSet(args []Value, newTarget *Object) *Object {
  168. if newTarget == nil {
  169. panic(r.needNew("Set"))
  170. }
  171. proto := r.getPrototypeFromCtor(newTarget, r.global.Set, r.global.SetPrototype)
  172. o := &Object{runtime: r}
  173. so := &setObject{}
  174. so.class = classObject
  175. so.val = o
  176. so.extensible = true
  177. o.self = so
  178. so.prototype = proto
  179. so.init()
  180. if len(args) > 0 {
  181. if arg := args[0]; arg != nil && arg != _undefined && arg != _null {
  182. adder := so.getStr("add", nil)
  183. stdArr := r.checkStdArrayIter(arg)
  184. if adder == r.global.setAdder {
  185. if stdArr != nil {
  186. for _, v := range stdArr.values {
  187. so.m.set(v, nil)
  188. }
  189. } else {
  190. r.getIterator(arg, nil).iterate(func(item Value) {
  191. so.m.set(item, nil)
  192. })
  193. }
  194. } else {
  195. adderFn := toMethod(adder)
  196. if adderFn == nil {
  197. panic(r.NewTypeError("Set.add in missing"))
  198. }
  199. if stdArr != nil {
  200. for _, item := range stdArr.values {
  201. adderFn(FunctionCall{This: o, Arguments: []Value{item}})
  202. }
  203. } else {
  204. r.getIterator(arg, nil).iterate(func(item Value) {
  205. adderFn(FunctionCall{This: o, Arguments: []Value{item}})
  206. })
  207. }
  208. }
  209. }
  210. }
  211. return o
  212. }
  213. func (r *Runtime) createSetIterator(setValue Value, kind iterationKind) Value {
  214. obj := r.toObject(setValue)
  215. setObj, ok := obj.self.(*setObject)
  216. if !ok {
  217. panic(r.NewTypeError("Object is not a Set"))
  218. }
  219. o := &Object{runtime: r}
  220. si := &setIterObject{
  221. iter: setObj.m.newIter(),
  222. kind: kind,
  223. }
  224. si.class = classObject
  225. si.val = o
  226. si.extensible = true
  227. o.self = si
  228. si.prototype = r.getSetIteratorPrototype()
  229. si.init()
  230. return o
  231. }
  232. func (r *Runtime) setIterProto_next(call FunctionCall) Value {
  233. thisObj := r.toObject(call.This)
  234. if iter, ok := thisObj.self.(*setIterObject); ok {
  235. return iter.next()
  236. }
  237. panic(r.NewTypeError("Method Set Iterator.prototype.next called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj})))
  238. }
  239. func (r *Runtime) createSetProto(val *Object) objectImpl {
  240. o := newBaseObjectObj(val, r.global.ObjectPrototype, classObject)
  241. o._putProp("constructor", r.getSet(), true, false, true)
  242. r.global.setAdder = r.newNativeFunc(r.setProto_add, "add", 1)
  243. o._putProp("add", r.global.setAdder, true, false, true)
  244. o._putProp("clear", r.newNativeFunc(r.setProto_clear, "clear", 0), true, false, true)
  245. o._putProp("delete", r.newNativeFunc(r.setProto_delete, "delete", 1), true, false, true)
  246. o._putProp("forEach", r.newNativeFunc(r.setProto_forEach, "forEach", 1), true, false, true)
  247. o._putProp("has", r.newNativeFunc(r.setProto_has, "has", 1), true, false, true)
  248. o.setOwnStr("size", &valueProperty{
  249. getterFunc: r.newNativeFunc(r.setProto_getSize, "get size", 0),
  250. accessor: true,
  251. writable: true,
  252. configurable: true,
  253. }, true)
  254. valuesFunc := r.newNativeFunc(r.setProto_values, "values", 0)
  255. o._putProp("values", valuesFunc, true, false, true)
  256. o._putProp("keys", valuesFunc, true, false, true)
  257. o._putProp("entries", r.newNativeFunc(r.setProto_entries, "entries", 0), true, false, true)
  258. o._putSym(SymIterator, valueProp(valuesFunc, true, false, true))
  259. o._putSym(SymToStringTag, valueProp(asciiString(classSet), false, false, true))
  260. return o
  261. }
  262. func (r *Runtime) createSet(val *Object) objectImpl {
  263. o := r.newNativeConstructOnly(val, r.builtin_newSet, r.getSetPrototype(), "Set", 0)
  264. r.putSpeciesReturnThis(o)
  265. return o
  266. }
  267. func (r *Runtime) createSetIterProto(val *Object) objectImpl {
  268. o := newBaseObjectObj(val, r.getIteratorPrototype(), classObject)
  269. o._putProp("next", r.newNativeFunc(r.setIterProto_next, "next", 0), true, false, true)
  270. o._putSym(SymToStringTag, valueProp(asciiString(classSetIterator), false, false, true))
  271. return o
  272. }
  273. func (r *Runtime) getSetIteratorPrototype() *Object {
  274. var o *Object
  275. if o = r.global.SetIteratorPrototype; o == nil {
  276. o = &Object{runtime: r}
  277. r.global.SetIteratorPrototype = o
  278. o.self = r.createSetIterProto(o)
  279. }
  280. return o
  281. }
  282. func (r *Runtime) getSetPrototype() *Object {
  283. ret := r.global.SetPrototype
  284. if ret == nil {
  285. ret = &Object{runtime: r}
  286. r.global.SetPrototype = ret
  287. ret.self = r.createSetProto(ret)
  288. }
  289. return ret
  290. }
  291. func (r *Runtime) getSet() *Object {
  292. ret := r.global.Set
  293. if ret == nil {
  294. ret = &Object{runtime: r}
  295. r.global.Set = ret
  296. ret.self = r.createSet(ret)
  297. }
  298. return ret
  299. }