123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255 |
- package goja
- import (
- "io"
- "strconv"
- "unicode/utf16"
- "unicode/utf8"
- )
- const (
- __proto__ = "__proto__"
- )
- var (
- stringTrue valueString = asciiString("true")
- stringFalse valueString = asciiString("false")
- stringNull valueString = asciiString("null")
- stringUndefined valueString = asciiString("undefined")
- stringObjectC valueString = asciiString("object")
- stringFunction valueString = asciiString("function")
- stringBoolean valueString = asciiString("boolean")
- stringString valueString = asciiString("string")
- stringSymbol valueString = asciiString("symbol")
- stringNumber valueString = asciiString("number")
- stringNaN valueString = asciiString("NaN")
- stringInfinity = asciiString("Infinity")
- stringPlusInfinity = asciiString("+Infinity")
- stringNegInfinity = asciiString("-Infinity")
- stringEmpty valueString = asciiString("")
- stringError valueString = asciiString("Error")
- stringTypeError valueString = asciiString("TypeError")
- stringReferenceError valueString = asciiString("ReferenceError")
- stringSyntaxError valueString = asciiString("SyntaxError")
- stringRangeError valueString = asciiString("RangeError")
- stringEvalError valueString = asciiString("EvalError")
- stringURIError valueString = asciiString("URIError")
- stringGoError valueString = asciiString("GoError")
- stringObjectNull valueString = asciiString("[object Null]")
- stringObjectObject valueString = asciiString("[object Object]")
- stringObjectUndefined valueString = asciiString("[object Undefined]")
- stringGlobalObject valueString = asciiString("Global Object")
- stringInvalidDate valueString = asciiString("Invalid Date")
- )
- type valueString interface {
- Value
- charAt(int64) rune
- length() int64
- concat(valueString) valueString
- substring(start, end int64) valueString
- compareTo(valueString) int
- reader(start int) io.RuneReader
- index(valueString, int64) int64
- lastIndex(valueString, int64) int64
- toLower() valueString
- toUpper() valueString
- toTrimmedUTF8() string
- }
- type stringObject struct {
- baseObject
- value valueString
- length int64
- lengthProp valueProperty
- }
- func newUnicodeString(s string) valueString {
- return unicodeString(utf16.Encode([]rune(s)))
- }
- func newStringValue(s string) valueString {
- for _, chr := range s {
- if chr >= utf8.RuneSelf {
- return newUnicodeString(s)
- }
- }
- return asciiString(s)
- }
- func (s *stringObject) init() {
- s.baseObject.init()
- s.setLength()
- }
- func (s *stringObject) setLength() {
- if s.value != nil {
- s.length = s.value.length()
- }
- s.lengthProp.value = intToValue(s.length)
- s._put("length", &s.lengthProp)
- }
- func (s *stringObject) getStr(name string, receiver Value) Value {
- if i := strToIdx64(name); i >= 0 && i < s.length {
- return s._getIdx(i)
- }
- return s.baseObject.getStr(name, receiver)
- }
- func (s *stringObject) getIdx(idx valueInt, receiver Value) Value {
- i := int64(idx)
- if i >= 0 {
- if i < s.length {
- return s._getIdx(i)
- }
- return nil
- }
- return s.baseObject.getStr(idx.String(), receiver)
- }
- func (s *stringObject) getOwnPropStr(name string) Value {
- if i := strToIdx64(name); i >= 0 && i < s.length {
- val := s._getIdx(i)
- return &valueProperty{
- value: val,
- enumerable: true,
- }
- }
- return s.baseObject.getOwnPropStr(name)
- }
- func (s *stringObject) getOwnPropIdx(idx valueInt) Value {
- i := int64(idx)
- if i >= 0 {
- if i < s.length {
- val := s._getIdx(i)
- return &valueProperty{
- value: val,
- enumerable: true,
- }
- }
- return nil
- }
- return s.baseObject.getOwnPropStr(idx.String())
- }
- func (s *stringObject) _getIdx(idx int64) Value {
- return s.value.substring(idx, idx+1)
- }
- func (s *stringObject) setOwnStr(name string, val Value, throw bool) bool {
- if i := strToIdx64(name); i >= 0 && i < s.length {
- s.val.runtime.typeErrorResult(throw, "Cannot assign to read only property '%d' of a String", i)
- return false
- }
- return s.baseObject.setOwnStr(name, val, throw)
- }
- func (s *stringObject) setOwnIdx(idx valueInt, val Value, throw bool) bool {
- i := int64(idx)
- if i >= 0 && i < s.length {
- s.val.runtime.typeErrorResult(throw, "Cannot assign to read only property '%d' of a String", i)
- return false
- }
- return s.baseObject.setOwnStr(idx.String(), val, throw)
- }
- func (s *stringObject) setForeignStr(name string, val, receiver Value, throw bool) (bool, bool) {
- return s._setForeignStr(name, s.getOwnPropStr(name), val, receiver, throw)
- }
- func (s *stringObject) setForeignIdx(idx valueInt, val, receiver Value, throw bool) (bool, bool) {
- return s._setForeignIdx(idx, s.getOwnPropIdx(idx), val, receiver, throw)
- }
- func (s *stringObject) defineOwnPropertyStr(name string, descr PropertyDescriptor, throw bool) bool {
- if i := strToIdx64(name); i >= 0 && i < s.length {
- s.val.runtime.typeErrorResult(throw, "Cannot redefine property: %d", i)
- return false
- }
- return s.baseObject.defineOwnPropertyStr(name, descr, throw)
- }
- func (s *stringObject) defineOwnPropertyIdx(idx valueInt, descr PropertyDescriptor, throw bool) bool {
- i := int64(idx)
- if i >= 0 && i < s.length {
- s.val.runtime.typeErrorResult(throw, "Cannot redefine property: %d", i)
- return false
- }
- return s.baseObject.defineOwnPropertyStr(idx.String(), descr, throw)
- }
- type stringPropIter struct {
- str valueString // separate, because obj can be the singleton
- obj *stringObject
- idx, length int64
- }
- func (i *stringPropIter) next() (propIterItem, iterNextFunc) {
- if i.idx < i.length {
- name := strconv.FormatInt(i.idx, 10)
- i.idx++
- return propIterItem{name: name, enumerable: _ENUM_TRUE}, i.next
- }
- return i.obj.baseObject.enumerateUnfiltered()()
- }
- func (s *stringObject) enumerateUnfiltered() iterNextFunc {
- return (&stringPropIter{
- str: s.value,
- obj: s,
- length: s.length,
- }).next
- }
- func (s *stringObject) ownKeys(all bool, accum []Value) []Value {
- for i := int64(0); i < s.length; i++ {
- accum = append(accum, asciiString(strconv.FormatInt(i, 10)))
- }
- return s.baseObject.ownKeys(all, accum)
- }
- func (s *stringObject) deleteStr(name string, throw bool) bool {
- if i := strToIdx64(name); i >= 0 && i < s.length {
- s.val.runtime.typeErrorResult(throw, "Cannot delete property '%d' of a String", i)
- return false
- }
- return s.baseObject.deleteStr(name, throw)
- }
- func (s *stringObject) deleteIdx(idx valueInt, throw bool) bool {
- i := int64(idx)
- if i >= 0 && i < s.length {
- s.val.runtime.typeErrorResult(throw, "Cannot delete property '%d' of a String", i)
- return false
- }
- return s.baseObject.deleteStr(idx.String(), throw)
- }
- func (s *stringObject) hasOwnPropertyStr(name string) bool {
- if i := strToIdx64(name); i >= 0 && i < s.length {
- return true
- }
- return s.baseObject.hasOwnPropertyStr(name)
- }
- func (s *stringObject) hasOwnPropertyIdx(idx valueInt) bool {
- i := int64(idx)
- if i >= 0 && i < s.length {
- return true
- }
- return s.baseObject.hasOwnPropertyStr(idx.String())
- }
|