using System.Collections.Generic;
using System.Linq;
using Jint.Native;
namespace Jint.Runtime.Environments
{
///
/// Represents a declarative environment record
/// http://www.ecma-international.org/ecma-262/5.1/#sec-10.2.1.1
///
public sealed class DeclarativeEnvironmentRecord : EnvironmentRecord
{
private readonly Engine _engine;
private readonly IDictionary _bindings = new Dictionary();
public DeclarativeEnvironmentRecord(Engine engine) : base(engine)
{
_engine = engine;
}
public override bool HasBinding(string name)
{
return _bindings.ContainsKey(name);
}
public override void CreateMutableBinding(string name, bool canBeDeleted = false)
{
_bindings.Add(name, new Binding
{
Value = Undefined.Instance,
CanBeDeleted = canBeDeleted,
Mutable = true
});
}
public override void SetMutableBinding(string name, JsValue value, bool strict)
{
var binding = _bindings[name];
if (binding.Mutable)
{
binding.Value = value;
}
else
{
if (strict)
{
throw new JavaScriptException(_engine.TypeError, "Can't update the value of an immutable binding.");
}
}
}
public override JsValue GetBindingValue(string name, bool strict)
{
var binding = _bindings[name];
if (!binding.Mutable && binding.Value == Undefined.Instance)
{
if (strict)
{
throw new JavaScriptException(_engine.ReferenceError, "Can't access anm uninitiazed immutable binding.");
}
return Undefined.Instance;
}
return binding.Value;
}
public override bool DeleteBinding(string name)
{
Binding binding;
if (!_bindings.TryGetValue(name, out binding))
{
return true;
}
if (!binding.CanBeDeleted)
{
return false;
}
_bindings.Remove(name);
return true;
}
public override JsValue ImplicitThisValue()
{
return Undefined.Instance;
}
///
/// Creates a new but uninitialised immutable binding in an environment record.
///
/// The identifier of the binding.
public void CreateImmutableBinding(string name)
{
_bindings.Add(name, new Binding
{
Value = Undefined.Instance,
Mutable = false,
CanBeDeleted = false
});
}
///
/// Sets the value of an already existing but uninitialised immutable binding in an environment record.
///
/// The identifier of the binding.
/// The value of the binding.
public void InitializeImmutableBinding(string name, JsValue value)
{
var binding = _bindings[name];
binding.Value = value;
}
///
/// Returns an array of all the defined binding names
///
/// The array of all defined bindings
public override string[] GetAllBindingNames()
{
return _bindings.Keys.ToArray();
}
}
}