From 1a4f5d6c38aeedde1bc9abfced5eb0447fb053ad Mon Sep 17 00:00:00 2001 From: RiESAEX <2597245950@qq.com> Date: Fri, 14 Jan 2022 19:23:17 +0800 Subject: [PATCH 1/5] use var for _len and _args --- .../src/es2015/parameters.rs | 2 +- .../tests/es2015_parameters.rs | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/crates/swc_ecma_transforms_compat/src/es2015/parameters.rs b/crates/swc_ecma_transforms_compat/src/es2015/parameters.rs index c28afecf2bb1..8b1834949cdd 100644 --- a/crates/swc_ecma_transforms_compat/src/es2015/parameters.rs +++ b/crates/swc_ecma_transforms_compat/src/es2015/parameters.rs @@ -278,7 +278,7 @@ impl Params { unpack_rest = Some(Stmt::For(ForStmt { span, init: Some(VarDeclOrExpr::VarDecl(VarDecl { - kind: VarDeclKind::Let, + kind: VarDeclKind::Var, span, decls: vec![ // _len = arguments.length - i diff --git a/crates/swc_ecma_transforms_compat/tests/es2015_parameters.rs b/crates/swc_ecma_transforms_compat/tests/es2015_parameters.rs index 9dffb91263d0..74f7335a751b 100644 --- a/crates/swc_ecma_transforms_compat/tests/es2015_parameters.rs +++ b/crates/swc_ecma_transforms_compat/tests/es2015_parameters.rs @@ -1628,7 +1628,7 @@ function foo(...a) { const a = 'bar'; function foo() { - for (let _len = arguments.length, a = new Array(_len), _key = 0; _key < _len; _key++) { + for (var _len = arguments.length, a = new Array(_len), _key = 0; _key < _len; _key++) { a[_key] = arguments[_key]; } @@ -1692,7 +1692,7 @@ test!( ", " const arrow = function() { - for(let _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){ + for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){ args[_key] = arguments[_key]; } console.log(args); @@ -1711,7 +1711,7 @@ test!( ", " const arrow = ()=>function() { - for(let _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){ + for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){ args[_key] = arguments[_key]; } console.log(args); @@ -1732,7 +1732,7 @@ test!( const arrow = ()=>{ var _this = this; return function() { - for(let _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; \ + for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; \ _key++){ args[_key] = arguments[_key]; } @@ -1755,7 +1755,7 @@ test!( const arrow = ()=>{ var _this = this; return this, function() { - for(let _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){ + for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){ args[_key] = arguments[_key]; } console.log(_this, args); @@ -1776,14 +1776,14 @@ test!( " var _this = this; const arrow = function() { - for(let _len1 = arguments.length, args = new Array(_len1), _key1 = 0; _key1 < _len1; \ + for(var _len1 = arguments.length, args = new Array(_len1), _key1 = 0; _key1 < _len1; \ _key1++){ args[_key1] = arguments[_key1]; } return _this, ()=>{ var _this1 = _this; return function() { - for(let _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; \ + for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; \ _key++){ args[_key] = arguments[_key]; } From e90b74fa3f6d0926d1ed051b6d645af1bddd6d43 Mon Sep 17 00:00:00 2001 From: RiESAEX <2597245950@qq.com> Date: Fri, 14 Jan 2022 19:54:44 +0800 Subject: [PATCH 2/5] update --- .../tests/es2017_async_to_generator.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/swc_ecma_transforms_compat/tests/es2017_async_to_generator.rs b/crates/swc_ecma_transforms_compat/tests/es2017_async_to_generator.rs index a5731cf18df1..8b70045c2a47 100644 --- a/crates/swc_ecma_transforms_compat/tests/es2017_async_to_generator.rs +++ b/crates/swc_ecma_transforms_compat/tests/es2017_async_to_generator.rs @@ -221,7 +221,7 @@ async function s(x, ...args) { } function _s() { _s = _asyncToGenerator(function*(x) { - for(let _len1 = arguments.length, args = new Array(_len1 > 1 ? _len1 - 1 : 0), _key1 = 1; _key1 < _len1; _key1++){ + for(var _len1 = arguments.length, args = new Array(_len1 > 1 ? _len1 - 1 : 0), _key1 = 1; _key1 < _len1; _key1++){ args[_key1 - 1] = arguments[_key1]; } var _this = this, _arguments = arguments; @@ -230,7 +230,7 @@ function _s() { var _this1 = _this, _arguments1 = _arguments; let r = function() { var _r = _asyncToGenerator(function*(z, b) { - for(let _len = arguments.length, innerArgs = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++){ + for(var _len = arguments.length, innerArgs = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++){ innerArgs[_key - 2] = arguments[_key]; } yield z; From 6bb99fbdc6a2561da507f6a951a2346dbed7133f Mon Sep 17 00:00:00 2001 From: RiESAEX <2597245950@qq.com> Date: Sat, 15 Jan 2022 21:34:44 +0800 Subject: [PATCH 3/5] fix(ecma/parser): throw IllegalLanguageModeDirective --- crates/swc_ecma_parser/src/error.rs | 4 + .../src/parser/class_and_fn.rs | 82 ++++++++++++++++--- crates/swc_ecma_parser/src/parser/expr.rs | 29 +++++-- crates/swc_ecma_parser/src/parser/tests.rs | 55 +++++++++++++ .../swc_ecma_parser/src/parser/typescript.rs | 6 +- 5 files changed, 153 insertions(+), 23 deletions(-) diff --git a/crates/swc_ecma_parser/src/error.rs b/crates/swc_ecma_parser/src/error.rs index 10773cb0dc85..9ae997b5f788 100644 --- a/crates/swc_ecma_parser/src/error.rs +++ b/crates/swc_ecma_parser/src/error.rs @@ -88,6 +88,7 @@ pub enum SyntaxError { InvalidIdentInStrict, /// 'eval' and 'arguments' are invalid identifier in strict mode. EvalAndArgumentsInStrict, + IllegalLanguageModeDirective, UnaryInExp { left: String, left_span: Span, @@ -300,6 +301,9 @@ impl SyntaxError { SyntaxError::EvalAndArgumentsInStrict => "'eval' and 'arguments' cannot be used as a \ binding identifier in strict mode" .into(), + SyntaxError::IllegalLanguageModeDirective => { + "Illegal 'use strict' directive in function with non-simple parameter list.".into() + } SyntaxError::UnaryInExp { .. } => "** cannot be applied to unary expression".into(), SyntaxError::Hash => "Unexpected token '#'".into(), SyntaxError::LineBreakInThrow => "LineBreak cannot follow 'throw'".into(), diff --git a/crates/swc_ecma_parser/src/parser/class_and_fn.rs b/crates/swc_ecma_parser/src/parser/class_and_fn.rs index f3fad4db8912..91dfb3a181e5 100644 --- a/crates/swc_ecma_parser/src/parser/class_and_fn.rs +++ b/crates/swc_ecma_parser/src/parser/class_and_fn.rs @@ -1,5 +1,5 @@ use super::{ident::MaybeOptionalIdentParser, *}; -use crate::{error::SyntaxError, lexer::TokenContext, Tokens}; +use crate::{error::SyntaxError, lexer::TokenContext, parser::stmt::IsDirective, Tokens}; use either::Either; use swc_atoms::js_word; use swc_common::{Spanned, SyntaxContext}; @@ -667,7 +667,8 @@ impl<'a, I: Tokens> Parser { self.emit_err(type_ann.type_ann.span(), SyntaxError::TS1093); } - let body: Option<_> = self.parse_fn_body(false, false)?; + let body: Option<_> = + self.parse_fn_body(false, false, params.is_simple_parameter_list())?; if self.syntax().typescript() && body.is_none() { // Declare constructors cannot have assignment pattern in parameters @@ -1110,7 +1111,8 @@ impl<'a, I: Tokens> Parser { None }; - let body: Option<_> = p.parse_fn_body(is_async, is_generator)?; + let body: Option<_> = + p.parse_fn_body(is_async, is_generator, params.is_simple_parameter_list())?; if p.syntax().typescript() && body.is_none() { // Declare functions cannot have assignment pattern in parameters @@ -1149,7 +1151,12 @@ impl<'a, I: Tokens> Parser { } } - pub(super) fn parse_fn_body(&mut self, is_async: bool, is_generator: bool) -> PResult + pub(super) fn parse_fn_body( + &mut self, + is_async: bool, + is_generator: bool, + is_simple_parameter_list: bool, + ) -> PResult where Self: FnBodyParser, { @@ -1173,7 +1180,9 @@ impl<'a, I: Tokens> Parser { labels: vec![], ..Default::default() }; - self.with_ctx(ctx).with_state(state).parse_fn_body_inner() + self.with_ctx(ctx) + .with_state(state) + .parse_fn_body_inner(is_simple_parameter_list) } } @@ -1373,13 +1382,25 @@ impl OutputType for Decl { } pub(super) trait FnBodyParser { - fn parse_fn_body_inner(&mut self) -> PResult; + fn parse_fn_body_inner(&mut self, is_simple_parameter_list: bool) -> PResult; +} +fn has_use_strict(block: &BlockStmt) -> Option { + match block.stmts.iter().find(|stmt| stmt.is_use_strict()) { + Some(Stmt::Expr(ExprStmt { span, expr: _ })) => Some(*span), + _ => None, + } } - impl FnBodyParser for Parser { - fn parse_fn_body_inner(&mut self) -> PResult { + fn parse_fn_body_inner(&mut self, is_simple_parameter_list: bool) -> PResult { if is!(self, '{') { - self.parse_block(false).map(BlockStmtOrExpr::BlockStmt) + self.parse_block(false).map(|block_stmt| { + if !is_simple_parameter_list { + if let Some(span) = has_use_strict(&block_stmt) { + self.emit_err(span, SyntaxError::IllegalLanguageModeDirective); + } + } + BlockStmtOrExpr::BlockStmt(block_stmt) + }) } else { self.parse_assignment_expr().map(BlockStmtOrExpr::Expr) } @@ -1387,12 +1408,51 @@ impl FnBodyParser for Parser { } impl FnBodyParser> for Parser { - fn parse_fn_body_inner(&mut self) -> PResult> { + fn parse_fn_body_inner( + &mut self, + is_simple_parameter_list: bool, + ) -> PResult> { // allow omitting body and allow placing `{` on next line if self.input.syntax().typescript() && !is!(self, '{') && eat!(self, ';') { return Ok(None); } - self.include_in_expr(true).parse_block(true).map(Some) + let block = self.include_in_expr(true).parse_block(true); + block.map(|block_stmt| { + if !is_simple_parameter_list { + if let Some(span) = has_use_strict(&block_stmt) { + self.emit_err(span, SyntaxError::IllegalLanguageModeDirective); + } + } + Some(block_stmt) + }) + } +} + +pub(super) trait IsSimpleParameterList { + fn is_simple_parameter_list(&self) -> bool; +} +impl IsSimpleParameterList for Vec { + fn is_simple_parameter_list(&self) -> bool { + !self.iter().any(|param| !matches!(param.pat, Pat::Ident(_))) + } +} +impl IsSimpleParameterList for Vec { + fn is_simple_parameter_list(&self) -> bool { + !self.iter().any(|pat| !matches!(pat, Pat::Ident(_))) + } +} +impl IsSimpleParameterList for Vec { + fn is_simple_parameter_list(&self) -> bool { + !self.iter().any(|param| { + !matches!( + param, + ParamOrTsParamProp::TsParamProp(..) + | ParamOrTsParamProp::Param(Param { + pat: Pat::Ident(_), + .. + }) + ) + }) } } diff --git a/crates/swc_ecma_parser/src/parser/expr.rs b/crates/swc_ecma_parser/src/parser/expr.rs index 3a9933847121..461d50fc45e1 100644 --- a/crates/swc_ecma_parser/src/parser/expr.rs +++ b/crates/swc_ecma_parser/src/parser/expr.rs @@ -1,5 +1,7 @@ use super::{pat::PatType, util::ExprExt, *}; -use crate::{lexer::TokenContext, token::AssignOpToken}; +use crate::{ + lexer::TokenContext, parser::class_and_fn::IsSimpleParameterList, token::AssignOpToken, +}; use either::Either; use swc_atoms::js_word; use swc_common::{ast_node, util::take::Take, Spanned}; @@ -394,7 +396,7 @@ impl<'a, I: Tokens> Parser { let arg = Pat::from(ident); let params = vec![arg]; expect!(self, "=>"); - let body = self.parse_fn_body(true, false)?; + let body = self.parse_fn_body(true, false, params.is_simple_parameter_list())?; return Ok(Box::new(Expr::Arrow(ArrowExpr { span: span!(self, start), @@ -407,7 +409,7 @@ impl<'a, I: Tokens> Parser { }))); } else if can_be_arrow && !self.input.had_line_break_before_cur() && eat!(self, "=>") { let params = vec![id.into()]; - let body = self.parse_fn_body(false, false)?; + let body = self.parse_fn_body(false, false, params.is_simple_parameter_list())?; return Ok(Box::new(Expr::Arrow(ArrowExpr { span: span!(self, start), @@ -681,12 +683,16 @@ impl<'a, I: Tokens> Parser { expect!(p, "=>"); - let params = p + let params: Vec = p .parse_paren_items_as_params(items_ref.clone())? .into_iter() .collect(); - let body: BlockStmtOrExpr = p.parse_fn_body(async_span.is_some(), false)?; + let body: BlockStmtOrExpr = p.parse_fn_body( + async_span.is_some(), + false, + params.is_simple_parameter_list(), + )?; if is_direct_child_of_cond { if !is_one_of!(p, ':', ';') { @@ -733,12 +739,16 @@ impl<'a, I: Tokens> Parser { } expect!(self, "=>"); - let params = self + let params: Vec = self .parse_paren_items_as_params(paren_items)? .into_iter() .collect(); - let body: BlockStmtOrExpr = self.parse_fn_body(async_span.is_some(), false)?; + let body: BlockStmtOrExpr = self.parse_fn_body( + async_span.is_some(), + false, + params.is_simple_parameter_list(), + )?; let arrow_expr = ArrowExpr { span: span!(self, expr_start), is_async: async_span.is_some(), @@ -1633,12 +1643,13 @@ impl<'a, I: Tokens> Parser { _ => false, } } { - let params = self + let params: Vec = self .parse_paren_items_as_params(items.clone())? .into_iter() .collect(); - let body: BlockStmtOrExpr = self.parse_fn_body(false, false)?; + let body: BlockStmtOrExpr = + self.parse_fn_body(false, false, params.is_simple_parameter_list())?; let span = span!(self, start); items.push(PatOrExprOrSpread::ExprOrSpread(ExprOrSpread { diff --git a/crates/swc_ecma_parser/src/parser/tests.rs b/crates/swc_ecma_parser/src/parser/tests.rs index b27151428fda..e13b9b708cc6 100644 --- a/crates/swc_ecma_parser/src/parser/tests.rs +++ b/crates/swc_ecma_parser/src/parser/tests.rs @@ -301,3 +301,58 @@ fn issue_2853_2() { Ok(program) }); } + +#[test] +fn illegal_language_mode_directive1() { + test_parser( + r#"function f(a = 0) { "use strict"; }"#, + Default::default(), + |p| { + let program = p.parse_program()?; + + let errors = p.take_errors(); + assert_eq!( + errors, + vec![Error { + error: Box::new(( + Span { + lo: BytePos(20), + hi: BytePos(33), + ctxt: swc_common::SyntaxContext::empty() + }, + crate::parser::SyntaxError::IllegalLanguageModeDirective + )) + }] + ); + + Ok(program) + }, + ); +} +#[test] +fn illegal_language_mode_directive2() { + test_parser( + r#"let f = (a = 0) => { "use strict"; }"#, + Default::default(), + |p| { + let program = p.parse_program()?; + + let errors = p.take_errors(); + assert_eq!( + errors, + vec![Error { + error: Box::new(( + Span { + lo: BytePos(21), + hi: BytePos(34), + ctxt: swc_common::SyntaxContext::empty() + }, + crate::parser::SyntaxError::IllegalLanguageModeDirective + )) + }] + ); + + Ok(program) + }, + ); +} diff --git a/crates/swc_ecma_parser/src/parser/typescript.rs b/crates/swc_ecma_parser/src/parser/typescript.rs index 77c668823616..1bd89a69f8d3 100644 --- a/crates/swc_ecma_parser/src/parser/typescript.rs +++ b/crates/swc_ecma_parser/src/parser/typescript.rs @@ -1,5 +1,5 @@ use super::*; -use crate::lexer::TokenContexts; +use crate::{lexer::TokenContexts, parser::class_and_fn::IsSimpleParameterList}; use either::Either; use swc_atoms::js_word; use swc_common::{Spanned, SyntaxContext}; @@ -2474,7 +2474,7 @@ impl Parser { let type_params = p.parse_ts_type_params()?; // Don't use overloaded parseFunctionParams which would look for "<" again. expect!(p, '('); - let params = p + let params: Vec = p .parse_formal_params()? .into_iter() .map(|p| p.pat) @@ -2502,7 +2502,7 @@ impl Parser { self.with_ctx(ctx).parse_with(|p| { let is_generator = false; let is_async = true; - let body = p.parse_fn_body(true, false)?; + let body = p.parse_fn_body(true, false, params.is_simple_parameter_list())?; Ok(Some(ArrowExpr { span: span!(p, start), body, From ddfcb7e18144691cb21aad65ef82274f6b123768 Mon Sep 17 00:00:00 2001 From: RiESAEX <2597245950@qq.com> Date: Sat, 15 Jan 2022 21:50:09 +0800 Subject: [PATCH 4/5] refactor --- crates/swc_ecma_parser/src/parser/class_and_fn.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/swc_ecma_parser/src/parser/class_and_fn.rs b/crates/swc_ecma_parser/src/parser/class_and_fn.rs index 91dfb3a181e5..bbae51da1d5d 100644 --- a/crates/swc_ecma_parser/src/parser/class_and_fn.rs +++ b/crates/swc_ecma_parser/src/parser/class_and_fn.rs @@ -1433,18 +1433,18 @@ pub(super) trait IsSimpleParameterList { } impl IsSimpleParameterList for Vec { fn is_simple_parameter_list(&self) -> bool { - !self.iter().any(|param| !matches!(param.pat, Pat::Ident(_))) + self.iter().all(|param| matches!(param.pat, Pat::Ident(_))) } } impl IsSimpleParameterList for Vec { fn is_simple_parameter_list(&self) -> bool { - !self.iter().any(|pat| !matches!(pat, Pat::Ident(_))) + self.iter().all(|pat| matches!(pat, Pat::Ident(_))) } } impl IsSimpleParameterList for Vec { fn is_simple_parameter_list(&self) -> bool { - !self.iter().any(|param| { - !matches!( + self.iter().all(|param| { + matches!( param, ParamOrTsParamProp::TsParamProp(..) | ParamOrTsParamProp::Param(Param { From fa4e3ab15286c6b58758d2b560b241378a223d54 Mon Sep 17 00:00:00 2001 From: RiESAEX <2597245950@qq.com> Date: Sat, 15 Jan 2022 23:29:20 +0800 Subject: [PATCH 5/5] add test, don't emit error in ts --- .../src/parser/class_and_fn.rs | 4 +- .../span/js/issue-3236/arrow_function.js | 3 + .../js/issue-3236/arrow_function.js.spans | 169 ++++++++++++++++++ .../tests/span/js/issue-3236/function.js | 3 + .../span/js/issue-3236/function.js.spans | 141 +++++++++++++++ .../tests/typescript/issue-3236/input.ts | 3 + .../tests/typescript/issue-3236/input.ts.json | 107 +++++++++++ 7 files changed, 428 insertions(+), 2 deletions(-) create mode 100644 crates/swc_ecma_parser/tests/span/js/issue-3236/arrow_function.js create mode 100644 crates/swc_ecma_parser/tests/span/js/issue-3236/arrow_function.js.spans create mode 100644 crates/swc_ecma_parser/tests/span/js/issue-3236/function.js create mode 100644 crates/swc_ecma_parser/tests/span/js/issue-3236/function.js.spans create mode 100644 crates/swc_ecma_parser/tests/typescript/issue-3236/input.ts create mode 100644 crates/swc_ecma_parser/tests/typescript/issue-3236/input.ts.json diff --git a/crates/swc_ecma_parser/src/parser/class_and_fn.rs b/crates/swc_ecma_parser/src/parser/class_and_fn.rs index bbae51da1d5d..03434c254c82 100644 --- a/crates/swc_ecma_parser/src/parser/class_and_fn.rs +++ b/crates/swc_ecma_parser/src/parser/class_and_fn.rs @@ -1394,7 +1394,7 @@ impl FnBodyParser for Parser { fn parse_fn_body_inner(&mut self, is_simple_parameter_list: bool) -> PResult { if is!(self, '{') { self.parse_block(false).map(|block_stmt| { - if !is_simple_parameter_list { + if !self.input.syntax().typescript() && !is_simple_parameter_list { if let Some(span) = has_use_strict(&block_stmt) { self.emit_err(span, SyntaxError::IllegalLanguageModeDirective); } @@ -1418,7 +1418,7 @@ impl FnBodyParser> for Parser { } let block = self.include_in_expr(true).parse_block(true); block.map(|block_stmt| { - if !is_simple_parameter_list { + if !self.input.syntax().typescript() && !is_simple_parameter_list { if let Some(span) = has_use_strict(&block_stmt) { self.emit_err(span, SyntaxError::IllegalLanguageModeDirective); } diff --git a/crates/swc_ecma_parser/tests/span/js/issue-3236/arrow_function.js b/crates/swc_ecma_parser/tests/span/js/issue-3236/arrow_function.js new file mode 100644 index 000000000000..ab95598da68a --- /dev/null +++ b/crates/swc_ecma_parser/tests/span/js/issue-3236/arrow_function.js @@ -0,0 +1,3 @@ +let f = (a = 0) => { + "use strict"; +} \ No newline at end of file diff --git a/crates/swc_ecma_parser/tests/span/js/issue-3236/arrow_function.js.spans b/crates/swc_ecma_parser/tests/span/js/issue-3236/arrow_function.js.spans new file mode 100644 index 000000000000..3daff15aa2cb --- /dev/null +++ b/crates/swc_ecma_parser/tests/span/js/issue-3236/arrow_function.js.spans @@ -0,0 +1,169 @@ +warning: Module + --> $DIR/tests/span/js/issue-3236/arrow_function.js:1:1 + | +1 | / let f = (a = 0) => { +2 | | "use strict"; +3 | | } + | |_^ + +warning: ModuleItem + --> $DIR/tests/span/js/issue-3236/arrow_function.js:1:1 + | +1 | / let f = (a = 0) => { +2 | | "use strict"; +3 | | } + | |_^ + +warning: Stmt + --> $DIR/tests/span/js/issue-3236/arrow_function.js:1:1 + | +1 | / let f = (a = 0) => { +2 | | "use strict"; +3 | | } + | |_^ + +warning: Decl + --> $DIR/tests/span/js/issue-3236/arrow_function.js:1:1 + | +1 | / let f = (a = 0) => { +2 | | "use strict"; +3 | | } + | |_^ + +warning: VarDecl + --> $DIR/tests/span/js/issue-3236/arrow_function.js:1:1 + | +1 | / let f = (a = 0) => { +2 | | "use strict"; +3 | | } + | |_^ + +warning: VarDeclarator + --> $DIR/tests/span/js/issue-3236/arrow_function.js:1:5 + | +1 | let f = (a = 0) => { + | _____^ +2 | | "use strict"; +3 | | } + | |_^ + +warning: Pat + --> $DIR/tests/span/js/issue-3236/arrow_function.js:1:5 + | +1 | let f = (a = 0) => { + | ^ + +warning: Ident + --> $DIR/tests/span/js/issue-3236/arrow_function.js:1:5 + | +1 | let f = (a = 0) => { + | ^ + +warning: Expr + --> $DIR/tests/span/js/issue-3236/arrow_function.js:1:9 + | +1 | let f = (a = 0) => { + | _________^ +2 | | "use strict"; +3 | | } + | |_^ + +warning: ArrowExpr + --> $DIR/tests/span/js/issue-3236/arrow_function.js:1:9 + | +1 | let f = (a = 0) => { + | _________^ +2 | | "use strict"; +3 | | } + | |_^ + +warning: Pat + --> $DIR/tests/span/js/issue-3236/arrow_function.js:1:10 + | +1 | let f = (a = 0) => { + | ^^^^^ + +warning: AssignPat + --> $DIR/tests/span/js/issue-3236/arrow_function.js:1:10 + | +1 | let f = (a = 0) => { + | ^^^^^ + +warning: Pat + --> $DIR/tests/span/js/issue-3236/arrow_function.js:1:10 + | +1 | let f = (a = 0) => { + | ^ + +warning: Ident + --> $DIR/tests/span/js/issue-3236/arrow_function.js:1:10 + | +1 | let f = (a = 0) => { + | ^ + +warning: Expr + --> $DIR/tests/span/js/issue-3236/arrow_function.js:1:14 + | +1 | let f = (a = 0) => { + | ^ + +warning: Lit + --> $DIR/tests/span/js/issue-3236/arrow_function.js:1:14 + | +1 | let f = (a = 0) => { + | ^ + +warning: Number + --> $DIR/tests/span/js/issue-3236/arrow_function.js:1:14 + | +1 | let f = (a = 0) => { + | ^ + +warning: BlockStmtOrExpr + --> $DIR/tests/span/js/issue-3236/arrow_function.js:1:20 + | +1 | let f = (a = 0) => { + | ____________________^ +2 | | "use strict"; +3 | | } + | |_^ + +warning: BlockStmt + --> $DIR/tests/span/js/issue-3236/arrow_function.js:1:20 + | +1 | let f = (a = 0) => { + | ____________________^ +2 | | "use strict"; +3 | | } + | |_^ + +warning: Stmt + --> $DIR/tests/span/js/issue-3236/arrow_function.js:2:5 + | +2 | "use strict"; + | ^^^^^^^^^^^^^ + +warning: ExprStmt + --> $DIR/tests/span/js/issue-3236/arrow_function.js:2:5 + | +2 | "use strict"; + | ^^^^^^^^^^^^^ + +warning: Expr + --> $DIR/tests/span/js/issue-3236/arrow_function.js:2:5 + | +2 | "use strict"; + | ^^^^^^^^^^^^ + +warning: Lit + --> $DIR/tests/span/js/issue-3236/arrow_function.js:2:5 + | +2 | "use strict"; + | ^^^^^^^^^^^^ + +warning: Str + --> $DIR/tests/span/js/issue-3236/arrow_function.js:2:5 + | +2 | "use strict"; + | ^^^^^^^^^^^^ + diff --git a/crates/swc_ecma_parser/tests/span/js/issue-3236/function.js b/crates/swc_ecma_parser/tests/span/js/issue-3236/function.js new file mode 100644 index 000000000000..2cdd2686e42c --- /dev/null +++ b/crates/swc_ecma_parser/tests/span/js/issue-3236/function.js @@ -0,0 +1,3 @@ +function f(a = 0) { + "use strict"; +} \ No newline at end of file diff --git a/crates/swc_ecma_parser/tests/span/js/issue-3236/function.js.spans b/crates/swc_ecma_parser/tests/span/js/issue-3236/function.js.spans new file mode 100644 index 000000000000..a8d9d59fc46e --- /dev/null +++ b/crates/swc_ecma_parser/tests/span/js/issue-3236/function.js.spans @@ -0,0 +1,141 @@ +warning: Module + --> $DIR/tests/span/js/issue-3236/function.js:1:1 + | +1 | / function f(a = 0) { +2 | | "use strict"; +3 | | } + | |_^ + +warning: ModuleItem + --> $DIR/tests/span/js/issue-3236/function.js:1:1 + | +1 | / function f(a = 0) { +2 | | "use strict"; +3 | | } + | |_^ + +warning: Stmt + --> $DIR/tests/span/js/issue-3236/function.js:1:1 + | +1 | / function f(a = 0) { +2 | | "use strict"; +3 | | } + | |_^ + +warning: Decl + --> $DIR/tests/span/js/issue-3236/function.js:1:1 + | +1 | / function f(a = 0) { +2 | | "use strict"; +3 | | } + | |_^ + +warning: FnDecl + --> $DIR/tests/span/js/issue-3236/function.js:1:1 + | +1 | / function f(a = 0) { +2 | | "use strict"; +3 | | } + | |_^ + +warning: Ident + --> $DIR/tests/span/js/issue-3236/function.js:1:10 + | +1 | function f(a = 0) { + | ^ + +warning: Function + --> $DIR/tests/span/js/issue-3236/function.js:1:1 + | +1 | / function f(a = 0) { +2 | | "use strict"; +3 | | } + | |_^ + +warning: Param + --> $DIR/tests/span/js/issue-3236/function.js:1:12 + | +1 | function f(a = 0) { + | ^^^^^ + +warning: Pat + --> $DIR/tests/span/js/issue-3236/function.js:1:12 + | +1 | function f(a = 0) { + | ^^^^^ + +warning: AssignPat + --> $DIR/tests/span/js/issue-3236/function.js:1:12 + | +1 | function f(a = 0) { + | ^^^^^ + +warning: Pat + --> $DIR/tests/span/js/issue-3236/function.js:1:12 + | +1 | function f(a = 0) { + | ^ + +warning: Ident + --> $DIR/tests/span/js/issue-3236/function.js:1:12 + | +1 | function f(a = 0) { + | ^ + +warning: Expr + --> $DIR/tests/span/js/issue-3236/function.js:1:16 + | +1 | function f(a = 0) { + | ^ + +warning: Lit + --> $DIR/tests/span/js/issue-3236/function.js:1:16 + | +1 | function f(a = 0) { + | ^ + +warning: Number + --> $DIR/tests/span/js/issue-3236/function.js:1:16 + | +1 | function f(a = 0) { + | ^ + +warning: BlockStmt + --> $DIR/tests/span/js/issue-3236/function.js:1:19 + | +1 | function f(a = 0) { + | ___________________^ +2 | | "use strict"; +3 | | } + | |_^ + +warning: Stmt + --> $DIR/tests/span/js/issue-3236/function.js:2:5 + | +2 | "use strict"; + | ^^^^^^^^^^^^^ + +warning: ExprStmt + --> $DIR/tests/span/js/issue-3236/function.js:2:5 + | +2 | "use strict"; + | ^^^^^^^^^^^^^ + +warning: Expr + --> $DIR/tests/span/js/issue-3236/function.js:2:5 + | +2 | "use strict"; + | ^^^^^^^^^^^^ + +warning: Lit + --> $DIR/tests/span/js/issue-3236/function.js:2:5 + | +2 | "use strict"; + | ^^^^^^^^^^^^ + +warning: Str + --> $DIR/tests/span/js/issue-3236/function.js:2:5 + | +2 | "use strict"; + | ^^^^^^^^^^^^ + diff --git a/crates/swc_ecma_parser/tests/typescript/issue-3236/input.ts b/crates/swc_ecma_parser/tests/typescript/issue-3236/input.ts new file mode 100644 index 000000000000..2cdd2686e42c --- /dev/null +++ b/crates/swc_ecma_parser/tests/typescript/issue-3236/input.ts @@ -0,0 +1,3 @@ +function f(a = 0) { + "use strict"; +} \ No newline at end of file diff --git a/crates/swc_ecma_parser/tests/typescript/issue-3236/input.ts.json b/crates/swc_ecma_parser/tests/typescript/issue-3236/input.ts.json new file mode 100644 index 000000000000..66d5e49a1346 --- /dev/null +++ b/crates/swc_ecma_parser/tests/typescript/issue-3236/input.ts.json @@ -0,0 +1,107 @@ +{ + "type": "Script", + "span": { + "start": 0, + "end": 39, + "ctxt": 0 + }, + "body": [ + { + "type": "FunctionDeclaration", + "identifier": { + "type": "Identifier", + "span": { + "start": 9, + "end": 10, + "ctxt": 0 + }, + "value": "f", + "optional": false + }, + "declare": false, + "params": [ + { + "type": "Parameter", + "span": { + "start": 11, + "end": 16, + "ctxt": 0 + }, + "decorators": [], + "pat": { + "type": "AssignmentPattern", + "span": { + "start": 11, + "end": 16, + "ctxt": 0 + }, + "left": { + "type": "Identifier", + "span": { + "start": 11, + "end": 12, + "ctxt": 0 + }, + "value": "a", + "optional": false, + "typeAnnotation": null + }, + "right": { + "type": "NumericLiteral", + "span": { + "start": 15, + "end": 16, + "ctxt": 0 + }, + "value": 0.0 + }, + "typeAnnotation": null + } + } + ], + "decorators": [], + "span": { + "start": 0, + "end": 39, + "ctxt": 0 + }, + "body": { + "type": "BlockStatement", + "span": { + "start": 18, + "end": 39, + "ctxt": 0 + }, + "stmts": [ + { + "type": "ExpressionStatement", + "span": { + "start": 24, + "end": 37, + "ctxt": 0 + }, + "expression": { + "type": "StringLiteral", + "span": { + "start": 24, + "end": 36, + "ctxt": 0 + }, + "value": "use strict", + "hasEscape": false, + "kind": { + "type": "normal", + "containsQuote": true + } + } + } + ] + }, + "generator": false, + "async": false, + "typeParameters": null, + "returnType": null + } + ], + "interpreter": null +}