123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- package goja
- import "reflect"
- type objectGoMapReflect struct {
- objectGoReflect
- keyType, valueType reflect.Type
- }
- func (o *objectGoMapReflect) init() {
- o.objectGoReflect.init()
- o.keyType = o.value.Type().Key()
- o.valueType = o.value.Type().Elem()
- }
- func (o *objectGoMapReflect) toKey(n Value) reflect.Value {
- key, err := o.val.runtime.toReflectValue(n, o.keyType)
- if err != nil {
- o.val.runtime.typeErrorResult(true, "map key conversion error: %v", err)
- panic("unreachable")
- }
- return key
- }
- func (o *objectGoMapReflect) strToKey(name string) reflect.Value {
- if o.keyType.Kind() == reflect.String {
- return reflect.ValueOf(name).Convert(o.keyType)
- }
- return o.toKey(newStringValue(name))
- }
- func (o *objectGoMapReflect) _get(n Value) Value {
- if v := o.value.MapIndex(o.toKey(n)); v.IsValid() {
- return o.val.runtime.ToValue(v.Interface())
- }
- return nil
- }
- func (o *objectGoMapReflect) _getStr(name string) Value {
- if v := o.value.MapIndex(o.strToKey(name)); v.IsValid() {
- return o.val.runtime.ToValue(v.Interface())
- }
- return nil
- }
- func (o *objectGoMapReflect) get(n Value) Value {
- if v := o._get(n); v != nil {
- return v
- }
- return o.objectGoReflect.get(n)
- }
- func (o *objectGoMapReflect) getStr(name string) Value {
- if v := o._getStr(name); v != nil {
- return v
- }
- return o.objectGoReflect.getStr(name)
- }
- func (o *objectGoMapReflect) getProp(n Value) Value {
- return o.get(n)
- }
- func (o *objectGoMapReflect) getPropStr(name string) Value {
- return o.getStr(name)
- }
- func (o *objectGoMapReflect) getOwnProp(name string) Value {
- if v := o._getStr(name); v != nil {
- return &valueProperty{
- value: v,
- writable: true,
- enumerable: true,
- }
- }
- return o.objectGoReflect.getOwnProp(name)
- }
- func (o *objectGoMapReflect) toValue(val Value, throw bool) (reflect.Value, bool) {
- v, err := o.val.runtime.toReflectValue(val, o.valueType)
- if err != nil {
- o.val.runtime.typeErrorResult(throw, "map value conversion error: %v", err)
- return reflect.Value{}, false
- }
- return v, true
- }
- func (o *objectGoMapReflect) put(key, val Value, throw bool) {
- k := o.toKey(key)
- v, ok := o.toValue(val, throw)
- if !ok {
- return
- }
- o.value.SetMapIndex(k, v)
- }
- func (o *objectGoMapReflect) putStr(name string, val Value, throw bool) {
- k := o.strToKey(name)
- v, ok := o.toValue(val, throw)
- if !ok {
- return
- }
- o.value.SetMapIndex(k, v)
- }
- func (o *objectGoMapReflect) _putProp(name string, value Value, writable, enumerable, configurable bool) Value {
- o.putStr(name, value, true)
- return value
- }
- func (o *objectGoMapReflect) defineOwnProperty(n Value, descr propertyDescr, throw bool) bool {
- name := n.String()
- if !o.val.runtime.checkHostObjectPropertyDescr(name, descr, throw) {
- return false
- }
- o.put(n, descr.Value, throw)
- return true
- }
- func (o *objectGoMapReflect) hasOwnPropertyStr(name string) bool {
- return o.value.MapIndex(o.strToKey(name)).IsValid()
- }
- func (o *objectGoMapReflect) hasOwnProperty(n Value) bool {
- return o.value.MapIndex(o.toKey(n)).IsValid()
- }
- func (o *objectGoMapReflect) hasProperty(n Value) bool {
- if o.hasOwnProperty(n) {
- return true
- }
- return o.objectGoReflect.hasProperty(n)
- }
- func (o *objectGoMapReflect) hasPropertyStr(name string) bool {
- if o.hasOwnPropertyStr(name) {
- return true
- }
- return o.objectGoReflect.hasPropertyStr(name)
- }
- func (o *objectGoMapReflect) delete(n Value, throw bool) bool {
- o.value.SetMapIndex(o.toKey(n), reflect.Value{})
- return true
- }
- func (o *objectGoMapReflect) deleteStr(name string, throw bool) bool {
- o.value.SetMapIndex(o.strToKey(name), reflect.Value{})
- return true
- }
- type gomapReflectPropIter struct {
- o *objectGoMapReflect
- keys []reflect.Value
- idx int
- recursive bool
- }
- func (i *gomapReflectPropIter) next() (propIterItem, iterNextFunc) {
- for i.idx < len(i.keys) {
- key := i.keys[i.idx]
- v := i.o.value.MapIndex(key)
- i.idx++
- if v.IsValid() {
- return propIterItem{name: key.String(), enumerable: _ENUM_TRUE}, i.next
- }
- }
- if i.recursive {
- return i.o.objectGoReflect._enumerate(true)()
- }
- return propIterItem{}, nil
- }
- func (o *objectGoMapReflect) _enumerate(recusrive bool) iterNextFunc {
- r := &gomapReflectPropIter{
- o: o,
- keys: o.value.MapKeys(),
- recursive: recusrive,
- }
- return r.next
- }
- func (o *objectGoMapReflect) enumerate(all, recursive bool) iterNextFunc {
- return (&propFilterIter{
- wrapped: o._enumerate(recursive),
- all: all,
- seen: make(map[string]bool),
- }).next
- }
- func (o *objectGoMapReflect) equal(other objectImpl) bool {
- if other, ok := other.(*objectGoMapReflect); ok {
- return o.value.Interface() == other.value.Interface()
- }
- return false
- }
|