diff --git a/src/lib.rs b/src/lib.rs
index 36aea59..508c041 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -217,13 +217,27 @@ test!(
t19,
r#"
{
+ array.map((item) => item)
+ }
+ {
+ array.map((item) => item * x)
+ }
+ {
array.map((item) => {
- return
{item * 2}
+ return item * x;
})
}
+ {
+ array.map((item) => {
+ return
{item * x}
+ })
+ }
+ {
+ array.map((item) =>
{item * x}
)
+ }
{
array.filter((item) => {
- return
{item * 2}
+ return
{item * x}
})
}
{
@@ -234,3 +248,106 @@ test!(
"#
);
+
+test!(
+ Syntax::Es(EsSyntax {
+ jsx: true,
+ ..Default::default()
+ },),
+ |_| TransformVisitor,
+ t20,
+ r#""#
+);
+
+test!(
+ Syntax::Es(EsSyntax {
+ jsx: true,
+ ..Default::default()
+ },),
+ |_| TransformVisitor,
+ t21,
+ r#""#
+);
+
+test!(
+ Syntax::Es(EsSyntax {
+ jsx: true,
+ ..Default::default()
+ },),
+ |_| TransformVisitor,
+ t22,
+ r#"const x = arr.map(a => a*2)"#
+);
+
+test!(
+ Syntax::Es(EsSyntax {
+ jsx: true,
+ ..Default::default()
+ },),
+ |_| TransformVisitor,
+ t23,
+ r#"const x = $(arr.map(a => a*2))"#
+);
+
+test!(
+ Syntax::Es(EsSyntax {
+ jsx: true,
+ ..Default::default()
+ },),
+ |_| TransformVisitor,
+ t24,
+ r#"const x = $(() => x + 1)"#
+);
+
+
+test!(
+ Syntax::Es(EsSyntax {
+ jsx: true,
+ ..Default::default()
+ },),
+ |_| TransformVisitor,
+ t25,
+ r#"const x = $(x.$.y)"#
+);
+
+test!(
+ Syntax::Es(EsSyntax {
+ jsx: true,
+ ..Default::default()
+ },),
+ |_| TransformVisitor,
+ t26,
+ r#"
+ const x = {x+1}
;
+ const x = $({x+1}
);
+ "#
+);
+
+
+test!(
+ Syntax::Es(EsSyntax {
+ jsx: true,
+ ..Default::default()
+ },),
+ |_| TransformVisitor,
+ t27,
+ r#"
+ const x = $([
+ 1,2,y+1
+ ])
+ "#
+);
+
+test!(
+ Syntax::Es(EsSyntax {
+ jsx: true,
+ ..Default::default()
+ },),
+ |_| TransformVisitor,
+ t28,
+ r#"
+ const x = $([
+ 1,2,3
+ ])
+ "#
+);
\ No newline at end of file
diff --git a/src/visitor.rs b/src/visitor.rs
index 4e26ac3..26781ee 100644
--- a/src/visitor.rs
+++ b/src/visitor.rs
@@ -1,5 +1,5 @@
-use swc_core::ecma::ast::{IdentName, JSXAttr, JSXAttrName, JSXAttrValue, JSXElement, JSXElementChild, JSXSpreadChild, MemberExpr, MemberProp};
-use swc_core::ecma::visit::VisitWith;
+use swc_core::ecma::ast::{FnExpr, IdentName, JSXAttr, JSXAttrName, JSXAttrValue, JSXElement, JSXElementChild, JSXSpreadChild, MemberExpr, MemberProp};
+use swc_core::ecma::visit::{FoldWith, VisitWith};
use swc_core::{
atoms::Atom,
common::{util::take::Take, SyntaxContext, DUMMY_SP},
@@ -91,7 +91,10 @@ impl TransformVisitor {
Default::default(),
)))),
args: vec![
- m.obj.clone().into(),
+ ExprOrSpread {
+ expr: self.transform_expr_reactive(m.obj.clone()),
+ spread: None
+ },
// convert prop to string
match &m.prop {
MemberProp::Ident(_) => Expr::Lit(Lit::Str(Str {
@@ -131,7 +134,31 @@ impl TransformVisitor {
format!("$.{}", prop.as_ident().unwrap().sym).to_string()
)),
}))),
- args: c.args.clone(),
+ // transform first arg if it's a function, keep others
+ args: c.args.clone().into_iter().map(|a| {
+ match a {
+ ExprOrSpread {
+ expr: e,
+ spread: None,
+ } => match e.unwrap_parens() {
+ Expr::Arrow(a1) => ExprOrSpread {
+ expr: {
+ let mut a2 = a1.clone();
+ a2.body = Box::new(
+ *a2.body.fold_with(self)
+ );
+ Box::new(Expr::Arrow(a2))
+ },
+ spread: None,
+ },
+ _ => ExprOrSpread {
+ expr: e,
+ spread: None,
+ }
+ },
+ _ => a
+ }
+ }).collect(),
type_args: Take::dummy(),
ctxt: Default::default(),
}))
@@ -141,7 +168,7 @@ impl TransformVisitor {
// already has an always() or $$() wrapper
Expr::Call(c)
if c.callee.is_expr()
- && (c.callee.as_expr().unwrap().is_ident_ref_to("always")
+ && (c.callee.as_expr().unwrap().is_ident_ref_to("_$")
|| c.callee.as_expr().unwrap().is_ident_ref_to("$$")) =>
{
e
@@ -158,7 +185,7 @@ impl TransformVisitor {
_ => Box::new(Expr::Call(CallExpr {
span: DUMMY_SP,
callee: Callee::Expr(Box::new(Expr::Ident(Ident::new(
- "always".into(),
+ "_$".into(),
DUMMY_SP,
Default::default(),
)))),
@@ -299,33 +326,45 @@ impl Fold for TransformVisitor {
DUMMY_SP,
call.ctxt,
)))),
- args: vec![arg.into()],
+ args: vec![arg.fold_with(self).into()],
type_args: Take::dummy(),
ctxt: call.ctxt,
},
// default: wrap in always
- _ => CallExpr {
- span: DUMMY_SP,
- callee: Callee::Expr(Box::new(Expr::Ident(Ident::new(
- "always".into(),
- DUMMY_SP,
- call.ctxt,
- )))),
- args: vec![Expr::Arrow(ArrowExpr {
- span: DUMMY_SP,
- params: Take::dummy(),
- body: Box::new(BlockStmtOrExpr::Expr(arg)),
- is_async: false,
- is_generator: false,
- type_params: Take::dummy(),
- return_type: Take::dummy(),
- ctxt: call.ctxt,
- })
- .into()],
- type_args: Take::dummy(),
- ctxt: call.ctxt,
- },
+ _ => {
+ let reactive = self.transform_expr_reactive(arg.clone());
+ match reactive.unwrap_parens() {
+ Expr::Call(c) => c.clone(),
+ // transform_expr_reactive returns a CallExpr in all cases except for Expr::Arrow(_) | Expr::Fn
+ _ => CallExpr {
+ span: DUMMY_SP,
+ callee: Callee::Expr(Box::new(Expr::Ident(Ident::new(
+ "_$".into(),
+ DUMMY_SP,
+ call.ctxt,
+ )))),
+ args: vec![
+ match arg.unwrap_parens() {
+ Expr::Arrow(_) | Expr::Fn(_) => arg.into(),
+ _ => Expr::Arrow(ArrowExpr {
+ span: DUMMY_SP,
+ params: Take::dummy(),
+ body: Box::new(BlockStmtOrExpr::Expr(arg)),
+ is_async: false,
+ is_generator: false,
+ type_params: Take::dummy(),
+ return_type: Take::dummy(),
+ ctxt: call.ctxt,
+ })
+ .into(),
+ }
+ ],
+ type_args: Take::dummy(),
+ ctxt: call.ctxt,
+ }
+ }
+ }
};
}
@@ -343,7 +382,7 @@ impl Fold for TransformVisitor {
// if n.callee.is_expr() && n.callee.expect_expr().expect_ident().sym.eq_ignore_ascii_case("$") {
// return CallExpr {
// span: DUMMY_SP,
- // callee: Callee::Expr(Box::new(Expr::Ident(Ident::new("always".into(), DUMMY_SP)))),
+ // callee: Callee::Expr(Box::new(Expr::Ident(Ident::new("_$".into(), DUMMY_SP)))),
// args: vec![Expr::Arrow(ArrowExpr {
// span: DUMMY_SP,
// params: Take::dummy(),
diff --git a/tests/__swc_snapshots__/src/lib.rs/t11.js b/tests/__swc_snapshots__/src/lib.rs/t11.js
index 0ced79a..4785e07 100644
--- a/tests/__swc_snapshots__/src/lib.rs/t11.js
+++ b/tests/__swc_snapshots__/src/lib.rs/t11.js
@@ -1 +1 @@
-{always(()=>x + 1)}
;
+{_$(()=>x + 1)}
;
diff --git a/tests/__swc_snapshots__/src/lib.rs/t12.js b/tests/__swc_snapshots__/src/lib.rs/t12.js
index 408e302..778de2e 100644
--- a/tests/__swc_snapshots__/src/lib.rs/t12.js
+++ b/tests/__swc_snapshots__/src/lib.rs/t12.js
@@ -1,5 +1,5 @@
- {always(()=>x + 1)}
- {always(()=>y + 1)}
- X + Y = {always(()=>x + y)}
+ {_$(()=>x + 1)}
+ {_$(()=>y + 1)}
+ X + Y = {_$(()=>x + y)}
;
diff --git a/tests/__swc_snapshots__/src/lib.rs/t13.js b/tests/__swc_snapshots__/src/lib.rs/t13.js
index 239da97..bbcc2d3 100644
--- a/tests/__swc_snapshots__/src/lib.rs/t13.js
+++ b/tests/__swc_snapshots__/src/lib.rs/t13.js
@@ -1,3 +1,3 @@
- {always(()=>x ? {x + 1} : False)}
+ {_$(()=>x ? {x + 1} : False)}
;
diff --git a/tests/__swc_snapshots__/src/lib.rs/t19.js b/tests/__swc_snapshots__/src/lib.rs/t19.js
index 0f0a283..d511639 100644
--- a/tests/__swc_snapshots__/src/lib.rs/t19.js
+++ b/tests/__swc_snapshots__/src/lib.rs/t19.js
@@ -1,11 +1,17 @@
+ {array.$.map((item)=>item)}
+ {array.$.map((item)=>item * x)}
+ {array.$.map((item)=>{
+ return item * x;
+})}
{array.$.map((item)=>{
- return
{item * 2};
+ return
{_$(()=>item * x)};
})}
+ {array.$.map((item)=>
{_$(()=>item * x)}
)}
{array.$.filter((item)=>{
- return
{item * 2};
+ return
{_$(()=>item * x)};
})}
- {always(()=>array.normalMethod((item)=>{
+ {_$(()=>array.normalMethod((item)=>{
return
{item * 2};
}))}
;
diff --git a/tests/__swc_snapshots__/src/lib.rs/t2.js b/tests/__swc_snapshots__/src/lib.rs/t2.js
index 28e6fd0..5d5444f 100644
--- a/tests/__swc_snapshots__/src/lib.rs/t2.js
+++ b/tests/__swc_snapshots__/src/lib.rs/t2.js
@@ -1 +1 @@
-const y = always(()=>y * 2);
+const y = _$(()=>y * 2);
diff --git a/tests/__swc_snapshots__/src/lib.rs/t20.js b/tests/__swc_snapshots__/src/lib.rs/t20.js
new file mode 100644
index 0000000..787cfce
--- /dev/null
+++ b/tests/__swc_snapshots__/src/lib.rs/t20.js
@@ -0,0 +1 @@
+;
diff --git a/tests/__swc_snapshots__/src/lib.rs/t21.js b/tests/__swc_snapshots__/src/lib.rs/t21.js
new file mode 100644
index 0000000..275afcc
--- /dev/null
+++ b/tests/__swc_snapshots__/src/lib.rs/t21.js
@@ -0,0 +1 @@
+;
diff --git a/tests/__swc_snapshots__/src/lib.rs/t22.js b/tests/__swc_snapshots__/src/lib.rs/t22.js
new file mode 100644
index 0000000..a831390
--- /dev/null
+++ b/tests/__swc_snapshots__/src/lib.rs/t22.js
@@ -0,0 +1 @@
+const x = arr.map((a)=>a * 2);
diff --git a/tests/__swc_snapshots__/src/lib.rs/t23.js b/tests/__swc_snapshots__/src/lib.rs/t23.js
new file mode 100644
index 0000000..98eb294
--- /dev/null
+++ b/tests/__swc_snapshots__/src/lib.rs/t23.js
@@ -0,0 +1 @@
+const x = arr.$.map((a)=>a * 2);
diff --git a/tests/__swc_snapshots__/src/lib.rs/t24.js b/tests/__swc_snapshots__/src/lib.rs/t24.js
new file mode 100644
index 0000000..c2d6d10
--- /dev/null
+++ b/tests/__swc_snapshots__/src/lib.rs/t24.js
@@ -0,0 +1 @@
+const x = _$(()=>x + 1);
diff --git a/tests/__swc_snapshots__/src/lib.rs/t25.js b/tests/__swc_snapshots__/src/lib.rs/t25.js
new file mode 100644
index 0000000..f9bbd71
--- /dev/null
+++ b/tests/__swc_snapshots__/src/lib.rs/t25.js
@@ -0,0 +1 @@
+const x = _$(()=>x.$.y);
diff --git a/tests/__swc_snapshots__/src/lib.rs/t26.js b/tests/__swc_snapshots__/src/lib.rs/t26.js
new file mode 100644
index 0000000..8b27ad9
--- /dev/null
+++ b/tests/__swc_snapshots__/src/lib.rs/t26.js
@@ -0,0 +1,2 @@
+const x = {_$(()=>x + 1)}
;
+const x = $$({_$(()=>x + 1)}
);
diff --git a/tests/__swc_snapshots__/src/lib.rs/t27.js b/tests/__swc_snapshots__/src/lib.rs/t27.js
new file mode 100644
index 0000000..aa6ea3a
--- /dev/null
+++ b/tests/__swc_snapshots__/src/lib.rs/t27.js
@@ -0,0 +1,5 @@
+const x = _$(()=>[
+ 1,
+ 2,
+ y + 1
+ ]);
diff --git a/tests/__swc_snapshots__/src/lib.rs/t28.js b/tests/__swc_snapshots__/src/lib.rs/t28.js
new file mode 100644
index 0000000..1cc1ee0
--- /dev/null
+++ b/tests/__swc_snapshots__/src/lib.rs/t28.js
@@ -0,0 +1,5 @@
+const x = _$(()=>[
+ 1,
+ 2,
+ 3
+ ]);
diff --git a/tests/__swc_snapshots__/src/lib.rs/t7.js b/tests/__swc_snapshots__/src/lib.rs/t7.js
index accb4b6..d5913e5 100644
--- a/tests/__swc_snapshots__/src/lib.rs/t7.js
+++ b/tests/__swc_snapshots__/src/lib.rs/t7.js
@@ -1 +1 @@
-