use super::SwcGenerator;
use crate::parser::*;
use crate::codegen::swc_decorator::*;
use crate::codegen::decorated_ast::*;
impl SwcGenerator {
pub(super) fn is_visitor_method(&self, f: &FnDecl) -> bool {
if !f.name.starts_with("visit_") {
return false;
}
if f.return_type.is_some() {
return false;
}
if let Some(first_param) = f.params.first() {
if let Type::Reference { mutable, .. } = &first_param.ty {
return *mutable;
}
}
false
}
pub(super) fn gen_decorated_visitor_method(&mut self, func: &DecoratedFnDecl) {
let swc_name = self.visitor_name_to_swc(&func.name);
let swc_type = self.visitor_name_to_swc_type(&func.name);
self.emit_line("");
self.emit_line(&format!("fn {}(&mut self, n: &mut {}) {{", swc_name, swc_type));
self.indent += 1;
for param in &func.params {
self.param_renames.insert(param.name.clone(), "n".to_string());
}
self.gen_decorated_block(&func.body);
for param in &func.params {
self.param_renames.remove(¶m.name);
}
self.indent -= 1;
self.emit_line("}");
}
pub(super) fn gen_visitor_method(&mut self, f: &FnDecl) {
let swc_name = self.visitor_name_to_swc(&f.name);
let swc_type = self.visitor_name_to_swc_type(&f.name);
self.emit_line("");
self.emit_line(&format!("fn {}(&mut self, n: &mut {}) {{", swc_name, swc_type));
self.indent += 1;
if let Some(first_param) = f.params.first() {
self.param_renames.insert(first_param.name.clone(), "n".to_string());
}
self.type_env.push_scope();
let param_ctx = TypeContext {
reluxscript_type: swc_type.clone(),
swc_type: swc_type.clone(),
kind: super::type_context::SwcTypeKind::Struct,
known_variant: None,
needs_deref: false,
};
self.type_env.define("n", param_ctx.clone());
if let Some(first_param) = f.params.first() {
self.type_env.define(&first_param.name, param_ctx);
}
self.gen_block(&f.body);
self.type_env.pop_scope();
self.param_renames.clear();
self.indent -= 1;
self.emit_line("}");
}
pub(super) fn gen_visit_method(&mut self, f: &FnDecl) {
let mut swc_name = self.visitor_name_to_swc(&f.name);
if swc_name.starts_with("visit_mut_") {
swc_name = swc_name.replace("visit_mut_", "visit_");
}
let swc_type = self.visitor_name_to_swc_type(&f.name);
self.emit_line("");
self.emit_line(&format!("fn {}(&mut self, n: &{}) {{", swc_name, swc_type));
self.indent += 1;
if let Some(first_param) = f.params.first() {
self.param_renames.insert(first_param.name.clone(), "n".to_string());
}
self.type_env.push_scope();
let param_ctx = TypeContext {
reluxscript_type: swc_type.clone(),
swc_type: swc_type.clone(),
kind: super::type_context::SwcTypeKind::Struct,
known_variant: None,
needs_deref: false,
};
self.type_env.define("n", param_ctx.clone());
if let Some(first_param) = f.params.first() {
self.type_env.define(&first_param.name, param_ctx);
}
for stmt in &f.body.stmts {
self.gen_stmt(stmt);
}
self.type_env.pop_scope();
self.param_renames.clear();
self.indent -= 1;
self.emit_line("}");
}
}