123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- package goja
- import (
- "reflect"
- "github.com/dop251/goja/unistring"
- )
- type objectGoMapSimple struct {
- baseObject
- data map[string]interface{}
- }
- func (o *objectGoMapSimple) init() {
- o.baseObject.init()
- o.prototype = o.val.runtime.global.ObjectPrototype
- o.class = classObject
- o.extensible = true
- }
- func (o *objectGoMapSimple) _getStr(name string) Value {
- v, exists := o.data[name]
- if !exists {
- return nil
- }
- return o.val.runtime.ToValue(v)
- }
- func (o *objectGoMapSimple) getStr(name unistring.String, receiver Value) Value {
- if v := o._getStr(name.String()); v != nil {
- return v
- }
- return o.baseObject.getStr(name, receiver)
- }
- func (o *objectGoMapSimple) getOwnPropStr(name unistring.String) Value {
- if v := o._getStr(name.String()); v != nil {
- return v
- }
- return nil
- }
- func (o *objectGoMapSimple) setOwnStr(name unistring.String, val Value, throw bool) bool {
- n := name.String()
- if _, exists := o.data[n]; exists {
- o.data[n] = val.Export()
- return true
- }
- if proto := o.prototype; proto != nil {
- // we know it's foreign because prototype loops are not allowed
- if res, ok := proto.self.setForeignStr(name, val, o.val, throw); ok {
- return res
- }
- }
- // new property
- if !o.extensible {
- o.val.runtime.typeErrorResult(throw, "Cannot add property %s, object is not extensible", name)
- return false
- } else {
- o.data[n] = val.Export()
- }
- return true
- }
- func trueValIfPresent(present bool) Value {
- if present {
- return valueTrue
- }
- return nil
- }
- func (o *objectGoMapSimple) setForeignStr(name unistring.String, val, receiver Value, throw bool) (bool, bool) {
- return o._setForeignStr(name, trueValIfPresent(o._hasStr(name.String())), val, receiver, throw)
- }
- func (o *objectGoMapSimple) _hasStr(name string) bool {
- _, exists := o.data[name]
- return exists
- }
- func (o *objectGoMapSimple) hasOwnPropertyStr(name unistring.String) bool {
- return o._hasStr(name.String())
- }
- func (o *objectGoMapSimple) defineOwnPropertyStr(name unistring.String, descr PropertyDescriptor, throw bool) bool {
- if !o.val.runtime.checkHostObjectPropertyDescr(name, descr, throw) {
- return false
- }
- n := name.String()
- if o.extensible || o._hasStr(n) {
- o.data[n] = descr.Value.Export()
- return true
- }
- o.val.runtime.typeErrorResult(throw, "Cannot define property %s, object is not extensible", n)
- return false
- }
- func (o *objectGoMapSimple) deleteStr(name unistring.String, _ bool) bool {
- delete(o.data, name.String())
- return true
- }
- type gomapPropIter struct {
- o *objectGoMapSimple
- propNames []string
- idx int
- }
- func (i *gomapPropIter) next() (propIterItem, iterNextFunc) {
- for i.idx < len(i.propNames) {
- name := i.propNames[i.idx]
- i.idx++
- if _, exists := i.o.data[name]; exists {
- return propIterItem{name: newStringValue(name), enumerable: _ENUM_TRUE}, i.next
- }
- }
- return propIterItem{}, nil
- }
- func (o *objectGoMapSimple) iterateStringKeys() iterNextFunc {
- propNames := make([]string, len(o.data))
- i := 0
- for key := range o.data {
- propNames[i] = key
- i++
- }
- return (&gomapPropIter{
- o: o,
- propNames: propNames,
- }).next
- }
- func (o *objectGoMapSimple) stringKeys(_ bool, accum []Value) []Value {
- // all own keys are enumerable
- for key := range o.data {
- accum = append(accum, newStringValue(key))
- }
- return accum
- }
- func (o *objectGoMapSimple) export(*objectExportCtx) interface{} {
- return o.data
- }
- func (o *objectGoMapSimple) exportType() reflect.Type {
- return reflectTypeMap
- }
- func (o *objectGoMapSimple) equal(other objectImpl) bool {
- if other, ok := other.(*objectGoMapSimple); ok {
- return o == other
- }
- return false
- }
|