Skip to content

Commit f34bd8f

Browse files
committed
fix: better support for comments in conditional types
1 parent f9eb198 commit f34bd8f

File tree

5 files changed

+196
-90
lines changed

5 files changed

+196
-90
lines changed

rust-toolchain.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
[toolchain]
2-
channel = "1.59.0"
2+
channel = "1.61.0"
33
components = ["clippy"]

src/generation/generate.rs

Lines changed: 135 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1790,7 +1790,8 @@ fn gen_binary_expr<'a>(node: &'a BinExpr, context: &mut Context<'a>) -> PrintIte
17901790
ir_helpers::gen_separated_values(
17911791
|_| {
17921792
let mut generated_nodes = Vec::new();
1793-
for bin_expr_item in flattened_binary_expr.into_iter() {
1793+
let mut bin_expr_items_iter = flattened_binary_expr.into_iter().peekable();
1794+
while let Some(bin_expr_item) = bin_expr_items_iter.next() {
17941795
let lines_span = Some(ir_helpers::LinesSpan {
17951796
start_line: bin_expr_item.expr.start_line_fast(context.program),
17961797
end_line: bin_expr_item.expr.end_line_fast(context.program),
@@ -1800,22 +1801,9 @@ fn gen_binary_expr<'a>(node: &'a BinExpr, context: &mut Context<'a>) -> PrintIte
18001801
let pre_op = bin_expr_item.pre_op;
18011802
let post_op = bin_expr_item.post_op;
18021803
let (leading_pre_op_comments, trailing_pre_op_comments) = if let Some(op) = &pre_op {
1803-
let op_line = op.token.start_line_fast(context.program);
18041804
(
1805-
gen_op_comments(
1806-
op.token
1807-
.leading_comments_fast(context.program)
1808-
.filter(|x| x.kind == CommentKind::Block && x.start_line_fast(context.program) == op_line)
1809-
.collect(),
1810-
context,
1811-
),
1812-
gen_op_comments(
1813-
op.token
1814-
.trailing_comments_fast(context.program)
1815-
.filter(|x| x.kind == CommentKind::Block && x.start_line_fast(context.program) == op_line)
1816-
.collect(),
1817-
context,
1818-
),
1805+
gen_leading_comments_same_line(&op.token.range(), context),
1806+
gen_trailing_comments_same_line(&op.token.range(), context),
18191807
)
18201808
} else {
18211809
(PrintItems::new(), PrintItems::new())
@@ -1826,15 +1814,13 @@ fn gen_binary_expr<'a>(node: &'a BinExpr, context: &mut Context<'a>) -> PrintIte
18261814
if let Some(op) = pre_op {
18271815
if !leading_pre_op_comments.is_empty() {
18281816
items.extend(leading_pre_op_comments);
1829-
items.push_str(" ");
18301817
}
18311818
items.push_str(op.op.as_str());
18321819
if trailing_pre_op_comments.is_empty() {
18331820
if use_space_surrounding_operator {
18341821
items.push_str(" ");
18351822
}
18361823
} else {
1837-
items.push_str(" ");
18381824
items.extend(trailing_pre_op_comments);
18391825
items.push_str(" ");
18401826
}
@@ -1864,35 +1850,25 @@ fn gen_binary_expr<'a>(node: &'a BinExpr, context: &mut Context<'a>) -> PrintIte
18641850
});
18651851

18661852
if let Some(op) = post_op {
1867-
let op_line = op.token.start_line_fast(context.program);
1868-
let leading_post_op_comments = gen_op_comments(
1869-
op.token
1870-
.leading_comments_fast(context.program)
1871-
.filter(|x| x.kind == CommentKind::Block && x.start_line_fast(context.program) == op_line)
1872-
.collect(),
1873-
context,
1874-
);
1875-
let trailing_post_op_comments = gen_op_comments(
1876-
op.token
1877-
.trailing_comments_fast(context.program)
1878-
.filter(|x| x.start_line_fast(context.program) == op_line)
1879-
.collect(),
1880-
context,
1881-
);
1853+
let leading_post_op_comments = gen_leading_comments_same_line(&op.token.range(), context);
1854+
let trailing_post_op_comments = gen_trailing_comments_same_line(&op.token.range(), context);
18821855
if leading_post_op_comments.is_empty() {
18831856
if use_space_surrounding_operator {
18841857
items.push_str(" ");
18851858
}
18861859
} else {
18871860
items.push_str(" ");
18881861
items.extend(leading_post_op_comments);
1889-
items.push_str(" ");
18901862
}
18911863
items.push_str(op.op.as_str());
18921864
if !trailing_post_op_comments.is_empty() {
1893-
items.push_str(" ");
18941865
items.extend(trailing_post_op_comments);
18951866
}
1867+
} else if let Some(next_item) = bin_expr_items_iter.peek() {
1868+
// put any line comments after the next pre-op on this line instead
1869+
if let Some(pre_op) = &next_item.pre_op {
1870+
items.extend(gen_trailing_comments_if_line_comment_same_line(&pre_op.token.range(), context));
1871+
}
18961872
}
18971873

18981874
items
@@ -1957,23 +1933,6 @@ fn gen_binary_expr<'a>(node: &'a BinExpr, context: &mut Context<'a>) -> PrintIte
19571933
}
19581934
}
19591935

1960-
fn gen_op_comments(comments: Vec<&Comment>, context: &mut Context) -> PrintItems {
1961-
let mut items = PrintItems::new();
1962-
let mut had_comment_last = false;
1963-
for comment in comments {
1964-
if had_comment_last {
1965-
items.push_str(" ");
1966-
}
1967-
if let Some(comment) = gen_comment(comment, context) {
1968-
items.extend(comment);
1969-
had_comment_last = true;
1970-
} else {
1971-
had_comment_last = false;
1972-
}
1973-
}
1974-
items
1975-
}
1976-
19771936
fn get_use_space_surrounding_operator(op: &BinaryOp, context: &Context) -> bool {
19781937
if op.is_bitwise_or_arithmetic() {
19791938
context.config.binary_expression_space_surrounding_bitwise_and_arithmetic_operator
@@ -5034,10 +4993,22 @@ fn gen_conditional_type<'a>(node: &'a TsConditionalType, context: &mut Context<'
50344993
node.extends_type.into(),
50354994
context,
50364995
))));
5037-
items.push_signal(Signal::SpaceOrNewLine);
4996+
4997+
// add any preceeding comments of the question token
4998+
let question_token_start = context.token_finder.get_next_token_pos_after(&node.extends_type);
4999+
items.extend({
5000+
let comment_items = gen_leading_comments_on_previous_lines(&question_token_start, context);
5001+
if comment_items.is_empty() {
5002+
Signal::SpaceOrNewLine.into()
5003+
} else {
5004+
surround_with_new_lines(with_indent(comment_items))
5005+
}
5006+
});
5007+
50385008
items.push_condition({
50395009
let inner_items = {
50405010
let mut items = PrintItems::new();
5011+
items.extend(gen_leading_comments_same_line(&question_token_start, context));
50415012
items.push_str("? ");
50425013
items.extend(ir_helpers::new_line_group(gen_node(node.true_type.into(), context)));
50435014
items
@@ -5061,9 +5032,19 @@ fn gen_conditional_type<'a>(node: &'a TsConditionalType, context: &mut Context<'
50615032
));
50625033
}
50635034

5035+
// add any preceeding comments of the colon token
5036+
let colon_token_start = context.token_finder.get_next_token_pos_after(&node.true_type);
5037+
{
5038+
let comment_items = gen_leading_comments_on_previous_lines(&colon_token_start, context);
5039+
if !comment_items.is_empty() {
5040+
items.extend(with_indent(comment_items));
5041+
}
5042+
}
5043+
50645044
let false_type_generated = {
50655045
let mut items = PrintItems::new();
50665046
items.push_info(before_false_ln);
5047+
items.extend(gen_leading_comments_same_line(&colon_token_start, context));
50675048
items.push_str(": ");
50685049
items.extend(ir_helpers::new_line_group(gen_node(node.false_type.into(), context)));
50695050
items
@@ -5821,18 +5802,54 @@ fn gen_comments_as_leading<'a>(node: &dyn SourceRanged, comments: CommentsIterat
58215802
}
58225803

58235804
fn gen_trailing_comments_as_statements<'a>(node: &dyn SourceRanged, context: &mut Context<'a>) -> PrintItems {
5824-
let unhandled_comments = get_trailing_comments_as_statements(node, context);
5825-
gen_comments_as_statements(unhandled_comments.into_iter(), Some(node), context)
5805+
let comments = get_trailing_comments_as_statements(node, context);
5806+
gen_comments_as_statements(comments.into_iter(), Some(node), context)
5807+
}
5808+
5809+
fn gen_leading_comments_on_previous_lines<'a>(node: &dyn SourceRanged, context: &mut Context<'a>) -> PrintItems {
5810+
let unhandled_comments = get_leading_comments_on_previous_lines(node, context);
5811+
gen_comments_as_statements(unhandled_comments.into_iter(), None, context)
58265812
}
58275813

