use crate::{
builtins::{
property::Property,
value::{Value, ValueData},
},
environment::{
environment_record_trait::EnvironmentRecordTrait,
lexical_environment::{Environment, EnvironmentType},
},
};
use gc::Gc;
use gc_derive::{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 prop = Property::default()
.value(Gc::new(ValueData::Undefined))
.writable(true)
.enumerable(true)
.configurable(deletion);
bindings.set_prop(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 bindings = &mut self.bindings;
bindings.update_prop(name, Some(value.clone()), None, None, Some(strict));
}
fn get_binding_value(&self, name: &str, strict: bool) -> Value {
if self.bindings.has_field(name) {
self.bindings.get_field_slice(name)
} else {
if strict {
}
Gc::new(ValueData::Undefined)
}
}
fn delete_binding(&mut self, name: &str) -> bool {
self.bindings.remove_prop(name);
true
}
fn has_this_binding(&self) -> bool {
false
}
fn has_super_binding(&self) -> bool {
false
}
fn with_base_object(&self) -> Value {
if self.with_environment {
return self.bindings.clone();
}
Gc::new(ValueData::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
}
}
}