diff --git a/Libraries/LibJS/AST.cpp b/Libraries/LibJS/AST.cpp index 8d1fd4a4a07..199567a5f64 100644 --- a/Libraries/LibJS/AST.cpp +++ b/Libraries/LibJS/AST.cpp @@ -391,7 +391,11 @@ Value UnaryExpression::execute(Interpreter& interpreter) const return js_string(interpreter, "object"); case Value::Type::Boolean: return js_string(interpreter, "boolean"); + default: + ASSERT_NOT_REACHED(); } + case UnaryOp::Void: + return js_undefined(); } ASSERT_NOT_REACHED(); @@ -539,6 +543,9 @@ void UnaryExpression::dump(int indent) const case UnaryOp::Typeof: op_string = "typeof "; break; + case UnaryOp::Void: + op_string = "void "; + break; } print_indent(indent); diff --git a/Libraries/LibJS/AST.h b/Libraries/LibJS/AST.h index de935fba911..a9ff48e94ec 100644 --- a/Libraries/LibJS/AST.h +++ b/Libraries/LibJS/AST.h @@ -395,6 +395,7 @@ enum class UnaryOp { Plus, Minus, Typeof, + Void, }; class UnaryExpression : public Expression { diff --git a/Libraries/LibJS/Parser.cpp b/Libraries/LibJS/Parser.cpp index cb4e8d3992d..c04b189cc53 100644 --- a/Libraries/LibJS/Parser.cpp +++ b/Libraries/LibJS/Parser.cpp @@ -185,6 +185,7 @@ Associativity Parser::operator_associativity(TokenType type) const case TokenType::EqualsEqualsEquals: case TokenType::ExclamationMarkEqualsEquals: case TokenType::Typeof: + case TokenType::Void: case TokenType::Ampersand: case TokenType::Caret: case TokenType::Pipe: @@ -416,6 +417,9 @@ NonnullRefPtr Parser::parse_unary_prefixed_expression() case TokenType::Typeof: consume(); return create_ast_node(UnaryOp::Typeof, parse_expression(precedence, associativity)); + case TokenType::Void: + consume(); + return create_ast_node(UnaryOp::Void, parse_expression(precedence, associativity)); default: m_parser_state.m_has_errors = true; expected("primary expression (missing switch case)"); @@ -968,7 +972,8 @@ bool Parser::match_unary_prefixed_expression() const || type == TokenType::Tilde || type == TokenType::Plus || type == TokenType::Minus - || type == TokenType::Typeof; + || type == TokenType::Typeof + || type == TokenType::Void; } bool Parser::match_secondary_expression() const diff --git a/Libraries/LibJS/Tests/void-basic.js b/Libraries/LibJS/Tests/void-basic.js new file mode 100644 index 00000000000..d96ee0239f0 --- /dev/null +++ b/Libraries/LibJS/Tests/void-basic.js @@ -0,0 +1,20 @@ +load("test-common.js"); + +try { + assert(void "" === undefined); + assert(void "foo" === undefined); + assert(void 1 === undefined); + assert(void 42 === undefined); + assert(void true === undefined); + assert(void false === undefined); + assert(void null === undefined); + assert(void undefined === undefined); + assert(void function () {} === undefined); + assert(void (() => {}) === undefined); + assert(void (() => "hello friends")() === undefined); + assert((() => void "hello friends")() === undefined); + + console.log("PASS"); +} catch (e) { + console.log("FAIL: " + e); +}