diff --git a/src/data_model.rs b/src/data_model.rs index 484745f5..67bb626c 100644 --- a/src/data_model.rs +++ b/src/data_model.rs @@ -1311,38 +1311,41 @@ impl<'a> DocBuild<'a> for GenericIdentifier { } } } + +#[derive(Debug)] +pub struct ElseClause { + pub else_node: ValueNode, // The 'else' keyword node + pub statement: Statement, // The actual else-block or nested if +} + #[derive(Debug)] pub struct IfStatement { pub condition: ParenthesizedExpression, pub consequence: Statement, - pub alternative: Option, + 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 { pub fn new(node: Node) -> Self { assert_check(node, "if_statement"); - 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 + let alternative = node.try_c_by_n("alternative").map(|alt_stmt| { + let else_node = 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); + .expect("a mandatory `else` node is missing"); + + ElseClause { + else_node: ValueNode::new(else_node), + statement: Statement::new(alt_stmt), + } + }); 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), } } @@ -1363,29 +1366,24 @@ impl<'a> DocBuild<'a> for IfStatement { } // Handle the 'else' part - if let Some(ref a) = self.alternative { + if let Some(ref alt) = self.alternative { 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(" ")); - } + result.push(b.txt(" ")); + + result.push(alt.else_node.build(b)); + result.push(b.txt(" ")); } else { result.push(b.nl()); - result.push(b.txt("else")); - if self.has_else_and_followed_by_new_line_comment { - result.push(b.nl()); - } - if !matches!(a, Statement::If(_) | Statement::Block(_)) { + result.push(alt.else_node.build(b)); + + if !matches!(alt.statement, Statement::If(_) | Statement::Block(_)) { result.push(b.indent(b.nl())); } else { result.push(b.txt(" ")); } } - - result.push(a.build(b)); + result.push(alt.statement.build(b)); } }); } diff --git a/src/formatter.rs b/src/formatter.rs index b35b701e..d1148c9b 100644 --- a/src/formatter.rs +++ b/src/formatter.rs @@ -158,7 +158,7 @@ impl Formatter { let result = pretty_print(doc_ref, config.max_width); // debugging tool: use this to print named node value + comments in bucket - print_comment_map(&ast_tree); + // print_comment_map(&ast_tree); assert_no_missing_comments(); diff --git a/src/utility.rs b/src/utility.rs index 3e1a72fd..70b0b6a0 100644 --- a/src/utility.rs +++ b/src/utility.rs @@ -131,13 +131,17 @@ pub fn assert_no_missing_comments() { } pub fn is_punctuation_node(node: &Node) -> bool { - node.kind() == "," || node.kind() == ";" + matches!(node.kind(), "," | ";") +} + +fn is_associable_unnamed_node(node: &Node) -> bool { + is_punctuation_node(node) || matches!(node.kind(), "else") } pub fn collect_comments(cursor: &mut TreeCursor, comment_map: &mut CommentMap) { let node = cursor.node(); - if (!node.is_named() || node.is_extra()) && !is_punctuation_node(&node) { + if (!node.is_named() || node.is_extra()) && !is_associable_unnamed_node(&node) { return; } @@ -217,7 +221,7 @@ pub fn collect_comments(cursor: &mut TreeCursor, comment_map: &mut CommentMap) { // There's no "last associable node" yet, so keep it pending pending_pre_comments.push(comment); } - } else if child.is_named() || is_punctuation_node(&child) { + } else if child.is_named() || is_associable_unnamed_node(&child) { // It's an associable node let child_id = child.id(); diff --git a/tests/battle_test/repos.txt b/tests/battle_test/repos.txt index 77153064..c0275396 100644 --- a/tests/battle_test/repos.txt +++ b/tests/battle_test/repos.txt @@ -2,9 +2,7 @@ https://bitbucket.org/aidan_harding/sobjectindex.git https://github.com/PropicSignifi/Query.apex.git https://github.com/SalesforceFoundation/Affiliations.git https://github.com/SalesforceFoundation/Contacts_and_Organizations.git -https://github.com/SalesforceFoundation/EDA.git https://github.com/SalesforceFoundation/Households.git -https://github.com/SalesforceFoundation/NPSP.git https://github.com/SalesforceFoundation/PMM.git https://github.com/SalesforceFoundation/Relationships.git https://github.com/SalesforceFoundation/Volunteers-for-Salesforce.git diff --git a/tests/static/idempotent2.cls b/tests/static/idempotent2.cls index 1f42945a..16d2b293 100644 --- a/tests/static/idempotent2.cls +++ b/tests/static/idempotent2.cls @@ -2,8 +2,7 @@ class TestClass { { if (true) { - } else - // comment 1 + } else // comment 1 { } }