1package goja 2 3import ( 4 "reflect" 5 6 "github.com/dop251/goja/unistring" 7) 8 9type objectGoMapSimple struct { 10 baseObject 11 data map[string]interface{} 12} 13 14func (o *objectGoMapSimple) init() { 15 o.baseObject.init() 16 o.prototype = o.val.runtime.global.ObjectPrototype 17 o.class = classObject 18 o.extensible = true 19} 20 21func (o *objectGoMapSimple) _getStr(name string) Value { 22 v, exists := o.data[name] 23 if !exists { 24 return nil 25 } 26 return o.val.runtime.ToValue(v) 27} 28 29func (o *objectGoMapSimple) getStr(name unistring.String, receiver Value) Value { 30 if v := o._getStr(name.String()); v != nil { 31 return v 32 } 33 return o.baseObject.getStr(name, receiver) 34} 35 36func (o *objectGoMapSimple) getOwnPropStr(name unistring.String) Value { 37 if v := o._getStr(name.String()); v != nil { 38 return v 39 } 40 return nil 41} 42 43func (o *objectGoMapSimple) setOwnStr(name unistring.String, val Value, throw bool) bool { 44 n := name.String() 45 if _, exists := o.data[n]; exists { 46 o.data[n] = val.Export() 47 return true 48 } 49 if proto := o.prototype; proto != nil { 50 // we know it's foreign because prototype loops are not allowed 51 if res, ok := proto.self.setForeignStr(name, val, o.val, throw); ok { 52 return res 53 } 54 } 55 // new property 56 if !o.extensible { 57 o.val.runtime.typeErrorResult(throw, "Cannot add property %s, object is not extensible", name) 58 return false 59 } else { 60 o.data[n] = val.Export() 61 } 62 return true 63} 64 65func trueValIfPresent(present bool) Value { 66 if present { 67 return valueTrue 68 } 69 return nil 70} 71 72func (o *objectGoMapSimple) setForeignStr(name unistring.String, val, receiver Value, throw bool) (bool, bool) { 73 return o._setForeignStr(name, trueValIfPresent(o._hasStr(name.String())), val, receiver, throw) 74} 75 76func (o *objectGoMapSimple) _hasStr(name string) bool { 77 _, exists := o.data[name] 78 return exists 79} 80 81func (o *objectGoMapSimple) hasOwnPropertyStr(name unistring.String) bool { 82 return o._hasStr(name.String()) 83} 84 85func (o *objectGoMapSimple) defineOwnPropertyStr(name unistring.String, descr PropertyDescriptor, throw bool) bool { 86 if !o.val.runtime.checkHostObjectPropertyDescr(name, descr, throw) { 87 return false 88 } 89 90 n := name.String() 91 if o.extensible || o._hasStr(n) { 92 o.data[n] = descr.Value.Export() 93 return true 94 } 95 96 o.val.runtime.typeErrorResult(throw, "Cannot define property %s, object is not extensible", n) 97 return false 98} 99 100/* 101func (o *objectGoMapSimple) toPrimitiveNumber() Value { 102 return o.toPrimitiveString() 103} 104 105func (o *objectGoMapSimple) toPrimitiveString() Value { 106 return stringObjectObject 107} 108 109func (o *objectGoMapSimple) toPrimitive() Value { 110 return o.toPrimitiveString() 111} 112 113func (o *objectGoMapSimple) assertCallable() (call func(FunctionCall) Value, ok bool) { 114 return nil, false 115} 116*/ 117 118func (o *objectGoMapSimple) deleteStr(name unistring.String, _ bool) bool { 119 delete(o.data, name.String()) 120 return true 121} 122 123type gomapPropIter struct { 124 o *objectGoMapSimple 125 propNames []string 126 idx int 127} 128 129func (i *gomapPropIter) next() (propIterItem, iterNextFunc) { 130 for i.idx < len(i.propNames) { 131 name := i.propNames[i.idx] 132 i.idx++ 133 if _, exists := i.o.data[name]; exists { 134 return propIterItem{name: unistring.NewFromString(name), enumerable: _ENUM_TRUE}, i.next 135 } 136 } 137 138 return propIterItem{}, nil 139} 140 141func (o *objectGoMapSimple) enumerateOwnKeys() iterNextFunc { 142 propNames := make([]string, len(o.data)) 143 i := 0 144 for key := range o.data { 145 propNames[i] = key 146 i++ 147 } 148 149 return (&gomapPropIter{ 150 o: o, 151 propNames: propNames, 152 }).next 153} 154 155func (o *objectGoMapSimple) ownKeys(_ bool, accum []Value) []Value { 156 // all own keys are enumerable 157 for key := range o.data { 158 accum = append(accum, newStringValue(key)) 159 } 160 return accum 161} 162 163func (o *objectGoMapSimple) export(*objectExportCtx) interface{} { 164 return o.data 165} 166 167func (o *objectGoMapSimple) exportType() reflect.Type { 168 return reflectTypeMap 169} 170 171func (o *objectGoMapSimple) equal(other objectImpl) bool { 172 if other, ok := other.(*objectGoMapSimple); ok { 173 return o == other 174 } 175 return false 176} 177