Browse Source

Implement unary void, delete operators (#388)

pull/391/head
Alexander Kryvomaz 5 years ago committed by GitHub
parent
commit
9cd9a39aa6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      boa/src/builtins/value/mod.rs
  2. 21
      boa/src/exec/mod.rs
  3. 69
      boa/src/exec/tests.rs

6
boa/src/builtins/value/mod.rs

@ -334,11 +334,13 @@ impl ValueData {
/// Removes a property from a Value object. /// Removes a property from a Value object.
/// ///
/// It will return a boolean based on if the value was removed, if there was no value to remove false is returned /// It will return a boolean based on if the value was removed, if there was no value to remove false is returned
pub fn remove_property(&self, field: &str) { pub fn remove_property(&self, field: &str) -> bool {
match *self { let removed = match *self {
Self::Object(ref obj) => obj.borrow_mut().deref_mut().properties.remove(field), Self::Object(ref obj) => obj.borrow_mut().deref_mut().properties.remove(field),
_ => None, _ => None,
}; };
removed.is_some()
} }
/// Resolve the property in the object. /// Resolve the property in the object.

21
boa/src/exec/mod.rs

@ -403,6 +403,27 @@ impl Executor for Interpreter {
!(num_v_a as i32) !(num_v_a as i32)
}) })
} }
UnaryOp::Void => Value::undefined(),
UnaryOp::Delete => match a.deref() {
Node::GetConstField(ref obj, ref field) => {
Value::boolean(self.run(obj)?.remove_property(field))
}
Node::GetField(ref obj, ref field) => Value::boolean(
self.run(obj)?
.remove_property(&self.run(field)?.to_string()),
),
Node::Local(_) => Value::boolean(false),
Node::ArrayDecl(_)
| Node::Block(_)
| Node::Const(_)
| Node::FunctionDecl(_, _, _)
| Node::FunctionExpr(_, _, _)
| Node::New(_)
| Node::Object(_)
| Node::TypeOf(_)
| Node::UnaryOp(_, _) => Value::boolean(true),
_ => panic!("SyntaxError: wrong delete argument {}", node),
},
_ => unimplemented!(), _ => unimplemented!(),
}) })
} }

69
boa/src/exec/tests.rs

@ -428,6 +428,75 @@ fn unary_post() {
assert_eq!(&exec(execs_after_dec), "true"); assert_eq!(&exec(execs_after_dec), "true");
} }
#[test]
fn unary_void() {
let void_should_return_undefined = r#"
const a = 0;
void a;
"#;
assert_eq!(&exec(void_should_return_undefined), "undefined");
let void_invocation = r#"
let a = 0;
const test = () => a = 42;
const b = void test() + '';
a + b
"#;
assert_eq!(&exec(void_invocation), "42undefined");
}
#[test]
fn unary_delete() {
let delete_var = r#"
let a = 5;
const b = delete a + '';
a + b
"#;
assert_eq!(&exec(delete_var), "5false");
let delete_prop = r#"
const a = { b: 5 };
const c = delete a.b + '';
a.b + c
"#;
assert_eq!(&exec(delete_prop), "undefinedtrue");
let delete_not_existing_prop = r#"
const a = { b: 5 };
const c = delete a.c + '';
a.b + c
"#;
assert_eq!(&exec(delete_not_existing_prop), "5false");
let delete_field = r#"
const a = { b: 5 };
const c = delete a['b'] + '';
a.b + c
"#;
assert_eq!(&exec(delete_field), "undefinedtrue");
let delete_object = r#"
const a = { b: 5 };
delete a
"#;
assert_eq!(&exec(delete_object), "false");
let delete_array = r#"
delete [];
"#;
assert_eq!(&exec(delete_array), "true");
let delete_func = r#"
delete function() {};
"#;
assert_eq!(&exec(delete_func), "true");
let delete_recursive = r#"
delete delete delete 1;
"#;
assert_eq!(&exec(delete_recursive), "true");
}
#[cfg(test)] #[cfg(test)]
mod in_operator { mod in_operator {
use super::*; use super::*;

Loading…
Cancel
Save