ai_old/goja/builtin_symbol.go

178 lines
4.8 KiB
Go
Raw Normal View History

2024-09-20 16:50:35 +08:00
package goja
import "apigo.cc/ai/ai/goja/unistring"
2024-09-20 16:50:35 +08:00
var (
SymHasInstance = newSymbol(asciiString("Symbol.hasInstance"))
SymIsConcatSpreadable = newSymbol(asciiString("Symbol.isConcatSpreadable"))
SymIterator = newSymbol(asciiString("Symbol.iterator"))
SymMatch = newSymbol(asciiString("Symbol.match"))
SymMatchAll = newSymbol(asciiString("Symbol.matchAll"))
SymReplace = newSymbol(asciiString("Symbol.replace"))
SymSearch = newSymbol(asciiString("Symbol.search"))
SymSpecies = newSymbol(asciiString("Symbol.species"))
SymSplit = newSymbol(asciiString("Symbol.split"))
SymToPrimitive = newSymbol(asciiString("Symbol.toPrimitive"))
SymToStringTag = newSymbol(asciiString("Symbol.toStringTag"))
SymUnscopables = newSymbol(asciiString("Symbol.unscopables"))
)
func (r *Runtime) builtin_symbol(call FunctionCall) Value {
var desc String
if arg := call.Argument(0); !IsUndefined(arg) {
desc = arg.toString()
}
return newSymbol(desc)
}
func (r *Runtime) symbolproto_tostring(call FunctionCall) Value {
sym, ok := call.This.(*Symbol)
if !ok {
if obj, ok := call.This.(*Object); ok {
if v, ok := obj.self.(*primitiveValueObject); ok {
if sym1, ok := v.pValue.(*Symbol); ok {
sym = sym1
}
}
}
}
if sym == nil {
panic(r.NewTypeError("Method Symbol.prototype.toString is called on incompatible receiver"))
}
return sym.descriptiveString()
}
func (r *Runtime) symbolproto_valueOf(call FunctionCall) Value {
_, ok := call.This.(*Symbol)
if ok {
return call.This
}
if obj, ok := call.This.(*Object); ok {
if v, ok := obj.self.(*primitiveValueObject); ok {
if sym, ok := v.pValue.(*Symbol); ok {
return sym
}
}
}
panic(r.NewTypeError("Symbol.prototype.valueOf requires that 'this' be a Symbol"))
}
func (r *Runtime) symbol_for(call FunctionCall) Value {
key := call.Argument(0).toString()
keyStr := key.string()
if v := r.symbolRegistry[keyStr]; v != nil {
return v
}
if r.symbolRegistry == nil {
r.symbolRegistry = make(map[unistring.String]*Symbol)
}
v := newSymbol(key)
r.symbolRegistry[keyStr] = v
return v
}
func (r *Runtime) symbol_keyfor(call FunctionCall) Value {
arg := call.Argument(0)
sym, ok := arg.(*Symbol)
if !ok {
panic(r.NewTypeError("%s is not a symbol", arg.String()))
}
for key, s := range r.symbolRegistry {
if s == sym {
return stringValueFromRaw(key)
}
}
return _undefined
}
func (r *Runtime) thisSymbolValue(v Value) *Symbol {
if sym, ok := v.(*Symbol); ok {
return sym
}
if obj, ok := v.(*Object); ok {
if pVal, ok := obj.self.(*primitiveValueObject); ok {
if sym, ok := pVal.pValue.(*Symbol); ok {
return sym
}
}
}
panic(r.NewTypeError("Value is not a Symbol"))
}
func (r *Runtime) createSymbolProto(val *Object) objectImpl {
o := &baseObject{
class: classObject,
val: val,
extensible: true,
prototype: r.global.ObjectPrototype,
}
o.init()
o._putProp("constructor", r.getSymbol(), true, false, true)
o.setOwnStr("description", &valueProperty{
configurable: true,
getterFunc: r.newNativeFunc(func(call FunctionCall) Value {
return r.thisSymbolValue(call.This).desc
}, "get description", 0),
accessor: true,
}, false)
o._putProp("toString", r.newNativeFunc(r.symbolproto_tostring, "toString", 0), true, false, true)
o._putProp("valueOf", r.newNativeFunc(r.symbolproto_valueOf, "valueOf", 0), true, false, true)
o._putSym(SymToPrimitive, valueProp(r.newNativeFunc(r.symbolproto_valueOf, "[Symbol.toPrimitive]", 1), false, false, true))
o._putSym(SymToStringTag, valueProp(newStringValue("Symbol"), false, false, true))
return o
}
func (r *Runtime) createSymbol(val *Object) objectImpl {
o := r.newNativeFuncAndConstruct(val, r.builtin_symbol, func(args []Value, newTarget *Object) *Object {
panic(r.NewTypeError("Symbol is not a constructor"))
}, r.getSymbolPrototype(), "Symbol", _positiveZero)
o._putProp("for", r.newNativeFunc(r.symbol_for, "for", 1), true, false, true)
o._putProp("keyFor", r.newNativeFunc(r.symbol_keyfor, "keyFor", 1), true, false, true)
for _, s := range []*Symbol{
SymHasInstance,
SymIsConcatSpreadable,
SymIterator,
SymMatch,
SymMatchAll,
SymReplace,
SymSearch,
SymSpecies,
SymSplit,
SymToPrimitive,
SymToStringTag,
SymUnscopables,
} {
n := s.desc.(asciiString)
n = n[len("Symbol."):]
o._putProp(unistring.String(n), s, false, false, false)
}
return o
}
func (r *Runtime) getSymbolPrototype() *Object {
ret := r.global.SymbolPrototype
if ret == nil {
ret = &Object{runtime: r}
r.global.SymbolPrototype = ret
ret.self = r.createSymbolProto(ret)
}
return ret
}
func (r *Runtime) getSymbol() *Object {
ret := r.global.Symbol
if ret == nil {
ret = &Object{runtime: r}
r.global.Symbol = ret
ret.self = r.createSymbol(ret)
}
return ret
}