Browse Source

Fix invalid syntex errors for allower `let` as variable names (#3743)

pull/3746/head
raskad 8 months ago committed by GitHub
parent
commit
06b1c3394d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 17
      core/parser/src/parser/statement/declaration/lexical.rs
  2. 2
      core/parser/src/parser/statement/declaration/mod.rs
  3. 42
      core/parser/src/parser/statement/iteration/for_statement.rs
  4. 21
      core/parser/src/parser/statement/mod.rs

17
core/parser/src/parser/statement/declaration/lexical.rs

@ -8,7 +8,7 @@
//! [spec]: https://tc39.es/ecma262/#sec-let-and-const-declarations
use crate::{
lexer::{Error as LexError, TokenKind},
lexer::{Error as LexError, Token, TokenKind},
parser::{
cursor::{Cursor, SemicolonResult},
expression::Initializer,
@ -123,6 +123,21 @@ where
}
}
/// Check if the given token is valid after the `let` keyword of a lexical declaration.
pub(crate) fn allowed_token_after_let(token: Option<&Token>) -> bool {
matches!(
token.map(Token::kind),
Some(
TokenKind::IdentifierName(_)
| TokenKind::Keyword((
Keyword::Await | Keyword::Yield | Keyword::Let | Keyword::Async,
_
))
| TokenKind::Punctuator(Punctuator::OpenBlock | Punctuator::OpenBracket),
)
)
}
/// Parses a binding list.
///
/// It will return an error if a `const` declaration is being parsed and there is no

2
core/parser/src/parser/statement/declaration/mod.rs

@ -20,7 +20,7 @@ pub(in crate::parser) use self::{
class_decl::ClassTail, ClassDeclaration, FunctionDeclaration, HoistableDeclaration,
},
import::ImportDeclaration,
lexical::LexicalDeclaration,
lexical::{allowed_token_after_let, LexicalDeclaration},
};
use crate::{
lexer::TokenKind,

42
core/parser/src/parser/statement/iteration/for_statement.rs

@ -11,8 +11,11 @@ use crate::{
lexer::{Error as LexError, TokenKind},
parser::{
expression::{AssignmentExpression, Expression},
statement::declaration::LexicalDeclaration,
statement::{variable::VariableDeclarationList, Statement},
statement::{
declaration::{allowed_token_after_let, LexicalDeclaration},
variable::VariableDeclarationList,
Statement,
},
AllowAwait, AllowReturn, AllowYield, Cursor, OrAbrupt, ParseResult, TokenParser,
},
source::ReadChar,
@ -20,6 +23,7 @@ use crate::{
};
use ast::{
declaration::Binding,
expression::Identifier,
operations::{bound_names, var_declared_names},
};
use boa_ast::{
@ -107,7 +111,7 @@ where
}
};
let init = match cursor.peek(0, interner).or_abrupt()?.kind() {
let init = match cursor.peek(0, interner).or_abrupt()?.kind().clone() {
TokenKind::Keyword((Keyword::Var, _)) => {
cursor.advance(interner);
Some(
@ -116,20 +120,15 @@ where
.into(),
)
}
TokenKind::Keyword((Keyword::Let, _)) => Some('exit: {
if !cursor.strict() {
if let Some(token) = cursor.peek(1, interner)? {
if token.kind() == &TokenKind::Keyword((Keyword::In, false)) {
cursor.advance(interner);
break 'exit boa_ast::Expression::Identifier(Sym::LET.into()).into();
}
}
}
LexicalDeclaration::new(false, self.allow_yield, self.allow_await, true)
.parse(cursor, interner)?
.into()
}),
TokenKind::Keyword((Keyword::Let, false))
if allowed_token_after_let(cursor.peek(1, interner)?) =>
{
Some(
LexicalDeclaration::new(false, self.allow_yield, self.allow_await, true)
.parse(cursor, interner)?
.into(),
)
}
TokenKind::Keyword((Keyword::Const, _)) => Some(
LexicalDeclaration::new(false, self.allow_yield, self.allow_await, true)
.parse(cursor, interner)?
@ -174,6 +173,15 @@ where
));
}
(Some(init), TokenKind::Keyword((kw @ (Keyword::In | Keyword::Of), false))) => {
if kw == &Keyword::Of
&& init
== ForLoopInitializer::Expression(ast::Expression::Identifier(
Identifier::new(Sym::LET),
))
{
return Err(Error::general("unexpected token", position));
}
let in_loop = kw == &Keyword::In;
let init = initializer_to_iterable_loop_initializer(
init,

21
core/parser/src/parser/statement/mod.rs

@ -26,7 +26,7 @@ use self::{
block::BlockStatement,
break_stm::BreakStatement,
continue_stm::ContinueStatement,
declaration::{Declaration, ExportDeclaration, ImportDeclaration},
declaration::{allowed_token_after_let, Declaration, ExportDeclaration, ImportDeclaration},
expression::ExpressionStatement,
if_stm::IfStatement,
iteration::{DoWhileStatement, ForStatement, WhileStatement},
@ -412,12 +412,19 @@ where
let _timer = Profiler::global().start_event("StatementListItem", "Parsing");
let tok = cursor.peek(0, interner).or_abrupt()?;
match *tok.kind() {
TokenKind::Keyword(
(Keyword::Function | Keyword::Class | Keyword::Const, _) | (Keyword::Let, false),
) => Declaration::new(self.allow_yield, self.allow_await)
.parse(cursor, interner)
.map(ast::StatementListItem::from),
match tok.kind().clone() {
TokenKind::Keyword((Keyword::Function | Keyword::Class | Keyword::Const, _)) => {
Declaration::new(self.allow_yield, self.allow_await)
.parse(cursor, interner)
.map(ast::StatementListItem::from)
}
TokenKind::Keyword((Keyword::Let, false))
if allowed_token_after_let(cursor.peek(1, interner)?) =>
{
Declaration::new(self.allow_yield, self.allow_await)
.parse(cursor, interner)
.map(ast::StatementListItem::from)
}
TokenKind::Keyword((Keyword::Async, false)) => {
let skip_n = if cursor.peek_is_line_terminator(0, interner).or_abrupt()? {
2

Loading…
Cancel
Save