Skip to content

Commit 248fa13

Browse files
committed
Fix comments losing newlines between them in some cases
Also rename some functions
1 parent 94fcd06 commit 248fa13

3 files changed

Lines changed: 80 additions & 16 deletions

File tree

src/formatter.rs

Lines changed: 50 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,17 @@ fn process_body(
430430
render_elements.push(RenderElement::Space);
431431
}
432432
} else if last_processed_child_kind == Some(GDScriptNodeKind::Comment) {
433-
if statement_has_inline_comment && current_is_declaration {
433+
if current_child_kind == GDScriptNodeKind::Comment {
434+
add_spacing_between_body_children(
435+
previous_end,
436+
child.start_byte(),
437+
input,
438+
render_elements,
439+
last_processed_child_kind,
440+
current_child_kind,
441+
false,
442+
);
443+
} else if statement_has_inline_comment && current_is_declaration {
434444
let needs_two_blank_lines = needs_two_blank_lines(current_child_kind);
435445
add_spacing_between_body_children(
436446
previous_end,
@@ -988,7 +998,7 @@ fn output_pending_before_declaration(
988998
}
989999
render_elements.push(RenderElement::BlankLine);
9901000
}
991-
emit_pending_block(render_elements, input, pending);
1001+
process_pending_block(render_elements, input, pending);
9921002
// pending is reused across declarations, so we need to clear it here
9931003
// now that its contents have been emitted.
9941004
pending.clear();
@@ -1029,7 +1039,7 @@ fn output_pending_before_declaration(
10291039
render_elements.push(RenderElement::HardLine);
10301040
render_elements.push(RenderElement::BlankLine);
10311041
}
1032-
emit_pending_block(render_elements, input, &leading_block);
1042+
process_pending_block(render_elements, input, &leading_block);
10331043
render_elements.push(RenderElement::HardLine);
10341044
return;
10351045
}
@@ -1045,7 +1055,7 @@ fn output_pending_before_declaration(
10451055
render_elements.push(RenderElement::HardLine);
10461056
}
10471057
render_elements.push(RenderElement::BlankLine);
1048-
emit_pending_block(render_elements, input, &leading_block);
1058+
process_pending_block(render_elements, input, &leading_block);
10491059
render_elements.push(RenderElement::HardLine);
10501060
} else if attached_to_declaration {
10511061
render_elements.push(RenderElement::HardLine);
@@ -1062,7 +1072,7 @@ fn output_pending_before_declaration(
10621072
/// Outputs a batch of buffered comments or annotations. Iterates through the
10631073
/// pending list and inserts spaces, hard lines, or blank lines between items
10641074
/// based on the newline counts recorded when they were buffered.
1065-
fn emit_pending_block(
1075+
fn process_pending_block(
10661076
render_elements: &mut Vec<RenderElement>,
10671077
input: &ParseInput,
10681078
pending: &[(tree_sitter::Node, usize)],
@@ -1200,7 +1210,7 @@ fn process_setget(
12001210
while inner < child_count {
12011211
if let Some(inner_child) = node.child(inner as u32) {
12021212
if let Some(ref previous_child) = previous {
1203-
emit_inter_child_separator(
1213+
process_separator_between_sibling_nodes(
12041214
GDScriptNodeKind::SetGet,
12051215
previous_child,
12061216
&inner_child,
@@ -1311,7 +1321,7 @@ fn process_container(
13111321
if previous_kind == GDScriptNodeKind::Comment {
13121322
render_elements.push(RenderElement::HardLine);
13131323
} else {
1314-
emit_inter_child_separator(
1324+
process_separator_between_sibling_nodes(
13151325
node_kind,
13161326
previous_child,
13171327
&child,
@@ -1457,7 +1467,7 @@ fn process_parenthesized_expression(
14571467
while index < end {
14581468
if let Some(child) = node.child(index) {
14591469
if let Some(ref previous_child) = previous {
1460-
emit_inter_child_separator(
1470+
process_separator_between_sibling_nodes(
14611471
GDScriptNodeKind::ParenthesizedExpression,
14621472
previous_child,
14631473
&child,
@@ -1973,7 +1983,7 @@ fn process_method_call_flat(
19731983
while argument_index < body_end {
19741984
if let Some(child_argument) = args.child(argument_index) {
19751985
if let Some(ref previous_node) = previous_child {
1976-
emit_inter_child_separator(
1986+
process_separator_between_sibling_nodes(
19771987
args_kind,
19781988
previous_node,
19791989
&child_argument,
@@ -1987,7 +1997,12 @@ fn process_method_call_flat(
19871997
}
19881998
if let Some(close) = args.child(close_parenthesis_index) {
19891999
if let Some(ref previous_node) = previous_child {
1990-
emit_inter_child_separator(args_kind, previous_node, &close, render_elements);
2000+
process_separator_between_sibling_nodes(
2001+
args_kind,
2002+
previous_node,
2003+
&close,
2004+
render_elements,
2005+
);
19912006
}
19922007
process_node(input, close, render_elements);
19932008
}
@@ -2031,7 +2046,7 @@ fn process_lambda(
20312046
});
20322047
render_elements.push(RenderElement::Space);
20332048
} else {
2034-
emit_lambda_separator(previous_kind, child_kind, render_elements);
2049+
process_lambda_separator(previous_kind, child_kind, render_elements);
20352050
}
20362051
}
20372052
process_node(input, child, render_elements);
@@ -2075,7 +2090,7 @@ fn process_lambda(
20752090
/// Handles spacing between children of a lambda node. Deals with comments (hard
20762091
/// line), body-like nodes (hard line), specific token pairs that need no
20772092
/// separator, and defaults to a space.
2078-
fn emit_lambda_separator(
2093+
fn process_lambda_separator(
20792094
previous_kind: GDScriptNodeKind,
20802095
current_kind: GDScriptNodeKind,
20812096
render_elements: &mut Vec<RenderElement>,
@@ -2132,7 +2147,7 @@ fn process_children_with_spacing(
21322147
let region = disabled_run.region;
21332148
if child.start_byte() == region.start {
21342149
if let Some(ref previous_child) = previous {
2135-
emit_inter_child_separator(
2150+
process_separator_between_sibling_nodes(
21362151
parent_kind,
21372152
previous_child,
21382153
&child,
@@ -2165,7 +2180,12 @@ fn process_children_with_spacing(
21652180
let child_kind = GDScriptNodeKind::get_kind_from_ast_node(child);
21662181
if let Some(ref previous_child) = previous {
21672182
let previous_kind = GDScriptNodeKind::get_kind_from_ast_node(*previous_child);
2168-
emit_inter_child_separator(parent_kind, previous_child, &child, render_elements);
2183+
process_separator_between_sibling_nodes(
2184+
parent_kind,
2185+
previous_child,
2186+
&child,
2187+
render_elements,
2188+
);
21692189
if previous_kind == GDScriptNodeKind::LineContinuation {
21702190
let indent_index =
21712191
begin_indent(render_elements, input.continuation_indent_level);
@@ -2200,7 +2220,7 @@ fn process_children_with_spacing(
22002220
/// a blank line, or nothing. Handles tokens (parens, brackets, dots, commas,
22012221
/// colons), body nodes, comments, annotations, and special parent cases like
22022222
/// InferredType and UnaryOperator.
2203-
fn emit_inter_child_separator(
2223+
fn process_separator_between_sibling_nodes(
22042224
parent_kind: GDScriptNodeKind,
22052225
previous_child: &tree_sitter::Node,
22062226
current: &tree_sitter::Node,
@@ -2213,6 +2233,20 @@ fn emit_inter_child_separator(
22132233
return;
22142234
}
22152235

2236+
if current_kind == GDScriptNodeKind::Comment {
2237+
let previous_end_row = previous_child.end_position().row;
2238+
let current_start_row = current.start_position().row;
2239+
if current_start_row == previous_end_row {
2240+
render_elements.push(RenderElement::Space);
2241+
} else {
2242+
render_elements.push(RenderElement::HardLine);
2243+
if current_start_row > previous_end_row + 1 {
2244+
render_elements.push(RenderElement::BlankLine);
2245+
}
2246+
}
2247+
return;
2248+
}
2249+
22162250
if current_kind == GDScriptNodeKind::ElifStatement
22172251
|| current_kind == GDScriptNodeKind::ElseStatement
22182252
{
@@ -2448,7 +2482,7 @@ fn process_source_reorder(
24482482
continue;
24492483
}
24502484
if let Some(ref previous_node) = previous_node {
2451-
emit_inter_child_separator(
2485+
process_separator_between_sibling_nodes(
24522486
parent_kind,
24532487
previous_node,
24542488
&sub,
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Tests that the line spacing between comments is preserved after formatting.
2+
func test():
3+
# first comment
4+
5+
# second comment
6+
pass
7+
8+
9+
func test2():
10+
if true:
11+
pass
12+
# first comment
13+
# second comment
14+
elif false:
15+
pass

tests/input/comment_edge_cases.gd

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Tests that the line spacing between comments is preserved after formatting.
2+
func test():
3+
# first comment
4+
5+
6+
# second comment
7+
pass
8+
9+
func test2():
10+
if true:
11+
pass
12+
# first comment
13+
# second comment
14+
elif false:
15+
pass

0 commit comments

Comments
 (0)