From 6558d4c155d9ad2b2ec48decccbb836b68e1f87b Mon Sep 17 00:00:00 2001 From: Priyanshu Dangare Date: Sat, 9 May 2026 00:48:07 +0530 Subject: [PATCH] fix: codegen per-field show/hide blocks for struct-typed lists and variables --- src/codegen/sb3.rs | 4 ++-- src/codegen/stmt.rs | 22 +++++++++++----------- src/visitor/pass2.rs | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 13 deletions(-) diff --git a/src/codegen/sb3.rs b/src/codegen/sb3.rs index 2897b6ae..e581756e 100644 --- a/src/codegen/sb3.rs +++ b/src/codegen/sb3.rs @@ -1183,8 +1183,8 @@ where T: Write + Seek is_cloud, } => self.set_var(s, d, this_id, name, value, type_, is_local, is_cloud), Stmt::ChangeVar { name, value } => self.change_var(s, d, this_id, name, value), - Stmt::Show(name) => self.show(s, d, name), - Stmt::Hide(name) => self.hide(s, d, name), + Stmt::Show(name) => self.show_or_hide_monitor(s, d, name), + Stmt::Hide(name) => self.show_or_hide_monitor(s, d, name), Stmt::AddToList { name, value } => self.add_to_list(s, d, this_id, name, value), Stmt::DeleteListIndex { name, index } => { self.delete_list_index(s, d, this_id, name, index) diff --git a/src/codegen/stmt.rs b/src/codegen/stmt.rs index 578a892c..47ca4028 100644 --- a/src/codegen/stmt.rs +++ b/src/codegen/stmt.rs @@ -178,23 +178,23 @@ where T: Write + Seek self.expr(s, d, value, value_id, this_id) } - pub fn show(&mut self, s: S, d: D, name: &Name) -> io::Result<()> { - self.begin_inputs()?; - self.end_obj()?; // inputs + pub fn show_or_hide_monitor(&mut self, s: S, d: D, name: &Name) -> io::Result<()> { match s.qualify_name(Some(d), name) { Some(QualifiedName::Var(qualified_name, _)) => { - self.single_field_id("VARIABLE", &qualified_name)? + self.begin_inputs()?; + self.end_obj()?; // inputs + self.single_field_id("VARIABLE", &qualified_name)?; + self.end_obj()?; // node } Some(QualifiedName::List(qualified_name, _)) => { - self.single_field_id("LIST", &qualified_name)? + self.begin_inputs()?; + self.end_obj()?; // inputs + self.single_field_id("LIST", &qualified_name)?; + self.end_obj()?; // node } - None => {} + _ => {} } - self.end_obj() // node - } - - pub fn hide(&mut self, s: S, d: D, name: &Name) -> io::Result<()> { - self.show(s, d, name) + Ok(()) } pub fn add_to_list( diff --git a/src/visitor/pass2.rs b/src/visitor/pass2.rs index 61b85f22..4cb2ce17 100644 --- a/src/visitor/pass2.rs +++ b/src/visitor/pass2.rs @@ -197,6 +197,8 @@ fn visit_stmts(stmts: &mut Vec, s: S, d: D, top_level: bool) { let mut i = 0; while i < stmts.len() { let replace = match &stmts[i] { + Stmt::Show(name) => visit_show_or_hide_monitor(name, s, d, true), + Stmt::Hide(name) => visit_show_or_hide_monitor(name, s, d, false), Stmt::SetVar { name, value, @@ -729,3 +731,41 @@ fn const_struct_literal( } } } + +fn visit_show_or_hide_monitor(name: &Name, s: S, _d: D, is_show: bool) -> Option> { + if name.fieldname().is_some() { + return None; + } + let basename = name.basename(); + let type_ = s + .get_list(basename) + .map(|list| &list.type_) + .or_else(|| s.get_var(basename).map(|var| &var.type_))?; + let (type_name, _) = type_.struct_()?; + let struct_ = s.get_struct(type_name)?; + Some( + struct_ + .fields + .iter() + .map(|field| { + if is_show { + Stmt::Show(Name::DotName { + lhs: name.basename().clone(), + lhs_span: name.basespan().clone(), + rhs: field.name.clone(), + rhs_span: field.span.clone(), + is_generated: true, + }) + } else { + Stmt::Hide(Name::DotName { + lhs: name.basename().clone(), + lhs_span: name.basespan().clone(), + rhs: field.name.clone(), + rhs_span: field.span.clone(), + is_generated: true, + }) + } + }) + .collect(), + ) +}