From 07b60f43ce30857b7b036e9cbc42f166adea8cb7 Mon Sep 17 00:00:00 2001 From: nekevss Date: Thu, 9 Jun 2022 21:27:03 -0400 Subject: [PATCH 01/41] initial commit -- new, from_iterator, entries, keys --- boa_engine/src/object/jsmap.rs | 77 ++++++++++++++++++++++++++++++++++ test262 | 2 +- 2 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 boa_engine/src/object/jsmap.rs diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs new file mode 100644 index 00000000000..a6cee2b4c51 --- /dev/null +++ b/boa_engine/src/object/jsmap.rs @@ -0,0 +1,77 @@ +// This module is a wrapper for the Map Builtin Javascript Object + +use crate::{ + builtins::Map::{self, map_iterator::MapIterator, ordered_map::OrderedMap}, + object::{JsObject, JsObjectType}, + property::{PropertyNameKind}, + Context, JsResult, JsValue +}; + +use boa_gc::{Finalize, Trace}; +use std::ops::Deref; + +#[derive(Debug, Clone, Trace, Finalize)] +pub struct JsMap { + inner: JsObject, +} + +impl JsMap { + /// Create new Empty Map Object + #[inline] + pub fn new(context: &mut Context) -> Self { + // Get default Map prototype + let prototype = context.intrinsics().constructors().map().prototype(); + + // Create a default map object with [[MapData]] as a new empty list + let map = JsObject::from_proto_and_data(prototype, ObjectData::map(OrderedMap::new())); + + map + } + + /// Create a new map object for any object that has a `@@Iterator` field. + #[inline] + pub fn from_iterable(iterable: JsObject, context: &mut Context) -> JsResult { + // Create a new map + let map = Self::new(); + + // Let adder be Get(map, "set") per spec. This action should not fail with default map + let adder = map.get("set", context).expect("creating a map with the default prototype must not fail"); + + let inner = Map::add_entries_from_iterable(&map, iterable, &adder, context)?; + + Ok(Self { inner }) + } + + /// Create a [`JsMap`] from a [`JsObject`], if the object is not a map, throw a `TypeError`. + #[inline] + pub fn from_object(object: JsObject, context: &mut Context) -> JsResult { + if object.borrow().is_map() { + Ok(Self{ inner: object}) + } else { + context.throw_type_error("object is not a Map") + } + } + + /// Return a new Iterator object that contains the [key, value] pairs in order of assertion + #[inline] + pub fn entries(&self, context: &mut Context) -> JsResult { + MapIterator::create_map_iterator(self, PropertyNameKind::KeyAndValue, context) + } + + /// Return the keys Iterator object + #[inline] + pub fn keys(&self, context: &mut Context) -> JsResult { + MapIterator::create_map_iterator(self, PropertyNameKind::Key, context) + } +} + +impl Deref for JsMap { + type Target = JsObject; + + #[inline] + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +impl JsObjectType for JsMap {} \ No newline at end of file diff --git a/test262 b/test262 index 74656ae4ec6..74de3d1d327 160000 --- a/test262 +++ b/test262 @@ -1 +1 @@ -Subproject commit 74656ae4ec63b11421da7ca99e452b89d5cfe3a2 +Subproject commit 74de3d1d327b3238d6193242c3cc157746f2faad From 51267946a9296177326cdc28d9c2c521b3f189a2 Mon Sep 17 00:00:00 2001 From: nekevss Date: Fri, 10 Jun 2022 00:17:59 -0400 Subject: [PATCH 02/41] complete initial method implementation --- boa_engine/src/object/jsmap.rs | 72 +++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 2 deletions(-) diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs index a6cee2b4c51..c9e1f6ada4e 100644 --- a/boa_engine/src/object/jsmap.rs +++ b/boa_engine/src/object/jsmap.rs @@ -55,13 +55,81 @@ impl JsMap { /// Return a new Iterator object that contains the [key, value] pairs in order of assertion #[inline] pub fn entries(&self, context: &mut Context) -> JsResult { - MapIterator::create_map_iterator(self, PropertyNameKind::KeyAndValue, context) + MapIterator::create_map_iterator(&self.inner.clone().into(), PropertyNameKind::KeyAndValue, context) } /// Return the keys Iterator object #[inline] pub fn keys(&self, context: &mut Context) -> JsResult { - MapIterator::create_map_iterator(self, PropertyNameKind::Key, context) + MapIterator::create_map_iterator(&self.inner.clone().into(), PropertyNameKind::Key, context) + } + + /// Insert a new entry into the Map object + #[inline] + pub fn set(&self, key: T, value: T, context: &mut Context) -> JsResult + where + T: Into + { + Map::set(&self.inner.clone().into(), &[key.into(), value.into()], context) + } + + /// Obtains the size of the map + #[inline] + pub fn get_size(&self, context: &mut Context) -> JsResult { + Map::get_size(&self.inner.clone().into(), &[], context) + } + + /// Remove entry from Map associated with key + #[inline] + pub fn delete(&self, key: T, context: &mut Context) -> JsResult + where + T: Into + { + Map::delete(&self.inner.clone().into(), &[key.into()], context) + } + + /// Returns value associated to key + #[inline] + pub fn get(&self, key: T, context: &mut Context) -> JsResult + where + T: Into + { + Map::get(&self.inner.clone().into(), &[key.into()], context) + } + + /// Removes all entries from a map + #[inline] + pub fn clear(&self, context: &mut Context) -> JsResult { + Map::clear(&self.inner.clone().into(), &[], context) + } + + /// Checks if map contains provided key + #[inline] + pub fn has(&self, key: T, context: &mut Context) -> JsResult + where + T: Into + { + Map::has(&self.inner.clone().into(), &[key.into()], context) + } + + /// Returns new Iterator object of value elements of the Map + #[inline] + pub fn values(&self, context: &mut Context) -> JsResult { + MapIterator::create_map_iterator(&self.inner.clone().into(), PropertyNameKind::Value, context) + } +} + +impl From for JsObject { + #[inline] + fn from(o: JsMap) -> Self { + o.inner.clone() + } +} + +impl From for JsValue { + #[inline] + fn from(o: JsMap) -> Self { + o.inner.clone().into() } } From 58c57f8efc144d2846b561cc18ff5a5931c4cf8a Mon Sep 17 00:00:00 2001 From: nekevss Date: Fri, 10 Jun 2022 01:32:29 -0400 Subject: [PATCH 03/41] fixing existing issues --- boa_engine/src/object/jsmap.rs | 36 +++++++++++++++++++++------------- boa_engine/src/object/mod.rs | 2 ++ boa_examples/src/bin/jsmap.rs | 1 + 3 files changed, 25 insertions(+), 14 deletions(-) create mode 100644 boa_examples/src/bin/jsmap.rs diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs index c9e1f6ada4e..570da624baa 100644 --- a/boa_engine/src/object/jsmap.rs +++ b/boa_engine/src/object/jsmap.rs @@ -1,9 +1,10 @@ // This module is a wrapper for the Map Builtin Javascript Object use crate::{ - builtins::Map::{self, map_iterator::MapIterator, ordered_map::OrderedMap}, - object::{JsObject, JsObjectType}, - property::{PropertyNameKind}, + builtins::Map, + builtins::map::{add_entries_from_iterable, map_iterator::MapIterator, ordered_map::OrderedMap}, + object::{JsObject, ObjectData, JsObjectType}, + property::PropertyNameKind, Context, JsResult, JsValue }; @@ -19,29 +20,25 @@ impl JsMap { /// Create new Empty Map Object #[inline] pub fn new(context: &mut Context) -> Self { - // Get default Map prototype - let prototype = context.intrinsics().constructors().map().prototype(); - - // Create a default map object with [[MapData]] as a new empty list - let map = JsObject::from_proto_and_data(prototype, ObjectData::map(OrderedMap::new())); - - map + let map = Self::create_map(context); + Self { inner: map } } /// Create a new map object for any object that has a `@@Iterator` field. #[inline] - pub fn from_iterable(iterable: JsObject, context: &mut Context) -> JsResult { + pub fn from_iterable(iterable: &JsValue, context: &mut Context) -> JsResult { // Create a new map - let map = Self::new(); + let map = Self::create_map(context); // Let adder be Get(map, "set") per spec. This action should not fail with default map let adder = map.get("set", context).expect("creating a map with the default prototype must not fail"); - let inner = Map::add_entries_from_iterable(&map, iterable, &adder, context)?; + let iterator_record = add_entries_from_iterable(&map, iterable, &adder, context)?.to_object(context)?; - Ok(Self { inner }) + Ok(Self { inner: iterator_record }) } + /// Create a [`JsMap`] from a [`JsObject`], if the object is not a map, throw a `TypeError`. #[inline] pub fn from_object(object: JsObject, context: &mut Context) -> JsResult { @@ -52,6 +49,17 @@ impl JsMap { } } + // utility function to generate default Map object + fn create_map(context: &mut Context) -> JsObject { + // Get default Map prototype + let prototype = context.intrinsics().constructors().map().prototype(); + + // Create a default map object with [[MapData]] as a new empty list + let map = JsObject::from_proto_and_data(prototype, ObjectData::map(OrderedMap::new())); + + map + } + /// Return a new Iterator object that contains the [key, value] pairs in order of assertion #[inline] pub fn entries(&self, context: &mut Context) -> JsResult { diff --git a/boa_engine/src/object/mod.rs b/boa_engine/src/object/mod.rs index 31e10166a10..66b2ba123bc 100644 --- a/boa_engine/src/object/mod.rs +++ b/boa_engine/src/object/mod.rs @@ -63,6 +63,7 @@ mod tests; pub(crate) mod internal_methods; mod jsarray; mod jsfunction; +mod jsmap; mod jsobject; mod jsproxy; mod jstypedarray; @@ -71,6 +72,7 @@ mod property_map; pub use jsarray::*; pub use jsfunction::*; +pub use jsmap::*; pub use jsproxy::*; pub use jstypedarray::*; diff --git a/boa_examples/src/bin/jsmap.rs b/boa_examples/src/bin/jsmap.rs new file mode 100644 index 00000000000..5494eae6b17 --- /dev/null +++ b/boa_examples/src/bin/jsmap.rs @@ -0,0 +1 @@ +use boa_engine::{object::JsMap, Context, JsResult, JsValue}; From cb81fb609ddf2e59d2f2a6142c36ddcbe32924ec Mon Sep 17 00:00:00 2001 From: nekevss Date: Fri, 10 Jun 2022 19:57:52 -0400 Subject: [PATCH 04/41] finished basic outline of JsMap --- boa_engine/src/object/jsmap.rs | 23 ++++++++++++----------- boa_examples/src/bin/jsmap.rs | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs index 570da624baa..ee648ae177b 100644 --- a/boa_engine/src/object/jsmap.rs +++ b/boa_engine/src/object/jsmap.rs @@ -1,10 +1,11 @@ // This module is a wrapper for the Map Builtin Javascript Object - +// +// TODO: improve Iterator object interaction: entries, keys, values +// forEach implementation is missing use crate::{ builtins::Map, - builtins::map::{add_entries_from_iterable, map_iterator::MapIterator, ordered_map::OrderedMap}, + builtins::map::{add_entries_from_iterable, ordered_map::OrderedMap}, object::{JsObject, ObjectData, JsObjectType}, - property::PropertyNameKind, Context, JsResult, JsValue }; @@ -23,19 +24,19 @@ impl JsMap { let map = Self::create_map(context); Self { inner: map } } - + /// Create a new map object for any object that has a `@@Iterator` field. #[inline] - pub fn from_iterable(iterable: &JsValue, context: &mut Context) -> JsResult { + pub fn from_js_iterable(iterable: &JsValue, context: &mut Context) -> JsResult { // Create a new map let map = Self::create_map(context); // Let adder be Get(map, "set") per spec. This action should not fail with default map let adder = map.get("set", context).expect("creating a map with the default prototype must not fail"); - let iterator_record = add_entries_from_iterable(&map, iterable, &adder, context)?.to_object(context)?; + add_entries_from_iterable(&map, iterable, &adder, context)?; - Ok(Self { inner: iterator_record }) + Ok(Self { inner: map }) } @@ -63,13 +64,13 @@ impl JsMap { /// Return a new Iterator object that contains the [key, value] pairs in order of assertion #[inline] pub fn entries(&self, context: &mut Context) -> JsResult { - MapIterator::create_map_iterator(&self.inner.clone().into(), PropertyNameKind::KeyAndValue, context) + Map::entries(&self.inner.clone().into(), &[], context) } /// Return the keys Iterator object #[inline] pub fn keys(&self, context: &mut Context) -> JsResult { - MapIterator::create_map_iterator(&self.inner.clone().into(), PropertyNameKind::Key, context) + Map::keys(&self.inner.clone().into(), &[], context) } /// Insert a new entry into the Map object @@ -96,7 +97,7 @@ impl JsMap { Map::delete(&self.inner.clone().into(), &[key.into()], context) } - /// Returns value associated to key + /// Returns value associated to key or undefined #[inline] pub fn get(&self, key: T, context: &mut Context) -> JsResult where @@ -123,7 +124,7 @@ impl JsMap { /// Returns new Iterator object of value elements of the Map #[inline] pub fn values(&self, context: &mut Context) -> JsResult { - MapIterator::create_map_iterator(&self.inner.clone().into(), PropertyNameKind::Value, context) + Map::values(&self.inner.clone().into(), &[], context) } } diff --git a/boa_examples/src/bin/jsmap.rs b/boa_examples/src/bin/jsmap.rs index 5494eae6b17..d4a42d1da14 100644 --- a/boa_examples/src/bin/jsmap.rs +++ b/boa_examples/src/bin/jsmap.rs @@ -1 +1,32 @@ -use boa_engine::{object::JsMap, Context, JsResult, JsValue}; +use boa_engine::{ + object::JsMap, + Context, JsResult, JsValue +}; + +fn main() -> JsResult<()> { + + let context = &mut Context::default(); + + let map = JsMap::new(context); + + map.set(JsValue::new("Key-1"), JsValue::new("Value-1"), context)?; + + let map_check = map.has(JsValue::new("Key-1"), context)?; + assert_eq!(map_check, JsValue::new(true)); + + map.set(JsValue::new("Key-2"), JsValue::new("Value-2"), context)?; + + assert_eq!(map.get_size(context)?, JsValue::new(2)); + + let current_key_one = map.get(JsValue::new("Key-1"), context)?; + assert_eq!(current_key_one, JsValue::new("Value-1")); + + map.delete(JsValue::new("Key-1"), context)?; + assert_eq!(map.get_size(context)?, JsValue::new(1)); + + let deleted_key_one = map.get(JsValue::new("Key-1"), context)?; + + assert_eq!(deleted_key_one, JsValue::undefined()); + + Ok(()) +} From b33c46e558b1d8bfb4d20927ee3df46e91d7bcbc Mon Sep 17 00:00:00 2001 From: nekevss Date: Fri, 10 Jun 2022 23:47:34 -0400 Subject: [PATCH 05/41] MapIterator implemented - examples built out --- boa_engine/src/object/jsmap.rs | 71 +++++++++++++++---------- boa_engine/src/object/jsmap_iterator.rs | 51 ++++++++++++++++++ boa_engine/src/object/jsobject.rs | 13 ++++- boa_engine/src/object/mod.rs | 2 + boa_examples/src/bin/jsmap.rs | 34 ++++++++++-- 5 files changed, 137 insertions(+), 34 deletions(-) create mode 100644 boa_engine/src/object/jsmap_iterator.rs diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs index ee648ae177b..113c0a82f0b 100644 --- a/boa_engine/src/object/jsmap.rs +++ b/boa_engine/src/object/jsmap.rs @@ -1,12 +1,12 @@ // This module is a wrapper for the Map Builtin Javascript Object -// -// TODO: improve Iterator object interaction: entries, keys, values +// +// TODO: improve Iterator object interaction: entries, keys, values // forEach implementation is missing use crate::{ - builtins::Map, builtins::map::{add_entries_from_iterable, ordered_map::OrderedMap}, - object::{JsObject, ObjectData, JsObjectType}, - Context, JsResult, JsValue + builtins::Map, + object::{JsMapIterator, JsObject, JsObjectType, ObjectData}, + Context, JsResult, JsValue, }; use boa_gc::{Finalize, Trace}; @@ -24,7 +24,7 @@ impl JsMap { let map = Self::create_map(context); Self { inner: map } } - + /// Create a new map object for any object that has a `@@Iterator` field. #[inline] pub fn from_js_iterable(iterable: &JsValue, context: &mut Context) -> JsResult { @@ -32,54 +32,65 @@ impl JsMap { let map = Self::create_map(context); // Let adder be Get(map, "set") per spec. This action should not fail with default map - let adder = map.get("set", context).expect("creating a map with the default prototype must not fail"); + let adder = map + .get("set", context) + .expect("creating a map with the default prototype must not fail"); add_entries_from_iterable(&map, iterable, &adder, context)?; Ok(Self { inner: map }) } - - /// Create a [`JsMap`] from a [`JsObject`], if the object is not a map, throw a `TypeError`. + /// Create a [`JsMap`] from a [`JsObject`], if the object is not a `Map`, throw a `TypeError`. #[inline] pub fn from_object(object: JsObject, context: &mut Context) -> JsResult { if object.borrow().is_map() { - Ok(Self{ inner: object}) + Ok(Self { inner: object }) } else { context.throw_type_error("object is not a Map") } } - + // utility function to generate default Map object fn create_map(context: &mut Context) -> JsObject { // Get default Map prototype let prototype = context.intrinsics().constructors().map().prototype(); // Create a default map object with [[MapData]] as a new empty list - let map = JsObject::from_proto_and_data(prototype, ObjectData::map(OrderedMap::new())); - - map - } + JsObject::from_proto_and_data(prototype, ObjectData::map(OrderedMap::new())) + } /// Return a new Iterator object that contains the [key, value] pairs in order of assertion #[inline] - pub fn entries(&self, context: &mut Context) -> JsResult { - Map::entries(&self.inner.clone().into(), &[], context) + pub fn entries(&self, context: &mut Context) -> JsResult { + let iterator_record = Map::entries(&self.inner.clone().into(), &[], context)? + .get_iterator(context, None, None)?; + let map_iterator_object = iterator_record + .iterator_object() + .as_object() + .expect("MapIterator for Map.prototype.entries() should not fail"); + JsMapIterator::from_object(map_iterator_object.clone(), context) } /// Return the keys Iterator object #[inline] - pub fn keys(&self, context: &mut Context) -> JsResult { - Map::keys(&self.inner.clone().into(), &[], context) + pub fn keys(&self, context: &mut Context) -> JsResult { + let iterator_record = Map::keys(&self.inner.clone().into(), &[], context)?.get_iterator(context, None, None)?; + let map_iterator_object = iterator_record.iterator_object().as_object().expect("MapIterator for Map.prototype.keys() should not fail"); + JsMapIterator::from_object(map_iterator_object.clone(), context) } /// Insert a new entry into the Map object #[inline] pub fn set(&self, key: T, value: T, context: &mut Context) -> JsResult where - T: Into + T: Into, { - Map::set(&self.inner.clone().into(), &[key.into(), value.into()], context) + Map::set( + &self.inner.clone().into(), + &[key.into(), value.into()], + context, + ) } /// Obtains the size of the map @@ -90,9 +101,9 @@ impl JsMap { /// Remove entry from Map associated with key #[inline] - pub fn delete(&self, key: T, context: &mut Context) -> JsResult + pub fn delete(&self, key: T, context: &mut Context) -> JsResult where - T: Into + T: Into, { Map::delete(&self.inner.clone().into(), &[key.into()], context) } @@ -101,7 +112,7 @@ impl JsMap { #[inline] pub fn get(&self, key: T, context: &mut Context) -> JsResult where - T: Into + T: Into, { Map::get(&self.inner.clone().into(), &[key.into()], context) } @@ -116,15 +127,17 @@ impl JsMap { #[inline] pub fn has(&self, key: T, context: &mut Context) -> JsResult where - T: Into + T: Into, { Map::has(&self.inner.clone().into(), &[key.into()], context) } /// Returns new Iterator object of value elements of the Map #[inline] - pub fn values(&self, context: &mut Context) -> JsResult { - Map::values(&self.inner.clone().into(), &[], context) + pub fn values(&self, context: &mut Context) -> JsResult { + let iterator_record = Map::values(&self.inner.clone().into(), &[], context)?.get_iterator(context, None, None)?; + let map_iterator_object = iterator_record.iterator_object().as_object().expect("MapIterator for Map.prototype.values() should not fail"); + JsMapIterator::from_object(map_iterator_object.clone(), context) } } @@ -144,11 +157,11 @@ impl From for JsValue { impl Deref for JsMap { type Target = JsObject; - + #[inline] fn deref(&self) -> &Self::Target { &self.inner } } -impl JsObjectType for JsMap {} \ No newline at end of file +impl JsObjectType for JsMap {} diff --git a/boa_engine/src/object/jsmap_iterator.rs b/boa_engine/src/object/jsmap_iterator.rs new file mode 100644 index 00000000000..07a2443ed19 --- /dev/null +++ b/boa_engine/src/object/jsmap_iterator.rs @@ -0,0 +1,51 @@ +// API wrapper for MapIterator +use crate::{ + builtins::map::map_iterator::MapIterator, object::JsObject, Context, JsResult, JsValue, +}; + +use boa_gc::{Finalize, Trace}; +use std::ops::Deref; + +#[derive(Debug, Clone, Finalize, Trace)] +pub struct JsMapIterator { + inner: JsObject, +} + +impl JsMapIterator { + /// Create a [`JsMapIterator`] from a [`JsObject`]. If object is not a `MapIterator`, throw `TypeError` + #[inline] + pub fn from_object(object: JsObject, context: &mut Context) -> JsResult { + if object.borrow().is_map_iterator() { + Ok(Self { inner: object }) + } else { + context.throw_type_error("object is not a MapIterator") + } + } + + pub fn next(&self, context: &mut Context) -> JsResult { + MapIterator::next(&self.inner.clone().into(), &[], context) + } +} + +impl From for JsObject { + #[inline] + fn from(o: JsMapIterator) -> Self { + o.inner.clone() + } +} + +impl From for JsValue { + #[inline] + fn from(o: JsMapIterator) -> Self { + o.inner.clone().into() + } +} + +impl Deref for JsMapIterator { + type Target = JsObject; + + #[inline] + fn deref(&self) -> &Self::Target { + &self.inner + } +} diff --git a/boa_engine/src/object/jsobject.rs b/boa_engine/src/object/jsobject.rs index e144897504f..02b2a474254 100644 --- a/boa_engine/src/object/jsobject.rs +++ b/boa_engine/src/object/jsobject.rs @@ -328,7 +328,7 @@ impl JsObject { self.borrow().is_array_buffer() } - /// Checks if it is a `Map` object.pub + /// Checks if it is a `Map` object. /// /// # Panics /// @@ -339,6 +339,17 @@ impl JsObject { self.borrow().is_map() } + /// Checks if it's a `MapIterator` object + /// + /// # Panics + /// + /// Panics if the object is currently mutably borrowed. + #[inline] + #[track_caller] + pub fn is_map_iterator(&self) -> bool { + self.borrow().is_map_iterator() + } + /// Checks if it's a `String` object. /// /// # Panics diff --git a/boa_engine/src/object/mod.rs b/boa_engine/src/object/mod.rs index 66b2ba123bc..9cb1839cdc3 100644 --- a/boa_engine/src/object/mod.rs +++ b/boa_engine/src/object/mod.rs @@ -64,6 +64,7 @@ pub(crate) mod internal_methods; mod jsarray; mod jsfunction; mod jsmap; +mod jsmap_iterator; mod jsobject; mod jsproxy; mod jstypedarray; @@ -73,6 +74,7 @@ mod property_map; pub use jsarray::*; pub use jsfunction::*; pub use jsmap::*; +pub use jsmap_iterator::*; pub use jsproxy::*; pub use jstypedarray::*; diff --git a/boa_examples/src/bin/jsmap.rs b/boa_examples/src/bin/jsmap.rs index d4a42d1da14..6a1a5b7daec 100644 --- a/boa_examples/src/bin/jsmap.rs +++ b/boa_examples/src/bin/jsmap.rs @@ -1,10 +1,9 @@ use boa_engine::{ - object::JsMap, - Context, JsResult, JsValue + object::{JsArray, JsMap}, + Context, JsResult, JsValue, }; fn main() -> JsResult<()> { - let context = &mut Context::default(); let map = JsMap::new(context); @@ -20,7 +19,7 @@ fn main() -> JsResult<()> { let current_key_one = map.get(JsValue::new("Key-1"), context)?; assert_eq!(current_key_one, JsValue::new("Value-1")); - + map.delete(JsValue::new("Key-1"), context)?; assert_eq!(map.get_size(context)?, JsValue::new(1)); @@ -28,5 +27,32 @@ fn main() -> JsResult<()> { assert_eq!(deleted_key_one, JsValue::undefined()); + let entries = map.entries(context)?; + + let _first_value = entries.next(context)?; + + let js_array = JsArray::new(context); + + let vec_one = vec![JsValue::new("first-key"), JsValue::new("first-value")]; + let vec_two = vec![JsValue::new("second-key"), JsValue::new("second-value")]; + + js_array.push(JsArray::from_iter(vec_one, context), context)?; + js_array.push(JsArray::from_iter(vec_two, context), context)?; + + let iter_map = JsMap::from_js_iterable(&js_array.into(), context)?; + + assert_eq!( + iter_map.get(JsValue::new("first-key"), context)?, + "first-value".into() + ); + + iter_map.set( + JsValue::new("third-key"), + JsValue::new("third-value"), + context, + )?; + + assert_eq!(iter_map.get_size(context)?, JsValue::new(3)); + Ok(()) } From 10dd0220ed63aaeff8babb18cb84201e576e8363 Mon Sep 17 00:00:00 2001 From: nekevss Date: Sat, 11 Jun 2022 13:01:16 -0400 Subject: [PATCH 06/41] Store add_entries_from_iterable to completion_record variable --- boa_engine/src/object/jsmap.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs index 113c0a82f0b..e903e013ffd 100644 --- a/boa_engine/src/object/jsmap.rs +++ b/boa_engine/src/object/jsmap.rs @@ -36,7 +36,7 @@ impl JsMap { .get("set", context) .expect("creating a map with the default prototype must not fail"); - add_entries_from_iterable(&map, iterable, &adder, context)?; + let _completion_record = add_entries_from_iterable(&map, iterable, &adder, context)?; Ok(Self { inner: map }) } From 86cc23f4a69eeb50365ce3fa26460a61fbf0816a Mon Sep 17 00:00:00 2001 From: nekevss Date: Sat, 11 Jun 2022 18:07:52 -0400 Subject: [PATCH 07/41] Add comments to JsMap example --- boa_engine/src/object/jsmap.rs | 16 ++++++++++++---- boa_examples/src/bin/jsmap.rs | 12 ++++++++++-- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs index e903e013ffd..dacdb02cd01 100644 --- a/boa_engine/src/object/jsmap.rs +++ b/boa_engine/src/object/jsmap.rs @@ -75,8 +75,12 @@ impl JsMap { /// Return the keys Iterator object #[inline] pub fn keys(&self, context: &mut Context) -> JsResult { - let iterator_record = Map::keys(&self.inner.clone().into(), &[], context)?.get_iterator(context, None, None)?; - let map_iterator_object = iterator_record.iterator_object().as_object().expect("MapIterator for Map.prototype.keys() should not fail"); + let iterator_record = Map::keys(&self.inner.clone().into(), &[], context)? + .get_iterator(context, None, None)?; + let map_iterator_object = iterator_record + .iterator_object() + .as_object() + .expect("MapIterator for Map.prototype.keys() should not fail"); JsMapIterator::from_object(map_iterator_object.clone(), context) } @@ -135,8 +139,12 @@ impl JsMap { /// Returns new Iterator object of value elements of the Map #[inline] pub fn values(&self, context: &mut Context) -> JsResult { - let iterator_record = Map::values(&self.inner.clone().into(), &[], context)?.get_iterator(context, None, None)?; - let map_iterator_object = iterator_record.iterator_object().as_object().expect("MapIterator for Map.prototype.values() should not fail"); + let iterator_record = Map::values(&self.inner.clone().into(), &[], context)? + .get_iterator(context, None, None)?; + let map_iterator_object = iterator_record + .iterator_object() + .as_object() + .expect("MapIterator for Map.prototype.values() should not fail"); JsMapIterator::from_object(map_iterator_object.clone(), context) } } diff --git a/boa_examples/src/bin/jsmap.rs b/boa_examples/src/bin/jsmap.rs index 6a1a5b7daec..a849fc902b4 100644 --- a/boa_examples/src/bin/jsmap.rs +++ b/boa_examples/src/bin/jsmap.rs @@ -4,22 +4,27 @@ use boa_engine::{ }; fn main() -> JsResult<()> { + // Create a `Context` for the Javascript executor let context = &mut Context::default(); + // Create a new empty map let map = JsMap::new(context); + // Set a key-value for the map map.set(JsValue::new("Key-1"), JsValue::new("Value-1"), context)?; let map_check = map.has(JsValue::new("Key-1"), context)?; - assert_eq!(map_check, JsValue::new(true)); + assert_eq!(map_check, JsValue::new(true)); // true + // Set a second key-value map.set(JsValue::new("Key-2"), JsValue::new("Value-2"), context)?; - assert_eq!(map.get_size(context)?, JsValue::new(2)); + assert_eq!(map.get_size(context)?, JsValue::new(2)); //true let current_key_one = map.get(JsValue::new("Key-1"), context)?; assert_eq!(current_key_one, JsValue::new("Value-1")); + // Delete an entry with the key map.delete(JsValue::new("Key-1"), context)?; assert_eq!(map.get_size(context)?, JsValue::new(1)); @@ -27,10 +32,12 @@ fn main() -> JsResult<()> { assert_eq!(deleted_key_one, JsValue::undefined()); + // Retrieve a MapIterator for all entries in the Map let entries = map.entries(context)?; let _first_value = entries.next(context)?; + // Create a multidimensional array with key value pairs -> [[first-key, first-value], [second-key, second-value]] let js_array = JsArray::new(context); let vec_one = vec![JsValue::new("first-key"), JsValue::new("first-value")]; @@ -39,6 +46,7 @@ fn main() -> JsResult<()> { js_array.push(JsArray::from_iter(vec_one, context), context)?; js_array.push(JsArray::from_iter(vec_two, context), context)?; + // Create a map from the JsArray using it's iterable property let iter_map = JsMap::from_js_iterable(&js_array.into(), context)?; assert_eq!( From 2588ba48703a53bceacfc9b0d8eeaee90c9c2a7c Mon Sep 17 00:00:00 2001 From: nekevss Date: Tue, 14 Jun 2022 22:25:51 -0400 Subject: [PATCH 08/41] Fix comments for consistency --- boa_engine/src/object/jsmap.rs | 22 +++++++++++----------- boa_examples/src/bin/jsmap.rs | 14 +++++++------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs index dacdb02cd01..6861cbd6bd8 100644 --- a/boa_engine/src/object/jsmap.rs +++ b/boa_engine/src/object/jsmap.rs @@ -18,7 +18,7 @@ pub struct JsMap { } impl JsMap { - /// Create new Empty Map Object + /// Create new Empty Map Object. #[inline] pub fn new(context: &mut Context) -> Self { let map = Self::create_map(context); @@ -28,10 +28,10 @@ impl JsMap { /// Create a new map object for any object that has a `@@Iterator` field. #[inline] pub fn from_js_iterable(iterable: &JsValue, context: &mut Context) -> JsResult { - // Create a new map + // Create a new map object. let map = Self::create_map(context); - // Let adder be Get(map, "set") per spec. This action should not fail with default map + // Let adder be Get(map, "set") per spec. This action should not fail with default map. let adder = map .get("set", context) .expect("creating a map with the default prototype must not fail"); @@ -51,7 +51,7 @@ impl JsMap { } } - // utility function to generate default Map object + // Utility function to generate default Map object. fn create_map(context: &mut Context) -> JsObject { // Get default Map prototype let prototype = context.intrinsics().constructors().map().prototype(); @@ -60,7 +60,7 @@ impl JsMap { JsObject::from_proto_and_data(prototype, ObjectData::map(OrderedMap::new())) } - /// Return a new Iterator object that contains the [key, value] pairs in order of assertion + /// Return a new Iterator object that contains the [key, value] pairs in order of assertion. #[inline] pub fn entries(&self, context: &mut Context) -> JsResult { let iterator_record = Map::entries(&self.inner.clone().into(), &[], context)? @@ -97,13 +97,13 @@ impl JsMap { ) } - /// Obtains the size of the map + /// Obtains the size of the map. #[inline] pub fn get_size(&self, context: &mut Context) -> JsResult { Map::get_size(&self.inner.clone().into(), &[], context) } - /// Remove entry from Map associated with key + /// Remove entry from Map associated with key. #[inline] pub fn delete(&self, key: T, context: &mut Context) -> JsResult where @@ -112,7 +112,7 @@ impl JsMap { Map::delete(&self.inner.clone().into(), &[key.into()], context) } - /// Returns value associated to key or undefined + /// Returns value associated to key or undefined. #[inline] pub fn get(&self, key: T, context: &mut Context) -> JsResult where @@ -121,13 +121,13 @@ impl JsMap { Map::get(&self.inner.clone().into(), &[key.into()], context) } - /// Removes all entries from a map + /// Removes all entries from a map. #[inline] pub fn clear(&self, context: &mut Context) -> JsResult { Map::clear(&self.inner.clone().into(), &[], context) } - /// Checks if map contains provided key + /// Checks if map contains provided key. #[inline] pub fn has(&self, key: T, context: &mut Context) -> JsResult where @@ -136,7 +136,7 @@ impl JsMap { Map::has(&self.inner.clone().into(), &[key.into()], context) } - /// Returns new Iterator object of value elements of the Map + /// Returns new Iterator object of value elements of the Map. #[inline] pub fn values(&self, context: &mut Context) -> JsResult { let iterator_record = Map::values(&self.inner.clone().into(), &[], context)? diff --git a/boa_examples/src/bin/jsmap.rs b/boa_examples/src/bin/jsmap.rs index a849fc902b4..9f4feeb10f6 100644 --- a/boa_examples/src/bin/jsmap.rs +++ b/boa_examples/src/bin/jsmap.rs @@ -4,19 +4,19 @@ use boa_engine::{ }; fn main() -> JsResult<()> { - // Create a `Context` for the Javascript executor + // Create a `Context` for the Javascript executor. let context = &mut Context::default(); - // Create a new empty map + // Create a new empty map. let map = JsMap::new(context); - // Set a key-value for the map + // Set a key-value for the map. map.set(JsValue::new("Key-1"), JsValue::new("Value-1"), context)?; let map_check = map.has(JsValue::new("Key-1"), context)?; assert_eq!(map_check, JsValue::new(true)); // true - // Set a second key-value + // Set a second key-value to the same map. map.set(JsValue::new("Key-2"), JsValue::new("Value-2"), context)?; assert_eq!(map.get_size(context)?, JsValue::new(2)); //true @@ -24,7 +24,7 @@ fn main() -> JsResult<()> { let current_key_one = map.get(JsValue::new("Key-1"), context)?; assert_eq!(current_key_one, JsValue::new("Value-1")); - // Delete an entry with the key + // Delete an entry with a provided key. map.delete(JsValue::new("Key-1"), context)?; assert_eq!(map.get_size(context)?, JsValue::new(1)); @@ -32,7 +32,7 @@ fn main() -> JsResult<()> { assert_eq!(deleted_key_one, JsValue::undefined()); - // Retrieve a MapIterator for all entries in the Map + // Retrieve a MapIterator for all entries in the Map. let entries = map.entries(context)?; let _first_value = entries.next(context)?; @@ -46,7 +46,7 @@ fn main() -> JsResult<()> { js_array.push(JsArray::from_iter(vec_one, context), context)?; js_array.push(JsArray::from_iter(vec_two, context), context)?; - // Create a map from the JsArray using it's iterable property + // Create a map from the JsArray using it's iterable property. let iter_map = JsMap::from_js_iterable(&js_array.into(), context)?; assert_eq!( From b20c098944abdb60c98f90372f22a4d25097eb2f Mon Sep 17 00:00:00 2001 From: nekevss Date: Tue, 14 Jun 2022 23:45:22 -0400 Subject: [PATCH 09/41] Implement method, update test262 submodule --- boa_engine/src/object/jsmap.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs index 6861cbd6bd8..bc88383e911 100644 --- a/boa_engine/src/object/jsmap.rs +++ b/boa_engine/src/object/jsmap.rs @@ -5,7 +5,7 @@ use crate::{ builtins::map::{add_entries_from_iterable, ordered_map::OrderedMap}, builtins::Map, - object::{JsMapIterator, JsObject, JsObjectType, ObjectData}, + object::{JsFunction, JsMapIterator, JsObject, JsObjectType, ObjectData}, Context, JsResult, JsValue, }; @@ -136,6 +136,21 @@ impl JsMap { Map::has(&self.inner.clone().into(), &[key.into()], context) } + // Executes provided callback function for each key-value pair. + #[inline] + pub fn for_each( + &self, + callback: JsFunction, + this_arg: JsValue, + context: &mut Context, + ) -> JsResult { + Map::for_each( + &self.inner.clone().into(), + &[callback.into(), this_arg], + context, + ) + } + /// Returns new Iterator object of value elements of the Map. #[inline] pub fn values(&self, context: &mut Context) -> JsResult { From 106bc143a573c30eccb7f01c1437519fa2cb1f50 Mon Sep 17 00:00:00 2001 From: nekevss Date: Wed, 22 Jun 2022 22:48:44 -0400 Subject: [PATCH 10/41] Removed uneeded TODO --- boa_engine/src/object/jsmap.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs index bc88383e911..d8dfa810dbc 100644 --- a/boa_engine/src/object/jsmap.rs +++ b/boa_engine/src/object/jsmap.rs @@ -1,7 +1,4 @@ // This module is a wrapper for the Map Builtin Javascript Object -// -// TODO: improve Iterator object interaction: entries, keys, values -// forEach implementation is missing use crate::{ builtins::map::{add_entries_from_iterable, ordered_map::OrderedMap}, builtins::Map, From 8c11b7a404647b8744b0f9f66491a5bf76c42ee3 Mon Sep 17 00:00:00 2001 From: nekevss Date: Wed, 22 Jun 2022 23:03:59 -0400 Subject: [PATCH 11/41] Adjust to new method --- boa_engine/src/object/jsmap.rs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs index d8dfa810dbc..0421025461f 100644 --- a/boa_engine/src/object/jsmap.rs +++ b/boa_engine/src/object/jsmap.rs @@ -63,9 +63,7 @@ impl JsMap { let iterator_record = Map::entries(&self.inner.clone().into(), &[], context)? .get_iterator(context, None, None)?; let map_iterator_object = iterator_record - .iterator_object() - .as_object() - .expect("MapIterator for Map.prototype.entries() should not fail"); + .iterator(); JsMapIterator::from_object(map_iterator_object.clone(), context) } @@ -75,9 +73,7 @@ impl JsMap { let iterator_record = Map::keys(&self.inner.clone().into(), &[], context)? .get_iterator(context, None, None)?; let map_iterator_object = iterator_record - .iterator_object() - .as_object() - .expect("MapIterator for Map.prototype.keys() should not fail"); + .iterator(); JsMapIterator::from_object(map_iterator_object.clone(), context) } @@ -154,9 +150,7 @@ impl JsMap { let iterator_record = Map::values(&self.inner.clone().into(), &[], context)? .get_iterator(context, None, None)?; let map_iterator_object = iterator_record - .iterator_object() - .as_object() - .expect("MapIterator for Map.prototype.values() should not fail"); + .iterator(); JsMapIterator::from_object(map_iterator_object.clone(), context) } } From e073cd1d2d1d4ae340666b43e7afac0bbba5a892 Mon Sep 17 00:00:00 2001 From: nekevss Date: Wed, 22 Jun 2022 23:22:15 -0400 Subject: [PATCH 12/41] alter comment --- boa_engine/src/object/jsmap.rs | 2 +- test262 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs index 0421025461f..3e6b1169640 100644 --- a/boa_engine/src/object/jsmap.rs +++ b/boa_engine/src/object/jsmap.rs @@ -129,7 +129,7 @@ impl JsMap { Map::has(&self.inner.clone().into(), &[key.into()], context) } - // Executes provided callback function for each key-value pair. + /// Executes provided callback function for each key-value pair. #[inline] pub fn for_each( &self, diff --git a/test262 b/test262 index 74de3d1d327..babd46c40a1 160000 --- a/test262 +++ b/test262 @@ -1 +1 @@ -Subproject commit 74de3d1d327b3238d6193242c3cc157746f2faad +Subproject commit babd46c40a11f10a7dc6f77aeabe243e5d9b4bd9 From f6029381bfa9b5a1d124f381f47976bf9c80609b Mon Sep 17 00:00:00 2001 From: nekevss Date: Wed, 22 Jun 2022 23:32:26 -0400 Subject: [PATCH 13/41] Run Rust fmt and clippy --- boa_engine/src/object/jsmap.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs index 3e6b1169640..dd3b7031ea2 100644 --- a/boa_engine/src/object/jsmap.rs +++ b/boa_engine/src/object/jsmap.rs @@ -62,8 +62,7 @@ impl JsMap { pub fn entries(&self, context: &mut Context) -> JsResult { let iterator_record = Map::entries(&self.inner.clone().into(), &[], context)? .get_iterator(context, None, None)?; - let map_iterator_object = iterator_record - .iterator(); + let map_iterator_object = iterator_record.iterator(); JsMapIterator::from_object(map_iterator_object.clone(), context) } @@ -72,8 +71,7 @@ impl JsMap { pub fn keys(&self, context: &mut Context) -> JsResult { let iterator_record = Map::keys(&self.inner.clone().into(), &[], context)? .get_iterator(context, None, None)?; - let map_iterator_object = iterator_record - .iterator(); + let map_iterator_object = iterator_record.iterator(); JsMapIterator::from_object(map_iterator_object.clone(), context) } @@ -149,8 +147,7 @@ impl JsMap { pub fn values(&self, context: &mut Context) -> JsResult { let iterator_record = Map::values(&self.inner.clone().into(), &[], context)? .get_iterator(context, None, None)?; - let map_iterator_object = iterator_record - .iterator(); + let map_iterator_object = iterator_record.iterator(); JsMapIterator::from_object(map_iterator_object.clone(), context) } } From a660235b3a05fc9adf1509bc77580fcae0337288 Mon Sep 17 00:00:00 2001 From: nekevss Date: Thu, 9 Jun 2022 21:27:03 -0400 Subject: [PATCH 14/41] initial commit -- new, from_iterator, entries, keys --- boa_engine/src/object/jsmap.rs | 77 ++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 boa_engine/src/object/jsmap.rs diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs new file mode 100644 index 00000000000..a6cee2b4c51 --- /dev/null +++ b/boa_engine/src/object/jsmap.rs @@ -0,0 +1,77 @@ +// This module is a wrapper for the Map Builtin Javascript Object + +use crate::{ + builtins::Map::{self, map_iterator::MapIterator, ordered_map::OrderedMap}, + object::{JsObject, JsObjectType}, + property::{PropertyNameKind}, + Context, JsResult, JsValue +}; + +use boa_gc::{Finalize, Trace}; +use std::ops::Deref; + +#[derive(Debug, Clone, Trace, Finalize)] +pub struct JsMap { + inner: JsObject, +} + +impl JsMap { + /// Create new Empty Map Object + #[inline] + pub fn new(context: &mut Context) -> Self { + // Get default Map prototype + let prototype = context.intrinsics().constructors().map().prototype(); + + // Create a default map object with [[MapData]] as a new empty list + let map = JsObject::from_proto_and_data(prototype, ObjectData::map(OrderedMap::new())); + + map + } + + /// Create a new map object for any object that has a `@@Iterator` field. + #[inline] + pub fn from_iterable(iterable: JsObject, context: &mut Context) -> JsResult { + // Create a new map + let map = Self::new(); + + // Let adder be Get(map, "set") per spec. This action should not fail with default map + let adder = map.get("set", context).expect("creating a map with the default prototype must not fail"); + + let inner = Map::add_entries_from_iterable(&map, iterable, &adder, context)?; + + Ok(Self { inner }) + } + + /// Create a [`JsMap`] from a [`JsObject`], if the object is not a map, throw a `TypeError`. + #[inline] + pub fn from_object(object: JsObject, context: &mut Context) -> JsResult { + if object.borrow().is_map() { + Ok(Self{ inner: object}) + } else { + context.throw_type_error("object is not a Map") + } + } + + /// Return a new Iterator object that contains the [key, value] pairs in order of assertion + #[inline] + pub fn entries(&self, context: &mut Context) -> JsResult { + MapIterator::create_map_iterator(self, PropertyNameKind::KeyAndValue, context) + } + + /// Return the keys Iterator object + #[inline] + pub fn keys(&self, context: &mut Context) -> JsResult { + MapIterator::create_map_iterator(self, PropertyNameKind::Key, context) + } +} + +impl Deref for JsMap { + type Target = JsObject; + + #[inline] + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +impl JsObjectType for JsMap {} \ No newline at end of file From 421426102ac4c592ba96a26cd90cd1612e1fd035 Mon Sep 17 00:00:00 2001 From: nekevss Date: Fri, 10 Jun 2022 00:17:59 -0400 Subject: [PATCH 15/41] complete initial method implementation --- boa_engine/src/object/jsmap.rs | 72 +++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 2 deletions(-) diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs index a6cee2b4c51..c9e1f6ada4e 100644 --- a/boa_engine/src/object/jsmap.rs +++ b/boa_engine/src/object/jsmap.rs @@ -55,13 +55,81 @@ impl JsMap { /// Return a new Iterator object that contains the [key, value] pairs in order of assertion #[inline] pub fn entries(&self, context: &mut Context) -> JsResult { - MapIterator::create_map_iterator(self, PropertyNameKind::KeyAndValue, context) + MapIterator::create_map_iterator(&self.inner.clone().into(), PropertyNameKind::KeyAndValue, context) } /// Return the keys Iterator object #[inline] pub fn keys(&self, context: &mut Context) -> JsResult { - MapIterator::create_map_iterator(self, PropertyNameKind::Key, context) + MapIterator::create_map_iterator(&self.inner.clone().into(), PropertyNameKind::Key, context) + } + + /// Insert a new entry into the Map object + #[inline] + pub fn set(&self, key: T, value: T, context: &mut Context) -> JsResult + where + T: Into + { + Map::set(&self.inner.clone().into(), &[key.into(), value.into()], context) + } + + /// Obtains the size of the map + #[inline] + pub fn get_size(&self, context: &mut Context) -> JsResult { + Map::get_size(&self.inner.clone().into(), &[], context) + } + + /// Remove entry from Map associated with key + #[inline] + pub fn delete(&self, key: T, context: &mut Context) -> JsResult + where + T: Into + { + Map::delete(&self.inner.clone().into(), &[key.into()], context) + } + + /// Returns value associated to key + #[inline] + pub fn get(&self, key: T, context: &mut Context) -> JsResult + where + T: Into + { + Map::get(&self.inner.clone().into(), &[key.into()], context) + } + + /// Removes all entries from a map + #[inline] + pub fn clear(&self, context: &mut Context) -> JsResult { + Map::clear(&self.inner.clone().into(), &[], context) + } + + /// Checks if map contains provided key + #[inline] + pub fn has(&self, key: T, context: &mut Context) -> JsResult + where + T: Into + { + Map::has(&self.inner.clone().into(), &[key.into()], context) + } + + /// Returns new Iterator object of value elements of the Map + #[inline] + pub fn values(&self, context: &mut Context) -> JsResult { + MapIterator::create_map_iterator(&self.inner.clone().into(), PropertyNameKind::Value, context) + } +} + +impl From for JsObject { + #[inline] + fn from(o: JsMap) -> Self { + o.inner.clone() + } +} + +impl From for JsValue { + #[inline] + fn from(o: JsMap) -> Self { + o.inner.clone().into() } } From ffa27a57c16b919e9cc4b2f08ad24334c37a1a1f Mon Sep 17 00:00:00 2001 From: nekevss Date: Fri, 10 Jun 2022 01:32:29 -0400 Subject: [PATCH 16/41] fixing existing issues --- boa_engine/src/object/jsmap.rs | 36 +++++++++++++++++++++------------- boa_engine/src/object/mod.rs | 2 ++ boa_examples/src/bin/jsmap.rs | 1 + 3 files changed, 25 insertions(+), 14 deletions(-) create mode 100644 boa_examples/src/bin/jsmap.rs diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs index c9e1f6ada4e..570da624baa 100644 --- a/boa_engine/src/object/jsmap.rs +++ b/boa_engine/src/object/jsmap.rs @@ -1,9 +1,10 @@ // This module is a wrapper for the Map Builtin Javascript Object use crate::{ - builtins::Map::{self, map_iterator::MapIterator, ordered_map::OrderedMap}, - object::{JsObject, JsObjectType}, - property::{PropertyNameKind}, + builtins::Map, + builtins::map::{add_entries_from_iterable, map_iterator::MapIterator, ordered_map::OrderedMap}, + object::{JsObject, ObjectData, JsObjectType}, + property::PropertyNameKind, Context, JsResult, JsValue }; @@ -19,29 +20,25 @@ impl JsMap { /// Create new Empty Map Object #[inline] pub fn new(context: &mut Context) -> Self { - // Get default Map prototype - let prototype = context.intrinsics().constructors().map().prototype(); - - // Create a default map object with [[MapData]] as a new empty list - let map = JsObject::from_proto_and_data(prototype, ObjectData::map(OrderedMap::new())); - - map + let map = Self::create_map(context); + Self { inner: map } } /// Create a new map object for any object that has a `@@Iterator` field. #[inline] - pub fn from_iterable(iterable: JsObject, context: &mut Context) -> JsResult { + pub fn from_iterable(iterable: &JsValue, context: &mut Context) -> JsResult { // Create a new map - let map = Self::new(); + let map = Self::create_map(context); // Let adder be Get(map, "set") per spec. This action should not fail with default map let adder = map.get("set", context).expect("creating a map with the default prototype must not fail"); - let inner = Map::add_entries_from_iterable(&map, iterable, &adder, context)?; + let iterator_record = add_entries_from_iterable(&map, iterable, &adder, context)?.to_object(context)?; - Ok(Self { inner }) + Ok(Self { inner: iterator_record }) } + /// Create a [`JsMap`] from a [`JsObject`], if the object is not a map, throw a `TypeError`. #[inline] pub fn from_object(object: JsObject, context: &mut Context) -> JsResult { @@ -52,6 +49,17 @@ impl JsMap { } } + // utility function to generate default Map object + fn create_map(context: &mut Context) -> JsObject { + // Get default Map prototype + let prototype = context.intrinsics().constructors().map().prototype(); + + // Create a default map object with [[MapData]] as a new empty list + let map = JsObject::from_proto_and_data(prototype, ObjectData::map(OrderedMap::new())); + + map + } + /// Return a new Iterator object that contains the [key, value] pairs in order of assertion #[inline] pub fn entries(&self, context: &mut Context) -> JsResult { diff --git a/boa_engine/src/object/mod.rs b/boa_engine/src/object/mod.rs index 31e10166a10..66b2ba123bc 100644 --- a/boa_engine/src/object/mod.rs +++ b/boa_engine/src/object/mod.rs @@ -63,6 +63,7 @@ mod tests; pub(crate) mod internal_methods; mod jsarray; mod jsfunction; +mod jsmap; mod jsobject; mod jsproxy; mod jstypedarray; @@ -71,6 +72,7 @@ mod property_map; pub use jsarray::*; pub use jsfunction::*; +pub use jsmap::*; pub use jsproxy::*; pub use jstypedarray::*; diff --git a/boa_examples/src/bin/jsmap.rs b/boa_examples/src/bin/jsmap.rs new file mode 100644 index 00000000000..5494eae6b17 --- /dev/null +++ b/boa_examples/src/bin/jsmap.rs @@ -0,0 +1 @@ +use boa_engine::{object::JsMap, Context, JsResult, JsValue}; From d3f3a61496b960b023548343e05608d4021e3937 Mon Sep 17 00:00:00 2001 From: nekevss Date: Fri, 10 Jun 2022 19:57:52 -0400 Subject: [PATCH 17/41] finished basic outline of JsMap --- boa_engine/src/object/jsmap.rs | 23 ++++++++++++----------- boa_examples/src/bin/jsmap.rs | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs index 570da624baa..ee648ae177b 100644 --- a/boa_engine/src/object/jsmap.rs +++ b/boa_engine/src/object/jsmap.rs @@ -1,10 +1,11 @@ // This module is a wrapper for the Map Builtin Javascript Object - +// +// TODO: improve Iterator object interaction: entries, keys, values +// forEach implementation is missing use crate::{ builtins::Map, - builtins::map::{add_entries_from_iterable, map_iterator::MapIterator, ordered_map::OrderedMap}, + builtins::map::{add_entries_from_iterable, ordered_map::OrderedMap}, object::{JsObject, ObjectData, JsObjectType}, - property::PropertyNameKind, Context, JsResult, JsValue }; @@ -23,19 +24,19 @@ impl JsMap { let map = Self::create_map(context); Self { inner: map } } - + /// Create a new map object for any object that has a `@@Iterator` field. #[inline] - pub fn from_iterable(iterable: &JsValue, context: &mut Context) -> JsResult { + pub fn from_js_iterable(iterable: &JsValue, context: &mut Context) -> JsResult { // Create a new map let map = Self::create_map(context); // Let adder be Get(map, "set") per spec. This action should not fail with default map let adder = map.get("set", context).expect("creating a map with the default prototype must not fail"); - let iterator_record = add_entries_from_iterable(&map, iterable, &adder, context)?.to_object(context)?; + add_entries_from_iterable(&map, iterable, &adder, context)?; - Ok(Self { inner: iterator_record }) + Ok(Self { inner: map }) } @@ -63,13 +64,13 @@ impl JsMap { /// Return a new Iterator object that contains the [key, value] pairs in order of assertion #[inline] pub fn entries(&self, context: &mut Context) -> JsResult { - MapIterator::create_map_iterator(&self.inner.clone().into(), PropertyNameKind::KeyAndValue, context) + Map::entries(&self.inner.clone().into(), &[], context) } /// Return the keys Iterator object #[inline] pub fn keys(&self, context: &mut Context) -> JsResult { - MapIterator::create_map_iterator(&self.inner.clone().into(), PropertyNameKind::Key, context) + Map::keys(&self.inner.clone().into(), &[], context) } /// Insert a new entry into the Map object @@ -96,7 +97,7 @@ impl JsMap { Map::delete(&self.inner.clone().into(), &[key.into()], context) } - /// Returns value associated to key + /// Returns value associated to key or undefined #[inline] pub fn get(&self, key: T, context: &mut Context) -> JsResult where @@ -123,7 +124,7 @@ impl JsMap { /// Returns new Iterator object of value elements of the Map #[inline] pub fn values(&self, context: &mut Context) -> JsResult { - MapIterator::create_map_iterator(&self.inner.clone().into(), PropertyNameKind::Value, context) + Map::values(&self.inner.clone().into(), &[], context) } } diff --git a/boa_examples/src/bin/jsmap.rs b/boa_examples/src/bin/jsmap.rs index 5494eae6b17..d4a42d1da14 100644 --- a/boa_examples/src/bin/jsmap.rs +++ b/boa_examples/src/bin/jsmap.rs @@ -1 +1,32 @@ -use boa_engine::{object::JsMap, Context, JsResult, JsValue}; +use boa_engine::{ + object::JsMap, + Context, JsResult, JsValue +}; + +fn main() -> JsResult<()> { + + let context = &mut Context::default(); + + let map = JsMap::new(context); + + map.set(JsValue::new("Key-1"), JsValue::new("Value-1"), context)?; + + let map_check = map.has(JsValue::new("Key-1"), context)?; + assert_eq!(map_check, JsValue::new(true)); + + map.set(JsValue::new("Key-2"), JsValue::new("Value-2"), context)?; + + assert_eq!(map.get_size(context)?, JsValue::new(2)); + + let current_key_one = map.get(JsValue::new("Key-1"), context)?; + assert_eq!(current_key_one, JsValue::new("Value-1")); + + map.delete(JsValue::new("Key-1"), context)?; + assert_eq!(map.get_size(context)?, JsValue::new(1)); + + let deleted_key_one = map.get(JsValue::new("Key-1"), context)?; + + assert_eq!(deleted_key_one, JsValue::undefined()); + + Ok(()) +} From 6bc353b676f730cb580f84b902d8fadb4a21eed0 Mon Sep 17 00:00:00 2001 From: nekevss Date: Fri, 10 Jun 2022 23:47:34 -0400 Subject: [PATCH 18/41] MapIterator implemented - examples built out --- boa_engine/src/object/jsmap.rs | 71 +++++++++++++++---------- boa_engine/src/object/jsmap_iterator.rs | 51 ++++++++++++++++++ boa_engine/src/object/jsobject.rs | 13 ++++- boa_engine/src/object/mod.rs | 2 + boa_examples/src/bin/jsmap.rs | 34 ++++++++++-- 5 files changed, 137 insertions(+), 34 deletions(-) create mode 100644 boa_engine/src/object/jsmap_iterator.rs diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs index ee648ae177b..113c0a82f0b 100644 --- a/boa_engine/src/object/jsmap.rs +++ b/boa_engine/src/object/jsmap.rs @@ -1,12 +1,12 @@ // This module is a wrapper for the Map Builtin Javascript Object -// -// TODO: improve Iterator object interaction: entries, keys, values +// +// TODO: improve Iterator object interaction: entries, keys, values // forEach implementation is missing use crate::{ - builtins::Map, builtins::map::{add_entries_from_iterable, ordered_map::OrderedMap}, - object::{JsObject, ObjectData, JsObjectType}, - Context, JsResult, JsValue + builtins::Map, + object::{JsMapIterator, JsObject, JsObjectType, ObjectData}, + Context, JsResult, JsValue, }; use boa_gc::{Finalize, Trace}; @@ -24,7 +24,7 @@ impl JsMap { let map = Self::create_map(context); Self { inner: map } } - + /// Create a new map object for any object that has a `@@Iterator` field. #[inline] pub fn from_js_iterable(iterable: &JsValue, context: &mut Context) -> JsResult { @@ -32,54 +32,65 @@ impl JsMap { let map = Self::create_map(context); // Let adder be Get(map, "set") per spec. This action should not fail with default map - let adder = map.get("set", context).expect("creating a map with the default prototype must not fail"); + let adder = map + .get("set", context) + .expect("creating a map with the default prototype must not fail"); add_entries_from_iterable(&map, iterable, &adder, context)?; Ok(Self { inner: map }) } - - /// Create a [`JsMap`] from a [`JsObject`], if the object is not a map, throw a `TypeError`. + /// Create a [`JsMap`] from a [`JsObject`], if the object is not a `Map`, throw a `TypeError`. #[inline] pub fn from_object(object: JsObject, context: &mut Context) -> JsResult { if object.borrow().is_map() { - Ok(Self{ inner: object}) + Ok(Self { inner: object }) } else { context.throw_type_error("object is not a Map") } } - + // utility function to generate default Map object fn create_map(context: &mut Context) -> JsObject { // Get default Map prototype let prototype = context.intrinsics().constructors().map().prototype(); // Create a default map object with [[MapData]] as a new empty list - let map = JsObject::from_proto_and_data(prototype, ObjectData::map(OrderedMap::new())); - - map - } + JsObject::from_proto_and_data(prototype, ObjectData::map(OrderedMap::new())) + } /// Return a new Iterator object that contains the [key, value] pairs in order of assertion #[inline] - pub fn entries(&self, context: &mut Context) -> JsResult { - Map::entries(&self.inner.clone().into(), &[], context) + pub fn entries(&self, context: &mut Context) -> JsResult { + let iterator_record = Map::entries(&self.inner.clone().into(), &[], context)? + .get_iterator(context, None, None)?; + let map_iterator_object = iterator_record + .iterator_object() + .as_object() + .expect("MapIterator for Map.prototype.entries() should not fail"); + JsMapIterator::from_object(map_iterator_object.clone(), context) } /// Return the keys Iterator object #[inline] - pub fn keys(&self, context: &mut Context) -> JsResult { - Map::keys(&self.inner.clone().into(), &[], context) + pub fn keys(&self, context: &mut Context) -> JsResult { + let iterator_record = Map::keys(&self.inner.clone().into(), &[], context)?.get_iterator(context, None, None)?; + let map_iterator_object = iterator_record.iterator_object().as_object().expect("MapIterator for Map.prototype.keys() should not fail"); + JsMapIterator::from_object(map_iterator_object.clone(), context) } /// Insert a new entry into the Map object #[inline] pub fn set(&self, key: T, value: T, context: &mut Context) -> JsResult where - T: Into + T: Into, { - Map::set(&self.inner.clone().into(), &[key.into(), value.into()], context) + Map::set( + &self.inner.clone().into(), + &[key.into(), value.into()], + context, + ) } /// Obtains the size of the map @@ -90,9 +101,9 @@ impl JsMap { /// Remove entry from Map associated with key #[inline] - pub fn delete(&self, key: T, context: &mut Context) -> JsResult + pub fn delete(&self, key: T, context: &mut Context) -> JsResult where - T: Into + T: Into, { Map::delete(&self.inner.clone().into(), &[key.into()], context) } @@ -101,7 +112,7 @@ impl JsMap { #[inline] pub fn get(&self, key: T, context: &mut Context) -> JsResult where - T: Into + T: Into, { Map::get(&self.inner.clone().into(), &[key.into()], context) } @@ -116,15 +127,17 @@ impl JsMap { #[inline] pub fn has(&self, key: T, context: &mut Context) -> JsResult where - T: Into + T: Into, { Map::has(&self.inner.clone().into(), &[key.into()], context) } /// Returns new Iterator object of value elements of the Map #[inline] - pub fn values(&self, context: &mut Context) -> JsResult { - Map::values(&self.inner.clone().into(), &[], context) + pub fn values(&self, context: &mut Context) -> JsResult { + let iterator_record = Map::values(&self.inner.clone().into(), &[], context)?.get_iterator(context, None, None)?; + let map_iterator_object = iterator_record.iterator_object().as_object().expect("MapIterator for Map.prototype.values() should not fail"); + JsMapIterator::from_object(map_iterator_object.clone(), context) } } @@ -144,11 +157,11 @@ impl From for JsValue { impl Deref for JsMap { type Target = JsObject; - + #[inline] fn deref(&self) -> &Self::Target { &self.inner } } -impl JsObjectType for JsMap {} \ No newline at end of file +impl JsObjectType for JsMap {} diff --git a/boa_engine/src/object/jsmap_iterator.rs b/boa_engine/src/object/jsmap_iterator.rs new file mode 100644 index 00000000000..07a2443ed19 --- /dev/null +++ b/boa_engine/src/object/jsmap_iterator.rs @@ -0,0 +1,51 @@ +// API wrapper for MapIterator +use crate::{ + builtins::map::map_iterator::MapIterator, object::JsObject, Context, JsResult, JsValue, +}; + +use boa_gc::{Finalize, Trace}; +use std::ops::Deref; + +#[derive(Debug, Clone, Finalize, Trace)] +pub struct JsMapIterator { + inner: JsObject, +} + +impl JsMapIterator { + /// Create a [`JsMapIterator`] from a [`JsObject`]. If object is not a `MapIterator`, throw `TypeError` + #[inline] + pub fn from_object(object: JsObject, context: &mut Context) -> JsResult { + if object.borrow().is_map_iterator() { + Ok(Self { inner: object }) + } else { + context.throw_type_error("object is not a MapIterator") + } + } + + pub fn next(&self, context: &mut Context) -> JsResult { + MapIterator::next(&self.inner.clone().into(), &[], context) + } +} + +impl From for JsObject { + #[inline] + fn from(o: JsMapIterator) -> Self { + o.inner.clone() + } +} + +impl From for JsValue { + #[inline] + fn from(o: JsMapIterator) -> Self { + o.inner.clone().into() + } +} + +impl Deref for JsMapIterator { + type Target = JsObject; + + #[inline] + fn deref(&self) -> &Self::Target { + &self.inner + } +} diff --git a/boa_engine/src/object/jsobject.rs b/boa_engine/src/object/jsobject.rs index e144897504f..02b2a474254 100644 --- a/boa_engine/src/object/jsobject.rs +++ b/boa_engine/src/object/jsobject.rs @@ -328,7 +328,7 @@ impl JsObject { self.borrow().is_array_buffer() } - /// Checks if it is a `Map` object.pub + /// Checks if it is a `Map` object. /// /// # Panics /// @@ -339,6 +339,17 @@ impl JsObject { self.borrow().is_map() } + /// Checks if it's a `MapIterator` object + /// + /// # Panics + /// + /// Panics if the object is currently mutably borrowed. + #[inline] + #[track_caller] + pub fn is_map_iterator(&self) -> bool { + self.borrow().is_map_iterator() + } + /// Checks if it's a `String` object. /// /// # Panics diff --git a/boa_engine/src/object/mod.rs b/boa_engine/src/object/mod.rs index 66b2ba123bc..9cb1839cdc3 100644 --- a/boa_engine/src/object/mod.rs +++ b/boa_engine/src/object/mod.rs @@ -64,6 +64,7 @@ pub(crate) mod internal_methods; mod jsarray; mod jsfunction; mod jsmap; +mod jsmap_iterator; mod jsobject; mod jsproxy; mod jstypedarray; @@ -73,6 +74,7 @@ mod property_map; pub use jsarray::*; pub use jsfunction::*; pub use jsmap::*; +pub use jsmap_iterator::*; pub use jsproxy::*; pub use jstypedarray::*; diff --git a/boa_examples/src/bin/jsmap.rs b/boa_examples/src/bin/jsmap.rs index d4a42d1da14..6a1a5b7daec 100644 --- a/boa_examples/src/bin/jsmap.rs +++ b/boa_examples/src/bin/jsmap.rs @@ -1,10 +1,9 @@ use boa_engine::{ - object::JsMap, - Context, JsResult, JsValue + object::{JsArray, JsMap}, + Context, JsResult, JsValue, }; fn main() -> JsResult<()> { - let context = &mut Context::default(); let map = JsMap::new(context); @@ -20,7 +19,7 @@ fn main() -> JsResult<()> { let current_key_one = map.get(JsValue::new("Key-1"), context)?; assert_eq!(current_key_one, JsValue::new("Value-1")); - + map.delete(JsValue::new("Key-1"), context)?; assert_eq!(map.get_size(context)?, JsValue::new(1)); @@ -28,5 +27,32 @@ fn main() -> JsResult<()> { assert_eq!(deleted_key_one, JsValue::undefined()); + let entries = map.entries(context)?; + + let _first_value = entries.next(context)?; + + let js_array = JsArray::new(context); + + let vec_one = vec![JsValue::new("first-key"), JsValue::new("first-value")]; + let vec_two = vec![JsValue::new("second-key"), JsValue::new("second-value")]; + + js_array.push(JsArray::from_iter(vec_one, context), context)?; + js_array.push(JsArray::from_iter(vec_two, context), context)?; + + let iter_map = JsMap::from_js_iterable(&js_array.into(), context)?; + + assert_eq!( + iter_map.get(JsValue::new("first-key"), context)?, + "first-value".into() + ); + + iter_map.set( + JsValue::new("third-key"), + JsValue::new("third-value"), + context, + )?; + + assert_eq!(iter_map.get_size(context)?, JsValue::new(3)); + Ok(()) } From 70e029f47359a10b21e403039474e09369ffe35f Mon Sep 17 00:00:00 2001 From: nekevss Date: Sat, 11 Jun 2022 13:01:16 -0400 Subject: [PATCH 19/41] Store add_entries_from_iterable to completion_record variable --- boa_engine/src/object/jsmap.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs index 113c0a82f0b..e903e013ffd 100644 --- a/boa_engine/src/object/jsmap.rs +++ b/boa_engine/src/object/jsmap.rs @@ -36,7 +36,7 @@ impl JsMap { .get("set", context) .expect("creating a map with the default prototype must not fail"); - add_entries_from_iterable(&map, iterable, &adder, context)?; + let _completion_record = add_entries_from_iterable(&map, iterable, &adder, context)?; Ok(Self { inner: map }) } From fcda28fada57555714b5fcf6d30d7a3572f3dce8 Mon Sep 17 00:00:00 2001 From: nekevss Date: Sat, 11 Jun 2022 18:07:52 -0400 Subject: [PATCH 20/41] Add comments to JsMap example --- boa_engine/src/object/jsmap.rs | 16 ++++++++++++---- boa_examples/src/bin/jsmap.rs | 12 ++++++++++-- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs index e903e013ffd..dacdb02cd01 100644 --- a/boa_engine/src/object/jsmap.rs +++ b/boa_engine/src/object/jsmap.rs @@ -75,8 +75,12 @@ impl JsMap { /// Return the keys Iterator object #[inline] pub fn keys(&self, context: &mut Context) -> JsResult { - let iterator_record = Map::keys(&self.inner.clone().into(), &[], context)?.get_iterator(context, None, None)?; - let map_iterator_object = iterator_record.iterator_object().as_object().expect("MapIterator for Map.prototype.keys() should not fail"); + let iterator_record = Map::keys(&self.inner.clone().into(), &[], context)? + .get_iterator(context, None, None)?; + let map_iterator_object = iterator_record + .iterator_object() + .as_object() + .expect("MapIterator for Map.prototype.keys() should not fail"); JsMapIterator::from_object(map_iterator_object.clone(), context) } @@ -135,8 +139,12 @@ impl JsMap { /// Returns new Iterator object of value elements of the Map #[inline] pub fn values(&self, context: &mut Context) -> JsResult { - let iterator_record = Map::values(&self.inner.clone().into(), &[], context)?.get_iterator(context, None, None)?; - let map_iterator_object = iterator_record.iterator_object().as_object().expect("MapIterator for Map.prototype.values() should not fail"); + let iterator_record = Map::values(&self.inner.clone().into(), &[], context)? + .get_iterator(context, None, None)?; + let map_iterator_object = iterator_record + .iterator_object() + .as_object() + .expect("MapIterator for Map.prototype.values() should not fail"); JsMapIterator::from_object(map_iterator_object.clone(), context) } } diff --git a/boa_examples/src/bin/jsmap.rs b/boa_examples/src/bin/jsmap.rs index 6a1a5b7daec..a849fc902b4 100644 --- a/boa_examples/src/bin/jsmap.rs +++ b/boa_examples/src/bin/jsmap.rs @@ -4,22 +4,27 @@ use boa_engine::{ }; fn main() -> JsResult<()> { + // Create a `Context` for the Javascript executor let context = &mut Context::default(); + // Create a new empty map let map = JsMap::new(context); + // Set a key-value for the map map.set(JsValue::new("Key-1"), JsValue::new("Value-1"), context)?; let map_check = map.has(JsValue::new("Key-1"), context)?; - assert_eq!(map_check, JsValue::new(true)); + assert_eq!(map_check, JsValue::new(true)); // true + // Set a second key-value map.set(JsValue::new("Key-2"), JsValue::new("Value-2"), context)?; - assert_eq!(map.get_size(context)?, JsValue::new(2)); + assert_eq!(map.get_size(context)?, JsValue::new(2)); //true let current_key_one = map.get(JsValue::new("Key-1"), context)?; assert_eq!(current_key_one, JsValue::new("Value-1")); + // Delete an entry with the key map.delete(JsValue::new("Key-1"), context)?; assert_eq!(map.get_size(context)?, JsValue::new(1)); @@ -27,10 +32,12 @@ fn main() -> JsResult<()> { assert_eq!(deleted_key_one, JsValue::undefined()); + // Retrieve a MapIterator for all entries in the Map let entries = map.entries(context)?; let _first_value = entries.next(context)?; + // Create a multidimensional array with key value pairs -> [[first-key, first-value], [second-key, second-value]] let js_array = JsArray::new(context); let vec_one = vec![JsValue::new("first-key"), JsValue::new("first-value")]; @@ -39,6 +46,7 @@ fn main() -> JsResult<()> { js_array.push(JsArray::from_iter(vec_one, context), context)?; js_array.push(JsArray::from_iter(vec_two, context), context)?; + // Create a map from the JsArray using it's iterable property let iter_map = JsMap::from_js_iterable(&js_array.into(), context)?; assert_eq!( From 341d65fc723db9392a3f952162b609b5abdd3ebe Mon Sep 17 00:00:00 2001 From: nekevss Date: Tue, 14 Jun 2022 22:25:51 -0400 Subject: [PATCH 21/41] Fix comments for consistency --- boa_engine/src/object/jsmap.rs | 22 +++++++++++----------- boa_examples/src/bin/jsmap.rs | 14 +++++++------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs index dacdb02cd01..6861cbd6bd8 100644 --- a/boa_engine/src/object/jsmap.rs +++ b/boa_engine/src/object/jsmap.rs @@ -18,7 +18,7 @@ pub struct JsMap { } impl JsMap { - /// Create new Empty Map Object + /// Create new Empty Map Object. #[inline] pub fn new(context: &mut Context) -> Self { let map = Self::create_map(context); @@ -28,10 +28,10 @@ impl JsMap { /// Create a new map object for any object that has a `@@Iterator` field. #[inline] pub fn from_js_iterable(iterable: &JsValue, context: &mut Context) -> JsResult { - // Create a new map + // Create a new map object. let map = Self::create_map(context); - // Let adder be Get(map, "set") per spec. This action should not fail with default map + // Let adder be Get(map, "set") per spec. This action should not fail with default map. let adder = map .get("set", context) .expect("creating a map with the default prototype must not fail"); @@ -51,7 +51,7 @@ impl JsMap { } } - // utility function to generate default Map object + // Utility function to generate default Map object. fn create_map(context: &mut Context) -> JsObject { // Get default Map prototype let prototype = context.intrinsics().constructors().map().prototype(); @@ -60,7 +60,7 @@ impl JsMap { JsObject::from_proto_and_data(prototype, ObjectData::map(OrderedMap::new())) } - /// Return a new Iterator object that contains the [key, value] pairs in order of assertion + /// Return a new Iterator object that contains the [key, value] pairs in order of assertion. #[inline] pub fn entries(&self, context: &mut Context) -> JsResult { let iterator_record = Map::entries(&self.inner.clone().into(), &[], context)? @@ -97,13 +97,13 @@ impl JsMap { ) } - /// Obtains the size of the map + /// Obtains the size of the map. #[inline] pub fn get_size(&self, context: &mut Context) -> JsResult { Map::get_size(&self.inner.clone().into(), &[], context) } - /// Remove entry from Map associated with key + /// Remove entry from Map associated with key. #[inline] pub fn delete(&self, key: T, context: &mut Context) -> JsResult where @@ -112,7 +112,7 @@ impl JsMap { Map::delete(&self.inner.clone().into(), &[key.into()], context) } - /// Returns value associated to key or undefined + /// Returns value associated to key or undefined. #[inline] pub fn get(&self, key: T, context: &mut Context) -> JsResult where @@ -121,13 +121,13 @@ impl JsMap { Map::get(&self.inner.clone().into(), &[key.into()], context) } - /// Removes all entries from a map + /// Removes all entries from a map. #[inline] pub fn clear(&self, context: &mut Context) -> JsResult { Map::clear(&self.inner.clone().into(), &[], context) } - /// Checks if map contains provided key + /// Checks if map contains provided key. #[inline] pub fn has(&self, key: T, context: &mut Context) -> JsResult where @@ -136,7 +136,7 @@ impl JsMap { Map::has(&self.inner.clone().into(), &[key.into()], context) } - /// Returns new Iterator object of value elements of the Map + /// Returns new Iterator object of value elements of the Map. #[inline] pub fn values(&self, context: &mut Context) -> JsResult { let iterator_record = Map::values(&self.inner.clone().into(), &[], context)? diff --git a/boa_examples/src/bin/jsmap.rs b/boa_examples/src/bin/jsmap.rs index a849fc902b4..9f4feeb10f6 100644 --- a/boa_examples/src/bin/jsmap.rs +++ b/boa_examples/src/bin/jsmap.rs @@ -4,19 +4,19 @@ use boa_engine::{ }; fn main() -> JsResult<()> { - // Create a `Context` for the Javascript executor + // Create a `Context` for the Javascript executor. let context = &mut Context::default(); - // Create a new empty map + // Create a new empty map. let map = JsMap::new(context); - // Set a key-value for the map + // Set a key-value for the map. map.set(JsValue::new("Key-1"), JsValue::new("Value-1"), context)?; let map_check = map.has(JsValue::new("Key-1"), context)?; assert_eq!(map_check, JsValue::new(true)); // true - // Set a second key-value + // Set a second key-value to the same map. map.set(JsValue::new("Key-2"), JsValue::new("Value-2"), context)?; assert_eq!(map.get_size(context)?, JsValue::new(2)); //true @@ -24,7 +24,7 @@ fn main() -> JsResult<()> { let current_key_one = map.get(JsValue::new("Key-1"), context)?; assert_eq!(current_key_one, JsValue::new("Value-1")); - // Delete an entry with the key + // Delete an entry with a provided key. map.delete(JsValue::new("Key-1"), context)?; assert_eq!(map.get_size(context)?, JsValue::new(1)); @@ -32,7 +32,7 @@ fn main() -> JsResult<()> { assert_eq!(deleted_key_one, JsValue::undefined()); - // Retrieve a MapIterator for all entries in the Map + // Retrieve a MapIterator for all entries in the Map. let entries = map.entries(context)?; let _first_value = entries.next(context)?; @@ -46,7 +46,7 @@ fn main() -> JsResult<()> { js_array.push(JsArray::from_iter(vec_one, context), context)?; js_array.push(JsArray::from_iter(vec_two, context), context)?; - // Create a map from the JsArray using it's iterable property + // Create a map from the JsArray using it's iterable property. let iter_map = JsMap::from_js_iterable(&js_array.into(), context)?; assert_eq!( From 0edd7da206cd467b519bc8cb248ac2b2455c6a07 Mon Sep 17 00:00:00 2001 From: nekevss Date: Tue, 14 Jun 2022 23:45:22 -0400 Subject: [PATCH 22/41] Implement method, update test262 submodule --- boa_engine/src/object/jsmap.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs index 6861cbd6bd8..bc88383e911 100644 --- a/boa_engine/src/object/jsmap.rs +++ b/boa_engine/src/object/jsmap.rs @@ -5,7 +5,7 @@ use crate::{ builtins::map::{add_entries_from_iterable, ordered_map::OrderedMap}, builtins::Map, - object::{JsMapIterator, JsObject, JsObjectType, ObjectData}, + object::{JsFunction, JsMapIterator, JsObject, JsObjectType, ObjectData}, Context, JsResult, JsValue, }; @@ -136,6 +136,21 @@ impl JsMap { Map::has(&self.inner.clone().into(), &[key.into()], context) } + // Executes provided callback function for each key-value pair. + #[inline] + pub fn for_each( + &self, + callback: JsFunction, + this_arg: JsValue, + context: &mut Context, + ) -> JsResult { + Map::for_each( + &self.inner.clone().into(), + &[callback.into(), this_arg], + context, + ) + } + /// Returns new Iterator object of value elements of the Map. #[inline] pub fn values(&self, context: &mut Context) -> JsResult { From 06432af5cc7ae519c7becaa60a1dcc96872d90a4 Mon Sep 17 00:00:00 2001 From: nekevss Date: Wed, 22 Jun 2022 22:48:44 -0400 Subject: [PATCH 23/41] Removed uneeded TODO --- boa_engine/src/object/jsmap.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs index bc88383e911..d8dfa810dbc 100644 --- a/boa_engine/src/object/jsmap.rs +++ b/boa_engine/src/object/jsmap.rs @@ -1,7 +1,4 @@ // This module is a wrapper for the Map Builtin Javascript Object -// -// TODO: improve Iterator object interaction: entries, keys, values -// forEach implementation is missing use crate::{ builtins::map::{add_entries_from_iterable, ordered_map::OrderedMap}, builtins::Map, From 6d3917c3c3bcf973efecffb938349190bdcba6b0 Mon Sep 17 00:00:00 2001 From: nekevss Date: Wed, 22 Jun 2022 23:03:59 -0400 Subject: [PATCH 24/41] Adjust to new method --- boa_engine/src/object/jsmap.rs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs index d8dfa810dbc..0421025461f 100644 --- a/boa_engine/src/object/jsmap.rs +++ b/boa_engine/src/object/jsmap.rs @@ -63,9 +63,7 @@ impl JsMap { let iterator_record = Map::entries(&self.inner.clone().into(), &[], context)? .get_iterator(context, None, None)?; let map_iterator_object = iterator_record - .iterator_object() - .as_object() - .expect("MapIterator for Map.prototype.entries() should not fail"); + .iterator(); JsMapIterator::from_object(map_iterator_object.clone(), context) } @@ -75,9 +73,7 @@ impl JsMap { let iterator_record = Map::keys(&self.inner.clone().into(), &[], context)? .get_iterator(context, None, None)?; let map_iterator_object = iterator_record - .iterator_object() - .as_object() - .expect("MapIterator for Map.prototype.keys() should not fail"); + .iterator(); JsMapIterator::from_object(map_iterator_object.clone(), context) } @@ -154,9 +150,7 @@ impl JsMap { let iterator_record = Map::values(&self.inner.clone().into(), &[], context)? .get_iterator(context, None, None)?; let map_iterator_object = iterator_record - .iterator_object() - .as_object() - .expect("MapIterator for Map.prototype.values() should not fail"); + .iterator(); JsMapIterator::from_object(map_iterator_object.clone(), context) } } From 3129c9ebfa73f797e31970fbb08e09c585a0749f Mon Sep 17 00:00:00 2001 From: nekevss Date: Wed, 22 Jun 2022 23:22:15 -0400 Subject: [PATCH 25/41] alter comment --- boa_engine/src/object/jsmap.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs index 0421025461f..3e6b1169640 100644 --- a/boa_engine/src/object/jsmap.rs +++ b/boa_engine/src/object/jsmap.rs @@ -129,7 +129,7 @@ impl JsMap { Map::has(&self.inner.clone().into(), &[key.into()], context) } - // Executes provided callback function for each key-value pair. + /// Executes provided callback function for each key-value pair. #[inline] pub fn for_each( &self, From 787313dc88736c4b6592156b2d8a7edc2a837f45 Mon Sep 17 00:00:00 2001 From: nekevss Date: Wed, 22 Jun 2022 23:32:26 -0400 Subject: [PATCH 26/41] Run Rust fmt and clippy --- boa_engine/src/object/jsmap.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs index 3e6b1169640..dd3b7031ea2 100644 --- a/boa_engine/src/object/jsmap.rs +++ b/boa_engine/src/object/jsmap.rs @@ -62,8 +62,7 @@ impl JsMap { pub fn entries(&self, context: &mut Context) -> JsResult { let iterator_record = Map::entries(&self.inner.clone().into(), &[], context)? .get_iterator(context, None, None)?; - let map_iterator_object = iterator_record - .iterator(); + let map_iterator_object = iterator_record.iterator(); JsMapIterator::from_object(map_iterator_object.clone(), context) } @@ -72,8 +71,7 @@ impl JsMap { pub fn keys(&self, context: &mut Context) -> JsResult { let iterator_record = Map::keys(&self.inner.clone().into(), &[], context)? .get_iterator(context, None, None)?; - let map_iterator_object = iterator_record - .iterator(); + let map_iterator_object = iterator_record.iterator(); JsMapIterator::from_object(map_iterator_object.clone(), context) } @@ -149,8 +147,7 @@ impl JsMap { pub fn values(&self, context: &mut Context) -> JsResult { let iterator_record = Map::values(&self.inner.clone().into(), &[], context)? .get_iterator(context, None, None)?; - let map_iterator_object = iterator_record - .iterator(); + let map_iterator_object = iterator_record.iterator(); JsMapIterator::from_object(map_iterator_object.clone(), context) } } From 92fd5e43f48054da0e257a482b40241b7e0da2d7 Mon Sep 17 00:00:00 2001 From: nekevss Date: Fri, 1 Jul 2022 16:56:29 -0400 Subject: [PATCH 27/41] Updated and built out comments and documentation --- boa_engine/src/object/jsmap.rs | 173 ++++++++++++++++++++++++++++++--- 1 file changed, 157 insertions(+), 16 deletions(-) diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs index dd3b7031ea2..c41fc3afeef 100644 --- a/boa_engine/src/object/jsmap.rs +++ b/boa_engine/src/object/jsmap.rs @@ -9,20 +9,93 @@ use crate::{ use boa_gc::{Finalize, Trace}; use std::ops::Deref; +/// `JsMap` provides an API wrapper for Boa's implementation of the Javascript `Map` object. +/// +/// # Examples +/// +/// Create a `JsMap` and set a new entry +/// ``` +/// fn main() -> JsResult<()> { +/// // Create default `Context` +/// let context = &mut Context::default(); +/// // Create a new empty `JsMap`. +/// let map = JsMap::new(context); +/// +/// // Set key-value pairs for the `JsMap`. +/// map.set("Key-1", "Value-1", context)?; +/// map.set("Key-2", 10, context)?; +/// +/// assert_eq!(map.get_size(context)?, 2.into()); +/// } +/// ``` +/// +/// Create a `JsMap` from a `JsArray` +/// ``` +/// fn main() -> JsResult<()> { +/// // Create a default `Context` +/// let context = &mut Context::default(); +/// +/// // Create an array of two `[key, value]` pairs +/// let js_array = JsArray::new(context); +/// +/// // Create a `[key, value]` pair of JsValues +/// let vec_one: Vec = vec![JsValue::new("first-key"), JsValue::new("first-value")]; +/// +/// // We create an push our `[key, value]` pair onto our array as a `JsArray` +/// js_array.push(JsArray::from_iter(vec_one, context), context)?; +/// +/// // Create a `JsMap` from the `JsArray` using it's iterable property. +/// let js_iterable_map = JsMap::from_js_iterable(&js_array.into(), context)?; +/// +/// assert_eq!(iter_map.get("first-key", context)?, "first-value".into()); +/// } +/// ``` +/// #[derive(Debug, Clone, Trace, Finalize)] pub struct JsMap { inner: JsObject, } impl JsMap { - /// Create new Empty Map Object. + /// Creates a new empty [`JsMap`] object. + /// + /// # Example + /// + /// ``` + /// fn main -> JsResult<()> { + /// // Create a new context. + /// let context = &mut Context::default(); + /// + /// // Create a new empty `JsMap`. + /// let map = JsMap::new(context); + /// } + /// ``` #[inline] pub fn new(context: &mut Context) -> Self { let map = Self::create_map(context); Self { inner: map } } - /// Create a new map object for any object that has a `@@Iterator` field. + /// Create a new [`JsMap`] object from a [`JsObject`] that has an `@@Iterator` field. + /// + /// # Examples + /// ``` + /// fn main() -> JsResult<()> { + /// // Create a default `Context` + /// let context = &mut Context::default(); + /// + /// // Create an array of two `[key, value]` pairs + /// let js_array = JsArray::new(context); + /// + /// // Create a `[key, value]` pair of JsValues and add it to the `JsArray` as a `JsArray` + /// let vec_one: Vec = vec![JsValue::new("first-key"), JsValue::new("first-value")]; + /// js_array.push(JsArray::from_iter(vec_one, context), context)?; + /// + /// // Create a `JsMap` from the `JsArray` using it's iterable property. + /// let js_iterable_map = JsMap::from_js_iterable(&js_array.into(), context)?; + /// } + /// ``` + /// #[inline] pub fn from_js_iterable(iterable: &JsValue, context: &mut Context) -> JsResult { // Create a new map object. @@ -38,7 +111,7 @@ impl JsMap { Ok(Self { inner: map }) } - /// Create a [`JsMap`] from a [`JsObject`], if the object is not a `Map`, throw a `TypeError`. + /// Creates a [`JsMap`] from a valid [`JsObject`], or returns a `TypeError` if the provided object is not a [`JsMap`] #[inline] pub fn from_object(object: JsObject, context: &mut Context) -> JsResult { if object.borrow().is_map() { @@ -48,7 +121,7 @@ impl JsMap { } } - // Utility function to generate default Map object. + // Utility function to generate the default `Map` object. fn create_map(context: &mut Context) -> JsObject { // Get default Map prototype let prototype = context.intrinsics().constructors().map().prototype(); @@ -57,7 +130,7 @@ impl JsMap { JsObject::from_proto_and_data(prototype, ObjectData::map(OrderedMap::new())) } - /// Return a new Iterator object that contains the [key, value] pairs in order of assertion. + /// Returns a new [`JsMapIterator`] object that yields the `[key, value]` pairs within the [`JsMap`] in insertion order. #[inline] pub fn entries(&self, context: &mut Context) -> JsResult { let iterator_record = Map::entries(&self.inner.clone().into(), &[], context)? @@ -66,7 +139,7 @@ impl JsMap { JsMapIterator::from_object(map_iterator_object.clone(), context) } - /// Return the keys Iterator object + /// Returns a new [`JsMapIterator`] object that yields the `key` for each element within the [`JsMap`] in insertion order. #[inline] pub fn keys(&self, context: &mut Context) -> JsResult { let iterator_record = Map::keys(&self.inner.clone().into(), &[], context)? @@ -75,11 +148,25 @@ impl JsMap { JsMapIterator::from_object(map_iterator_object.clone(), context) } - /// Insert a new entry into the Map object + /// Inserts a new entry into the [`JsMap`] object + /// + /// # Example + /// + /// ``` + /// let map = JsMap::new(context); + /// + /// map.set("foo", "bar", context)?; + /// map.set(2, 4, context)?; + /// + /// assert_eq!(map.get("foo", context)?, "bar".into()); + /// assert_eq!(map.get(2, context)?, 4.into()) + /// + /// ``` #[inline] - pub fn set(&self, key: T, value: T, context: &mut Context) -> JsResult + pub fn set(&self, key: K, value: V, context: &mut Context) -> JsResult where - T: Into, + K: Into, + V: Into, { Map::set( &self.inner.clone().into(), @@ -88,13 +175,37 @@ impl JsMap { ) } - /// Obtains the size of the map. + /// Gets the size of the [`JsMap`] object. + /// + /// # Example + /// + /// ``` + /// let map = JsMap::new(context); + /// + /// map.set("foo", "bar", context)?; + /// + /// let map_size = map.get_size(context)?; + /// + /// assert_eq!(map_size, 1.into()); + /// ``` #[inline] pub fn get_size(&self, context: &mut Context) -> JsResult { Map::get_size(&self.inner.clone().into(), &[], context) } - /// Remove entry from Map associated with key. + /// Removes element from [`JsMap`] with a matching `key` value. + /// + /// # Example + /// + /// ``` + /// js_map.set("foo", "bar", context)?; + /// js_map.set("hello", world, context)?; + /// + /// js_map.delete("foo", context)?; + /// + /// assert_eq!(js_map.get_size(context)?, 1.into()); + /// assert_eq!(js_map.get("foo", context)?, JsValue::undefined()); + /// ``` #[inline] pub fn delete(&self, key: T, context: &mut Context) -> JsResult where @@ -103,7 +214,17 @@ impl JsMap { Map::delete(&self.inner.clone().into(), &[key.into()], context) } - /// Returns value associated to key or undefined. + /// Gets the value associated with the specified key within the [`JsMap`], or `undefined` if the key does not exist. + /// + /// # Example + /// + /// ``` + /// js_map.set("foo", "bar", context)?; + /// + /// let retrieved_value = js_map.get("foo", context)?; + /// + /// assert_eq!(retrieved_value, "bar".into()); + /// ``` #[inline] pub fn get(&self, key: T, context: &mut Context) -> JsResult where @@ -112,13 +233,33 @@ impl JsMap { Map::get(&self.inner.clone().into(), &[key.into()], context) } - /// Removes all entries from a map. + /// Removes all entries from the [`JsMap`]. + /// + /// # Example + /// + /// ``` + /// js_map.set("foo", "bar", context)?; + /// js_map.set("hello", world, context)?; + /// + /// js_map.clear(context)?; + /// + /// assert_eq!(js_map.get_size(context)?, 0.into()); #[inline] pub fn clear(&self, context: &mut Context) -> JsResult { Map::clear(&self.inner.clone().into(), &[], context) } - /// Checks if map contains provided key. + /// Checks if [`JsMap`] has an entry with the provided `key` value. + /// + /// # Example + /// + /// ``` + /// js_map.set("foo", "bar", context)?; + /// + /// let has_key = js_map.has("foo", context)?; + /// + /// assert_eq!(has_key, true.into()); + /// ``` #[inline] pub fn has(&self, key: T, context: &mut Context) -> JsResult where @@ -127,7 +268,7 @@ impl JsMap { Map::has(&self.inner.clone().into(), &[key.into()], context) } - /// Executes provided callback function for each key-value pair. + /// Executes the provided callback function for each key-value pair within the [`JsMap`]. #[inline] pub fn for_each( &self, @@ -142,7 +283,7 @@ impl JsMap { ) } - /// Returns new Iterator object of value elements of the Map. + /// Returns a new [`JsMapIterator`] object that yields the `value` for each element within the [`JsMap`] in insertion order. #[inline] pub fn values(&self, context: &mut Context) -> JsResult { let iterator_record = Map::values(&self.inner.clone().into(), &[], context)? From 4d2f66dc9fab59cfe1dbc378e57328a12df77f71 Mon Sep 17 00:00:00 2001 From: nekevss Date: Fri, 1 Jul 2022 16:57:41 -0400 Subject: [PATCH 28/41] Remove overused --- boa_examples/src/bin/jsmap.rs | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/boa_examples/src/bin/jsmap.rs b/boa_examples/src/bin/jsmap.rs index 9f4feeb10f6..df18bebb7dc 100644 --- a/boa_examples/src/bin/jsmap.rs +++ b/boa_examples/src/bin/jsmap.rs @@ -11,24 +11,23 @@ fn main() -> JsResult<()> { let map = JsMap::new(context); // Set a key-value for the map. - map.set(JsValue::new("Key-1"), JsValue::new("Value-1"), context)?; + map.set("Key-1", "Value-1", context)?; - let map_check = map.has(JsValue::new("Key-1"), context)?; - assert_eq!(map_check, JsValue::new(true)); // true + let map_check = map.has("Key-1", context)?; + assert_eq!(map_check, true.into()); // true // Set a second key-value to the same map. - map.set(JsValue::new("Key-2"), JsValue::new("Value-2"), context)?; + map.set(2, 4, context)?; - assert_eq!(map.get_size(context)?, JsValue::new(2)); //true - - let current_key_one = map.get(JsValue::new("Key-1"), context)?; - assert_eq!(current_key_one, JsValue::new("Value-1")); + assert_eq!(map.get_size(context)?, 2.into()); //true + assert_eq!(map.get("Key-1", context)?, "Value-1".into()); + assert_eq!(map.get(2, context)?, 4.into()); // Delete an entry with a provided key. - map.delete(JsValue::new("Key-1"), context)?; - assert_eq!(map.get_size(context)?, JsValue::new(1)); + map.delete("Key-1", context)?; + assert_eq!(map.get_size(context)?, 1.into()); - let deleted_key_one = map.get(JsValue::new("Key-1"), context)?; + let deleted_key_one = map.get("Key-1", context)?; assert_eq!(deleted_key_one, JsValue::undefined()); @@ -49,16 +48,9 @@ fn main() -> JsResult<()> { // Create a map from the JsArray using it's iterable property. let iter_map = JsMap::from_js_iterable(&js_array.into(), context)?; - assert_eq!( - iter_map.get(JsValue::new("first-key"), context)?, - "first-value".into() - ); + assert_eq!(iter_map.get("first-key", context)?, "first-value".into()); - iter_map.set( - JsValue::new("third-key"), - JsValue::new("third-value"), - context, - )?; + iter_map.set("third-key", "third-value", context)?; assert_eq!(iter_map.get_size(context)?, JsValue::new(3)); From 3334d48748cf88dc5393e026f9766bca30cec607 Mon Sep 17 00:00:00 2001 From: nekevss Date: Fri, 1 Jul 2022 22:37:15 -0400 Subject: [PATCH 29/41] Add to comment and clean up --- boa_engine/src/object/jsmap.rs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs index c41fc3afeef..730f1635ef6 100644 --- a/boa_engine/src/object/jsmap.rs +++ b/boa_engine/src/object/jsmap.rs @@ -26,6 +26,8 @@ use std::ops::Deref; /// map.set("Key-2", 10, context)?; /// /// assert_eq!(map.get_size(context)?, 2.into()); +/// +/// Ok(()) /// } /// ``` /// @@ -48,6 +50,8 @@ use std::ops::Deref; /// let js_iterable_map = JsMap::from_js_iterable(&js_array.into(), context)?; /// /// assert_eq!(iter_map.get("first-key", context)?, "first-value".into()); +/// +/// Ok(()) /// } /// ``` /// @@ -112,6 +116,27 @@ impl JsMap { } /// Creates a [`JsMap`] from a valid [`JsObject`], or returns a `TypeError` if the provided object is not a [`JsMap`] + /// + /// # Examples + /// + /// Valid Example - returns JsMap object + /// ``` + /// // `some_object` can be any JavaScript `Map` object. + /// let some_object = JsObject::from_proto_and_data( + /// context.intrinsics().constructors().map().prototype(), + /// ObjectData::map(Ordered::new()) + /// ); + /// + /// // Create `JsMap` object with incoming object. + /// let js_map = JsMap::from_object(some_object, context)?; + /// ``` + /// + /// Invalid Example - returns `TypeError` with the message "object is not a Map" + /// ``` + /// let some_object = JsArray::new(context); + /// + /// let js_map = JsMap::from_object(some_object, context)?; + /// ``` #[inline] pub fn from_object(object: JsObject, context: &mut Context) -> JsResult { if object.borrow().is_map() { From f300ba78e4a16be9d0ab74294fed50ed23a5fc53 Mon Sep 17 00:00:00 2001 From: nekevss Date: Fri, 1 Jul 2022 23:30:32 -0400 Subject: [PATCH 30/41] finish comments on all files --- boa_engine/src/object/jsmap.rs | 73 ++----------------------- boa_engine/src/object/jsmap_iterator.rs | 10 +++- boa_examples/src/bin/jsmap.rs | 34 ------------ 3 files changed, 13 insertions(+), 104 deletions(-) diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs index 38eed7c7caf..8363b57b23b 100644 --- a/boa_engine/src/object/jsmap.rs +++ b/boa_engine/src/object/jsmap.rs @@ -1,4 +1,4 @@ -// This module is a wrapper for the Map Builtin Javascript Object +//! This module implements a wrapper for the Map Builtin Javascript Object use crate::{ builtins::map::{add_entries_from_iterable, ordered_map::OrderedMap}, builtins::Map, @@ -9,7 +9,6 @@ use crate::{ use boa_gc::{Finalize, Trace}; use std::ops::Deref; -<<<<<<< HEAD /// `JsMap` provides an API wrapper for Boa's implementation of the Javascript `Map` object. /// /// # Examples @@ -56,15 +55,12 @@ use std::ops::Deref; /// } /// ``` /// -======= ->>>>>>> 787313dc88736c4b6592156b2d8a7edc2a837f45 #[derive(Debug, Clone, Trace, Finalize)] pub struct JsMap { inner: JsObject, } impl JsMap { -<<<<<<< HEAD /// Creates a new empty [`JsMap`] object. /// /// # Example @@ -78,16 +74,12 @@ impl JsMap { /// let map = JsMap::new(context); /// } /// ``` -======= - /// Create new Empty Map Object. ->>>>>>> 787313dc88736c4b6592156b2d8a7edc2a837f45 #[inline] pub fn new(context: &mut Context) -> Self { let map = Self::create_map(context); Self { inner: map } } -<<<<<<< HEAD /// Create a new [`JsMap`] object from a [`JsObject`] that has an `@@Iterator` field. /// /// # Examples @@ -108,9 +100,6 @@ impl JsMap { /// } /// ``` /// -======= - /// Create a new map object for any object that has a `@@Iterator` field. ->>>>>>> 787313dc88736c4b6592156b2d8a7edc2a837f45 #[inline] pub fn from_js_iterable(iterable: &JsValue, context: &mut Context) -> JsResult { // Create a new map object. @@ -126,12 +115,11 @@ impl JsMap { Ok(Self { inner: map }) } -<<<<<<< HEAD /// Creates a [`JsMap`] from a valid [`JsObject`], or returns a `TypeError` if the provided object is not a [`JsMap`] /// /// # Examples /// - /// Valid Example - returns JsMap object + /// Valid Example - returns a `JsMap` object /// ``` /// // `some_object` can be any JavaScript `Map` object. /// let some_object = JsObject::from_proto_and_data( @@ -142,16 +130,13 @@ impl JsMap { /// // Create `JsMap` object with incoming object. /// let js_map = JsMap::from_object(some_object, context)?; /// ``` - /// - /// Invalid Example - returns `TypeError` with the message "object is not a Map" + /// + /// Invalid Example - returns a `TypeError` with the message "object is not a Map" /// ``` /// let some_object = JsArray::new(context); - /// + /// /// let js_map = JsMap::from_object(some_object, context)?; /// ``` -======= - /// Create a [`JsMap`] from a [`JsObject`], if the object is not a `Map`, throw a `TypeError`. ->>>>>>> 787313dc88736c4b6592156b2d8a7edc2a837f45 #[inline] pub fn from_object(object: JsObject, context: &mut Context) -> JsResult { if object.borrow().is_map() { @@ -161,11 +146,7 @@ impl JsMap { } } -<<<<<<< HEAD // Utility function to generate the default `Map` object. -======= - // Utility function to generate default Map object. ->>>>>>> 787313dc88736c4b6592156b2d8a7edc2a837f45 fn create_map(context: &mut Context) -> JsObject { // Get default Map prototype let prototype = context.intrinsics().constructors().map().prototype(); @@ -174,11 +155,7 @@ impl JsMap { JsObject::from_proto_and_data(prototype, ObjectData::map(OrderedMap::new())) } -<<<<<<< HEAD /// Returns a new [`JsMapIterator`] object that yields the `[key, value]` pairs within the [`JsMap`] in insertion order. -======= - /// Return a new Iterator object that contains the [key, value] pairs in order of assertion. ->>>>>>> 787313dc88736c4b6592156b2d8a7edc2a837f45 #[inline] pub fn entries(&self, context: &mut Context) -> JsResult { let iterator_record = Map::entries(&self.inner.clone().into(), &[], context)? @@ -187,11 +164,7 @@ impl JsMap { JsMapIterator::from_object(map_iterator_object.clone(), context) } -<<<<<<< HEAD /// Returns a new [`JsMapIterator`] object that yields the `key` for each element within the [`JsMap`] in insertion order. -======= - /// Return the keys Iterator object ->>>>>>> 787313dc88736c4b6592156b2d8a7edc2a837f45 #[inline] pub fn keys(&self, context: &mut Context) -> JsResult { let iterator_record = Map::keys(&self.inner.clone().into(), &[], context)? @@ -200,7 +173,6 @@ impl JsMap { JsMapIterator::from_object(map_iterator_object.clone(), context) } -<<<<<<< HEAD /// Inserts a new entry into the [`JsMap`] object /// /// # Example @@ -220,13 +192,6 @@ impl JsMap { where K: Into, V: Into, -======= - /// Insert a new entry into the Map object - #[inline] - pub fn set(&self, key: T, value: T, context: &mut Context) -> JsResult - where - T: Into, ->>>>>>> 787313dc88736c4b6592156b2d8a7edc2a837f45 { Map::set( &self.inner.clone().into(), @@ -235,7 +200,6 @@ impl JsMap { ) } -<<<<<<< HEAD /// Gets the size of the [`JsMap`] object. /// /// # Example @@ -249,15 +213,11 @@ impl JsMap { /// /// assert_eq!(map_size, 1.into()); /// ``` -======= - /// Obtains the size of the map. ->>>>>>> 787313dc88736c4b6592156b2d8a7edc2a837f45 #[inline] pub fn get_size(&self, context: &mut Context) -> JsResult { Map::get_size(&self.inner.clone().into(), &[], context) } -<<<<<<< HEAD /// Removes element from [`JsMap`] with a matching `key` value. /// /// # Example @@ -271,9 +231,6 @@ impl JsMap { /// assert_eq!(js_map.get_size(context)?, 1.into()); /// assert_eq!(js_map.get("foo", context)?, JsValue::undefined()); /// ``` -======= - /// Remove entry from Map associated with key. ->>>>>>> 787313dc88736c4b6592156b2d8a7edc2a837f45 #[inline] pub fn delete(&self, key: T, context: &mut Context) -> JsResult where @@ -282,7 +239,6 @@ impl JsMap { Map::delete(&self.inner.clone().into(), &[key.into()], context) } -<<<<<<< HEAD /// Gets the value associated with the specified key within the [`JsMap`], or `undefined` if the key does not exist. /// /// # Example @@ -294,9 +250,6 @@ impl JsMap { /// /// assert_eq!(retrieved_value, "bar".into()); /// ``` -======= - /// Returns value associated to key or undefined. ->>>>>>> 787313dc88736c4b6592156b2d8a7edc2a837f45 #[inline] pub fn get(&self, key: T, context: &mut Context) -> JsResult where @@ -305,7 +258,6 @@ impl JsMap { Map::get(&self.inner.clone().into(), &[key.into()], context) } -<<<<<<< HEAD /// Removes all entries from the [`JsMap`]. /// /// # Example @@ -317,15 +269,11 @@ impl JsMap { /// js_map.clear(context)?; /// /// assert_eq!(js_map.get_size(context)?, 0.into()); -======= - /// Removes all entries from a map. ->>>>>>> 787313dc88736c4b6592156b2d8a7edc2a837f45 #[inline] pub fn clear(&self, context: &mut Context) -> JsResult { Map::clear(&self.inner.clone().into(), &[], context) } -<<<<<<< HEAD /// Checks if [`JsMap`] has an entry with the provided `key` value. /// /// # Example @@ -337,9 +285,6 @@ impl JsMap { /// /// assert_eq!(has_key, true.into()); /// ``` -======= - /// Checks if map contains provided key. ->>>>>>> 787313dc88736c4b6592156b2d8a7edc2a837f45 #[inline] pub fn has(&self, key: T, context: &mut Context) -> JsResult where @@ -348,11 +293,7 @@ impl JsMap { Map::has(&self.inner.clone().into(), &[key.into()], context) } -<<<<<<< HEAD /// Executes the provided callback function for each key-value pair within the [`JsMap`]. -======= - /// Executes provided callback function for each key-value pair. ->>>>>>> 787313dc88736c4b6592156b2d8a7edc2a837f45 #[inline] pub fn for_each( &self, @@ -367,11 +308,7 @@ impl JsMap { ) } -<<<<<<< HEAD /// Returns a new [`JsMapIterator`] object that yields the `value` for each element within the [`JsMap`] in insertion order. -======= - /// Returns new Iterator object of value elements of the Map. ->>>>>>> 787313dc88736c4b6592156b2d8a7edc2a837f45 #[inline] pub fn values(&self, context: &mut Context) -> JsResult { let iterator_record = Map::values(&self.inner.clone().into(), &[], context)? diff --git a/boa_engine/src/object/jsmap_iterator.rs b/boa_engine/src/object/jsmap_iterator.rs index 07a2443ed19..ae19562cc2d 100644 --- a/boa_engine/src/object/jsmap_iterator.rs +++ b/boa_engine/src/object/jsmap_iterator.rs @@ -1,11 +1,14 @@ -// API wrapper for MapIterator +//! This module implements a wrapper for the `MapIterator` object use crate::{ - builtins::map::map_iterator::MapIterator, object::JsObject, Context, JsResult, JsValue, + builtins::map::map_iterator::MapIterator, + object::{JsObject, JsObjectType}, + Context, JsResult, JsValue, }; use boa_gc::{Finalize, Trace}; use std::ops::Deref; +/// JavaScript `MapIterator` rust object #[derive(Debug, Clone, Finalize, Trace)] pub struct JsMapIterator { inner: JsObject, @@ -22,6 +25,7 @@ impl JsMapIterator { } } + /// Advances the `JsMapIterator` and gets the next result in the `JsMap` pub fn next(&self, context: &mut Context) -> JsResult { MapIterator::next(&self.inner.clone().into(), &[], context) } @@ -49,3 +53,5 @@ impl Deref for JsMapIterator { &self.inner } } + +impl JsObjectType for JsMapIterator {} diff --git a/boa_examples/src/bin/jsmap.rs b/boa_examples/src/bin/jsmap.rs index 31bee5978e0..df18bebb7dc 100644 --- a/boa_examples/src/bin/jsmap.rs +++ b/boa_examples/src/bin/jsmap.rs @@ -11,7 +11,6 @@ fn main() -> JsResult<()> { let map = JsMap::new(context); // Set a key-value for the map. -<<<<<<< HEAD map.set("Key-1", "Value-1", context)?; let map_check = map.has("Key-1", context)?; @@ -29,26 +28,6 @@ fn main() -> JsResult<()> { assert_eq!(map.get_size(context)?, 1.into()); let deleted_key_one = map.get("Key-1", context)?; -======= - map.set(JsValue::new("Key-1"), JsValue::new("Value-1"), context)?; - - let map_check = map.has(JsValue::new("Key-1"), context)?; - assert_eq!(map_check, JsValue::new(true)); // true - - // Set a second key-value to the same map. - map.set(JsValue::new("Key-2"), JsValue::new("Value-2"), context)?; - - assert_eq!(map.get_size(context)?, JsValue::new(2)); //true - - let current_key_one = map.get(JsValue::new("Key-1"), context)?; - assert_eq!(current_key_one, JsValue::new("Value-1")); - - // Delete an entry with a provided key. - map.delete(JsValue::new("Key-1"), context)?; - assert_eq!(map.get_size(context)?, JsValue::new(1)); - - let deleted_key_one = map.get(JsValue::new("Key-1"), context)?; ->>>>>>> 787313dc88736c4b6592156b2d8a7edc2a837f45 assert_eq!(deleted_key_one, JsValue::undefined()); @@ -69,22 +48,9 @@ fn main() -> JsResult<()> { // Create a map from the JsArray using it's iterable property. let iter_map = JsMap::from_js_iterable(&js_array.into(), context)?; -<<<<<<< HEAD assert_eq!(iter_map.get("first-key", context)?, "first-value".into()); iter_map.set("third-key", "third-value", context)?; -======= - assert_eq!( - iter_map.get(JsValue::new("first-key"), context)?, - "first-value".into() - ); - - iter_map.set( - JsValue::new("third-key"), - JsValue::new("third-value"), - context, - )?; ->>>>>>> 787313dc88736c4b6592156b2d8a7edc2a837f45 assert_eq!(iter_map.get_size(context)?, JsValue::new(3)); From d51727ff1f8fc0acee2002100fdc18108fa1898d Mon Sep 17 00:00:00 2001 From: nekevss Date: Fri, 1 Jul 2022 23:32:08 -0400 Subject: [PATCH 31/41] Fix header line of --- boa_engine/src/object/jsmap.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs index 8363b57b23b..d2eea0ac04e 100644 --- a/boa_engine/src/object/jsmap.rs +++ b/boa_engine/src/object/jsmap.rs @@ -9,7 +9,7 @@ use crate::{ use boa_gc::{Finalize, Trace}; use std::ops::Deref; -/// `JsMap` provides an API wrapper for Boa's implementation of the Javascript `Map` object. +/// `JsMap` provides a wrapper for Boa's implementation of the Javascript `Map` object. /// /// # Examples /// From cb248f67c1910ba13ae2ed8c252e23b934eae89d Mon Sep 17 00:00:00 2001 From: nekevss Date: Sat, 2 Jul 2022 00:58:31 -0400 Subject: [PATCH 32/41] Add main functions and module imports to example documentation --- boa_engine/src/object/jsmap.rs | 139 ++++++++++++++++++++++++++++++--- 1 file changed, 129 insertions(+), 10 deletions(-) diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs index d2eea0ac04e..bfa42e26853 100644 --- a/boa_engine/src/object/jsmap.rs +++ b/boa_engine/src/object/jsmap.rs @@ -15,6 +15,11 @@ use std::ops::Deref; /// /// Create a `JsMap` and set a new entry /// ``` +/// use boa_engine::{ +/// object::JsMap, +/// Context, JsResult, JsValue, +/// }; +/// /// fn main() -> JsResult<()> { /// // Create default `Context` /// let context = &mut Context::default(); @@ -33,6 +38,11 @@ use std::ops::Deref; /// /// Create a `JsMap` from a `JsArray` /// ``` +/// use boa_engine::{ +/// object::{JsArray, JsMap}, +/// Context, JsResult, JsValue, +/// }; +/// /// fn main() -> JsResult<()> { /// // Create a default `Context` /// let context = &mut Context::default(); @@ -66,12 +76,19 @@ impl JsMap { /// # Example /// /// ``` + /// use boa_engine::{ + /// object::JsMap, + /// Context, JsResult, JsValue, + /// }; + /// /// fn main -> JsResult<()> { /// // Create a new context. /// let context = &mut Context::default(); /// /// // Create a new empty `JsMap`. /// let map = JsMap::new(context); + /// + /// Ok(()) /// } /// ``` #[inline] @@ -84,6 +101,11 @@ impl JsMap { /// /// # Examples /// ``` + /// use boa_engine::{ + /// object::{JsArray, JsMap}, + /// Context, JsResult, JsValue, + /// }; + /// /// fn main() -> JsResult<()> { /// // Create a default `Context` /// let context = &mut Context::default(); @@ -97,6 +119,8 @@ impl JsMap { /// /// // Create a `JsMap` from the `JsArray` using it's iterable property. /// let js_iterable_map = JsMap::from_js_iterable(&js_array.into(), context)?; + /// + /// Ok(()) /// } /// ``` /// @@ -121,21 +145,44 @@ impl JsMap { /// /// Valid Example - returns a `JsMap` object /// ``` + /// use boa_engine::{ + /// builtins::map::ordered_map::OrderedMap, + /// object::{JsObject, ObjectData, JsMap}, + /// Context, JsResult, JsValue, + /// }; + /// + /// fn main() -> JsResult<()> { + /// let context = Context::default(); + /// /// // `some_object` can be any JavaScript `Map` object. /// let some_object = JsObject::from_proto_and_data( /// context.intrinsics().constructors().map().prototype(), - /// ObjectData::map(Ordered::new()) + /// ObjectData::map(OrderedMap::new()) /// ); /// /// // Create `JsMap` object with incoming object. /// let js_map = JsMap::from_object(some_object, context)?; + /// + /// Ok(()) + /// } /// ``` /// /// Invalid Example - returns a `TypeError` with the message "object is not a Map" /// ``` + /// use boa_engine::{ + /// object::{JsObject, JsArray, JsMap}, + /// Context, JsResult, JsValue, + /// }; + /// + /// fn main() -> JsResult<()> { + /// let context = Context::default(); + /// /// let some_object = JsArray::new(context); /// - /// let js_map = JsMap::from_object(some_object, context)?; + /// let js_map = JsMap::from_object(some_object, context)?; /// + /// + /// Ok(()) + /// } /// ``` #[inline] pub fn from_object(object: JsObject, context: &mut Context) -> JsResult { @@ -178,13 +225,25 @@ impl JsMap { /// # Example /// /// ``` - /// let map = JsMap::new(context); + /// use boa_engine::{ + /// object::JsMap, + /// Context, JsResult, JsValue, + /// }; /// - /// map.set("foo", "bar", context)?; - /// map.set(2, 4, context)?; + /// fn main() -> JsResult<()> { + /// let context = Context::default(); + /// + /// let js_map = JsMap::new(context); /// - /// assert_eq!(map.get("foo", context)?, "bar".into()); - /// assert_eq!(map.get(2, context)?, 4.into()) + /// js_map.set("foo", "bar", context)?; + /// js_map.set(2, 4, context)?; + /// + /// assert_eq!(js_map.get("foo", context)?, "bar".into()); + /// assert_eq!(js_map.get(2, context)?, 4.into()) + /// + /// Ok(()) + /// } + /// /// ``` #[inline] @@ -205,13 +264,24 @@ impl JsMap { /// # Example /// /// ``` - /// let map = JsMap::new(context); + /// use boa_engine::{ + /// object::JsMap, + /// Context, JsResult, JsValue, + /// }; /// - /// map.set("foo", "bar", context)?; + /// fn main() -> JsResult<()> { + /// let context = Context::default(); /// - /// let map_size = map.get_size(context)?; + /// let js_map = JsMap::new(context); + /// + /// js_map.set("foo", "bar", context)?; + /// + /// let map_size = js_map.get_size(context)?; /// /// assert_eq!(map_size, 1.into()); + /// + /// Ok(()) + /// } /// ``` #[inline] pub fn get_size(&self, context: &mut Context) -> JsResult { @@ -223,6 +293,15 @@ impl JsMap { /// # Example /// /// ``` + /// use boa_engine::{ + /// object::JsMap, + /// Context, JsResult, JsValue, + /// }; + /// + /// fn main() -> JsResult<()> { + /// let context = Context::default(); + /// + /// let js_map = JsMap::new(context); /// js_map.set("foo", "bar", context)?; /// js_map.set("hello", world, context)?; /// @@ -230,6 +309,9 @@ impl JsMap { /// /// assert_eq!(js_map.get_size(context)?, 1.into()); /// assert_eq!(js_map.get("foo", context)?, JsValue::undefined()); + /// + /// Ok(()) + /// } /// ``` #[inline] pub fn delete(&self, key: T, context: &mut Context) -> JsResult @@ -244,11 +326,23 @@ impl JsMap { /// # Example /// /// ``` + /// use boa_engine::{ + /// object::JsMap, + /// Context, JsResult, JsValue, + /// }; + /// + /// fn main() -> JsResult<()> { + /// let context = Context::default(); + + /// let js_map = JsMap::new(context); /// js_map.set("foo", "bar", context)?; /// /// let retrieved_value = js_map.get("foo", context)?; /// /// assert_eq!(retrieved_value, "bar".into()); + /// + /// Ok(()) + /// } /// ``` #[inline] pub fn get(&self, key: T, context: &mut Context) -> JsResult @@ -263,12 +357,25 @@ impl JsMap { /// # Example /// /// ``` + /// use boa_engine::{ + /// object::JsMap, + /// Context, JsResult, JsValue, + /// }; + /// + /// fn main() -> JsResult<()> { + /// let context = Context::default(); + /// + /// let js_map = JsMap::new(context); /// js_map.set("foo", "bar", context)?; /// js_map.set("hello", world, context)?; /// /// js_map.clear(context)?; /// /// assert_eq!(js_map.get_size(context)?, 0.into()); + /// + /// Ok(()) + /// } + /// ``` #[inline] pub fn clear(&self, context: &mut Context) -> JsResult { Map::clear(&self.inner.clone().into(), &[], context) @@ -279,11 +386,23 @@ impl JsMap { /// # Example /// /// ``` + /// use boa_engine::{ + /// object::JsMap, + /// Context, JsResult, JsValue, + /// }; + /// + /// fn main() -> JsResult<()> { + /// let context = Context::default(); + /// + /// let js_map = JsMap::new(context); /// js_map.set("foo", "bar", context)?; /// /// let has_key = js_map.has("foo", context)?; /// /// assert_eq!(has_key, true.into()); + /// + /// Ok(()) + /// } /// ``` #[inline] pub fn has(&self, key: T, context: &mut Context) -> JsResult From 028f08c8b2e1320137f43fd5c2ef9b249d52e8f2 Mon Sep 17 00:00:00 2001 From: nekevss Date: Sat, 2 Jul 2022 01:18:53 -0400 Subject: [PATCH 33/41] remove main/JsResult functions, add 's where needed --- boa_engine/src/object/jsmap.rs | 214 ++++++++++++++------------------- 1 file changed, 88 insertions(+), 126 deletions(-) diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs index bfa42e26853..caae4427b76 100644 --- a/boa_engine/src/object/jsmap.rs +++ b/boa_engine/src/object/jsmap.rs @@ -17,52 +17,47 @@ use std::ops::Deref; /// ``` /// use boa_engine::{ /// object::JsMap, -/// Context, JsResult, JsValue, +/// Context, JsValue, /// }; /// -/// fn main() -> JsResult<()> { -/// // Create default `Context` -/// let context = &mut Context::default(); -/// // Create a new empty `JsMap`. -/// let map = JsMap::new(context); +/// // Create default `Context` +/// let context = &mut Context::default(); /// -/// // Set key-value pairs for the `JsMap`. -/// map.set("Key-1", "Value-1", context)?; -/// map.set("Key-2", 10, context)?; +/// // Create a new empty `JsMap`. +/// let map = JsMap::new(context); /// -/// assert_eq!(map.get_size(context)?, 2.into()); +/// // Set key-value pairs for the `JsMap`. +/// map.set("Key-1", "Value-1", context).unwrap(); +/// map.set("Key-2", 10, context).unwrap(); +/// +/// assert_eq!(map.get_size(context).unwrap(), 2.into()); /// -/// Ok(()) -/// } /// ``` /// /// Create a `JsMap` from a `JsArray` /// ``` /// use boa_engine::{ /// object::{JsArray, JsMap}, -/// Context, JsResult, JsValue, +/// Context, JsValue, /// }; /// -/// fn main() -> JsResult<()> { -/// // Create a default `Context` -/// let context = &mut Context::default(); +/// // Create a default `Context` +/// let context = &mut Context::default(); /// -/// // Create an array of two `[key, value]` pairs -/// let js_array = JsArray::new(context); +/// // Create an array of two `[key, value]` pairs +/// let js_array = JsArray::new(context); /// -/// // Create a `[key, value]` pair of JsValues -/// let vec_one: Vec = vec![JsValue::new("first-key"), JsValue::new("first-value")]; +/// // Create a `[key, value]` pair of JsValues +/// let vec_one: Vec = vec![JsValue::new("first-key"), JsValue::new("first-value")]; /// -/// // We create an push our `[key, value]` pair onto our array as a `JsArray` -/// js_array.push(JsArray::from_iter(vec_one, context), context)?; +/// // We create an push our `[key, value]` pair onto our array as a `JsArray` +/// js_array.push(JsArray::from_iter(vec_one, context), context).unwrap(); /// -/// // Create a `JsMap` from the `JsArray` using it's iterable property. -/// let js_iterable_map = JsMap::from_js_iterable(&js_array.into(), context)?; +/// // Create a `JsMap` from the `JsArray` using it's iterable property. +/// let js_iterable_map = JsMap::from_js_iterable(&js_array.into(), context).unwrap(); /// -/// assert_eq!(iter_map.get("first-key", context)?, "first-value".into()); +/// assert_eq!(iter_map.get("first-key", context).unwrap(), "first-value".into()); /// -/// Ok(()) -/// } /// ``` /// #[derive(Debug, Clone, Trace, Finalize)] @@ -78,18 +73,15 @@ impl JsMap { /// ``` /// use boa_engine::{ /// object::JsMap, - /// Context, JsResult, JsValue, + /// Context, JsValue, /// }; /// - /// fn main -> JsResult<()> { - /// // Create a new context. - /// let context = &mut Context::default(); + /// // Create a new context. + /// let context = &mut Context::default(); /// - /// // Create a new empty `JsMap`. - /// let map = JsMap::new(context); + /// // Create a new empty `JsMap`. + /// let map = JsMap::new(context); /// - /// Ok(()) - /// } /// ``` #[inline] pub fn new(context: &mut Context) -> Self { @@ -106,22 +98,19 @@ impl JsMap { /// Context, JsResult, JsValue, /// }; /// - /// fn main() -> JsResult<()> { - /// // Create a default `Context` - /// let context = &mut Context::default(); + /// // Create a default `Context` + /// let context = &mut Context::default(); /// - /// // Create an array of two `[key, value]` pairs - /// let js_array = JsArray::new(context); + /// // Create an array of two `[key, value]` pairs + /// let js_array = JsArray::new(context); /// - /// // Create a `[key, value]` pair of JsValues and add it to the `JsArray` as a `JsArray` - /// let vec_one: Vec = vec![JsValue::new("first-key"), JsValue::new("first-value")]; - /// js_array.push(JsArray::from_iter(vec_one, context), context)?; + /// // Create a `[key, value]` pair of JsValues and add it to the `JsArray` as a `JsArray` + /// let vec_one: Vec = vec![JsValue::new("first-key"), JsValue::new("first-value")]; + /// js_array.push(JsArray::from_iter(vec_one, context), context).unwrap(); /// - /// // Create a `JsMap` from the `JsArray` using it's iterable property. - /// let js_iterable_map = JsMap::from_js_iterable(&js_array.into(), context)?; + /// // Create a `JsMap` from the `JsArray` using it's iterable property. + /// let js_iterable_map = JsMap::from_js_iterable(&js_array.into(), context).unwrap(); /// - /// Ok(()) - /// } /// ``` /// #[inline] @@ -148,23 +137,20 @@ impl JsMap { /// use boa_engine::{ /// builtins::map::ordered_map::OrderedMap, /// object::{JsObject, ObjectData, JsMap}, - /// Context, JsResult, JsValue, + /// Context, JsValue, /// }; /// - /// fn main() -> JsResult<()> { - /// let context = Context::default(); + /// let context = Context::default(); /// - /// // `some_object` can be any JavaScript `Map` object. - /// let some_object = JsObject::from_proto_and_data( - /// context.intrinsics().constructors().map().prototype(), - /// ObjectData::map(OrderedMap::new()) - /// ); + /// // `some_object` can be any JavaScript `Map` object. + /// let some_object = JsObject::from_proto_and_data( + /// context.intrinsics().constructors().map().prototype(), + /// ObjectData::map(OrderedMap::new()) + /// ); /// - /// // Create `JsMap` object with incoming object. - /// let js_map = JsMap::from_object(some_object, context)?; + /// // Create `JsMap` object with incoming object. + /// let js_map = JsMap::from_object(some_object, context).unwrap(); /// - /// Ok(()) - /// } /// ``` /// /// Invalid Example - returns a `TypeError` with the message "object is not a Map" @@ -174,15 +160,12 @@ impl JsMap { /// Context, JsResult, JsValue, /// }; /// - /// fn main() -> JsResult<()> { - /// let context = Context::default(); + /// let context = Context::default(); /// - /// let some_object = JsArray::new(context); + /// let some_object = JsArray::new(context); /// - /// let js_map = JsMap::from_object(some_object, context)?; /// + /// let js_map = JsMap::from_object(some_object, context).unwrap(); /// - /// Ok(()) - /// } /// ``` #[inline] pub fn from_object(object: JsObject, context: &mut Context) -> JsResult { @@ -227,24 +210,19 @@ impl JsMap { /// ``` /// use boa_engine::{ /// object::JsMap, - /// Context, JsResult, JsValue, + /// Context, JsValue, /// }; /// - /// fn main() -> JsResult<()> { - /// let context = Context::default(); + /// let context = Context::default(); /// - /// let js_map = JsMap::new(context); + /// let js_map = JsMap::new(context); /// - /// js_map.set("foo", "bar", context)?; - /// js_map.set(2, 4, context)?; + /// js_map.set("foo", "bar", context).unwrap(); + /// js_map.set(2, 4, context).unwrap(); /// - /// assert_eq!(js_map.get("foo", context)?, "bar".into()); - /// assert_eq!(js_map.get(2, context)?, 4.into()) + /// assert_eq!(js_map.get("foo", context).unwrap(), "bar".into()); + /// assert_eq!(js_map.get(2, context).unwrap(), 4.into()) /// - /// Ok(()) - /// } - - /// /// ``` #[inline] pub fn set(&self, key: K, value: V, context: &mut Context) -> JsResult @@ -266,22 +244,19 @@ impl JsMap { /// ``` /// use boa_engine::{ /// object::JsMap, - /// Context, JsResult, JsValue, + /// Context, JsValue, /// }; /// - /// fn main() -> JsResult<()> { - /// let context = Context::default(); + /// let context = Context::default(); /// - /// let js_map = JsMap::new(context); + /// let js_map = JsMap::new(context); /// - /// js_map.set("foo", "bar", context)?; + /// js_map.set("foo", "bar", context).unwrap(); /// - /// let map_size = js_map.get_size(context)?; + /// let map_size = js_map.get_size(context).unwrap(); /// - /// assert_eq!(map_size, 1.into()); + /// assert_eq!(map_size, 1.into()); /// - /// Ok(()) - /// } /// ``` #[inline] pub fn get_size(&self, context: &mut Context) -> JsResult { @@ -295,23 +270,20 @@ impl JsMap { /// ``` /// use boa_engine::{ /// object::JsMap, - /// Context, JsResult, JsValue, + /// Context, JsValue, /// }; /// - /// fn main() -> JsResult<()> { - /// let context = Context::default(); + /// let context = Context::default(); /// - /// let js_map = JsMap::new(context); - /// js_map.set("foo", "bar", context)?; - /// js_map.set("hello", world, context)?; + /// let js_map = JsMap::new(context); + /// js_map.set("foo", "bar", context).unwrap(); + /// js_map.set("hello", world, context).unwrap(); /// - /// js_map.delete("foo", context)?; + /// js_map.delete("foo", context).unwrap(); /// - /// assert_eq!(js_map.get_size(context)?, 1.into()); - /// assert_eq!(js_map.get("foo", context)?, JsValue::undefined()); + /// assert_eq!(js_map.get_size(context).unwrap(), 1.into()); + /// assert_eq!(js_map.get("foo", context).unwrap(), JsValue::undefined()); /// - /// Ok(()) - /// } /// ``` #[inline] pub fn delete(&self, key: T, context: &mut Context) -> JsResult @@ -328,21 +300,17 @@ impl JsMap { /// ``` /// use boa_engine::{ /// object::JsMap, - /// Context, JsResult, JsValue, + /// Context, JsValue, /// }; /// - /// fn main() -> JsResult<()> { - /// let context = Context::default(); - - /// let js_map = JsMap::new(context); - /// js_map.set("foo", "bar", context)?; + /// let context = Context::default(); + /// let js_map = JsMap::new(context); + /// js_map.set("foo", "bar", context).unwrap(); /// - /// let retrieved_value = js_map.get("foo", context)?; + /// let retrieved_value = js_map.get("foo", context).unwrap(); /// - /// assert_eq!(retrieved_value, "bar".into()); + /// assert_eq!(retrieved_value, "bar".into()); /// - /// Ok(()) - /// } /// ``` #[inline] pub fn get(&self, key: T, context: &mut Context) -> JsResult @@ -359,22 +327,19 @@ impl JsMap { /// ``` /// use boa_engine::{ /// object::JsMap, - /// Context, JsResult, JsValue, + /// Context, JsValue, /// }; /// - /// fn main() -> JsResult<()> { - /// let context = Context::default(); + /// let context = Context::default(); /// - /// let js_map = JsMap::new(context); - /// js_map.set("foo", "bar", context)?; - /// js_map.set("hello", world, context)?; + /// let js_map = JsMap::new(context); + /// js_map.set("foo", "bar", context).unwrap(); + /// js_map.set("hello", world, context).unwrap(); /// - /// js_map.clear(context)?; + /// js_map.clear(context).unwrap(); /// - /// assert_eq!(js_map.get_size(context)?, 0.into()); + /// assert_eq!(js_map.get_size(context).unwrap(), 0.into()); /// - /// Ok(()) - /// } /// ``` #[inline] pub fn clear(&self, context: &mut Context) -> JsResult { @@ -388,21 +353,18 @@ impl JsMap { /// ``` /// use boa_engine::{ /// object::JsMap, - /// Context, JsResult, JsValue, + /// Context, JsValue, /// }; /// - /// fn main() -> JsResult<()> { - /// let context = Context::default(); + /// let context = Context::default(); /// - /// let js_map = JsMap::new(context); - /// js_map.set("foo", "bar", context)?; + /// let js_map = JsMap::new(context); + /// js_map.set("foo", "bar", context).unwrap(); /// - /// let has_key = js_map.has("foo", context)?; + /// let has_key = js_map.has("foo", context).unwrap(); /// - /// assert_eq!(has_key, true.into()); + /// assert_eq!(has_key, true.into()); /// - /// Ok(()) - /// } /// ``` #[inline] pub fn has(&self, key: T, context: &mut Context) -> JsResult From 2e2072cf525663ce0d96f13e7a4cdd70aef79010 Mon Sep 17 00:00:00 2001 From: nekevss Date: Sat, 2 Jul 2022 01:31:15 -0400 Subject: [PATCH 34/41] Fix context initialization --- boa_engine/src/object/jsmap.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs index caae4427b76..91a3a625df5 100644 --- a/boa_engine/src/object/jsmap.rs +++ b/boa_engine/src/object/jsmap.rs @@ -140,7 +140,7 @@ impl JsMap { /// Context, JsValue, /// }; /// - /// let context = Context::default(); + /// let context = &mut Context::default(); /// /// // `some_object` can be any JavaScript `Map` object. /// let some_object = JsObject::from_proto_and_data( @@ -160,7 +160,7 @@ impl JsMap { /// Context, JsResult, JsValue, /// }; /// - /// let context = Context::default(); + /// let context = &mut Context::default(); /// /// let some_object = JsArray::new(context); /// @@ -213,7 +213,7 @@ impl JsMap { /// Context, JsValue, /// }; /// - /// let context = Context::default(); + /// let context = &mut Context::default(); /// /// let js_map = JsMap::new(context); /// @@ -247,7 +247,7 @@ impl JsMap { /// Context, JsValue, /// }; /// - /// let context = Context::default(); + /// let context = &mut Context::default(); /// /// let js_map = JsMap::new(context); /// @@ -273,7 +273,7 @@ impl JsMap { /// Context, JsValue, /// }; /// - /// let context = Context::default(); + /// let context = &mut Context::default(); /// /// let js_map = JsMap::new(context); /// js_map.set("foo", "bar", context).unwrap(); @@ -303,7 +303,7 @@ impl JsMap { /// Context, JsValue, /// }; /// - /// let context = Context::default(); + /// let context = &mut Context::default(); /// let js_map = JsMap::new(context); /// js_map.set("foo", "bar", context).unwrap(); /// @@ -330,7 +330,7 @@ impl JsMap { /// Context, JsValue, /// }; /// - /// let context = Context::default(); + /// let context = &mut Context::default(); /// /// let js_map = JsMap::new(context); /// js_map.set("foo", "bar", context).unwrap(); @@ -356,7 +356,7 @@ impl JsMap { /// Context, JsValue, /// }; /// - /// let context = Context::default(); + /// let context = &mut Context::default(); /// /// let js_map = JsMap::new(context); /// js_map.set("foo", "bar", context).unwrap(); From e9664f90b3c9f36218573f1150f9a0830fc00e41 Mon Sep 17 00:00:00 2001 From: nekevss Date: Sat, 2 Jul 2022 01:37:20 -0400 Subject: [PATCH 35/41] Notate the should_panic on invalid from_object example --- boa_engine/src/object/jsmap.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs index 91a3a625df5..638ec62e6c8 100644 --- a/boa_engine/src/object/jsmap.rs +++ b/boa_engine/src/object/jsmap.rs @@ -154,7 +154,7 @@ impl JsMap { /// ``` /// /// Invalid Example - returns a `TypeError` with the message "object is not a Map" - /// ``` + /// ```should_panic /// use boa_engine::{ /// object::{JsObject, JsArray, JsMap}, /// Context, JsResult, JsValue, @@ -164,7 +164,7 @@ impl JsMap { /// /// let some_object = JsArray::new(context); /// - /// let js_map = JsMap::from_object(some_object, context).unwrap(); + /// let js_map = JsMap::from_object(some_object.into(), context).unwrap(); /// /// ``` #[inline] From 13c35c46d654058cae840a64d5dd58601e659d87 Mon Sep 17 00:00:00 2001 From: nekevss Date: Sat, 2 Jul 2022 07:25:56 -0400 Subject: [PATCH 36/41] Fixed comment errors --- boa_engine/src/object/jsmap.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs index 638ec62e6c8..ee177a207f0 100644 --- a/boa_engine/src/object/jsmap.rs +++ b/boa_engine/src/object/jsmap.rs @@ -56,7 +56,7 @@ use std::ops::Deref; /// // Create a `JsMap` from the `JsArray` using it's iterable property. /// let js_iterable_map = JsMap::from_js_iterable(&js_array.into(), context).unwrap(); /// -/// assert_eq!(iter_map.get("first-key", context).unwrap(), "first-value".into()); +/// assert_eq!(js_iterable_map.get("first-key", context).unwrap(), "first-value".into()); /// /// ``` /// @@ -277,7 +277,7 @@ impl JsMap { /// /// let js_map = JsMap::new(context); /// js_map.set("foo", "bar", context).unwrap(); - /// js_map.set("hello", world, context).unwrap(); + /// js_map.set("hello", "world", context).unwrap(); /// /// js_map.delete("foo", context).unwrap(); /// @@ -334,7 +334,7 @@ impl JsMap { /// /// let js_map = JsMap::new(context); /// js_map.set("foo", "bar", context).unwrap(); - /// js_map.set("hello", world, context).unwrap(); + /// js_map.set("hello", "world", context).unwrap(); /// /// js_map.clear(context).unwrap(); /// From 942e743b99cf64049fd43704cfd6db7c2719e00c Mon Sep 17 00:00:00 2001 From: nekevss Date: Sat, 2 Jul 2022 07:25:56 -0400 Subject: [PATCH 37/41] Fixed comment errors --- boa_engine/src/object/jsmap.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs index 638ec62e6c8..8464363bd89 100644 --- a/boa_engine/src/object/jsmap.rs +++ b/boa_engine/src/object/jsmap.rs @@ -56,7 +56,7 @@ use std::ops::Deref; /// // Create a `JsMap` from the `JsArray` using it's iterable property. /// let js_iterable_map = JsMap::from_js_iterable(&js_array.into(), context).unwrap(); /// -/// assert_eq!(iter_map.get("first-key", context).unwrap(), "first-value".into()); +/// assert_eq!(js_iterable_map.get("first-key", context).unwrap(), "first-value".into()); /// /// ``` /// @@ -154,7 +154,7 @@ impl JsMap { /// ``` /// /// Invalid Example - returns a `TypeError` with the message "object is not a Map" - /// ```should_panic + /// ``` /// use boa_engine::{ /// object::{JsObject, JsArray, JsMap}, /// Context, JsResult, JsValue, @@ -164,7 +164,7 @@ impl JsMap { /// /// let some_object = JsArray::new(context); /// - /// let js_map = JsMap::from_object(some_object.into(), context).unwrap(); + /// assert!(JsMap::from_object(some_object.into(), context).is_err()); /// /// ``` #[inline] @@ -277,7 +277,7 @@ impl JsMap { /// /// let js_map = JsMap::new(context); /// js_map.set("foo", "bar", context).unwrap(); - /// js_map.set("hello", world, context).unwrap(); + /// js_map.set("hello", "world", context).unwrap(); /// /// js_map.delete("foo", context).unwrap(); /// @@ -334,7 +334,7 @@ impl JsMap { /// /// let js_map = JsMap::new(context); /// js_map.set("foo", "bar", context).unwrap(); - /// js_map.set("hello", world, context).unwrap(); + /// js_map.set("hello", "world", context).unwrap(); /// /// js_map.clear(context).unwrap(); /// From 20b0aff2ca2ebd16b505f52bea0fb7ccff955f4e Mon Sep 17 00:00:00 2001 From: nekevss Date: Sat, 2 Jul 2022 07:33:51 -0400 Subject: [PATCH 38/41] Add assert on invalid example --- boa_engine/src/object/jsmap.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs index 8464363bd89..99b9f856910 100644 --- a/boa_engine/src/object/jsmap.rs +++ b/boa_engine/src/object/jsmap.rs @@ -164,6 +164,7 @@ impl JsMap { /// /// let some_object = JsArray::new(context); /// + /// // Some object is an Array object, not a map object /// assert!(JsMap::from_object(some_object.into(), context).is_err()); /// /// ``` From 0d76ca83d06870cd0f9ea325986b00ee8bfca757 Mon Sep 17 00:00:00 2001 From: nekevss Date: Tue, 5 Jul 2022 19:29:16 -0400 Subject: [PATCH 39/41] Hide imports in examples --- boa_engine/src/object/jsmap.rs | 98 +++++++++++++++++----------------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs index 99b9f856910..74770c20767 100644 --- a/boa_engine/src/object/jsmap.rs +++ b/boa_engine/src/object/jsmap.rs @@ -15,10 +15,10 @@ use std::ops::Deref; /// /// Create a `JsMap` and set a new entry /// ``` -/// use boa_engine::{ -/// object::JsMap, -/// Context, JsValue, -/// }; +/// # use boa_engine::{ +/// # object::JsMap, +/// # Context, JsValue, +/// # }; /// /// // Create default `Context` /// let context = &mut Context::default(); @@ -36,10 +36,10 @@ use std::ops::Deref; /// /// Create a `JsMap` from a `JsArray` /// ``` -/// use boa_engine::{ -/// object::{JsArray, JsMap}, -/// Context, JsValue, -/// }; +/// # use boa_engine::{ +/// # object::{JsArray, JsMap}, +/// # Context, JsValue, +/// # }; /// /// // Create a default `Context` /// let context = &mut Context::default(); @@ -71,10 +71,10 @@ impl JsMap { /// # Example /// /// ``` - /// use boa_engine::{ - /// object::JsMap, - /// Context, JsValue, - /// }; + /// # use boa_engine::{ + /// # object::JsMap, + /// # Context, JsValue, + /// # }; /// /// // Create a new context. /// let context = &mut Context::default(); @@ -93,10 +93,10 @@ impl JsMap { /// /// # Examples /// ``` - /// use boa_engine::{ - /// object::{JsArray, JsMap}, - /// Context, JsResult, JsValue, - /// }; + /// # use boa_engine::{ + /// # object::{JsArray, JsMap}, + /// # Context, JsResult, JsValue, + /// # }; /// /// // Create a default `Context` /// let context = &mut Context::default(); @@ -134,11 +134,11 @@ impl JsMap { /// /// Valid Example - returns a `JsMap` object /// ``` - /// use boa_engine::{ - /// builtins::map::ordered_map::OrderedMap, - /// object::{JsObject, ObjectData, JsMap}, - /// Context, JsValue, - /// }; + /// # use boa_engine::{ + /// # builtins::map::ordered_map::OrderedMap, + /// # object::{JsObject, ObjectData, JsMap}, + /// # Context, JsValue, + /// # };# /// /// let context = &mut Context::default(); /// @@ -155,10 +155,10 @@ impl JsMap { /// /// Invalid Example - returns a `TypeError` with the message "object is not a Map" /// ``` - /// use boa_engine::{ - /// object::{JsObject, JsArray, JsMap}, - /// Context, JsResult, JsValue, - /// }; + /// # use boa_engine::{ + /// # object::{JsObject, JsArray, JsMap}, + /// # Context, JsResult, JsValue, + /// # }; /// /// let context = &mut Context::default(); /// @@ -209,10 +209,10 @@ impl JsMap { /// # Example /// /// ``` - /// use boa_engine::{ - /// object::JsMap, - /// Context, JsValue, - /// }; + /// # use boa_engine::{ + /// # object::JsMap, + /// # Context, JsValue, + /// # }; /// /// let context = &mut Context::default(); /// @@ -243,10 +243,10 @@ impl JsMap { /// # Example /// /// ``` - /// use boa_engine::{ - /// object::JsMap, - /// Context, JsValue, - /// }; + /// # use boa_engine::{ + /// # object::JsMap, + /// # Context, JsValue, + /// # }; /// /// let context = &mut Context::default(); /// @@ -269,10 +269,10 @@ impl JsMap { /// # Example /// /// ``` - /// use boa_engine::{ - /// object::JsMap, - /// Context, JsValue, - /// }; + /// # use boa_engine::{ + /// # object::JsMap, + /// # Context, JsValue, + /// # }; /// /// let context = &mut Context::default(); /// @@ -299,10 +299,10 @@ impl JsMap { /// # Example /// /// ``` - /// use boa_engine::{ - /// object::JsMap, - /// Context, JsValue, - /// }; + /// # use boa_engine::{ + /// # object::JsMap, + /// # Context, JsValue, + /// # }; /// /// let context = &mut Context::default(); /// let js_map = JsMap::new(context); @@ -326,10 +326,10 @@ impl JsMap { /// # Example /// /// ``` - /// use boa_engine::{ - /// object::JsMap, - /// Context, JsValue, - /// }; + /// # use boa_engine::{ + /// # object::JsMap, + /// # Context, JsValue, + /// # }; /// /// let context = &mut Context::default(); /// @@ -352,10 +352,10 @@ impl JsMap { /// # Example /// /// ``` - /// use boa_engine::{ - /// object::JsMap, - /// Context, JsValue, - /// }; + /// # use boa_engine::{ + /// # object::JsMap, + /// # Context, JsValue, + /// # }; /// /// let context = &mut Context::default(); /// From 080512e3a96b5178e931815b11b4e6b30a1f33c6 Mon Sep 17 00:00:00 2001 From: nekevss Date: Tue, 5 Jul 2022 19:39:59 -0400 Subject: [PATCH 40/41] Run rustfmt --- boa_engine/src/object/jsmap.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs index 74770c20767..d9dd6bfbf16 100644 --- a/boa_engine/src/object/jsmap.rs +++ b/boa_engine/src/object/jsmap.rs @@ -138,7 +138,7 @@ impl JsMap { /// # builtins::map::ordered_map::OrderedMap, /// # object::{JsObject, ObjectData, JsMap}, /// # Context, JsValue, - /// # };# + /// # };# /// /// let context = &mut Context::default(); /// From 18bd5f6c88e3dff60f60caffc057a2557b0eeb14 Mon Sep 17 00:00:00 2001 From: nekevss Date: Tue, 5 Jul 2022 20:50:33 -0400 Subject: [PATCH 41/41] Removed extra pound symbol --- boa_engine/src/object/jsmap.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boa_engine/src/object/jsmap.rs b/boa_engine/src/object/jsmap.rs index d9dd6bfbf16..885929c708d 100644 --- a/boa_engine/src/object/jsmap.rs +++ b/boa_engine/src/object/jsmap.rs @@ -138,7 +138,7 @@ impl JsMap { /// # builtins::map::ordered_map::OrderedMap, /// # object::{JsObject, ObjectData, JsMap}, /// # Context, JsValue, - /// # };# + /// # }; /// /// let context = &mut Context::default(); ///