using System;
using System.Runtime.CompilerServices;
using Jint.Native;
using Jint.Runtime.Environments;
namespace Jint.Runtime.References
{
///
/// Represents the Reference Specification Type
/// http://www.ecma-international.org/ecma-262/5.1/#sec-8.7
///
public sealed class Reference
{
private JsValue _baseValue;
private JsValue _property;
internal bool _strict;
public Reference(JsValue baseValue, JsValue property, bool strict)
{
_baseValue = baseValue;
_property = property;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public JsValue GetBase() => _baseValue;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public JsValue GetReferencedName() => _property;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool IsStrictReference() => _strict;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool HasPrimitiveBase()
{
return (_baseValue._type & InternalTypes.Primitive) != 0;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool IsUnresolvableReference()
{
return _baseValue._type == InternalTypes.Undefined;
}
public bool IsSuperReference()
{
// TODO super not implemented
return false;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool IsPropertyReference()
{
// https://tc39.es/ecma262/#sec-ispropertyreference
return (_baseValue._type & (InternalTypes.Primitive | InternalTypes.Object)) != 0;
}
public JsValue GetThisValue()
{
if (IsSuperReference())
{
return ExceptionHelper.ThrowNotImplementedException();
}
return GetBase();
}
internal Reference Reassign(JsValue baseValue, JsValue name, bool strict)
{
_baseValue = baseValue;
_property = name;
_strict = strict;
return this;
}
internal void AssertValid(Engine engine)
{
if (_strict
&& (_baseValue._type & InternalTypes.ObjectEnvironmentRecord) != 0
&& (_property == CommonProperties.Eval || _property == CommonProperties.Arguments))
{
ExceptionHelper.ThrowSyntaxError(engine);
}
}
internal void InitializeReferencedBinding(JsValue value)
{
((EnvironmentRecord) _baseValue).InitializeBinding(TypeConverter.ToString(_property), value);
}
}
}