diff --git a/Cargo.lock b/Cargo.lock
index b05244ee0272..f1af33bb9a6f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3370,7 +3370,7 @@ dependencies = [
[[package]]
name = "swc_ecma_codegen"
-version = "0.74.2"
+version = "0.74.3"
dependencies = [
"bitflags",
"memchr",
@@ -3696,7 +3696,7 @@ dependencies = [
[[package]]
name = "swc_ecma_transforms_react"
-version = "0.48.0"
+version = "0.48.1"
dependencies = [
"ahash",
"base64 0.13.0",
diff --git a/ecmascript/codegen/Cargo.toml b/ecmascript/codegen/Cargo.toml
index fe775b86682f..e137ecf90191 100644
--- a/ecmascript/codegen/Cargo.toml
+++ b/ecmascript/codegen/Cargo.toml
@@ -7,7 +7,7 @@ include = ["Cargo.toml", "src/**/*.rs"]
license = "Apache-2.0/MIT"
name = "swc_ecma_codegen"
repository = "https://github.com/swc-project/swc.git"
-version = "0.74.2"
+version = "0.74.3"
[dependencies]
bitflags = "1"
diff --git a/ecmascript/codegen/src/lib.rs b/ecmascript/codegen/src/lib.rs
index e332e72f37f1..3a0a18db7bc3 100644
--- a/ecmascript/codegen/src/lib.rs
+++ b/ecmascript/codegen/src/lib.rs
@@ -2261,6 +2261,57 @@ where
emit!(node.body);
}
+ fn has_leading_comment(&self, arg: &Expr) -> bool {
+ if let Some(cmt) = self.comments {
+ let lo = arg.span().lo;
+
+ // see #415
+ if cmt.has_leading(lo) {
+ return true;
+ }
+ }
+
+ match arg {
+ Expr::Call(c) => match &c.callee {
+ ExprOrSuper::Super(callee) => {
+ if let Some(cmt) = self.comments {
+ let lo = callee.span.lo;
+
+ if cmt.has_leading(lo) {
+ return true;
+ }
+ }
+ }
+ ExprOrSuper::Expr(callee) => {
+ if self.has_leading_comment(&callee) {
+ return true;
+ }
+ }
+ },
+
+ Expr::Member(m) => match &m.obj {
+ ExprOrSuper::Super(obj) => {
+ if let Some(cmt) = self.comments {
+ let lo = obj.span.lo;
+
+ if cmt.has_leading(lo) {
+ return true;
+ }
+ }
+ }
+ ExprOrSuper::Expr(obj) => {
+ if self.has_leading_comment(&obj) {
+ return true;
+ }
+ }
+ },
+
+ _ => {}
+ }
+
+ false
+ }
+
#[emitter]
fn emit_return_stmt(&mut self, n: &ReturnStmt) -> Result {
self.emit_leading_comments_of_span(n.span, false)?;
@@ -2276,14 +2327,10 @@ where
if let Some(ref arg) = n.arg {
let need_paren = !n.arg.span().is_dummy()
- && if let Some(cmt) = self.comments {
- let lo = n.arg.span().lo();
-
- // see #415
- cmt.has_leading(lo)
- } else {
- false
- };
+ && n.arg
+ .as_deref()
+ .map(|expr| self.has_leading_comment(expr))
+ .unwrap_or(false);
if need_paren {
punct!("(");
} else {
diff --git a/ecmascript/transforms/react/Cargo.toml b/ecmascript/transforms/react/Cargo.toml
index c6e415b434a6..2e285dde3509 100644
--- a/ecmascript/transforms/react/Cargo.toml
+++ b/ecmascript/transforms/react/Cargo.toml
@@ -7,7 +7,7 @@ include = ["Cargo.toml", "src/**/*.rs"]
license = "Apache-2.0/MIT"
name = "swc_ecma_transforms_react"
repository = "https://github.com/swc-project/swc.git"
-version = "0.48.0"
+version = "0.48.1"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
diff --git a/ecmascript/transforms/react/src/jsx/mod.rs b/ecmascript/transforms/react/src/jsx/mod.rs
index cb05c1318952..df5f79d5d258 100644
--- a/ecmascript/transforms/react/src/jsx/mod.rs
+++ b/ecmascript/transforms/react/src/jsx/mod.rs
@@ -1178,9 +1178,12 @@ fn transform_jsx_attr_str(v: &str) -> String {
match c {
'\u{0008}' => buf.push_str("\\b"),
'\u{000c}' => buf.push_str("\\f"),
- '\n' => buf.push_str("\\n"),
- '\r' => buf.push_str("\\r"),
- '\t' => buf.push_str("\\t"),
+ ' ' | '\n' | '\r' | '\t' => {
+ if buf.ends_with(' ') {
+ } else {
+ buf.push(' ')
+ }
+ }
'\u{000b}' => buf.push_str("\\v"),
'\0' => buf.push_str("\\x00"),
diff --git a/ecmascript/transforms/react/tests/jsx/fixture/vercel/1/input.js b/ecmascript/transforms/react/tests/jsx/fixture/vercel/1/input.js
new file mode 100644
index 000000000000..30a56a5a954f
--- /dev/null
+++ b/ecmascript/transforms/react/tests/jsx/fixture/vercel/1/input.js
@@ -0,0 +1,6 @@
+export default
\ No newline at end of file
diff --git a/ecmascript/transforms/react/tests/jsx/fixture/vercel/1/output.mjs b/ecmascript/transforms/react/tests/jsx/fixture/vercel/1/output.mjs
new file mode 100644
index 000000000000..7e6b17883557
--- /dev/null
+++ b/ecmascript/transforms/react/tests/jsx/fixture/vercel/1/output.mjs
@@ -0,0 +1,5 @@
+export default React.createElement(A, {
+ className: b,
+ header: "C",
+ subheader: "D E"
+});
diff --git a/tests/fixture/codegen/comment-1/es5/input/.swcrc b/tests/fixture/codegen/comment-1/es5/input/.swcrc
new file mode 100644
index 000000000000..8f96e1fd0e9e
--- /dev/null
+++ b/tests/fixture/codegen/comment-1/es5/input/.swcrc
@@ -0,0 +1,10 @@
+{
+ "jsc": {
+ "target": "es5",
+ "externalHelpers": true,
+ "parser": {
+ "syntax": "typescript",
+ "tsx": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/fixture/codegen/comment-1/es5/input/index.tsx b/tests/fixture/codegen/comment-1/es5/input/index.tsx
new file mode 100644
index 000000000000..b062b8774304
--- /dev/null
+++ b/tests/fixture/codegen/comment-1/es5/input/index.tsx
@@ -0,0 +1,16 @@
+function a({ b = [] }: { b: C[] }) {
+ const t = useMemo(() => {
+ return [
+ // Cmt1
+ ...a.slice(0, 1),
+ // Cmt2
+ ...b,
+ // Cmt3
+ ...c.slice(1),
+ ];
+ }, [frameworks]);
+
+ return 1;
+}
+
+export default a;
diff --git a/tests/fixture/codegen/comment-1/es5/output/index.tsx b/tests/fixture/codegen/comment-1/es5/output/index.tsx
new file mode 100644
index 000000000000..3274b49e59e0
--- /dev/null
+++ b/tests/fixture/codegen/comment-1/es5/output/index.tsx
@@ -0,0 +1,14 @@
+import * as swcHelpers from "@swc/helpers";
+function a(param) {
+ var _b = param.b, b = _b === void 0 ? [] : _b;
+ var t = useMemo(function() {
+ return(// Cmt1
+ swcHelpers.toConsumableArray(a.slice(0, 1)).concat(// Cmt2
+ swcHelpers.toConsumableArray(b), // Cmt3
+ swcHelpers.toConsumableArray(c.slice(1))));
+ }, [
+ frameworks
+ ]);
+ return 1;
+}
+export default a;
diff --git a/tests/fixture/codegen/jsx-1/input/.swcrc b/tests/fixture/codegen/jsx-1/input/.swcrc
new file mode 100644
index 000000000000..77fb46ac78f2
--- /dev/null
+++ b/tests/fixture/codegen/jsx-1/input/.swcrc
@@ -0,0 +1,8 @@
+{
+ "jsc": {
+ "parser": {
+ "syntax": "ecmascript",
+ "jsx": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/fixture/codegen/jsx-1/input/index.js b/tests/fixture/codegen/jsx-1/input/index.js
new file mode 100644
index 000000000000..30a56a5a954f
--- /dev/null
+++ b/tests/fixture/codegen/jsx-1/input/index.js
@@ -0,0 +1,6 @@
+export default
\ No newline at end of file
diff --git a/tests/fixture/codegen/jsx-1/output/index.js b/tests/fixture/codegen/jsx-1/output/index.js
new file mode 100644
index 000000000000..6d260ba40c48
--- /dev/null
+++ b/tests/fixture/codegen/jsx-1/output/index.js
@@ -0,0 +1,5 @@
+export default /*#__PURE__*/ React.createElement(A, {
+ className: b,
+ header: "C",
+ subheader: "D E"
+});
diff --git a/tests/fixture/issue-1233/case-1/output/index.js b/tests/fixture/issue-1233/case-1/output/index.js
index 18c08969c864..0a97cf1bf7f5 100644
--- a/tests/fixture/issue-1233/case-1/output/index.js
+++ b/tests/fixture/issue-1233/case-1/output/index.js
@@ -1,5 +1,5 @@
function Component() {
return(/*#__PURE__*/ React.createElement("div", {
- name: "A\\n\\n B"
+ name: "A B"
}));
}
diff --git a/tests/fixture/issue-1661/case1/output/index.js b/tests/fixture/issue-1661/case1/output/index.js
index 7205b0b7a865..30b335c85b4d 100644
--- a/tests/fixture/issue-1661/case1/output/index.js
+++ b/tests/fixture/issue-1661/case1/output/index.js
@@ -1,3 +1,3 @@
console.log(/*#__PURE__*/ React.createElement("h1", {
- value: "abc\\nas"
+ value: "abc as"
}, "s"));