github.com/nuvolaris/goja@v0.0.0-20230825100449-967811910c6d/destruct.go (about) 1 package goja 2 3 import ( 4 "reflect" 5 6 "github.com/nuvolaris/goja/unistring" 7 ) 8 9 type destructKeyedSource struct { 10 r *Runtime 11 wrapped Value 12 usedKeys map[Value]struct{} 13 } 14 15 func newDestructKeyedSource(r *Runtime, wrapped Value) *destructKeyedSource { 16 return &destructKeyedSource{ 17 r: r, 18 wrapped: wrapped, 19 } 20 } 21 22 func (r *Runtime) newDestructKeyedSource(wrapped Value) *Object { 23 return &Object{ 24 runtime: r, 25 self: newDestructKeyedSource(r, wrapped), 26 } 27 } 28 29 func (d *destructKeyedSource) w() objectImpl { 30 return d.wrapped.ToObject(d.r).self 31 } 32 33 func (d *destructKeyedSource) recordKey(key Value) { 34 if d.usedKeys == nil { 35 d.usedKeys = make(map[Value]struct{}) 36 } 37 d.usedKeys[key] = struct{}{} 38 } 39 40 func (d *destructKeyedSource) sortLen() int { 41 return d.w().sortLen() 42 } 43 44 func (d *destructKeyedSource) sortGet(i int) Value { 45 return d.w().sortGet(i) 46 } 47 48 func (d *destructKeyedSource) swap(i int, i2 int) { 49 d.w().swap(i, i2) 50 } 51 52 func (d *destructKeyedSource) className() string { 53 return d.w().className() 54 } 55 56 func (d *destructKeyedSource) typeOf() String { 57 return d.w().typeOf() 58 } 59 60 func (d *destructKeyedSource) getStr(p unistring.String, receiver Value) Value { 61 d.recordKey(stringValueFromRaw(p)) 62 return d.w().getStr(p, receiver) 63 } 64 65 func (d *destructKeyedSource) getIdx(p valueInt, receiver Value) Value { 66 d.recordKey(p.toString()) 67 return d.w().getIdx(p, receiver) 68 } 69 70 func (d *destructKeyedSource) getSym(p *Symbol, receiver Value) Value { 71 d.recordKey(p) 72 return d.w().getSym(p, receiver) 73 } 74 75 func (d *destructKeyedSource) getOwnPropStr(u unistring.String) Value { 76 d.recordKey(stringValueFromRaw(u)) 77 return d.w().getOwnPropStr(u) 78 } 79 80 func (d *destructKeyedSource) getOwnPropIdx(v valueInt) Value { 81 d.recordKey(v.toString()) 82 return d.w().getOwnPropIdx(v) 83 } 84 85 func (d *destructKeyedSource) getOwnPropSym(symbol *Symbol) Value { 86 d.recordKey(symbol) 87 return d.w().getOwnPropSym(symbol) 88 } 89 90 func (d *destructKeyedSource) setOwnStr(p unistring.String, v Value, throw bool) bool { 91 return d.w().setOwnStr(p, v, throw) 92 } 93 94 func (d *destructKeyedSource) setOwnIdx(p valueInt, v Value, throw bool) bool { 95 return d.w().setOwnIdx(p, v, throw) 96 } 97 98 func (d *destructKeyedSource) setOwnSym(p *Symbol, v Value, throw bool) bool { 99 return d.w().setOwnSym(p, v, throw) 100 } 101 102 func (d *destructKeyedSource) setForeignStr(p unistring.String, v, receiver Value, throw bool) (res bool, handled bool) { 103 return d.w().setForeignStr(p, v, receiver, throw) 104 } 105 106 func (d *destructKeyedSource) setForeignIdx(p valueInt, v, receiver Value, throw bool) (res bool, handled bool) { 107 return d.w().setForeignIdx(p, v, receiver, throw) 108 } 109 110 func (d *destructKeyedSource) setForeignSym(p *Symbol, v, receiver Value, throw bool) (res bool, handled bool) { 111 return d.w().setForeignSym(p, v, receiver, throw) 112 } 113 114 func (d *destructKeyedSource) hasPropertyStr(u unistring.String) bool { 115 return d.w().hasPropertyStr(u) 116 } 117 118 func (d *destructKeyedSource) hasPropertyIdx(idx valueInt) bool { 119 return d.w().hasPropertyIdx(idx) 120 } 121 122 func (d *destructKeyedSource) hasPropertySym(s *Symbol) bool { 123 return d.w().hasPropertySym(s) 124 } 125 126 func (d *destructKeyedSource) hasOwnPropertyStr(u unistring.String) bool { 127 return d.w().hasOwnPropertyStr(u) 128 } 129 130 func (d *destructKeyedSource) hasOwnPropertyIdx(v valueInt) bool { 131 return d.w().hasOwnPropertyIdx(v) 132 } 133 134 func (d *destructKeyedSource) hasOwnPropertySym(s *Symbol) bool { 135 return d.w().hasOwnPropertySym(s) 136 } 137 138 func (d *destructKeyedSource) defineOwnPropertyStr(name unistring.String, desc PropertyDescriptor, throw bool) bool { 139 return d.w().defineOwnPropertyStr(name, desc, throw) 140 } 141 142 func (d *destructKeyedSource) defineOwnPropertyIdx(name valueInt, desc PropertyDescriptor, throw bool) bool { 143 return d.w().defineOwnPropertyIdx(name, desc, throw) 144 } 145 146 func (d *destructKeyedSource) defineOwnPropertySym(name *Symbol, desc PropertyDescriptor, throw bool) bool { 147 return d.w().defineOwnPropertySym(name, desc, throw) 148 } 149 150 func (d *destructKeyedSource) deleteStr(name unistring.String, throw bool) bool { 151 return d.w().deleteStr(name, throw) 152 } 153 154 func (d *destructKeyedSource) deleteIdx(idx valueInt, throw bool) bool { 155 return d.w().deleteIdx(idx, throw) 156 } 157 158 func (d *destructKeyedSource) deleteSym(s *Symbol, throw bool) bool { 159 return d.w().deleteSym(s, throw) 160 } 161 162 func (d *destructKeyedSource) assertCallable() (call func(FunctionCall) Value, ok bool) { 163 return d.w().assertCallable() 164 } 165 166 func (d *destructKeyedSource) vmCall(vm *vm, n int) { 167 d.w().vmCall(vm, n) 168 } 169 170 func (d *destructKeyedSource) assertConstructor() func(args []Value, newTarget *Object) *Object { 171 return d.w().assertConstructor() 172 } 173 174 func (d *destructKeyedSource) proto() *Object { 175 return d.w().proto() 176 } 177 178 func (d *destructKeyedSource) setProto(proto *Object, throw bool) bool { 179 return d.w().setProto(proto, throw) 180 } 181 182 func (d *destructKeyedSource) hasInstance(v Value) bool { 183 return d.w().hasInstance(v) 184 } 185 186 func (d *destructKeyedSource) isExtensible() bool { 187 return d.w().isExtensible() 188 } 189 190 func (d *destructKeyedSource) preventExtensions(throw bool) bool { 191 return d.w().preventExtensions(throw) 192 } 193 194 type destructKeyedSourceIter struct { 195 d *destructKeyedSource 196 wrapped iterNextFunc 197 } 198 199 func (i *destructKeyedSourceIter) next() (propIterItem, iterNextFunc) { 200 for { 201 item, next := i.wrapped() 202 if next == nil { 203 return item, nil 204 } 205 i.wrapped = next 206 if _, exists := i.d.usedKeys[item.name]; !exists { 207 return item, i.next 208 } 209 } 210 } 211 212 func (d *destructKeyedSource) iterateStringKeys() iterNextFunc { 213 return (&destructKeyedSourceIter{ 214 d: d, 215 wrapped: d.w().iterateStringKeys(), 216 }).next 217 } 218 219 func (d *destructKeyedSource) iterateSymbols() iterNextFunc { 220 return (&destructKeyedSourceIter{ 221 d: d, 222 wrapped: d.w().iterateSymbols(), 223 }).next 224 } 225 226 func (d *destructKeyedSource) iterateKeys() iterNextFunc { 227 return (&destructKeyedSourceIter{ 228 d: d, 229 wrapped: d.w().iterateKeys(), 230 }).next 231 } 232 233 func (d *destructKeyedSource) export(ctx *objectExportCtx) interface{} { 234 return d.w().export(ctx) 235 } 236 237 func (d *destructKeyedSource) exportType() reflect.Type { 238 return d.w().exportType() 239 } 240 241 func (d *destructKeyedSource) exportToMap(dst reflect.Value, typ reflect.Type, ctx *objectExportCtx) error { 242 return d.w().exportToMap(dst, typ, ctx) 243 } 244 245 func (d *destructKeyedSource) exportToArrayOrSlice(dst reflect.Value, typ reflect.Type, ctx *objectExportCtx) error { 246 return d.w().exportToArrayOrSlice(dst, typ, ctx) 247 } 248 249 func (d *destructKeyedSource) equal(impl objectImpl) bool { 250 return d.w().equal(impl) 251 } 252 253 func (d *destructKeyedSource) stringKeys(all bool, accum []Value) []Value { 254 var next iterNextFunc 255 if all { 256 next = d.iterateStringKeys() 257 } else { 258 next = (&enumerableIter{ 259 o: d.wrapped.ToObject(d.r), 260 wrapped: d.iterateStringKeys(), 261 }).next 262 } 263 for item, next := next(); next != nil; item, next = next() { 264 accum = append(accum, item.name) 265 } 266 return accum 267 } 268 269 func (d *destructKeyedSource) filterUsedKeys(keys []Value) []Value { 270 k := 0 271 for i, key := range keys { 272 if _, exists := d.usedKeys[key]; exists { 273 continue 274 } 275 if k != i { 276 keys[k] = key 277 } 278 k++ 279 } 280 return keys[:k] 281 } 282 283 func (d *destructKeyedSource) symbols(all bool, accum []Value) []Value { 284 return d.filterUsedKeys(d.w().symbols(all, accum)) 285 } 286 287 func (d *destructKeyedSource) keys(all bool, accum []Value) []Value { 288 return d.filterUsedKeys(d.w().keys(all, accum)) 289 } 290 291 func (d *destructKeyedSource) _putProp(name unistring.String, value Value, writable, enumerable, configurable bool) Value { 292 return d.w()._putProp(name, value, writable, enumerable, configurable) 293 } 294 295 func (d *destructKeyedSource) _putSym(s *Symbol, prop Value) { 296 d.w()._putSym(s, prop) 297 } 298 299 func (d *destructKeyedSource) getPrivateEnv(typ *privateEnvType, create bool) *privateElements { 300 return d.w().getPrivateEnv(typ, create) 301 }