From f90f976732577af17e7ec4918e9d8029a59a14d0 Mon Sep 17 00:00:00 2001 From: Jason Williams Date: Thu, 22 Aug 2019 12:04:22 +0100 Subject: [PATCH] move Property to its own module --- .../environment/object_environment_record.rs | 2 +- src/lib/js/array.rs | 3 +- src/lib/js/function.rs | 3 +- src/lib/js/mod.rs | 2 + src/lib/js/object.rs | 83 +------------------ src/lib/js/property.rs | 81 ++++++++++++++++++ src/lib/js/string.rs | 3 +- src/lib/js/value.rs | 3 +- 8 files changed, 94 insertions(+), 86 deletions(-) create mode 100644 src/lib/js/property.rs diff --git a/src/lib/environment/object_environment_record.rs b/src/lib/environment/object_environment_record.rs index 2cf6589168..5fe3201a33 100644 --- a/src/lib/environment/object_environment_record.rs +++ b/src/lib/environment/object_environment_record.rs @@ -12,7 +12,7 @@ use crate::{ lexical_environment::{Environment, EnvironmentType}, }, js::{ - object::Property, + property::Property, value::{Value, ValueData}, }, }; diff --git a/src/lib/js/array.rs b/src/lib/js/array.rs index b63a5f806e..d06817cec2 100644 --- a/src/lib/js/array.rs +++ b/src/lib/js/array.rs @@ -2,7 +2,8 @@ use crate::{ exec::Interpreter, js::{ function::NativeFunctionData, - object::{ObjectKind, Property, PROTOTYPE}, + object::{ObjectKind, PROTOTYPE}, + property::Property, value::{from_value, to_value, ResultValue, Value, ValueData}, }, }; diff --git a/src/lib/js/function.rs b/src/lib/js/function.rs index 642c5c8e57..936bb917b1 100644 --- a/src/lib/js/function.rs +++ b/src/lib/js/function.rs @@ -1,7 +1,8 @@ use crate::{ exec::Interpreter, js::{ - object::{Object, Property}, + object::Object, + property::Property, value::{to_value, ResultValue, Value, ValueData}, }, syntax::ast::expr::Expr, diff --git a/src/lib/js/mod.rs b/src/lib/js/mod.rs index 95a998b1d7..0895cdc6a7 100644 --- a/src/lib/js/mod.rs +++ b/src/lib/js/mod.rs @@ -16,3 +16,5 @@ pub mod object; pub mod string; /// Javascript values, utility methods and conversion between Javascript values and Rust values pub mod value; +// Property, used by `Object` +pub mod property; \ No newline at end of file diff --git a/src/lib/js/object.rs b/src/lib/js/object.rs index bfe36fb28f..e5b2f7a9cb 100644 --- a/src/lib/js/object.rs +++ b/src/lib/js/object.rs @@ -2,7 +2,8 @@ use crate::{ exec::Interpreter, js::{ function::NativeFunctionData, - value::{from_value, to_value, FromValue, ResultValue, ToValue, Value, ValueData}, + property::Property, + value::{from_value, to_value, ResultValue, Value, ValueData}, }, }; use gc::Gc; @@ -10,11 +11,9 @@ use gc_derive::{Finalize, Trace}; use std::{borrow::Borrow, collections::HashMap, ops::Deref}; /// Static `prototype`, usually set on constructors as a key to point to their respective prototype object. -/// As this string will be used a lot throughout the program, its best being a static global string which will be referenced pub static PROTOTYPE: &str = "prototype"; /// Static `__proto__`, usually set on Object instances as a key to point to their respective prototype object. -/// As this string will be used a lot throughout the program, its best being a static global string which will be referenced pub static INSTANCE_PROTOTYPE: &str = "__proto__"; /// `ObjectData` is the representation of an object in JavaScript @@ -105,70 +104,6 @@ pub enum ObjectKind { Number, } -/// A Javascript Property AKA The Property Descriptor -/// [[SPEC] - The Property Descriptor Specification Type](https://tc39.github.io/ecma262/#sec-property-descriptor-specification-type) -/// [[SPEC] - Default Attribute Values](https://tc39.github.io/ecma262/#table-4) -#[derive(Trace, Finalize, Clone, Debug)] -pub struct Property { - /// If the type of this can be changed and this can be deleted - pub configurable: bool, - /// If the property shows up in enumeration of the object - pub enumerable: bool, - /// If this property can be changed with an assignment - pub writable: bool, - /// The value associated with the property - pub value: Value, - /// The function serving as getter - pub get: Value, - /// The function serving as setter - pub set: Value, -} - -impl Property { - /// Checks if the provided Value can be used as a property key. - pub fn is_property_key(value: &Value) -> bool { - value.is_string() // || value.is_symbol() // Uncomment this when we are handeling symbols. - } - - /// Make a new property with the given value - pub fn new(value: Value) -> Self { - Self { - configurable: false, - enumerable: false, - writable: false, - value, - get: Gc::new(ValueData::Undefined), - set: Gc::new(ValueData::Undefined), - } - } -} - -impl ToValue for Property { - fn to_value(&self) -> Value { - let prop = ValueData::new_obj(None); - prop.set_field_slice("configurable", to_value(self.configurable)); - prop.set_field_slice("enumerable", to_value(self.enumerable)); - prop.set_field_slice("writable", to_value(self.writable)); - prop.set_field_slice("value", self.value.clone()); - prop.set_field_slice("get", self.get.clone()); - prop.set_field_slice("set", self.set.clone()); - prop - } -} - -impl FromValue for Property { - fn from_value(v: Value) -> Result { - Ok(Self { - configurable: from_value(v.get_field_slice("configurable")).unwrap(), - enumerable: from_value(v.get_field_slice("enumerable")).unwrap(), - writable: from_value(v.get_field_slice("writable")).unwrap(), - value: v.get_field_slice("value"), - get: v.get_field_slice("get"), - set: v.get_field_slice("set"), - }) - } -} - /// Create a new object pub fn make_object(_: &Value, _: &[Value], _: &mut Interpreter) -> ResultValue { Ok(Gc::new(ValueData::Undefined)) @@ -244,17 +179,3 @@ pub fn _create(global: &Value) -> Value { pub fn init(global: &Value) { global.set_field_slice("Object", _create(global)); } - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn is_property_key_test() { - let v = Value::new(ValueData::String(String::from("Boop"))); - assert!(Property::is_property_key(&v)); - - let v = Value::new(ValueData::Boolean(true)); - assert!(!Property::is_property_key(&v)); - } -} diff --git a/src/lib/js/property.rs b/src/lib/js/property.rs new file mode 100644 index 0000000000..852c88a5da --- /dev/null +++ b/src/lib/js/property.rs @@ -0,0 +1,81 @@ +use crate::js::value::{from_value, to_value, FromValue, ToValue, Value, ValueData}; +use gc::Gc; +use gc_derive::{Finalize, Trace}; + +/// A Javascript Property AKA The Property Descriptor +/// [[SPEC] - The Property Descriptor Specification Type](https://tc39.github.io/ecma262/#sec-property-descriptor-specification-type) +/// [[SPEC] - Default Attribute Values](https://tc39.github.io/ecma262/#table-4) +#[derive(Trace, Finalize, Clone, Debug)] +pub struct Property { + /// If the type of this can be changed and this can be deleted + pub configurable: bool, + /// If the property shows up in enumeration of the object + pub enumerable: bool, + /// If this property can be changed with an assignment + pub writable: bool, + /// The value associated with the property + pub value: Value, + /// The function serving as getter + pub get: Value, + /// The function serving as setter + pub set: Value, +} + +impl Property { + /// Checks if the provided Value can be used as a property key. + pub fn is_property_key(value: &Value) -> bool { + value.is_string() // || value.is_symbol() // Uncomment this when we are handeling symbols. + } + + /// Make a new property with the given value + pub fn new(value: Value) -> Self { + Self { + configurable: false, + enumerable: false, + writable: false, + value, + get: Gc::new(ValueData::Undefined), + set: Gc::new(ValueData::Undefined), + } + } +} + +impl ToValue for Property { + fn to_value(&self) -> Value { + let prop = ValueData::new_obj(None); + prop.set_field_slice("configurable", to_value(self.configurable)); + prop.set_field_slice("enumerable", to_value(self.enumerable)); + prop.set_field_slice("writable", to_value(self.writable)); + prop.set_field_slice("value", self.value.clone()); + prop.set_field_slice("get", self.get.clone()); + prop.set_field_slice("set", self.set.clone()); + prop + } +} + +impl FromValue for Property { + fn from_value(v: Value) -> Result { + Ok(Self { + configurable: from_value(v.get_field_slice("configurable")).unwrap(), + enumerable: from_value(v.get_field_slice("enumerable")).unwrap(), + writable: from_value(v.get_field_slice("writable")).unwrap(), + value: v.get_field_slice("value"), + get: v.get_field_slice("get"), + set: v.get_field_slice("set"), + }) + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn is_property_key_test() { + let v = Value::new(ValueData::String(String::from("Boop"))); + assert!(Property::is_property_key(&v)); + + let v = Value::new(ValueData::Boolean(true)); + assert!(!Property::is_property_key(&v)); + } +} diff --git a/src/lib/js/string.rs b/src/lib/js/string.rs index 0353c25c46..4ccd4bedda 100644 --- a/src/lib/js/string.rs +++ b/src/lib/js/string.rs @@ -2,7 +2,8 @@ use crate::{ exec::Interpreter, js::{ function::NativeFunctionData, - object::{ObjectKind, Property, PROTOTYPE}, + object::{ObjectKind, PROTOTYPE}, + property::Property, value::{from_value, to_value, ResultValue, Value, ValueData}, }, }; diff --git a/src/lib/js/value.rs b/src/lib/js/value.rs index 2ce37bc8a3..6fff1f3be3 100644 --- a/src/lib/js/value.rs +++ b/src/lib/js/value.rs @@ -1,6 +1,7 @@ use crate::js::{ function::{Function, NativeFunction, NativeFunctionData}, - object::{Object, ObjectKind, Property, INSTANCE_PROTOTYPE, PROTOTYPE}, + object::{Object, ObjectKind, INSTANCE_PROTOTYPE, PROTOTYPE}, + property::Property }; use gc::{Gc, GcCell}; use gc_derive::{Finalize, Trace};