Skip to content

Commit

Permalink
feat: generate bindings return statement in RenderFn mode
Browse files Browse the repository at this point in the history
  • Loading branch information
phoenix-ru committed Nov 2, 2023
1 parent 49a2420 commit af5170e
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 5 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ Code generator
- [x] Processing `<style scoped>`
- [ ] `<script setup>` support
- [x] Bindings collection;
- [ ] Return statement: inline vs render function;
- [x] Return statement: inline vs render function;
- [x] defineProps
- [x] defineEmits
- [x] defineExpose
Expand Down
51 changes: 47 additions & 4 deletions crates/fervid_codegen/src/control_flow/sfc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ use swc_core::{
common::{FileName, SourceMap, DUMMY_SP},
ecma::{
ast::{
BindingIdent, BlockStmt, Decl, ExportDefaultExpr, Expr, Function,
Ident, ImportDecl, MethodProp, Module, ModuleDecl, ModuleItem, ObjectLit, Param, Pat,
Prop, PropName, PropOrSpread, ReturnStmt, Stmt, Str, VarDecl, VarDeclKind, ArrowExpr, BlockStmtOrExpr,
ArrowExpr, BindingIdent, BlockStmt, BlockStmtOrExpr, Decl, ExportDefaultExpr, Expr,
Function, Ident, ImportDecl, MethodProp, Module, ModuleDecl, ModuleItem, ObjectLit,
Param, Pat, Prop, PropName, PropOrSpread, ReturnStmt, Stmt, Str, VarDecl, VarDeclKind,
},
atoms::JsWord,
},
Expand Down Expand Up @@ -69,6 +69,26 @@ impl CodegenContext {
TemplateGenerationMode::RenderFn => {
let render_fn = self.generate_render_fn(template_expr);

// When a synthetic setup function is present,
// we need to return bindings as its last statement
'return_bindings: {
let Some(ref mut setup_fn) = synthetic_setup_fn else {
break 'return_bindings;
};

let Some(ref mut setup_body) = setup_fn.body else {
break 'return_bindings;
};

let return_bindings = self.generate_return_bindings();
if !return_bindings.props.is_empty() {
setup_body.stmts.push(Stmt::Return(ReturnStmt {
span: DUMMY_SP,
arg: Some(Box::new(Expr::Object(return_bindings))),
}));
}
}

sfc_export_obj
.props
.push(PropOrSpread::Prop(Box::new(Prop::Method(MethodProp {
Expand Down Expand Up @@ -166,7 +186,10 @@ impl CodegenContext {
span: DUMMY_SP,
}));

Box::new(BlockStmtOrExpr::BlockStmt(BlockStmt { span: DUMMY_SP, stmts }))
Box::new(BlockStmtOrExpr::BlockStmt(BlockStmt {
span: DUMMY_SP,
stmts,
}))
};

macro_rules! param {
Expand Down Expand Up @@ -262,6 +285,26 @@ impl CodegenContext {
}
}

/// Generates bindings for a synthetic setup function when used in combination
/// with `TemplateGenerationMode::RenderFn`.
pub fn generate_return_bindings(&self) -> ObjectLit {
let mut props =
Vec::<PropOrSpread>::with_capacity(self.bindings_helper.used_bindings.len());

for used_binding in self.bindings_helper.used_bindings.keys() {
props.push(PropOrSpread::Prop(Box::new(Prop::Shorthand(Ident {
span: DUMMY_SP,
sym: used_binding.to_owned(),
optional: false,
}))));
}

ObjectLit {
span: DUMMY_SP,
props,
}
}

pub fn stringify(source: &str, item: &impl Node, minify: bool) -> String {
// Emitting the result requires some setup with SWC
let cm: swc_core::common::sync::Lrc<SourceMap> = Default::default();
Expand Down
3 changes: 3 additions & 0 deletions crates/fervid_napi/__tests__/compileHelloWorld.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ test('should work', () => {
},
setup () {
const compilerName = ref('fervid');
return {
compilerName
};
}
};
"
Expand Down

0 comments on commit af5170e

Please sign in to comment.