use crate::{
environment::{
environment_record_trait::EnvironmentRecordTrait,
lexical_environment::{Environment, EnvironmentType},
},
property::{Attribute, Property},
Value,
};
use gc::{Finalize, Trace};
#[derive(Debug, Trace, Finalize, Clone)]
pub struct ObjectEnvironmentRecord {
pub bindings: Value,
pub with_environment: bool,
pub outer_env: Option<Environment>,
}
impl EnvironmentRecordTrait for ObjectEnvironmentRecord {
fn has_binding(&self, name: &str) -> bool {
if self.bindings.has_field(name) {
if self.with_environment {
}
true
} else {
false
}
}
fn create_mutable_binding(&mut self, name: String, deletion: bool) {
let bindings = &mut self.bindings;
let mut prop = Property::data_descriptor(
Value::undefined(),
Attribute::WRITABLE | Attribute::ENUMERABLE,
);
prop.set_configurable(deletion);
bindings.set_property(name, prop);
}
fn create_immutable_binding(&mut self, _name: String, _strict: bool) -> bool {
true
}
fn initialize_binding(&mut self, name: &str, value: Value) {
debug_assert!(self.has_binding(&name));
self.set_mutable_binding(name, value, false)
}
fn set_mutable_binding(&mut self, name: &str, value: Value, strict: bool) {
debug_assert!(value.is_object() || value.is_function());
let mut property = Property::data_descriptor(value, Attribute::ENUMERABLE);
property.set_configurable(strict);
self.bindings.update_property(name, property);
}
fn get_binding_value(&self, name: &str, strict: bool) -> Value {
if self.bindings.has_field(name) {
self.bindings.get_field(name)
} else {
if strict {
}
Value::undefined()
}
}
fn delete_binding(&mut self, name: &str) -> bool {
self.bindings.remove_property(name);
true
}
fn has_this_binding(&self) -> bool {
false
}
fn get_this_binding(&self) -> Value {
Value::undefined()
}
fn has_super_binding(&self) -> bool {
false
}
fn with_base_object(&self) -> Value {
if self.with_environment {
return self.bindings.clone();
}
Value::undefined()
}
fn get_outer_environment(&self) -> Option<Environment> {
match &self.outer_env {
Some(outer) => Some(outer.clone()),
None => None,
}
}
fn set_outer_environment(&mut self, env: Environment) {
self.outer_env = Some(env);
}
fn get_environment_type(&self) -> EnvironmentType {
EnvironmentType::Function
}
fn get_global_object(&self) -> Option<Value> {
if let Some(outer) = &self.outer_env {
outer.borrow().get_global_object()
} else {
None
}
}
}