Browse Source

Add early errors for `LexicalDeclaration` (#3207)

pull/3208/head
raskad 1 year ago committed by GitHub
parent
commit
22b014d5d5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 20
      boa_parser/src/parser/statement/declaration/lexical.rs
  2. 11
      boa_parser/src/parser/statement/declaration/tests.rs

20
boa_parser/src/parser/statement/declaration/lexical.rs

@ -21,6 +21,7 @@ use ast::operations::bound_names;
use boa_ast::{self as ast, declaration::Variable, pattern::Pattern, Keyword, Punctuator}; use boa_ast::{self as ast, declaration::Variable, pattern::Pattern, Keyword, Punctuator};
use boa_interner::{Interner, Sym}; use boa_interner::{Interner, Sym};
use boa_profiler::Profiler; use boa_profiler::Profiler;
use rustc_hash::FxHashSet;
use std::io::Read; use std::io::Read;
/// Parses a lexical declaration. /// Parses a lexical declaration.
@ -99,6 +100,25 @@ where
cursor.expect_semicolon("lexical declaration", interner)?; cursor.expect_semicolon("lexical declaration", interner)?;
} }
// It is a Syntax Error if the BoundNames of BindingList contains "let".
// It is a Syntax Error if the BoundNames of BindingList contains any duplicate entries.
let bound_names = bound_names(&lexical_declaration);
let mut names = FxHashSet::default();
for name in bound_names {
if name.sym() == Sym::LET {
return Err(Error::general(
"'let' is disallowed as a lexically bound name",
tok.span().start(),
));
}
if !names.insert(name) {
return Err(Error::general(
"lexical name declared multiple times",
tok.span().start(),
));
}
}
Ok(lexical_declaration) Ok(lexical_declaration)
} }
} }

11
boa_parser/src/parser/statement/declaration/tests.rs

@ -349,3 +349,14 @@ fn multiple_const_declaration() {
interner, interner,
); );
} }
/// Checks `LexicalDeclaration` early errors.
#[test]
fn lexical_declaration_early_errors() {
check_invalid_script("let let = 0");
check_invalid_script("let a = 0, a = 0");
check_invalid_script("const a = 0, a = 0");
check_invalid_script("for (let let = 0; ; ) {}");
check_invalid_script("for (let a = 0, a = 0; ; ) {}");
check_invalid_script("for (const a = 0, a = 0; ; ) {}");
}

Loading…
Cancel
Save