From 9a6f89b828416164d24da58be1aa363f3473c85d Mon Sep 17 00:00:00 2001 From: jedel1043 Date: Wed, 17 May 2023 20:23:55 -0600 Subject: [PATCH] Parse `import` as call expression --- .../expression/left_hand_side/member.rs | 26 ++-------- .../parser/expression/left_hand_side/mod.rs | 50 +++++++++++++++---- 2 files changed, 43 insertions(+), 33 deletions(-) diff --git a/boa_parser/src/parser/expression/left_hand_side/member.rs b/boa_parser/src/parser/expression/left_hand_side/member.rs index 883eb39811e..e42c34fe729 100644 --- a/boa_parser/src/parser/expression/left_hand_side/member.rs +++ b/boa_parser/src/parser/expression/left_hand_side/member.rs @@ -10,14 +10,13 @@ use crate::{ lexer::{token::ContainsEscapeSequence, InputElement, TokenKind}, parser::{ expression::{ - left_hand_side::template::TaggedTemplateLiteral, primary::PrimaryExpression, - AssignmentExpression, Expression, + left_hand_side::template::TaggedTemplateLiteral, primary::PrimaryExpression, Expression, }, AllowAwait, AllowYield, Cursor, OrAbrupt, ParseResult, TokenParser, }, Error, }; -use ast::{expression::ImportCall, function::PrivateName}; +use ast::function::PrivateName; use boa_ast::{ self as ast, expression::{ @@ -74,7 +73,7 @@ where let token = cursor.peek(0, interner).or_abrupt()?; let mut lhs = match token.kind() { - TokenKind::Keyword((Keyword::New | Keyword::Super | Keyword::Import, true)) => { + TokenKind::Keyword((Keyword::New | Keyword::Super, true)) => { return Err(Error::general( "keyword must not contain escaped characters", token.span().start(), @@ -172,25 +171,6 @@ where } } } - TokenKind::Keyword((Keyword::Import, false)) => { - cursor.advance(interner); - cursor.expect( - TokenKind::Punctuator(Punctuator::OpenParen), - "import call", - interner, - )?; - - let arg = AssignmentExpression::new(None, true, self.allow_yield, self.allow_await) - .parse(cursor, interner)?; - - cursor.expect( - TokenKind::Punctuator(Punctuator::CloseParen), - "import call", - interner, - )?; - - ImportCall::new(arg).into() - } _ => PrimaryExpression::new(self.name, self.allow_yield, self.allow_await) .parse(cursor, interner)?, }; diff --git a/boa_parser/src/parser/expression/left_hand_side/mod.rs b/boa_parser/src/parser/expression/left_hand_side/mod.rs index 191c7a35a54..debbd42df47 100644 --- a/boa_parser/src/parser/expression/left_hand_side/mod.rs +++ b/boa_parser/src/parser/expression/left_hand_side/mod.rs @@ -19,15 +19,16 @@ mod template; use crate::{ lexer::{InputElement, TokenKind}, parser::{ - expression::left_hand_side::{ + expression::{left_hand_side::{ arguments::Arguments, call::CallExpression, member::MemberExpression, optional::OptionalExpression, - }, - AllowAwait, AllowYield, Cursor, ParseResult, TokenParser, + }, AssignmentExpression}, + AllowAwait, AllowYield, Cursor, OrAbrupt, ParseResult, TokenParser, }, + Error, }; use boa_ast::{ - expression::{Identifier, SuperCall}, + expression::{Identifier, SuperCall, ImportCall}, Expression, Keyword, Punctuator, }; use boa_interner::Interner; @@ -96,6 +97,7 @@ where } Ok(false) } + let _timer = Profiler::global().start_event("LeftHandSideExpression", "Parsing"); cursor.set_goal(InputElement::TemplateTail); @@ -106,15 +108,43 @@ where Arguments::new(self.allow_yield, self.allow_await).parse(cursor, interner)?; SuperCall::new(args).into() } else { - let mut member = MemberExpression::new(self.name, self.allow_yield, self.allow_await) - .parse(cursor, interner)?; - if let Some(tok) = cursor.peek(0, interner)? { - if tok.kind() == &TokenKind::Punctuator(Punctuator::OpenParen) { - member = CallExpression::new(self.allow_yield, self.allow_await, member) + let next = cursor.peek(0, interner).or_abrupt()?; + if let TokenKind::Keyword((Keyword::Import, escaped)) = next.kind() { + if *escaped { + return Err(Error::general( + "keyword `import` must not contain escaped characters", + next.span().start(), + )); + } + cursor.advance(interner); + cursor.expect( + TokenKind::Punctuator(Punctuator::OpenParen), + "import call", + interner, + )?; + + let arg = AssignmentExpression::new(None, true, self.allow_yield, self.allow_await) + .parse(cursor, interner)?; + + cursor.expect( + TokenKind::Punctuator(Punctuator::CloseParen), + "import call", + interner, + )?; + + ImportCall::new(arg).into() + } else { + let mut member = + MemberExpression::new(self.name, self.allow_yield, self.allow_await) .parse(cursor, interner)?; + if let Some(tok) = cursor.peek(0, interner)? { + if tok.kind() == &TokenKind::Punctuator(Punctuator::OpenParen) { + member = CallExpression::new(self.allow_yield, self.allow_await, member) + .parse(cursor, interner)?; + } } + member } - member }; if let Some(tok) = cursor.peek(0, interner)? {