From f9d831efc7844454d6a2f211714a06cb83040324 Mon Sep 17 00:00:00 2001 From: "alexander.akait" Date: Fri, 9 Dec 2022 14:21:26 +0300 Subject: [PATCH] fix(ecma/codegen): don't print trailing coma for rest argument --- crates/swc_ecma_codegen/src/ctx.rs | 55 +++++++++++++++++++ crates/swc_ecma_codegen/src/lib.rs | 13 +---- .../tests/fixture/issue-6589/js/input.js | 14 +++++ .../tests/fixture/issue-6589/js/output.js | 14 +++++ .../tests/fixture/issue-6589/js/output.min.js | 1 + .../tests/fixture/issue-6589/ts/input.ts | 21 +++++++ .../tests/fixture/issue-6589/ts/output.ts | 17 ++++++ 7 files changed, 123 insertions(+), 12 deletions(-) create mode 100644 crates/swc_ecma_codegen/src/ctx.rs create mode 100644 crates/swc_ecma_codegen/tests/fixture/issue-6589/js/input.js create mode 100644 crates/swc_ecma_codegen/tests/fixture/issue-6589/js/output.js create mode 100644 crates/swc_ecma_codegen/tests/fixture/issue-6589/js/output.min.js create mode 100644 crates/swc_ecma_codegen/tests/fixture/issue-6589/ts/input.ts create mode 100644 crates/swc_ecma_codegen/tests/fixture/issue-6589/ts/output.ts diff --git a/crates/swc_ecma_codegen/src/ctx.rs b/crates/swc_ecma_codegen/src/ctx.rs new file mode 100644 index 000000000000..cef307c2b0f2 --- /dev/null +++ b/crates/swc_ecma_codegen/src/ctx.rs @@ -0,0 +1,55 @@ +use std::ops::{Deref, DerefMut}; + +use swc_common::SourceMapper; +use swc_ecma_ast::SourceMapperExt; + +use crate::{text_writer::WriteJs, Emitter}; + +impl<'a, 'b, W, S: SourceMapper> Emitter<'a, W, S> +where + W: WriteJs, + S: SourceMapperExt, +{ + /// Original context is restored when returned guard is dropped. + #[inline] + pub(super) fn with_ctx(&mut self, ctx: Ctx) -> WithCtx<'b, W, S> { + let orig_ctx = self.ctx; + + self.ctx = ctx; + + WithCtx { + orig_ctx, + inner: self, + } + } +} + +#[derive(Debug, Default, Clone, Copy)] +pub(crate) struct Ctx { + pub in_function_params: bool, +} + +pub(super) struct WithCtx<'w, I: 'w + WriteJs, S: 'w + SourceMapper + SourceMapperExt> { + inner: &'w mut Emitter<'w, I, S>, + orig_ctx: Ctx, +} + +impl<'w, I: 'w + WriteJs, S: 'w + SourceMapper + SourceMapperExt> Deref for WithCtx<'w, I, S> { + type Target = Emitter<'w, I, S>; + + fn deref(&self) -> &Emitter<'w, I, S> { + self.inner + } +} + +impl<'w, I: 'w + WriteJs, S: 'w + SourceMapper + SourceMapperExt> DerefMut for WithCtx<'w, I, S> { + fn deref_mut(&mut self) -> &mut Emitter<'w, I, S> { + self.inner + } +} + +impl<'w, I: 'w + WriteJs, S: 'w + SourceMapper + SourceMapperExt> Drop for WithCtx<'w, I, S> { + fn drop(&mut self) { + self.inner.ctx = self.orig_ctx; + } +} diff --git a/crates/swc_ecma_codegen/src/lib.rs b/crates/swc_ecma_codegen/src/lib.rs index 21b76e4d2134..4afd25362e66 100644 --- a/crates/swc_ecma_codegen/src/lib.rs +++ b/crates/swc_ecma_codegen/src/lib.rs @@ -2481,23 +2481,12 @@ where self.emit_leading_comments_of_span(node.span(), false)?; srcmap!(node, true); - - let is_last_rest = match node.props.last() { - Some(ObjectPatProp::Rest(..)) => true, - _ => false, - }; - let format = if is_last_rest { - ListFormat::ObjectBindingPatternElements ^ ListFormat::AllowTrailingComma - } else { - ListFormat::ObjectBindingPatternElements - }; - punct!("{"); self.emit_list( node.span(), Some(&node.props), - format | ListFormat::CanSkipTrailingComma, + ListFormat::ObjectBindingPatternElements | ListFormat::CanSkipTrailingComma, )?; punct!("}"); diff --git a/crates/swc_ecma_codegen/tests/fixture/issue-6589/js/input.js b/crates/swc_ecma_codegen/tests/fixture/issue-6589/js/input.js new file mode 100644 index 000000000000..880d8e98c64f --- /dev/null +++ b/crates/swc_ecma_codegen/tests/fixture/issue-6589/js/input.js @@ -0,0 +1,14 @@ +export function func({a, b, ...rest}) { + console.log(a,b, rest) +} + +const other = { unknow: "foo" } + +let foo = { + ...other, + bar: "baz" +}; +let bar = { + bar: "baz", + ...other +}; diff --git a/crates/swc_ecma_codegen/tests/fixture/issue-6589/js/output.js b/crates/swc_ecma_codegen/tests/fixture/issue-6589/js/output.js new file mode 100644 index 000000000000..851cf1bb0cae --- /dev/null +++ b/crates/swc_ecma_codegen/tests/fixture/issue-6589/js/output.js @@ -0,0 +1,14 @@ +export function func({ a , b , ...rest }) { + console.log(a, b, rest); +} +const other = { + unknow: "foo" +}; +let foo = { + ...other, + bar: "baz" +}; +let bar = { + bar: "baz", + ...other +}; diff --git a/crates/swc_ecma_codegen/tests/fixture/issue-6589/js/output.min.js b/crates/swc_ecma_codegen/tests/fixture/issue-6589/js/output.min.js new file mode 100644 index 000000000000..839f23f76c4c --- /dev/null +++ b/crates/swc_ecma_codegen/tests/fixture/issue-6589/js/output.min.js @@ -0,0 +1 @@ +export function func({a,b,...rest}){console.log(a,b,rest)}const other={unknow:"foo"};let foo={...other,bar:"baz"};let bar={bar:"baz",...other}; diff --git a/crates/swc_ecma_codegen/tests/fixture/issue-6589/ts/input.ts b/crates/swc_ecma_codegen/tests/fixture/issue-6589/ts/input.ts new file mode 100644 index 000000000000..b62046906a7e --- /dev/null +++ b/crates/swc_ecma_codegen/tests/fixture/issue-6589/ts/input.ts @@ -0,0 +1,21 @@ +export function func({ + a, + b, + ...rest +}: { + a: string, + b: string, +}) { + console.log(a,b, rest) +} + +const other = { unknow: "foo" } + +let foo = { + ...other, + bar: "baz" +}; +let bar = { + bar: "baz", + ...other +}; diff --git a/crates/swc_ecma_codegen/tests/fixture/issue-6589/ts/output.ts b/crates/swc_ecma_codegen/tests/fixture/issue-6589/ts/output.ts new file mode 100644 index 000000000000..2e52b3d0e0c9 --- /dev/null +++ b/crates/swc_ecma_codegen/tests/fixture/issue-6589/ts/output.ts @@ -0,0 +1,17 @@ +export function func({ a , b , ...rest }: { + a: string; + b: string; +}) { + console.log(a, b, rest); +} +const other = { + unknow: "foo" +}; +let foo = { + ...other, + bar: "baz" +}; +let bar = { + bar: "baz", + ...other +};