...
1 package goja
2
3 import (
4 "reflect"
5
6 "github.com/dop251/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
51 if res, ok := proto.self.setForeignStr(name, val, o.val, throw); ok {
52 return res
53 }
54 }
55
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 func (o *objectGoMapSimple) deleteStr(name unistring.String, _ bool) bool {
101 delete(o.data, name.String())
102 return true
103 }
104
105 type gomapPropIter struct {
106 o *objectGoMapSimple
107 propNames []string
108 idx int
109 }
110
111 func (i *gomapPropIter) next() (propIterItem, iterNextFunc) {
112 for i.idx < len(i.propNames) {
113 name := i.propNames[i.idx]
114 i.idx++
115 if _, exists := i.o.data[name]; exists {
116 return propIterItem{name: newStringValue(name), enumerable: _ENUM_TRUE}, i.next
117 }
118 }
119
120 return propIterItem{}, nil
121 }
122
123 func (o *objectGoMapSimple) iterateStringKeys() iterNextFunc {
124 propNames := make([]string, len(o.data))
125 i := 0
126 for key := range o.data {
127 propNames[i] = key
128 i++
129 }
130
131 return (&gomapPropIter{
132 o: o,
133 propNames: propNames,
134 }).next
135 }
136
137 func (o *objectGoMapSimple) stringKeys(_ bool, accum []Value) []Value {
138
139 for key := range o.data {
140 accum = append(accum, newStringValue(key))
141 }
142 return accum
143 }
144
145 func (o *objectGoMapSimple) export(*objectExportCtx) interface{} {
146 return o.data
147 }
148
149 func (o *objectGoMapSimple) exportType() reflect.Type {
150 return reflectTypeMap
151 }
152
153 func (o *objectGoMapSimple) equal(other objectImpl) bool {
154 if other, ok := other.(*objectGoMapSimple); ok {
155 return o == other
156 }
157 return false
158 }
159
View as plain text