Skip to content

Commit

Permalink
Remove keywords for boolean and null literals
Browse files Browse the repository at this point in the history
  • Loading branch information
jedel1043 committed Jan 7, 2025
1 parent 4a15d6c commit 102c62b
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 70 deletions.
39 changes: 0 additions & 39 deletions core/ast/src/keyword/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,16 +196,6 @@ pub enum Keyword {
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/extends
Extends,

/// The `false` keyword.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-BooleanLiteral
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean
False,

/// The `finally` keyword.
///
/// More information:
Expand Down Expand Up @@ -308,16 +298,6 @@ pub enum Keyword {
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new
New,

/// The `null` keyword.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-NullLiteral
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null
Null,

/// The `of` keyword.
///
/// More information:
Expand Down Expand Up @@ -386,16 +366,6 @@ pub enum Keyword {
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw
Throw,

/// The `true` keyword
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-BooleanLiteral
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean
True,

/// The `try` keyword.
///
/// More information:
Expand Down Expand Up @@ -509,7 +479,6 @@ impl Keyword {
Self::Enum => ("enum", utf16!("enum")),
Self::Extends => ("extends", utf16!("extends")),
Self::Export => ("export", utf16!("export")),
Self::False => ("false", utf16!("false")),
Self::Finally => ("finally", utf16!("finally")),
Self::For => ("for", utf16!("for")),
Self::Function => ("function", utf16!("function")),
Expand All @@ -519,14 +488,12 @@ impl Keyword {
Self::Import => ("import", utf16!("import")),
Self::Let => ("let", utf16!("let")),
Self::New => ("new", utf16!("new")),
Self::Null => ("null", utf16!("null")),
Self::Of => ("of", utf16!("of")),
Self::Return => ("return", utf16!("return")),
Self::Super => ("super", utf16!("super")),
Self::Switch => ("switch", utf16!("switch")),
Self::This => ("this", utf16!("this")),
Self::Throw => ("throw", utf16!("throw")),
Self::True => ("true", utf16!("true")),
Self::Try => ("try", utf16!("try")),
Self::TypeOf => ("typeof", utf16!("typeof")),
Self::Var => ("var", utf16!("var")),
Expand Down Expand Up @@ -557,7 +524,6 @@ impl Keyword {
Self::Enum => Sym::ENUM,
Self::Export => Sym::EXPORT,
Self::Extends => Sym::EXTENDS,
Self::False => Sym::FALSE,
Self::Finally => Sym::FINALLY,
Self::For => Sym::FOR,
Self::Function => Sym::FUNCTION,
Expand All @@ -567,14 +533,12 @@ impl Keyword {
Self::Import => Sym::IMPORT,
Self::Let => Sym::LET,
Self::New => Sym::NEW,
Self::Null => Sym::NULL,
Self::Of => Sym::OF,
Self::Return => Sym::RETURN,
Self::Super => Sym::SUPER,
Self::Switch => Sym::SWITCH,
Self::This => Sym::THIS,
Self::Throw => Sym::THROW,
Self::True => Sym::TRUE,
Self::Try => Sym::TRY,
Self::TypeOf => Sym::TYPEOF,
Self::Var => Sym::VAR,
Expand Down Expand Up @@ -629,7 +593,6 @@ impl FromStr for Keyword {
"enum" => Ok(Self::Enum),
"extends" => Ok(Self::Extends),
"export" => Ok(Self::Export),
"false" => Ok(Self::False),
"finally" => Ok(Self::Finally),
"for" => Ok(Self::For),
"function" => Ok(Self::Function),
Expand All @@ -639,14 +602,12 @@ impl FromStr for Keyword {
"import" => Ok(Self::Import),
"let" => Ok(Self::Let),
"new" => Ok(Self::New),
"null" => Ok(Self::Null),
"of" => Ok(Self::Of),
"return" => Ok(Self::Return),
"super" => Ok(Self::Super),
"switch" => Ok(Self::Switch),
"this" => Ok(Self::This),
"throw" => Ok(Self::Throw),
"true" => Ok(Self::True),
"try" => Ok(Self::Try),
"typeof" => Ok(Self::TypeOf),
"var" => Ok(Self::Var),
Expand Down
21 changes: 0 additions & 21 deletions core/ast/src/keyword/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ fn all_keywords() -> impl Iterator<Item = Keyword> {
Keyword::Enum,
Keyword::Export,
Keyword::Extends,
Keyword::False,
Keyword::Finally,
Keyword::For,
Keyword::Function,
Expand All @@ -31,14 +30,12 @@ fn all_keywords() -> impl Iterator<Item = Keyword> {
Keyword::Import,
Keyword::Let,
Keyword::New,
Keyword::Null,
Keyword::Of,
Keyword::Return,
Keyword::Super,
Keyword::Switch,
Keyword::This,
Keyword::Throw,
Keyword::True,
Keyword::Try,
Keyword::TypeOf,
Keyword::Var,
Expand Down Expand Up @@ -135,10 +132,6 @@ fn as_str() {
assert_eq!(k, Keyword::Export);
assert_eq!(utf16, utf16!("export"));
}
("false", utf16) => {
assert_eq!(k, Keyword::False);
assert_eq!(utf16, utf16!("false"));
}
("finally", utf16) => {
assert_eq!(k, Keyword::Finally);
assert_eq!(utf16, utf16!("finally"));
Expand Down Expand Up @@ -175,10 +168,6 @@ fn as_str() {
assert_eq!(k, Keyword::New);
assert_eq!(utf16, utf16!("new"));
}
("null", utf16) => {
assert_eq!(k, Keyword::Null);
assert_eq!(utf16, utf16!("null"));
}
("of", utf16) => {
assert_eq!(k, Keyword::Of);
assert_eq!(utf16, utf16!("of"));
Expand All @@ -203,10 +192,6 @@ fn as_str() {
assert_eq!(k, Keyword::Throw);
assert_eq!(utf16, utf16!("throw"));
}
("true", utf16) => {
assert_eq!(k, Keyword::True);
assert_eq!(utf16, utf16!("true"));
}
("try", utf16) => {
assert_eq!(k, Keyword::Try);
assert_eq!(utf16, utf16!("try"));
Expand Down Expand Up @@ -260,7 +245,6 @@ fn to_sym() {
Sym::ENUM => assert_eq!(k, Keyword::Enum),
Sym::EXPORT => assert_eq!(k, Keyword::Export),
Sym::EXTENDS => assert_eq!(k, Keyword::Extends),
Sym::FALSE => assert_eq!(k, Keyword::False),
Sym::FINALLY => assert_eq!(k, Keyword::Finally),
Sym::FOR => assert_eq!(k, Keyword::For),
Sym::FUNCTION => assert_eq!(k, Keyword::Function),
Expand All @@ -270,14 +254,12 @@ fn to_sym() {
Sym::IMPORT => assert_eq!(k, Keyword::Import),
Sym::LET => assert_eq!(k, Keyword::Let),
Sym::NEW => assert_eq!(k, Keyword::New),
Sym::NULL => assert_eq!(k, Keyword::Null),
Sym::OF => assert_eq!(k, Keyword::Of),
Sym::RETURN => assert_eq!(k, Keyword::Return),
Sym::SUPER => assert_eq!(k, Keyword::Super),
Sym::SWITCH => assert_eq!(k, Keyword::Switch),
Sym::THIS => assert_eq!(k, Keyword::This),
Sym::THROW => assert_eq!(k, Keyword::Throw),
Sym::TRUE => assert_eq!(k, Keyword::True),
Sym::TRY => assert_eq!(k, Keyword::Try),
Sym::TYPEOF => assert_eq!(k, Keyword::TypeOf),
Sym::VAR => assert_eq!(k, Keyword::Var),
Expand Down Expand Up @@ -311,22 +293,19 @@ fn try_into_binary_op() {
| Keyword::Enum
| Keyword::Export
| Keyword::Extends
| Keyword::False
| Keyword::Finally
| Keyword::For
| Keyword::Function
| Keyword::If
| Keyword::Import
| Keyword::Let
| Keyword::New
| Keyword::Null
| Keyword::Of
| Keyword::Return
| Keyword::Super
| Keyword::Switch
| Keyword::This
| Keyword::Throw
| Keyword::True
| Keyword::Try
| Keyword::TypeOf
| Keyword::Var
Expand Down
12 changes: 6 additions & 6 deletions core/parser/src/lexer/identifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::lexer::{
token::ContainsEscapeSequence, Cursor, Error, StringLiteral, Token, TokenKind, Tokenizer,
};
use crate::source::ReadChar;
use boa_ast::{Keyword, Position, Span};
use boa_ast::{Position, Span};
use boa_interner::Interner;
use boa_profiler::Profiler;

Expand Down Expand Up @@ -68,17 +68,17 @@ impl<R> Tokenizer<R> for Identifier {
Self::take_identifier_name(cursor, start_pos, self.init)?;

let token_kind = match identifier_name.parse() {
Ok(Keyword::True) => {
Ok(keyword) => TokenKind::Keyword((keyword, contains_escaped_chars)),
Err(_) if identifier_name == "true" => {
TokenKind::BooleanLiteral((true, ContainsEscapeSequence(contains_escaped_chars)))
}
Ok(Keyword::False) => {
Err(_) if identifier_name == "false" => {
TokenKind::BooleanLiteral((false, ContainsEscapeSequence(contains_escaped_chars)))
}
Ok(Keyword::Null) => {
Err(_) if identifier_name == "null" => {
TokenKind::NullLiteral(ContainsEscapeSequence(contains_escaped_chars))
}
Ok(keyword) => TokenKind::Keyword((keyword, contains_escaped_chars)),
_ => TokenKind::IdentifierName((
Err(_) => TokenKind::IdentifierName((
interner.get_or_intern(identifier_name.as_str()),
ContainsEscapeSequence(contains_escaped_chars),
)),
Expand Down
4 changes: 4 additions & 0 deletions core/parser/src/parser/statement/declaration/export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,10 @@ where
}
TokenKind::IdentifierName((ident, _)) => Ok((*ident, false)),
TokenKind::Keyword((kw, _)) => Ok((kw.to_sym(), false)),
TokenKind::BooleanLiteral((b, _)) => {
Ok((if *b { Sym::TRUE } else { Sym::FALSE }, false))
}
TokenKind::NullLiteral(_) => Ok((Sym::NULL, false)),
_ => Err(Error::expected(
["identifier".to_owned(), "string literal".to_owned()],
tok.to_string(interner),
Expand Down
43 changes: 40 additions & 3 deletions core/parser/src/parser/statement/declaration/tests.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use crate::parser::tests::{check_invalid_script, check_script_parser};
use crate::parser::tests::{check_invalid_script, check_module_parser, check_script_parser};
use boa_ast::{
declaration::{LexicalDeclaration, VarDeclaration, Variable},
declaration::{
ExportDeclaration, ExportSpecifier, LexicalDeclaration, VarDeclaration, Variable,
},
expression::literal::Literal,
Declaration, Statement,
Declaration, ModuleItem, Statement,
};
use boa_interner::{Interner, Sym};
use boa_macros::utf16;
Expand Down Expand Up @@ -360,3 +362,38 @@ fn lexical_declaration_early_errors() {
check_invalid_script("for (let a = 0, a = 0; ; ) {}");
check_invalid_script("for (const a = 0, a = 0; ; ) {}");
}

/// Checks module exports with reserved keywords
#[test]
fn module_export_reserved() {
let interner = &mut Interner::default();
let val = interner.get_or_intern_static("val", utf16!("val"));
check_module_parser(
r#"
const val = null;
export { val as null, val as true, val as false };
"#,
vec![
ModuleItem::StatementListItem(
Declaration::Lexical(LexicalDeclaration::Const(
vec![Variable::from_identifier(
val.into(),
Some(Literal::Null.into()),
)]
.try_into()
.unwrap(),
))
.into(),
),
ModuleItem::ExportDeclaration(ExportDeclaration::List(
vec![
ExportSpecifier::new(Sym::NULL, val, false),
ExportSpecifier::new(Sym::TRUE, val, false),
ExportSpecifier::new(Sym::FALSE, val, false),
]
.into(),
)),
],
interner,
);
}
20 changes: 19 additions & 1 deletion core/parser/src/parser/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ use boa_ast::{
},
scope::Scope,
statement::{If, Return},
Expression, Script, Statement, StatementList, StatementListItem,
Expression, Module, ModuleItem, ModuleItemList, Script, Statement, StatementList,
StatementListItem,
};
use boa_interner::Interner;
use boa_macros::utf16;
Expand All @@ -46,6 +47,23 @@ where
);
}

/// Checks that the given JavaScript string gives the expected expression.
#[track_caller]
pub(super) fn check_module_parser<L>(js: &str, expr: L, interner: &mut Interner)
where
L: Into<Box<[ModuleItem]>>,
{
let mut module = Module::new(ModuleItemList::from(expr.into()));
let scope = Scope::new_global();
module.analyze_scope(&scope, interner);
assert_eq!(
Parser::new(Source::from_bytes(js))
.parse_module(&Scope::new_global(), interner)
.expect("failed to parse"),
module,
);
}

/// Checks that the given javascript string creates a parse error.
#[track_caller]
pub(super) fn check_invalid_script(js: &str) {
Expand Down

0 comments on commit 102c62b

Please sign in to comment.