Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions crates/swc/tests/fixture/issues-10xxx/11118/input/.swcrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"jsc": {
"parser": {
"syntax": "ecmascript",
"jsx": false
},
"target": "es5",
"loose": true,
"minify": {
"compress": false,
"mangle": false
}
},
"module": {
"type": "es6"
},
"minify": false,
"isModule": true
}
5 changes: 5 additions & 0 deletions crates/swc/tests/fixture/issues-10xxx/11118/input/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
function xxx() {
const b = [...arguments];
const c = [2, ...arguments];
return b.length + c.length;
}
7 changes: 7 additions & 0 deletions crates/swc/tests/fixture/issues-10xxx/11118/output/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
function xxx() {
var b = [].concat(Array.prototype.slice.call(arguments));
Copy link
Member Author

@magic-akari magic-akari Sep 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

var c = [].concat([
2
], Array.prototype.slice.call(arguments));
return b.length + c.length;
}
2 changes: 1 addition & 1 deletion crates/swc_ecma_compat_es2015/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ where
template_literal(c.template_literal),
classes(c.classes),
new_target(),
spread(c.spread),
spread(c.spread, unresolved_mark),
),
// https://github.com/Microsoft/TypeScript/issues/5441
if !c.typescript {
Expand Down
33 changes: 29 additions & 4 deletions crates/swc_ecma_compat_es2015/src/spread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::mem;

use serde::Deserialize;
use swc_atoms::atom;
use swc_common::{util::take::Take, Span, Spanned, DUMMY_SP};
use swc_common::{util::take::Take, Mark, Span, Spanned, SyntaxContext, DUMMY_SP};
use swc_ecma_ast::*;
use swc_ecma_transforms_base::{ext::ExprRefExt, helper, perf::Check};
use swc_ecma_transforms_macros::fast_path;
Expand All @@ -14,9 +14,11 @@ use swc_ecma_visit::{
};
use swc_trace_macro::swc_trace;

pub fn spread(c: Config) -> impl Pass {
pub fn spread(c: Config, unresolved_mark: Mark) -> impl Pass {
let unresolved_ctxt = SyntaxContext::empty().apply_mark(unresolved_mark);
visit_mut_pass(Spread {
c,
unresolved_ctxt,
vars: Default::default(),
})
}
Expand All @@ -28,9 +30,9 @@ pub struct Config {
}

/// es2015 - `SpreadElement`
#[derive(Default)]
struct Spread {
c: Config,
unresolved_ctxt: SyntaxContext,
vars: Vec<VarDeclarator>,
}

Expand Down Expand Up @@ -271,7 +273,7 @@ impl Spread {
for arg in args.flatten() {
let expr = arg.expr;
match arg.spread {
Some(_) => {
Some(span) => {
if !current_elems.is_empty() {
arg_list.push(
ArrayLit {
Expand All @@ -282,6 +284,29 @@ impl Spread {
);
current_elems = Vec::new();
}
// Special handling for `arguments` to call Array.prototype.slice
// https://github.com/babel/babel/blob/61ad8555b875cb0c0996f18f803b6bf1d2150173/packages/babel-plugin-transform-spread/src/index.ts#L43-L47
let expr = match *expr {
Expr::Ident(Ident { ref sym, ctxt, .. })
if &**sym == "arguments"
&& (ctxt == self.unresolved_ctxt
|| ctxt == SyntaxContext::empty()) =>
{
CallExpr {
span,
callee: member_expr!(
Default::default(),
DUMMY_SP,
Array.prototype.slice.call
)
.as_callee(),
args: vec![expr.as_arg()],
..Default::default()
}
.into()
}
_ => *expr,
};
arg_list.push(expr.as_arg());
}
None => {
Expand Down
2 changes: 1 addition & 1 deletion crates/swc_ecma_preset_env/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ where
let pass = add!(
pass,
Spread,
es2015::spread(es2015::spread::Config { loose }),
es2015::spread(es2015::spread::Config { loose }, unresolved_mark),
true
);
let pass = add!(pass, ObjectSuper, es2015::object_super());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ fn spec_tr(_: &Tester) -> impl Pass {
(
resolver(unresolved_mark, Mark::new(), false),
classes(Default::default()),
spread(Default::default()),
spread(Default::default(), unresolved_mark),
block_scoping(unresolved_mark),
)
}
Expand Down
Loading
Loading