object_gomap_reflect.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. package goja
  2. import "reflect"
  3. type objectGoMapReflect struct {
  4. objectGoReflect
  5. keyType, valueType reflect.Type
  6. }
  7. func (o *objectGoMapReflect) init() {
  8. o.objectGoReflect.init()
  9. o.keyType = o.value.Type().Key()
  10. o.valueType = o.value.Type().Elem()
  11. }
  12. func (o *objectGoMapReflect) toKey(n Value) reflect.Value {
  13. key, err := o.val.runtime.toReflectValue(n, o.keyType)
  14. if err != nil {
  15. o.val.runtime.typeErrorResult(true, "map key conversion error: %v", err)
  16. panic("unreachable")
  17. }
  18. return key
  19. }
  20. func (o *objectGoMapReflect) strToKey(name string) reflect.Value {
  21. if o.keyType.Kind() == reflect.String {
  22. return reflect.ValueOf(name).Convert(o.keyType)
  23. }
  24. return o.toKey(newStringValue(name))
  25. }
  26. func (o *objectGoMapReflect) _get(n Value) Value {
  27. if v := o.value.MapIndex(o.toKey(n)); v.IsValid() {
  28. return o.val.runtime.ToValue(v.Interface())
  29. }
  30. return nil
  31. }
  32. func (o *objectGoMapReflect) _getStr(name string) Value {
  33. if v := o.value.MapIndex(o.strToKey(name)); v.IsValid() {
  34. return o.val.runtime.ToValue(v.Interface())
  35. }
  36. return nil
  37. }
  38. func (o *objectGoMapReflect) get(n Value) Value {
  39. if v := o._get(n); v != nil {
  40. return v
  41. }
  42. return o.objectGoReflect.get(n)
  43. }
  44. func (o *objectGoMapReflect) getStr(name string) Value {
  45. if v := o._getStr(name); v != nil {
  46. return v
  47. }
  48. return o.objectGoReflect.getStr(name)
  49. }
  50. func (o *objectGoMapReflect) getProp(n Value) Value {
  51. return o.get(n)
  52. }
  53. func (o *objectGoMapReflect) getPropStr(name string) Value {
  54. return o.getStr(name)
  55. }
  56. func (o *objectGoMapReflect) getOwnProp(name string) Value {
  57. if v := o._getStr(name); v != nil {
  58. return &valueProperty{
  59. value: v,
  60. writable: true,
  61. enumerable: true,
  62. }
  63. }
  64. return o.objectGoReflect.getOwnProp(name)
  65. }
  66. func (o *objectGoMapReflect) toValue(val Value, throw bool) (reflect.Value, bool) {
  67. v, err := o.val.runtime.toReflectValue(val, o.valueType)
  68. if err != nil {
  69. o.val.runtime.typeErrorResult(throw, "map value conversion error: %v", err)
  70. return reflect.Value{}, false
  71. }
  72. return v, true
  73. }
  74. func (o *objectGoMapReflect) put(key, val Value, throw bool) {
  75. k := o.toKey(key)
  76. v, ok := o.toValue(val, throw)
  77. if !ok {
  78. return
  79. }
  80. o.value.SetMapIndex(k, v)
  81. }
  82. func (o *objectGoMapReflect) putStr(name string, val Value, throw bool) {
  83. k := o.strToKey(name)
  84. v, ok := o.toValue(val, throw)
  85. if !ok {
  86. return
  87. }
  88. o.value.SetMapIndex(k, v)
  89. }
  90. func (o *objectGoMapReflect) _putProp(name string, value Value, writable, enumerable, configurable bool) Value {
  91. o.putStr(name, value, true)
  92. return value
  93. }
  94. func (o *objectGoMapReflect) defineOwnProperty(n Value, descr propertyDescr, throw bool) bool {
  95. name := n.String()
  96. if !o.val.runtime.checkHostObjectPropertyDescr(name, descr, throw) {
  97. return false
  98. }
  99. o.put(n, descr.Value, throw)
  100. return true
  101. }
  102. func (o *objectGoMapReflect) hasOwnPropertyStr(name string) bool {
  103. return o.value.MapIndex(o.strToKey(name)).IsValid()
  104. }
  105. func (o *objectGoMapReflect) hasOwnProperty(n Value) bool {
  106. return o.value.MapIndex(o.toKey(n)).IsValid()
  107. }
  108. func (o *objectGoMapReflect) hasProperty(n Value) bool {
  109. if o.hasOwnProperty(n) {
  110. return true
  111. }
  112. return o.objectGoReflect.hasProperty(n)
  113. }
  114. func (o *objectGoMapReflect) hasPropertyStr(name string) bool {
  115. if o.hasOwnPropertyStr(name) {
  116. return true
  117. }
  118. return o.objectGoReflect.hasPropertyStr(name)
  119. }
  120. func (o *objectGoMapReflect) delete(n Value, throw bool) bool {
  121. o.value.SetMapIndex(o.toKey(n), reflect.Value{})
  122. return true
  123. }
  124. func (o *objectGoMapReflect) deleteStr(name string, throw bool) bool {
  125. o.value.SetMapIndex(o.strToKey(name), reflect.Value{})
  126. return true
  127. }
  128. type gomapReflectPropIter struct {
  129. o *objectGoMapReflect
  130. keys []reflect.Value
  131. idx int
  132. recursive bool
  133. }
  134. func (i *gomapReflectPropIter) next() (propIterItem, iterNextFunc) {
  135. for i.idx < len(i.keys) {
  136. key := i.keys[i.idx]
  137. v := i.o.value.MapIndex(key)
  138. i.idx++
  139. if v.IsValid() {
  140. return propIterItem{name: key.String(), enumerable: _ENUM_TRUE}, i.next
  141. }
  142. }
  143. if i.recursive {
  144. return i.o.objectGoReflect._enumerate(true)()
  145. }
  146. return propIterItem{}, nil
  147. }
  148. func (o *objectGoMapReflect) _enumerate(recusrive bool) iterNextFunc {
  149. r := &gomapReflectPropIter{
  150. o: o,
  151. keys: o.value.MapKeys(),
  152. recursive: recusrive,
  153. }
  154. return r.next
  155. }
  156. func (o *objectGoMapReflect) enumerate(all, recursive bool) iterNextFunc {
  157. return (&propFilterIter{
  158. wrapped: o._enumerate(recursive),
  159. all: all,
  160. seen: make(map[string]bool),
  161. }).next
  162. }
  163. func (o *objectGoMapReflect) equal(other objectImpl) bool {
  164. if other, ok := other.(*objectGoMapReflect); ok {
  165. return o.value.Interface() == other.value.Interface()
  166. }
  167. return false
  168. }