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  }