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