Skip to content

Commit c954855

Browse files
committed
fix(fmt): comment fixes, closes #100
1 parent 8ba7e28 commit c954855

File tree

7 files changed

+149
-19
lines changed

7 files changed

+149
-19
lines changed

crates/rhai-fmt/src/comments.rs

+107-11
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@
1717
//! ```
1818
1919
#![allow(dead_code)]
20-
use rhai_rowan::syntax::{SyntaxElement, SyntaxKind::*, SyntaxNode};
20+
use rhai_rowan::syntax::{
21+
SyntaxElement,
22+
SyntaxKind::{self, *},
23+
SyntaxNode,
24+
};
2125
use rowan::Direction;
2226

2327
use crate::{
@@ -125,20 +129,13 @@ impl<W: Write> Formatter<W> {
125129
.siblings_with_tokens(Direction::Next)
126130
.skip(1)
127131
.skip_while(|ws| {
128-
// Skip punctuation
129-
if ws.as_token().is_some()
130-
&& !matches!(ws.kind(), WHITESPACE | COMMENT_BLOCK | COMMENT_LINE)
131-
{
132-
return true;
133-
}
134-
135132
if let Some(token) = ws.as_token() {
136-
if break_count(token) != 0 {
137-
return false;
133+
if break_count(token) == 0 {
134+
return true;
138135
}
139136
}
140137

141-
true
138+
false
142139
})
143140
.take_while(|e| matches!(e.kind(), WHITESPACE | COMMENT_BLOCK | COMMENT_LINE))
144141
.filter_map(SyntaxElement::into_token)
@@ -186,6 +183,100 @@ impl<W: Write> Formatter<W> {
186183

187184
Ok(info)
188185
}
186+
187+
/// Add comments that are before the expression.
188+
pub(crate) fn comments_in_expr_before(&mut self, expr: &SyntaxNode) -> io::Result<()> {
189+
let comments_before = expr
190+
.children_with_tokens()
191+
.take_while(|t| t.as_node().is_none())
192+
.filter_map(SyntaxElement::into_token)
193+
.filter(|t| matches!(t.kind(), COMMENT_LINE | COMMENT_BLOCK));
194+
195+
let mut first = true;
196+
let mut hardbreak_last = false;
197+
for comment in comments_before {
198+
if !first {
199+
self.space();
200+
}
201+
first = false;
202+
match comment.kind() {
203+
COMMENT_LINE => {
204+
self.word(comment.static_text().trim_end())?;
205+
self.hardbreak();
206+
hardbreak_last = true;
207+
}
208+
COMMENT_BLOCK => {
209+
self.word(comment.static_text().trim_end())?;
210+
}
211+
_ => unreachable!(),
212+
}
213+
}
214+
215+
if !first && !hardbreak_last {
216+
self.space();
217+
}
218+
219+
Ok(())
220+
}
221+
222+
/// Add comments that are before the expression.
223+
pub(crate) fn comments_in_expr_after(&mut self, expr: &SyntaxNode) -> io::Result<()> {
224+
let comments_before = expr
225+
.children_with_tokens()
226+
.skip_while(|t| t.as_token().is_some())
227+
.filter_map(SyntaxElement::into_token)
228+
.filter(|t| matches!(t.kind(), COMMENT_LINE | COMMENT_BLOCK));
229+
230+
for comment in comments_before {
231+
self.space();
232+
match comment.kind() {
233+
COMMENT_LINE => {
234+
self.word(comment.static_text().trim_end())?;
235+
self.hardbreak();
236+
}
237+
COMMENT_BLOCK => {
238+
self.word(comment.static_text().trim_end())?;
239+
}
240+
_ => unreachable!(),
241+
}
242+
}
243+
244+
Ok(())
245+
}
246+
247+
pub(crate) fn comments_after_child(
248+
&mut self,
249+
node: &SyntaxNode,
250+
kind: SyntaxKind,
251+
) -> io::Result<()> {
252+
let comments_after = node
253+
.children_with_tokens()
254+
.skip_while(|t| t.kind() != kind)
255+
.skip_while(|t| t.kind() == kind)
256+
.filter_map(SyntaxElement::into_token)
257+
.filter(|t| matches!(t.kind(), COMMENT_BLOCK | COMMENT_LINE));
258+
259+
let mut first = true;
260+
for comment in comments_after {
261+
if first {
262+
self.space();
263+
}
264+
first = false;
265+
match comment.kind() {
266+
COMMENT_LINE => {
267+
self.word(comment.static_text().trim_end())?;
268+
self.hardbreak();
269+
}
270+
COMMENT_BLOCK => {
271+
self.word(comment.static_text().trim_end())?;
272+
self.space();
273+
}
274+
_ => unreachable!(),
275+
}
276+
}
277+
278+
Ok(())
279+
}
189280
}
190281

191282
#[derive(Default)]
@@ -205,3 +296,8 @@ impl CommentInfo {
205296
}
206297
}
207298
}
299+
300+
pub(crate) fn comments_in_expr(expr: &SyntaxNode) -> bool {
301+
expr.children_with_tokens()
302+
.any(|c| matches!(c.kind(), COMMENT_LINE | COMMENT_BLOCK))
303+
}

crates/rhai-fmt/src/expr.rs

