Skip to content

Commit 94b34f5

Browse files
committed
fix: improve formatting array with only comments
1 parent 0d1b278 commit 94b34f5

File tree

5 files changed

+145
-60
lines changed

5 files changed

+145
-60
lines changed

Cargo.toml

+5
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ panic = "abort"
2424
wasm = ["serde_json", "dprint-core/wasm"]
2525
tracing = ["dprint-core/tracing"]
2626

27+
[[test]]
28+
name = "specs"
29+
path = "tests/spec_test.rs"
30+
harness = false
31+
2732
[dependencies]
2833
anyhow = "1.0.65"
2934
dprint-core = { version = "0.66.2", features = ["formatting"] }

src/generation/generate.rs

+18-12
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ fn gen_node<'a>(node: SyntaxElement, context: &mut Context<'a>) -> PrintItems {
3535

3636
fn gen_node_with_inner<'a>(node: SyntaxElement, context: &mut Context<'a>, inner_parse: impl FnOnce(PrintItems, &mut Context<'a>) -> PrintItems) -> PrintItems {
3737
let mut items = PrintItems::new();
38-
// println!("{:?}", node);
38+
// eprintln!("{:?}", node);
3939

4040
if node.kind() != SyntaxKind::COMMENT {
4141
for comment in node.get_comments_on_previous_lines() {
@@ -146,17 +146,24 @@ fn allow_blank_line(previous_kind: Option<SyntaxKind>, current_kind: SyntaxKind)
146146

147147
fn gen_array<'a>(node: SyntaxNode, context: &mut Context<'a>) -> PrintItemsResult {
148148
let values = node.children();
149-
let open_token = get_token_with_kind(node.clone(), SyntaxKind::BRACKET_START)?;
150-
let close_token = get_token_with_kind(node.clone(), SyntaxKind::BRACKET_END)?;
149+
let open_token = get_token_with_kind(&node, SyntaxKind::BRACKET_START)?;
150+
let close_token = get_token_with_kind(&node, SyntaxKind::BRACKET_END)?;
151151
let is_in_inline_table = node.ancestors().any(|a| a.kind() == SyntaxKind::INLINE_TABLE);
152-
let force_use_new_lines = !is_in_inline_table && has_following_newline(open_token.clone());
152+
let force_use_new_lines = !is_in_inline_table && has_following_newline(open_token.clone()) && node.children_with_tokens().skip(3).next().is_some();
153153
ensure_all_kind(values.clone(), SyntaxKind::VALUE)?;
154154

155155
Ok(gen_surrounded_by_tokens(
156156
|context| {
157+
let nodes = values.into_iter().map(|v| v.into()).collect::<Vec<_>>();
158+
if nodes.is_empty() {
159+
if force_use_new_lines {
160+
return Signal::NewLine.into();
161+
}
162+
return PrintItems::new();
163+
}
157164
gen_comma_separated_values(
158165
ParseCommaSeparatedValuesOptions {
159-
nodes: values.into_iter().map(|v| v.into()).collect::<Vec<_>>(),
166+
nodes,
160167
prefer_hanging: false,
161168
force_use_new_lines,
162169
allow_blank_lines: true,
@@ -205,8 +212,8 @@ fn gen_inline_table<'a>(node: SyntaxNode, context: &mut Context<'a>) -> PrintIte
205212
}
206213

207214
fn gen_entry<'a>(node: SyntaxNode, context: &mut Context<'a>) -> PrintItemsResult {
208-
let key = get_child_with_kind(node.clone(), SyntaxKind::KEY)?;
209-
let value = get_child_with_kind(node.clone(), SyntaxKind::VALUE)?;
215+
let key = get_child_with_kind(&node, SyntaxKind::KEY)?;
216+
let value = get_child_with_kind(&node, SyntaxKind::VALUE)?;
210217
let mut items = PrintItems::new();
211218

212219
items.extend(gen_node(key.into(), context));
@@ -236,7 +243,7 @@ fn gen_children_inline<'a>(node: SyntaxNode, context: &mut Context<'a>) -> Print
236243

237244
fn gen_table_header<'a>(node: SyntaxNode, context: &mut Context<'a>) -> PrintItemsResult {
238245
// Spec: Naming rules for tables are the same as for keys
239-
let key = get_child_with_kind(node.clone(), SyntaxKind::KEY)?;
246+
let key = get_child_with_kind(&node, SyntaxKind::KEY)?;
240247
let mut items = PrintItems::new();
241248
items.push_sc(sc!("["));
242249
items.extend(gen_node(key.into(), context));
@@ -246,7 +253,7 @@ fn gen_table_header<'a>(node: SyntaxNode, context: &mut Context<'a>) -> PrintIte
246253

247254
fn gen_table_array_header<'a>(node: SyntaxNode, context: &mut Context<'a>) -> PrintItemsResult {
248255
// Spec: Naming rules for tables are the same as for keys
249-
let key = get_child_with_kind(node.clone(), SyntaxKind::KEY)?;
256+
let key = get_child_with_kind(&node, SyntaxKind::KEY)?;
250257
let mut items = PrintItems::new();
251258
items.push_sc(sc!("[["));
252259
items.extend(gen_node(key.into(), context));
@@ -264,7 +271,6 @@ fn gen_surrounded_by_tokens<'a, 'b>(
264271
opts: ParseSurroundedByTokensParams,
265272
context: &mut Context<'a>,
266273
) -> PrintItems {
267-
// parse
268274
let mut items = PrintItems::new();
269275
items.extend(gen_node(opts.open_token.clone().into(), context));
270276

@@ -533,14 +539,14 @@ fn get_children_with_non_trivia_tokens(node: SyntaxNode) -> impl Iterator<Item =
533539
})
534540
}
535541

536-
fn get_child_with_kind(node: SyntaxNode, kind: SyntaxKind) -> Result<SyntaxNode, ()> {
542+
fn get_child_with_kind(node: &SyntaxNode, kind: SyntaxKind) -> Result<SyntaxNode, ()> {
537543
match node.children().find(|c| c.kind() == kind) {
538544
Some(node) => Ok(node),
539545
None => Err(()),
540546
}
541547
}
542548

543-
fn get_token_with_kind(node: SyntaxNode, kind: SyntaxKind) -> Result<SyntaxToken, ()> {
549+
fn get_token_with_kind(node: &SyntaxNode, kind: SyntaxKind) -> Result<SyntaxToken, ()> {
544550
match node.children_with_tokens().find(|c| c.kind() == kind) {
545551
Some(NodeOrToken::Token(token)) => Ok(token),
546552
_ => Err(()),

tests/spec_test.rs

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
use std::path::PathBuf;
2+
use std::sync::Arc;
3+
4+
use dprint_core::configuration::*;
5+
use dprint_development::*;
6+
use dprint_plugin_toml::configuration::resolve_config;
7+
use dprint_plugin_toml::*;
8+
9+
fn main() {
10+
let global_config = GlobalConfiguration::default();
11+
12+
run_specs(
13+
&PathBuf::from("./tests/specs"),
14+
&ParseSpecOptions {
15+
default_file_name: "file.toml",
16+
},
17+
&RunSpecsOptions {
18+
fix_failures: false,
19+
format_twice: true,
20+
},
21+
{
22+
let global_config = global_config.clone();
23+
Arc::new(move |file_path, file_text, spec_config| {
24+
let spec_config: ConfigKeyMap = serde_json::from_value(spec_config.clone().into()).unwrap();
25+
let config_result = resolve_config(spec_config, &global_config);
26+
ensure_no_diagnostics(&config_result.diagnostics);
27+
28+
format_text(file_path, &file_text, &config_result.config)
29+
})
30+
},
31+
Arc::new(move |_file_path, _file_text, _spec_config| {
32+
#[cfg(feature = "tracing")]
33+
{
34+
let spec_config: ConfigKeyMap = serde_json::from_value(_spec_config.clone().into()).unwrap();
35+
let config_result = resolve_config(spec_config, &global_config);
36+
ensure_no_diagnostics(&config_result.diagnostics);
37+
return serde_json::to_string(&trace_file(_file_path, _file_text, &config_result.config)).unwrap();
38+
}
39+
40+
#[cfg(not(feature = "tracing"))]
41+
panic!("\n====\nPlease run with `cargo test --features tracing` to get trace output\n====\n")
42+
}),
43+
)
44+
}
+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
== should not add blank line at start of array with only comments ==
2+
disallowed-types = [
3+
# some comment
4+
# { path = "std::sync::Arc", reason = "use crate::sync::MaybeArc instead" },
5+
6+
# next comment
7+
]
8+
9+
[expect]
10+
disallowed-types = [
11+
# some comment
12+
# { path = "std::sync::Arc", reason = "use crate::sync::MaybeArc instead" },
13+
14+
# next comment
15+
]
16+
17+
== should format with nodes ==
18+
disallowed-types = [
19+
# some comment
20+
# { path = "std::sync::Arc", reason = "use crate::sync::MaybeArc instead" },
21+
22+
# next comment
23+
"test"
24+
]
25+
26+
[expect]
27+
disallowed-types = [
28+
# some comment
29+
# { path = "std::sync::Arc", reason = "use crate::sync::MaybeArc instead" },
30+
31+
# next comment
32+
"test",
33+
]
34+
35+
== comment first line ==
36+
disallowed-types = [ # comment
37+
"test",
38+
]
39+
40+
[expect]
41+
disallowed-types = [ # comment
42+
"test",
43+
]
44+
45+
== comment first line no elements ==
46+
disallowed-types = [ # comment
47+
]
48+
49+
[expect]
50+
disallowed-types = [ # comment
51+
]
52+
53+
== empty ==
54+
value = [
55+
]
56+
57+
[expect]
58+
value = []
59+
60+
== one element ==
61+
value = [
62+
"value"
63+
]
64+
65+
[expect]
66+
value = [
67+
"value",
68+
]
69+
70+
== one comment ==
71+
value = [
72+
# comment
73+
]
74+
75+
[expect]
76+
value = [
77+
# comment
78+
]

tests/test.rs

-48
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,8 @@
1-
extern crate dprint_development;
2-
extern crate dprint_plugin_toml;
3-
4-
//#[macro_use] extern crate debug_here;
5-
61
use std::path::PathBuf;
7-
use std::sync::Arc;
8-
// use std::time::Instant;
92

10-
use dprint_core::configuration::*;
11-
use dprint_development::*;
12-
use dprint_plugin_toml::configuration::resolve_config;
133
use dprint_plugin_toml::configuration::ConfigurationBuilder;
144
use dprint_plugin_toml::*;
155

16-
#[test]
17-
fn test_specs() {
18-
//debug_here!();
19-
let global_config = GlobalConfiguration::default();
20-
21-
run_specs(
22-
&PathBuf::from("./tests/specs"),
23-
&ParseSpecOptions {
24-
default_file_name: "file.toml",
25-
},
26-
&RunSpecsOptions {
27-
fix_failures: false,
28-
format_twice: true,
29-
},
30-
{
31-
let global_config = global_config.clone();
32-
Arc::new(move |file_path, file_text, spec_config| {
33-
let spec_config: ConfigKeyMap = serde_json::from_value(spec_config.clone().into()).unwrap();
34-
let config_result = resolve_config(spec_config, &global_config);
35-
ensure_no_diagnostics(&config_result.diagnostics);
36-
37-
format_text(file_path, &file_text, &config_result.config)
38-
})
39-
},
40-
Arc::new(move |_file_path, _file_text, _spec_config| {
41-
#[cfg(feature = "tracing")]
42-
{
43-
let config_result = resolve_config(parse_config_key_map(_spec_config), &global_config);
44-
ensure_no_diagnostics(&config_result.diagnostics);
45-
return serde_json::to_string(&trace_file(_file_name, _file_text, &config_result.config)).unwrap();
46-
}
47-
48-
#[cfg(not(feature = "tracing"))]
49-
panic!("\n====\nPlease run with `cargo test --features tracing` to get trace output\n====\n")
50-
}),
51-
)
52-
}
53-
546
#[test]
557
fn should_handle_windows_newlines() {
568
let config = ConfigurationBuilder::new().build();

0 commit comments

Comments
 (0)