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(); } } }