1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-24 19:27:35 +00:00

LibJS: Implement (no-op) debugger statement

This commit is contained in:
Linus Groh 2020-04-30 17:26:27 +01:00 committed by Andreas Kling
parent ea839861e5
commit 43c1fa9965
9 changed files with 41 additions and 1 deletions

View file

@ -102,6 +102,7 @@ static TextStyle style_for_token_type(Gfx::Palette palette, JS::TokenType type)
case JS::TokenType::Class: case JS::TokenType::Class:
case JS::TokenType::Const: case JS::TokenType::Const:
case JS::TokenType::Delete: case JS::TokenType::Delete:
case JS::TokenType::Debugger:
case JS::TokenType::Function: case JS::TokenType::Function:
case JS::TokenType::In: case JS::TokenType::In:
case JS::TokenType::Instanceof: case JS::TokenType::Instanceof:

View file

@ -1396,6 +1396,12 @@ Value SequenceExpression::execute(Interpreter& interpreter) const
return last_value; return last_value;
} }
Value DebuggerStatement::execute(Interpreter&) const
{
dbg() << "Sorry, no JavaScript debugger available (yet)!";
return js_undefined();
}
void ScopeNode::add_variables(NonnullRefPtrVector<VariableDeclaration> variables) void ScopeNode::add_variables(NonnullRefPtrVector<VariableDeclaration> variables)
{ {
m_variables.append(move(variables)); m_variables.append(move(variables));

View file

@ -923,4 +923,14 @@ private:
virtual const char* class_name() const override { return "ContinueStatement"; } virtual const char* class_name() const override { return "ContinueStatement"; }
}; };
class DebuggerStatement final : public Statement {
public:
DebuggerStatement() {}
virtual Value execute(Interpreter&) const override;
private:
virtual const char* class_name() const override { return "DebuggerStatement"; }
};
} }

View file

@ -49,6 +49,7 @@ Lexer::Lexer(StringView source)
s_keywords.set("class", TokenType::Class); s_keywords.set("class", TokenType::Class);
s_keywords.set("const", TokenType::Const); s_keywords.set("const", TokenType::Const);
s_keywords.set("continue", TokenType::Continue); s_keywords.set("continue", TokenType::Continue);
s_keywords.set("debugger", TokenType::Debugger);
s_keywords.set("default", TokenType::Default); s_keywords.set("default", TokenType::Default);
s_keywords.set("delete", TokenType::Delete); s_keywords.set("delete", TokenType::Delete);
s_keywords.set("do", TokenType::Do); s_keywords.set("do", TokenType::Do);

View file

@ -253,6 +253,8 @@ NonnullRefPtr<Statement> Parser::parse_statement()
return parse_do_while_statement(); return parse_do_while_statement();
case TokenType::While: case TokenType::While:
return parse_while_statement(); return parse_while_statement();
case TokenType::Debugger:
return parse_debugger_statement();
default: default:
if (match_expression()) { if (match_expression()) {
auto expr = parse_expression(0); auto expr = parse_expression(0);
@ -1044,6 +1046,13 @@ NonnullRefPtr<ForStatement> Parser::parse_for_statement()
return create_ast_node<ForStatement>(move(init), move(test), move(update), move(body)); return create_ast_node<ForStatement>(move(init), move(test), move(update), move(body));
} }
NonnullRefPtr<DebuggerStatement> Parser::parse_debugger_statement()
{
consume(TokenType::Debugger);
consume_or_insert_semicolon();
return create_ast_node<DebuggerStatement>();
}
bool Parser::match(TokenType type) const bool Parser::match(TokenType type) const
{ {
return m_parser_state.m_current_token.type() == type; return m_parser_state.m_current_token.type() == type;
@ -1156,7 +1165,8 @@ bool Parser::match_statement() const
|| type == TokenType::Switch || type == TokenType::Switch
|| type == TokenType::Break || type == TokenType::Break
|| type == TokenType::Continue || type == TokenType::Continue
|| type == TokenType::Var; || type == TokenType::Var
|| type == TokenType::Debugger;
} }
bool Parser::match_identifier_name() const bool Parser::match_identifier_name() const

View file

@ -61,6 +61,7 @@ public:
NonnullRefPtr<ContinueStatement> parse_continue_statement(); NonnullRefPtr<ContinueStatement> parse_continue_statement();
NonnullRefPtr<DoWhileStatement> parse_do_while_statement(); NonnullRefPtr<DoWhileStatement> parse_do_while_statement();
NonnullRefPtr<WhileStatement> parse_while_statement(); NonnullRefPtr<WhileStatement> parse_while_statement();
NonnullRefPtr<DebuggerStatement> parse_debugger_statement();
NonnullRefPtr<ConditionalExpression> parse_conditional_expression(NonnullRefPtr<Expression> test); NonnullRefPtr<ConditionalExpression> parse_conditional_expression(NonnullRefPtr<Expression> test);
NonnullRefPtr<Expression> parse_expression(int min_precedence, Associativity associate = Associativity::Right); NonnullRefPtr<Expression> parse_expression(int min_precedence, Associativity associate = Associativity::Right);

View file

@ -0,0 +1,9 @@
load("test-common.js");
try {
debugger;
console.log("PASS");
} catch (e) {
console.log("FAIL: " + e);
}

View file

@ -53,6 +53,7 @@ namespace JS {
__ENUMERATE_JS_TOKEN(Continue) \ __ENUMERATE_JS_TOKEN(Continue) \
__ENUMERATE_JS_TOKEN(CurlyClose) \ __ENUMERATE_JS_TOKEN(CurlyClose) \
__ENUMERATE_JS_TOKEN(CurlyOpen) \ __ENUMERATE_JS_TOKEN(CurlyOpen) \
__ENUMERATE_JS_TOKEN(Debugger) \
__ENUMERATE_JS_TOKEN(Default) \ __ENUMERATE_JS_TOKEN(Default) \
__ENUMERATE_JS_TOKEN(Delete) \ __ENUMERATE_JS_TOKEN(Delete) \
__ENUMERATE_JS_TOKEN(Do) \ __ENUMERATE_JS_TOKEN(Do) \

View file

@ -532,6 +532,7 @@ int main(int argc, char** argv)
break; break;
case JS::TokenType::Class: case JS::TokenType::Class:
case JS::TokenType::Const: case JS::TokenType::Const:
case JS::TokenType::Debugger:
case JS::TokenType::Delete: case JS::TokenType::Delete:
case JS::TokenType::Function: case JS::TokenType::Function:
case JS::TokenType::In: case JS::TokenType::In: