#pragma warning disable CA1859 // Use concrete types when possible for improved performance -- most of prototype methods return JsValue
using Jint.Collections;
using Jint.Native.Object;
using Jint.Runtime;
using Jint.Runtime.Descriptors;
using Jint.Runtime.Interop;
namespace Jint.Native.Symbol
{
///
/// https://tc39.es/ecma262/#sec-properties-of-the-symbol-prototype-object
///
internal sealed class SymbolPrototype : Prototype
{
private readonly SymbolConstructor _constructor;
internal SymbolPrototype(
Engine engine,
Realm realm,
SymbolConstructor symbolConstructor,
ObjectPrototype objectPrototype)
: base(engine, realm)
{
_prototype = objectPrototype;
_constructor = symbolConstructor;
}
protected override void Initialize()
{
const PropertyFlag lengthFlags = PropertyFlag.Configurable;
const PropertyFlag propertyFlags = PropertyFlag.Configurable;
SetProperties(new PropertyDictionary(5, checkExistingKeys: false)
{
["length"] = new PropertyDescriptor(JsNumber.PositiveZero, propertyFlags),
["constructor"] = new PropertyDescriptor(_constructor, PropertyFlag.Configurable | PropertyFlag.Writable),
["description"] = new GetSetPropertyDescriptor(new ClrFunction(Engine, "description", Description, 0, lengthFlags), Undefined, propertyFlags),
["toString"] = new PropertyDescriptor(new ClrFunction(Engine, "toString", ToSymbolString, 0, lengthFlags), PropertyFlag.Configurable | PropertyFlag.Writable),
["valueOf"] = new PropertyDescriptor(new ClrFunction(Engine, "valueOf", ValueOf, 0, lengthFlags), PropertyFlag.Configurable | PropertyFlag.Writable)
});
SetSymbols(new SymbolDictionary(1)
{
[GlobalSymbolRegistry.ToPrimitive] = new PropertyDescriptor(new ClrFunction(Engine, "[Symbol.toPrimitive]", ToPrimitive, 1, lengthFlags), propertyFlags), [GlobalSymbolRegistry.ToStringTag] = new PropertyDescriptor(new JsString("Symbol"), propertyFlags)
}
);
}
///
/// https://tc39.es/ecma262/#sec-symbol.prototype.description
///
private JsValue Description(JsValue thisObject, JsValue[] arguments)
{
var sym = ThisSymbolValue(thisObject);
return sym._value;
}
///
/// https://tc39.es/ecma262/#sec-symbol.prototype.tostring
///
private JsValue ToSymbolString(JsValue thisObject, JsValue[] arguments)
{
var sym = ThisSymbolValue(thisObject);
return new JsString(sym.ToString());
}
///
/// https://tc39.es/ecma262/#sec-symbol.prototype.valueof
///
private JsValue ValueOf(JsValue thisObject, JsValue[] arguments)
{
return ThisSymbolValue(thisObject);
}
///
/// https://tc39.es/ecma262/#sec-symbol.prototype-@@toprimitive
///
private JsValue ToPrimitive(JsValue thisObject, JsValue[] arguments)
{
return ThisSymbolValue(thisObject);
}
private JsSymbol ThisSymbolValue(JsValue thisObject)
{
if (thisObject is JsSymbol s)
{
return s;
}
if (thisObject is SymbolInstance instance)
{
return instance.SymbolData;
}
ExceptionHelper.ThrowTypeError(_realm);
return null;
}
}
}