58285814
fn get_leading_comments_on_previous_lines<'a>(node: &dyn SourceRanged, context: &mut Context<'a>) -> Vec<&'a Comment> {
5815+
let leading_comments = node.leading_comments_fast(context.program);
5816+
if leading_comments.is_empty() {
5817+
return Vec::new(); // avoid extra calculations
5818+
}
58295819
let node_start_line = node.start_line_fast(context.program);
5830-
node
5831-
.leading_comments_fast(context.program)
5832-
.take_while(|c| c.kind == CommentKind::Line || c.start_line_fast(context.program) < node_start_line)
5820+
let previous_token_line = node.previous_token_fast(context.program).map(|t| t.end_line_fast(context.program));
5821+
leading_comments
5822+
.take_while(|c| {
5823+
let line = c.start_line_fast(context.program);
5824+
line < node_start_line && previous_token_line.map(|line| line < node_start_line).unwrap_or(true)
5825+
})
58335826
.collect::<Vec<_>>()
58345827
}
58355828

5829+
fn get_leading_comments_on_same_line<'a>(node: &dyn SourceRanged, context: &mut Context<'a>) -> Vec<&'a Comment> {
5830+
let leading_comments = node.leading_comments_fast(context.program);
5831+
if leading_comments.is_empty() {
5832+
Vec::new()
5833+
} else {
5834+
let node_start_line = node.start_line_fast(context.program);
5835+
leading_comments
5836+
.filter(|c| c.kind == CommentKind::Block || c.start_line_fast(context.program) == node_start_line)
5837+
.collect::<Vec<_>>()
5838+
}
5839+
}
5840+
5841+
fn get_trailing_comments_on_same_line<'a>(node: &dyn SourceRanged, context: &mut Context<'a>) -> Vec<&'a Comment> {
5842+
let trailing_comments = node.trailing_comments_fast(context.program);
5843+
if trailing_comments.is_empty() {
5844+
Vec::new()
5845+
} else {
5846+
let node_start_line = node.start_line_fast(context.program);
5847+
trailing_comments
5848+
.take_while(|c| c.kind == CommentKind::Block || c.start_line_fast(context.program) == node_start_line)
5849+
.collect::<Vec<_>>()
5850+
}
5851+
}
5852+
58365853
fn get_trailing_comments_as_statements<'a>(node: &dyn SourceRanged, context: &mut Context<'a>) -> Vec<&'a Comment> {
58375854
let mut comments = Vec::new();
58385855
let node_end_line = node.end_line_fast(context.program);
@@ -5927,6 +5944,66 @@ fn gen_comment_collection<'a>(
59275944
items
59285945
}
59295946

