Skip to content

Commit 9dfce54

Browse files
committed
Tweak comment indentation
Before this change, the parser would default to setting the level of comments to the level of the current context, making an exception for comments inside a 'subroutine' or 'type block' context. This exception allows some comments to inherit the level of the next line. This change fixes an issue where only the last comment in a series would have this exception applied, and also flips the default handling so that this 'exception' is actually the norm. Usually, comments are 'supposed' to relate to what they precede, so we should try to set the level of the comment to the next 'thing'. However in some cases this makes little sense, because the next 'thing' may be a token that only exists to end a block context (e.g. 'end'). So the new exception is for comments in 'statement list' contexts to have the level of the context, but everything else has the level of the next line.
1 parent b999174 commit 9dfce54

File tree

2 files changed

+29
-18
lines changed

2 files changed

+29
-18
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4242
- `continuation_indents` now controls the number of indentations per continuation.
4343
- Parsing of `while`, `with`, `on`, `if`, case arm and `for` statements to use
4444
child lines for their nested statements.
45+
- Indentation level of comments in various edge cases.
4546

4647
### Added
4748

core/src/defaults/parser.rs

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ struct InternalDelphiLogicalLineParser<'a, 'b> {
169169
pass_index: usize,
170170
context: ParserContexts,
171171
unfinished_comment_lines: Vec<LogicalLineRef>,
172+
current_line_is_unfinished: bool,
172173
paren_level: u32,
173174
brack_level: u32,
174175
generic_level: u32,
@@ -195,6 +196,7 @@ impl<'a, 'b> InternalDelphiLogicalLineParser<'a, 'b> {
195196
pass_index: 0,
196197
context: ParserContexts::default(),
197198
unfinished_comment_lines: vec![],
199+
current_line_is_unfinished: false,
198200
paren_level: 0,
199201
brack_level: 0,
200202
generic_level: 0,
@@ -261,8 +263,6 @@ impl<'a, 'b> InternalDelphiLogicalLineParser<'a, 'b> {
261263
if let TT::CompilerDirective = kind {
262264
self.set_logical_line_type(LLT::CompilerDirective);
263265
}
264-
let line_ref = self.get_current_logical_line_ref();
265-
self.finish_logical_line();
266266
/*
267267
The lines are considered "unfinished" if their level is determined by the
268268
code that follows.
@@ -280,11 +280,10 @@ impl<'a, 'b> InternalDelphiLogicalLineParser<'a, 'b> {
280280
end;
281281
```
282282
*/
283-
if matches!(
284-
self.get_last_context_type(),
285-
Some(ContextType::SubRoutine | ContextType::TypeBlock)
286-
) {
287-
self.unfinished_comment_lines.push(line_ref);
283+
if self.is_in_statement_list() {
284+
self.finish_logical_line();
285+
} else {
286+
self.make_unfinished_line();
288287
}
289288
}
290289
TT::Keyword(
@@ -320,9 +319,7 @@ impl<'a, 'b> InternalDelphiLogicalLineParser<'a, 'b> {
320319
// If there is a `[` at the start of a line, it must be an attribute
321320
self.skip_pair();
322321
self.set_logical_line_type(LogicalLineType::Attribute);
323-
let line_ref = self.get_current_logical_line_ref();
324-
self.finish_logical_line();
325-
self.unfinished_comment_lines.push(line_ref);
322+
self.make_unfinished_line();
326323
}
327324
TT::Keyword(
328325
keyword_kind @ (KK::Interface
@@ -1175,6 +1172,12 @@ impl<'a, 'b> InternalDelphiLogicalLineParser<'a, 'b> {
11751172
self.parse_statement();
11761173
self.context.pop();
11771174
}
1175+
fn is_in_statement_list(&self) -> bool {
1176+
let mut contexts = self.context.contexts.iter().rev().map(|c| c.context_type);
1177+
1178+
matches!(contexts.next(), Some(ContextType::Statement(_)))
1179+
&& matches!(contexts.next(), Some(ContextType::StatementBlock(_)))
1180+
}
11781181
fn parse_statement_list_block(&mut self, context: ParserContext) {
11791182
self.parse_statement_block_with_kind(context, StatementKind::Normal);
11801183
}
@@ -1733,6 +1736,13 @@ impl<'a, 'b> InternalDelphiLogicalLineParser<'a, 'b> {
17331736
self.get_current_logical_line().tokens.is_empty()
17341737
}
17351738

1739+
fn make_unfinished_line(&mut self) {
1740+
let line_ref = self.get_current_logical_line_ref();
1741+
self.current_line_is_unfinished = true;
1742+
self.unfinished_comment_lines.push(line_ref);
1743+
self.finish_logical_line();
1744+
}
1745+
17361746
fn finish_logical_line(&mut self) {
17371747
if self.is_at_start_of_line() {
17381748
self.get_current_logical_line_mut().line_type = LLT::Unknown;
@@ -1749,11 +1759,14 @@ impl<'a, 'b> InternalDelphiLogicalLineParser<'a, 'b> {
17491759
}
17501760
let (parent, context_level) = self.get_context_level();
17511761

1752-
for unfinished_line in self.unfinished_comment_lines.drain(..).collect_vec() {
1753-
if let Some(line) = self.get_logical_line_from_ref_mut(unfinished_line) {
1754-
line.level = context_level;
1762+
if !self.current_line_is_unfinished {
1763+
for unfinished_line in self.unfinished_comment_lines.drain(..).collect_vec() {
1764+
if let Some(line) = self.get_logical_line_from_ref_mut(unfinished_line) {
1765+
line.level = context_level;
1766+
}
17551767
}
1756-
}
1768+
};
1769+
self.current_line_is_unfinished = false;
17571770

17581771
let line_ref = *self.current_line.last();
17591772

@@ -2010,10 +2023,7 @@ impl<'a, 'b> InternalDelphiLogicalLineParser<'a, 'b> {
20102023
self.context.contexts.last()
20112024
}
20122025
fn get_last_context_type(&self) -> Option<ContextType> {
2013-
self.context
2014-
.contexts
2015-
.last()
2016-
.map(|&ParserContext { context_type, .. }| context_type)
2026+
self.context.contexts.last().map(|ctx| ctx.context_type)
20172027
}
20182028
fn get_context_level(&self) -> (Option<LineParent>, u16) {
20192029
/*

0 commit comments

Comments
 (0)