Skip to content

Commit

Permalink
support more cases, use _$ function
Browse files Browse the repository at this point in the history
  • Loading branch information
Benedikt Strehle committed Sep 3, 2024
1 parent 8b63963 commit 060fb38
Show file tree
Hide file tree
Showing 18 changed files with 222 additions and 42 deletions.
121 changes: 119 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,13 +217,27 @@ test!(
t19,
r#"<div>
{
array.map((item) => item)
}
{
array.map((item) => item * x)
}
{
array.map((item) => {
return <span>{item * 2}</span>
return item * x;
})
}
{
array.map((item) => {
return <span>{item * x}</span>
})
}
{
array.map((item) => <div>{item * x}</div>)
}
{
array.filter((item) => {
return <span>{item * 2}</span>
return <span>{item * x}</span>
})
}
{
Expand All @@ -234,3 +248,106 @@ test!(
</div>
"#
);

test!(
Syntax::Es(EsSyntax {
jsx: true,
..Default::default()
},),
|_| TransformVisitor,
t20,
r#"<input value={x[0]}/>"#
);

test!(
Syntax::Es(EsSyntax {
jsx: true,
..Default::default()
},),
|_| TransformVisitor,
t21,
r#"<input value={x.y.z[0]}/>"#
);

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 = <div>{x+1}</div>;
const x = $(<div>{x+1}</div>);
"#
);


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
])
"#
);
97 changes: 68 additions & 29 deletions src/visitor.rs
Original file line number Diff line number Diff line change
@@ -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},
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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(),
}))
Expand All @@ -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
Expand All @@ -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(),
)))),
Expand Down Expand Up @@ -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,
}
}
}
};
}

Expand All @@ -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(),
Expand Down
2 changes: 1 addition & 1 deletion tests/__swc_snapshots__/src/lib.rs/t11.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<div>{always(()=>x + 1)}</div>;
<div>{_$(()=>x + 1)}</div>;
6 changes: 3 additions & 3 deletions tests/__swc_snapshots__/src/lib.rs/t12.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<div>
<span>{always(()=>x + 1)}</span>
<span>{always(()=>y + 1)}</span>
<span>X + Y = {always(()=>x + y)}</span>
<span>{_$(()=>x + 1)}</span>
<span>{_$(()=>y + 1)}</span>
<span>X + Y = {_$(()=>x + y)}</span>
</div>;
2 changes: 1 addition & 1 deletion tests/__swc_snapshots__/src/lib.rs/t13.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<div>
{always(()=>x ? <span>{x + 1}</span> : <span>False</span>)}
{_$(()=>x ? <span>{x + 1}</span> : <span>False</span>)}
</div>;
12 changes: 9 additions & 3 deletions tests/__swc_snapshots__/src/lib.rs/t19.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
<div>
{array.$.map((item)=>item)}
{array.$.map((item)=>item * x)}
{array.$.map((item)=>{
return item * x;
})}
{array.$.map((item)=>{
return <span>{item * 2}</span>;
return <span>{_$(()=>item * x)}</span>;
})}
{array.$.map((item)=><div>{_$(()=>item * x)}</div>)}
{array.$.filter((item)=>{
return <span>{item * 2}</span>;
return <span>{_$(()=>item * x)}</span>;
})}
{always(()=>array.normalMethod((item)=>{
{_$(()=>array.normalMethod((item)=>{
return <span>{item * 2}</span>;
}))}
</div>;
2 changes: 1 addition & 1 deletion tests/__swc_snapshots__/src/lib.rs/t2.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
const y = always(()=>y * 2);
const y = _$(()=>y * 2);
1 change: 1 addition & 0 deletions tests/__swc_snapshots__/src/lib.rs/t20.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<input value={prop(x, 0)}/>;
1 change: 1 addition & 0 deletions tests/__swc_snapshots__/src/lib.rs/t21.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<input value={prop(prop(prop(x, "y"), "z"), 0)}/>;
1 change: 1 addition & 0 deletions tests/__swc_snapshots__/src/lib.rs/t22.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
const x = arr.map((a)=>a * 2);
1 change: 1 addition & 0 deletions tests/__swc_snapshots__/src/lib.rs/t23.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
const x = arr.$.map((a)=>a * 2);
1 change: 1 addition & 0 deletions tests/__swc_snapshots__/src/lib.rs/t24.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
const x = _$(()=>x + 1);
1 change: 1 addition & 0 deletions tests/__swc_snapshots__/src/lib.rs/t25.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
const x = _$(()=>x.$.y);
2 changes: 2 additions & 0 deletions tests/__swc_snapshots__/src/lib.rs/t26.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
const x = <div>{_$(()=>x + 1)}</div>;
const x = $$(<div>{_$(()=>x + 1)}</div>);
5 changes: 5 additions & 0 deletions tests/__swc_snapshots__/src/lib.rs/t27.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const x = _$(()=>[
1,
2,
y + 1
]);
5 changes: 5 additions & 0 deletions tests/__swc_snapshots__/src/lib.rs/t28.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const x = _$(()=>[
1,
2,
3
]);
2 changes: 1 addition & 1 deletion tests/__swc_snapshots__/src/lib.rs/t7.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<button value={always(()=>x + 1)}/>;
<button value={_$(()=>x + 1)}/>;
2 changes: 1 addition & 1 deletion tests/__swc_snapshots__/src/lib.rs/t8.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<button value:frontend={always(()=>x + 1)}/>;
<button value:frontend={_$(()=>x + 1)}/>;

0 comments on commit 060fb38

Please sign in to comment.