go.ketch.com/lib/goja@v0.0.1/object_gomap.go (about) 1 package goja 2 3 import ( 4 "reflect" 5 6 "go.ketch.com/lib/goja/unistring" 7 ) 8 9 type objectGoMapSimple struct { 10 baseObject 11 data map[string]interface{} 12 } 13 14 func (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 21 func (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 29 func (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 36 func (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 43 func (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 65 func trueValIfPresent(present bool) Value { 66 if present { 67 return valueTrue 68 } 69 return nil 70 } 71 72 func (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 76 func (o *objectGoMapSimple) _hasStr(name string) bool { 77 _, exists := o.data[name] 78 return exists 79 } 80 81 func (o *objectGoMapSimple) hasOwnPropertyStr(name unistring.String) bool { 82 return o._hasStr(name.String()) 83 } 84 85 func (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 /* 101 func (o *objectGoMapSimple) toPrimitiveNumber() Value { 102 return o.toPrimitiveString() 103 } 104 105 func (o *objectGoMapSimple) toPrimitiveString() Value { 106 return stringObjectObject 107 } 108 109 func (o *objectGoMapSimple) toPrimitive() Value { 110 return o.toPrimitiveString() 111 } 112 113 func (o *objectGoMapSimple) assertCallable() (call func(FunctionCall) Value, ok bool) { 114 return nil, false 115 } 116 */ 117 118 func (o *objectGoMapSimple) deleteStr(name unistring.String, _ bool) bool { 119 delete(o.data, name.String()) 120 return true 121 } 122 123 type gomapPropIter struct { 124 o *objectGoMapSimple 125 propNames []string 126 idx int 127 } 128 129 func (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: newStringValue(name), enumerable: _ENUM_TRUE}, i.next 135 } 136 } 137 138 return propIterItem{}, nil 139 } 140 141 func (o *objectGoMapSimple) iterateStringKeys() 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 155 func (o *objectGoMapSimple) stringKeys(_ 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 163 func (o *objectGoMapSimple) export(*objectExportCtx) interface{} { 164 return o.data 165 } 166 167 func (o *objectGoMapSimple) exportType() reflect.Type { 168 return reflectTypeMap 169 } 170 171 func (o *objectGoMapSimple) equal(other objectImpl) bool { 172 if other, ok := other.(*objectGoMapSimple); ok { 173 return o == other 174 } 175 return false 176 }