From 8ced80fb2dd58742219205032dc8d74e35ec029c Mon Sep 17 00:00:00 2001 From: Xi Xiao Date: Fri, 14 Mar 2025 08:17:43 +0200 Subject: [PATCH] chore: better way to fix `else` idempotent issue --- src/context.rs | 9 -------- src/data_model.rs | 59 +++++++++++++++++++++++++---------------------- src/utility.rs | 6 ----- 3 files changed, 32 insertions(+), 42 deletions(-) diff --git a/src/context.rs b/src/context.rs index b698a41d..5040d196 100644 --- a/src/context.rs +++ b/src/context.rs @@ -114,10 +114,6 @@ impl Comment { self.metadata.has_empty_line_above } - pub fn has_prev_node_else_keyword(&self) -> bool { - self.metadata.has_prev_node_else_keyword - } - pub fn is_followed_by_bracket_composite_node(&self) -> bool { self.metadata.is_followed_by_bracket_composite_node } @@ -167,7 +163,6 @@ pub struct CommentMetadata { has_empty_line_above: bool, has_empty_line_below: bool, has_prev_node: bool, - has_prev_node_else_keyword: bool, is_followed_by_bracket_composite_node: bool, } @@ -176,9 +171,6 @@ impl CommentMetadata { let prev = node.prev_named_sibling(); let has_prev_node = prev.is_some(); - let prev_unnamed = node.prev_sibling(); - let has_prev_node_else_keyword = prev_unnamed.map(|n| n.kind() == "else").unwrap_or(false); - let has_leading_content = if let Some(prev_node) = prev { node.start_position().row == prev_node.end_position().row } else { @@ -221,7 +213,6 @@ impl CommentMetadata { has_empty_line_above, has_empty_line_below, has_prev_node, - has_prev_node_else_keyword, is_followed_by_bracket_composite_node, } } diff --git a/src/data_model.rs b/src/data_model.rs index f3bf1c33..6fd66345 100644 --- a/src/data_model.rs +++ b/src/data_model.rs @@ -1317,6 +1317,7 @@ pub struct IfStatement { pub consequence: Statement, pub alternative: Option, pub node_context: NodeContext, + pub has_else_and_followed_by_new_line_comment: bool, // https://github.com/xixiaofinland/afmt/issues/67 } impl IfStatement { @@ -1325,10 +1326,23 @@ impl IfStatement { let alternative = node.try_c_by_n("alternative").map(|a| Statement::new(a)); + let has_else_and_followed_by_new_line_comment = alternative.is_some() + && node + .children(&mut node.walk()) + .find(|n| n.kind() == "else") + .and_then(|else_node| { + else_node.next_sibling().map(|next_sibling| { + next_sibling.is_extra() + && next_sibling.start_position().row != else_node.end_position().row + }) + }) + .unwrap_or(false); + Self { condition: ParenthesizedExpression::new(node.c_by_n("condition")), consequence: Statement::new(node.c_by_n("consequence")), alternative, + has_else_and_followed_by_new_line_comment, node_context: NodeContext::with_punctuation(&node), } } @@ -1350,37 +1364,28 @@ impl<'a> DocBuild<'a> for IfStatement { // Handle the 'else' part if let Some(ref a) = self.alternative { - match a { - Statement::If(_) => { - if self.consequence.is_block() { - result.push(b.txt(" else ")); - } else { - result.push(b.nl()); - result.push(b.txt("else ")); - } - result.push(a.build(b)); // Recursively build the nested 'else if' statement + if self.consequence.is_block() { + result.push(b.txt(" else")); + if self.has_else_and_followed_by_new_line_comment { + result.push(b.nl()); + } else { + result.push(b.txt(" ")); } - Statement::Block(_) => { - if self.consequence.is_block() { - result.push(b.txt(" else ")); - } else { - result.push(b.nl()); - result.push(b.txt("else ")); - } - result.push(a.build(b)); + } else { + result.push(b.nl()); + result.push(b.txt("else")); + if self.has_else_and_followed_by_new_line_comment { + result.push(b.nl()); } - // Handle "else" with a single statement - _ => { - if self.consequence.is_block() { - result.push(b.txt(" else ")); - } else { - result.push(b.nl()); - result.push(b.txt("else")); - result.push(b.indent(b.nl())); - } - result.push(a.build(b)); // Build the else statement + + if !matches!(a, Statement::If(_) | Statement::Block(_)) { + result.push(b.indent(b.nl())); + } else { + result.push(b.txt(" ")); } } + + result.push(a.build(b)); } }); } diff --git a/src/utility.rs b/src/utility.rs index dc08b324..629f3857 100644 --- a/src/utility.rs +++ b/src/utility.rs @@ -355,15 +355,9 @@ pub fn handle_pre_comments<'a>( docs.push(b.txt(" ")); } else { // if it's in group(), then multi-line mode is selected in fits() - // otherwise, do nothing docs.push(b.force_break()); // 1st element heading logic is handled in the preceding node; - // except the preceding is an unnamed node like `else` - if comment.has_prev_node_else_keyword() { - docs.push(b.nl()); - } - if i != 0 { if comment.has_newline_above() { docs.push(b.empty_new_line());