5947+
fn gen_leading_comments_same_line(node: &dyn SourceRanged, context: &mut Context) -> PrintItems {
5948+
let comments = get_leading_comments_on_same_line(node, context);
5949+
if comments.is_empty() {
5950+
PrintItems::new()
5951+
} else {
5952+
let mut items = gen_comments_same_line(comments, context);
5953+
if !items.is_empty() {
5954+
items.push_str(" ");
5955+
}
5956+
items
5957+
}
5958+
}
5959+
5960+
fn gen_trailing_comments_same_line(node: &dyn SourceRanged, context: &mut Context) -> PrintItems {
5961+
let comments = get_trailing_comments_on_same_line(node, context);
5962+
if comments.is_empty() {
5963+
PrintItems::new()
5964+
} else {
5965+
let mut items = PrintItems::new();
5966+
let comment_items = gen_comments_same_line(comments, context);
5967+
if !comment_items.is_empty() {
5968+
items.push_str(" ");
5969+
items.extend(comment_items);
5970+
}
5971+
items
5972+
}
5973+
}
5974+
5975+
fn gen_trailing_comments_if_line_comment_same_line(node: &dyn SourceRanged, context: &mut Context) -> PrintItems {
5976+
let comments = get_trailing_comments_on_same_line(node, context);
5977+
if !comments.iter().any(|c| c.kind == CommentKind::Line) {
5978+
PrintItems::new()
5979+
} else {
5980+
let mut items = PrintItems::new();
5981+
let comment_items = gen_comments_same_line(comments, context);
5982+
if !comment_items.is_empty() {
5983+
items.push_str(" ");
5984+
items.extend(comment_items);
5985+
}
5986+
items
5987+
}
5988+
}
5989+
5990+
fn gen_comments_same_line(comments: Vec<&Comment>, context: &mut Context) -> PrintItems {
5991+
let mut items = PrintItems::new();
5992+
let mut had_comment_last = false;
5993+
for comment in comments {
5994+
if had_comment_last {
5995+
items.push_str(" ");
5996+
}
5997+
if let Some(comment) = gen_comment(comment, context) {
5998+
items.extend(comment);
5999+
had_comment_last = true;
6000+
} else {
6001+
had_comment_last = false;
6002+
}
6003+
}
6004+
items
6005+
}
6006+
59306007
struct GenCommentBasedOnLastNodeOptions {
59316008
separate_with_newlines: bool,
59326009
}

