summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordavidot <david.tuin@gmail.com>2021-07-12 01:25:32 +0200
committerAndreas Kling <kling@serenityos.org>2021-07-20 23:45:28 +0200
commit2a61b90fefe2064ada003d284fc37537f9efa5c8 (patch)
tree839e37343ba9b679daa83b8c689b1eab53b6ce66
parent41ebb12c9ef58cc31a0bb6384892df265487124e (diff)
downloadserenity-2a61b90fefe2064ada003d284fc37537f9efa5c8.zip
LibJS: Be less strict about 'use strict'
It is allowed to have (bogus) directives e.g. 'does nothing'; 'same'; 'use strict'; Should still trigger strict mode.
-rw-r--r--Userland/Libraries/LibJS/Parser.cpp41
1 files changed, 33 insertions, 8 deletions
diff --git a/Userland/Libraries/LibJS/Parser.cpp b/Userland/Libraries/LibJS/Parser.cpp
index da6ab77466..9a1349affc 100644
--- a/Userland/Libraries/LibJS/Parser.cpp
+++ b/Userland/Libraries/LibJS/Parser.cpp
@@ -286,26 +286,36 @@ NonnullRefPtr<Program> Parser::parse_program(bool starts_in_strict_mode)
m_state.strict_mode = true;
}
- bool first = true;
+ bool parsing_directives = true;
while (!done()) {
if (match_declaration()) {
program->append(parse_declaration());
+ parsing_directives = false;
} else if (match_statement()) {
auto statement = parse_statement();
program->append(statement);
if (statement_is_use_strict_directive(statement)) {
- if (first) {
+ if (parsing_directives) {
program->set_strict_mode();
m_state.strict_mode = true;
}
if (m_state.string_legacy_octal_escape_sequence_in_scope)
syntax_error("Octal escape sequence in string literal not allowed in strict mode");
}
+
+ if (parsing_directives && is<ExpressionStatement>(*statement)) {
+ auto& expression_statement = static_cast<ExpressionStatement&>(*statement);
+ auto& expression = expression_statement.expression();
+ parsing_directives = is<StringLiteral>(expression);
+ } else {
+ parsing_directives = false;
+ }
+
} else {
expected("statement or declaration");
consume();
+ parsing_directives = false;
}
- first = false;
}
if (m_state.var_scopes.size() == 1) {
scope.add_to_scope_node(program);
@@ -1511,30 +1521,45 @@ NonnullRefPtr<BlockStatement> Parser::parse_block_statement(bool& is_strict)
auto block = create_ast_node<BlockStatement>({ m_state.current_token.filename(), rule_start.position(), position() });
consume(TokenType::CurlyOpen);
- bool first = true;
bool initial_strict_mode_state = m_state.strict_mode;
if (initial_strict_mode_state)
is_strict = true;
+ bool parsing_directives = true;
while (!done() && !match(TokenType::CurlyClose)) {
if (match_declaration()) {
block->append(parse_declaration());
+ parsing_directives = false;
} else if (match_statement()) {
auto statement = parse_statement();
block->append(statement);
if (statement_is_use_strict_directive(statement)) {
- if (first && !initial_strict_mode_state) {
- is_strict = true;
- m_state.strict_mode = true;
+ if (parsing_directives) {
+ if (!initial_strict_mode_state) {
+ is_strict = true;
+ m_state.strict_mode = true;
+ }
}
if (m_state.string_legacy_octal_escape_sequence_in_scope)
syntax_error("Octal escape sequence in string literal not allowed in strict mode");
+
+ if (has_binding) {
+ syntax_error("Illegal 'use strict' directive in function with non-simple parameter list");
+ }
+ }
+
+ if (parsing_directives && is<ExpressionStatement>(*statement)) {
+ auto& expression_statement = static_cast<ExpressionStatement&>(*statement);
+ auto& expression = expression_statement.expression();
+ parsing_directives = is<StringLiteral>(expression);
+ } else {
+ parsing_directives = false;
}
} else {
expected("statement or declaration");
consume();
+ parsing_directives = false;
}
- first = false;
}
m_state.strict_mode = initial_strict_mode_state;
m_state.string_legacy_octal_escape_sequence_in_scope = false;