go-ethereum/vendor/github.com/dop251/goja/object_gomap_reflect.go
2019-06-27 09:00:06 +02:00

203 lines
4.6 KiB
Go

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
}