mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
203 lines
4.6 KiB
Go
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
|
|
}
|