Skip to content

Commit

Permalink
string objects now display their primitive value, to_function() metho…
Browse files Browse the repository at this point in the history
…d has been added to value, test added for String()
  • Loading branch information
Jason Williams committed Mar 21, 2019
1 parent bd6feb6 commit 7ba514b
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 14 deletions.
28 changes: 27 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

57 changes: 49 additions & 8 deletions src/lib/js/console.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,54 @@
use gc::Gc;
use crate::js::function::NativeFunctionData;
use crate::js::object::INSTANCE_PROTOTYPE;
use crate::js::value::{from_value, to_value, ResultValue, Value, ValueData};
use std::iter::FromIterator;
use chrono::Local;
use gc::Gc;
use std::fmt::Write;
use std::iter::FromIterator;

/// Print a javascript value to the standard output stream
/// https://console.spec.whatwg.org/#logger
pub fn log(_: Value, _: Value, args: Vec<Value>) -> ResultValue {
let args: Vec<String> = FromIterator::from_iter(
args.iter()
.map(|x| from_value::<String>(x.clone()).unwrap()),
);
let args: Vec<String> = FromIterator::from_iter(args.iter().map(|x| {
// Welcome to console.log! The output here is what the developer sees, so its best matching through value types and stringifying to the correct output
// The input is a vector of Values, we generate a vector of strings then pass them to println!
return match *x.clone() {
// We don't want to print private (compiler) or prototype properties
ValueData::Object(ref v, _) => {
// Create empty formatted string to start writing to
// TODO: once constructor is set on objects, we can do specific output for Strings, Numbers etc
let mut s = String::new();
write!(s, "{}", "{").unwrap();
match v.borrow().iter().last() {
Some((last_key, _)) => {
for (key, val) in v.borrow().iter() {
// Don't print prototype properties
if key == INSTANCE_PROTOTYPE {
continue;
}
write!(s, "{}: {}", key, val.value.clone()).unwrap();
if key != last_key {
write!(s, "{}", ", ").unwrap();
}
}
}
None => (),
}
write!(s, "{}", "}").unwrap();
s
}

_ => from_value::<String>(x.clone()).unwrap(),
};

println!("{}: {}", Local::now().format("%X").to_string(), args.join(" "));
// from_value::<String>(x.clone()).unwrap()
}));

println!(
"{}: {}",
Local::now().format("%X").to_string(),
args.join(" ")
);
Ok(Gc::new(ValueData::Undefined))
}
/// Print a javascript value to the standard error stream
Expand All @@ -20,7 +57,11 @@ pub fn error(_: Value, _: Value, args: Vec<Value>) -> ResultValue {
args.iter()
.map(|x| from_value::<String>(x.clone()).unwrap()),
);
println!("{}: {}", Local::now().format("%X").to_string(), args.join(" "));
println!(
"{}: {}",
Local::now().format("%X").to_string(),
args.join(" ")
);
Ok(Gc::new(ValueData::Undefined))
}
/// Create a new `console` object
Expand Down
8 changes: 5 additions & 3 deletions src/lib/js/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@ pub fn get_string_length(this: Value, _: Value, _: Vec<Value>) -> ResultValue {
Ok(to_value::<i32>(this_str.len() as i32))
}

/// Get the string representation of the error
pub fn to_string(_: Value, _: Value, _: Vec<Value>) -> ResultValue {
Ok(to_value(format!("{}", String::from("test")).to_string()))
/// Get the string value to a primitive string
pub fn to_string(this: Value, _: Value, _: Vec<Value>) -> ResultValue {
// Get String from String Object and send it back as a new value
let primitive_val = this.get_private_field(String::from("PrimitiveValue"));
Ok(to_value(format!("{}", primitive_val).to_string()))
}

/// Create a new `String` object
Expand Down
26 changes: 24 additions & 2 deletions src/lib/js/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,14 @@ impl ValueData {
}
}

/// Returns true if the value is a function
pub fn is_function(&self) -> bool {
match *self {
ValueData::Function(_) => true,
_ => false,
}
}

/// Returns true if the value is undefined
pub fn is_undefined(&self) -> bool {
match *self {
Expand Down Expand Up @@ -419,8 +427,9 @@ impl Display for ValueData {
_ => v.to_string(),
}
),
ValueData::Object(ref v, _) => {
ValueData::Object(ref v, ref p) => {
write!(f, "{}", "{")?;
// Print public properties
match v.borrow().iter().last() {
Some((last_key, _)) => {
for (key, val) in v.borrow().iter() {
Expand All @@ -431,7 +440,20 @@ impl Display for ValueData {
}
}
None => (),
}
};

// Print private properties
match p.borrow().iter().last() {
Some((last_key, _)) => {
for (key, val) in p.borrow().iter() {
r#try!(write!(f, "(Private) {}: {}", key, val.value.clone()));
if key != last_key {
r#try!(write!(f, "{}", ", "));
}
}
}
None => (),
};
write!(f, "{}", "}")
}
ValueData::Integer(v) => write!(f, "{}", v),
Expand Down
11 changes: 11 additions & 0 deletions tests/string_test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
extern crate boa;
use boa::js::string::_create;
use boa::js::object::PROTOTYPE;
use boa::js::value::{ValueData};

#[test]
fn check_string_constructor_is_function() {
let global = ValueData::new_obj(None);
let string_constructor = _create(global);
assert_eq!(string_constructor.is_function(), true);
}

0 comments on commit 7ba514b

Please sign in to comment.