+35-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rhai_rowan::{
1111

1212
use crate::{
1313
algorithm::Formatter,
14-
comments::CommentInfo,
14+
comments::{comments_in_expr, CommentInfo},
1515
source::needs_stmt_separator,
1616
util::{break_count, ScopedStatic},
1717
};
@@ -23,6 +23,16 @@ impl<S: Write> Formatter<S> {
2323
return Ok(());
2424
}
2525

26+
let syntax = expr.syntax();
27+
28+
let has_comments = comments_in_expr(&syntax);
29+
30+
if has_comments {
31+
self.ibox(0);
32+
}
33+
34+
self.comments_in_expr_before(&syntax)?;
35+
2636
match expr {
2737
Expr::Ident(expr) => {
2838
self.fmt_expr_ident(expr)?;
@@ -107,6 +117,12 @@ impl<S: Write> Formatter<S> {
107117
}
108118
}
109119

120+
self.comments_in_expr_after(&syntax)?;
121+
122+
if has_comments {
123+
self.end();
124+
}
125+
110126
Ok(())
111127
}
112128

@@ -766,13 +782,18 @@ impl<S: Write> Formatter<S> {
766782
false
767783
};
768784

785+
let syntax = expr.syntax();
786+
769787
if indent_expr {
770788
self.ibox(1);
771789
self.word("const")?;
772790
self.ibox(-1);
773791
self.nbsp()?;
792+
self.comments_after_child(&syntax, KW_CONST)?;
793+
774794
if let Some(ident) = expr.ident_token() {
775795
self.word(ident.static_text())?;
796+
self.comments_after_child(&syntax, IDENT)?;
776797
}
777798
self.end();
778799
if let Some(rhs) = expr.expr() {
@@ -784,8 +805,11 @@ impl<S: Write> Formatter<S> {
784805
self.ibox(0);
785806
self.word("const")?;
786807
self.nbsp()?;
808+
self.comments_after_child(&syntax, KW_CONST)?;
809+
787810
if let Some(ident) = expr.ident_token() {
788811
self.word(ident.static_text())?;
812+
self.comments_after_child(&syntax, IDENT)?;
789813
}
790814
self.end();
791815
if let Some(rhs) = expr.expr() {
@@ -803,13 +827,19 @@ impl<S: Write> Formatter<S> {
803827
false
804828
};
805829

830+
let syntax = expr.syntax();
831+
806832
if indent_expr {
807833
self.ibox(1);
808834
self.word("let")?;
809835
self.ibox(-1);
810836
self.nbsp()?;
837+
838+
self.comments_after_child(&syntax, KW_LET)?;
839+
811840
if let Some(ident) = expr.ident_token() {
812841
self.word(ident.static_text())?;
842+
self.comments_after_child(&syntax, IDENT)?;
813843
}
814844
self.end();
815845
if let Some(rhs) = expr.expr() {
@@ -821,8 +851,12 @@ impl<S: Write> Formatter<S> {
821851
self.ibox(0);
822852
self.word("let")?;
823853
self.nbsp()?;
854+
855+
self.comments_after_child(&syntax, KW_LET)?;
856+
824857
if let Some(ident) = expr.ident_token() {
825858
self.word(ident.static_text())?;
859+
self.comments_after_child(&syntax, IDENT)?;
826860
}
827861
self.end();
828862
if let Some(rhs) = expr.expr() {

crates/rhai-fmt/src/source.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ impl<S: Write> Formatter<S> {
1414

1515
if let Some(t) = rhai.shebang_token() {
1616
self.word(t.static_text())?;
17-
self.hardbreak();
17+
// No hardbreak required here, as we should
18+
// already have whitespace in the file.
1819
}
1920

2021
self.standalone_leading_comments_in(&rhai.syntax())?;

crates/rhai-fmt/src/util.rs

-1
Original file line numberDiff line numberDiff line change
@@ -143,4 +143,3 @@ pub(crate) fn break_count(t: &SyntaxToken) -> u64 {
143143
}
144144
t.text().chars().filter(|c| *c == '\n').count() as u64
145145
}
146-

crates/rhai-fmt/tests/snapshots/fmt__format@comments.snap

+3-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ expression: formatted
44
---
55
// I am a single line comment!
66

7-
let x = 5;
7+
let /* I am a spy in a variable declaration! */ x = 5;
88

99
/* I am a simple
1010
multi-line
@@ -13,5 +13,6 @@ let x = 5;
1313
/* look /* at /* that, /* multi-line */ comments */ can be */ nested */
1414

1515
/* surrounded by */
16-
let this_is_not_a_comment = true
16+
let this_is_not_a_comment = true // comments
17+
1718

crates/rhai-fmt/tests/snapshots/fmt__format@oop.snap

+2-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ if obj1.get_data() > 0 {// property access
3232
obj1.update(123); // call method
3333
} else {
3434
print("we have a problem here");
35-
}
35+
} // Define another object based on the first object
36+
3637
let obj2 = #{
3738
_data: 0,
3839
// data field - new value

crates/rhai-fmt/tests/snapshots/fmt__format@simple.snap

-2
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,10 @@ expression: formatted
44
---
55
#!/bin/echo hello
66

7-
87
// It's a
98
let a = "0";
109

1110
/// It's b
12-
1311
let b = a;
1412

1513
const c = b; /* */

0 commit comments

Comments
 (0)