tests/specs/expressions/BinaryExpression/BinaryExpression_OperatorPosition_NextLine.txt

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
~~ binaryExpression.operatorPosition: nextLine ~~
22
== should move the operator to the next line ==
33
1 + 2 * 6 // test
4-
+ 4 + // not worth effort, people can move this comment back
4+
+ 4 + // test
55
7 * 6 + 4
66
+ 5;
77

88
[expect]
99
1 + 2 * 6 // test
10-
+ 4
11-
// not worth effort, people can move this comment back
10+
+ 4 // test
1211
+ 7 * 6 + 4
1312
+ 5;
1413

@@ -28,14 +27,13 @@
2827

2928
== should move the operator to the next line ==
3029
1 && 2 || 6 // test
31-
&& 4 || // not worth effort, people can move this comment back
30+
&& 4 || // test
3231
7 && 6 || 4
3332
&& 5;
3433

3534
[expect]
3635
1 && 2 || 6 // test
37-
&& 4
38-
// not worth effort, people can move this comment back
36+
&& 4 // test
3937
|| 7 && 6 || 4
4038
&& 5;
4139

tests/specs/expressions/ConditionalExpression/ConditionalExpression_All.txt

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -110,28 +110,3 @@ test ? testingThis : outABittt;
110110
test
111111
? testingThis
112112
: outABittt;
113-
114-
== should have object type indented in true type ==
115-
type T = U extends true ? {
116-
prop1: string;
117-
prop2: number;
118-
}
119-
: true;
120-
type T = U extends testtestt ? {
121-
prop1: string;
122-
prop2: number;
123-
}
124-
: true;
125-
126-
[expect]
127-
type T = U extends true ? {
128-
prop1: string;
129-
prop2: number;
130-
}
131-
: true;
132-
type T = U extends testtestt
133-
? {
134-
prop1: string;
135-
prop2: number;
136-
}
137-
: true;

0 commit comments

Comments
 (0)