Support comments on attributes (#5850)

Signed-off-by: Nick Cameron <nrc@ncameron.org>
This commit is contained in:
Nick Cameron
2025-03-20 16:23:20 +13:00
committed by GitHub
parent 79be72c5f0
commit 461a2c3ab2
319 changed files with 37650 additions and 4752 deletions

View File

@ -23,19 +23,31 @@ impl Program {
.map(|sh| format!("{}\n\n", sh.inner.content))
.unwrap_or_default();
for attr in &self.inner_attrs {
result.push_str(&attr.recast(options, indentation_level));
}
for start in &self.non_code_meta.start_nodes {
result.push_str(&start.recast(options, indentation_level));
}
let result = result; // Remove mutation.
for attr in &self.inner_attrs {
result.push_str(&attr.recast(options, indentation_level));
}
if !self.inner_attrs.is_empty() {
result.push('\n');
}
let result = result; // Remove mutation.
let result = self
.body
.iter()
.map(|body_item| {
let mut result = String::new();
for comment in body_item.get_comments() {
if !comment.is_empty() {
result.push_str(&indentation);
result.push_str(comment);
}
if !result.ends_with("\n\n") && result != "\n" {
result.push('\n');
}
}
for attr in body_item.get_attrs() {
result.push_str(&attr.recast(options, indentation_level));
}
@ -173,7 +185,18 @@ impl Node<NonCodeNode> {
impl Node<Annotation> {
fn recast(&self, options: &FormatOptions, indentation_level: usize) -> String {
let mut result = "@".to_owned();
let indentation = options.get_indentation(indentation_level);
let mut result = String::new();
for comment in &self.pre_comments {
if !comment.is_empty() {
result.push_str(&indentation);
result.push_str(comment);
}
if !comment.ends_with("*/") && !result.ends_with("\n\n") && result != "\n" {
result.push('\n');
}
}
result.push('@');
if let Some(name) = &self.name {
result.push_str(&name.name);
}
@ -956,6 +979,7 @@ mod tests {
fn test_recast_annotations_in_function_body() {
let input = r#"fn myFunc() {
@meta(yes = true)
x = 2
}
"#;
@ -975,6 +999,25 @@ mod tests {
assert_eq!(output, input);
}
#[test]
fn recast_annotations_with_comments() {
let input = r#"// Start comment
// Comment on attr
@settings(defaultLengthUnit = in)
// Comment on item
foo = 42
// Comment on another item
@(impl = kcl)
bar = 0
"#;
let program = crate::parsing::top_level_parse(input).unwrap();
let output = program.recast(&Default::default(), 0);
assert_eq!(output, input);
}
#[test]
fn test_recast_if_else_if_same() {
let input = r#"b = if false {
@ -1241,7 +1284,6 @@ outsideRevolve = startSketchOn('XZ')
r#"// Ball Bearing
// A ball bearing is a type of rolling-element bearing that uses balls to maintain the separation between the bearing races. The primary purpose of a ball bearing is to reduce rotational friction and support radial and axial loads.
// Define constants like ball diameter, inside diameter, overhange length, and thickness
sphereDia = 0.5
insideDia = 1
@ -1643,6 +1685,7 @@ tabs_l = startSketchOn({
assert_eq!(
recasted,
r#"@settings(units = mm)
// define nts
radius = 6.0
width = 144.0
@ -2633,4 +2676,35 @@ sketch002 = startSketchOn({
);
}
}
#[test]
fn code_with_comment_and_extra_lines() {
let code = r#"yo = 'c'
/* this is
a
comment */
yo = 'bing'
"#;
let ast = crate::parsing::top_level_parse(code).unwrap();
let recasted = ast.recast(&FormatOptions::new(), 0);
assert_eq!(recasted, code);
}
#[test]
fn comments_in_a_fn_block() {
let code = r#"fn myFn() {
// this is a comment
yo = { a = { b = { c = '123' } } }
/* block
comment */
key = 'c'
// this is also a comment
}
"#;
let ast = crate::parsing::top_level_parse(code).unwrap();
let recasted = ast.recast(&FormatOptions::new(), 0);
assert_eq!(recasted, code);
}
}