diff --git a/CHANGELOG.md b/CHANGELOG.md index 54a830e..df75384 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,15 @@ Types of changes - Security in case of vulnerabilities. --> +### Added + +- Binary operators now support inline comments: + ```diff + - ++ + - # subsections go last + + ++ # subsections go last + ``` + ### Changed - Linux binaries now use [mimalloc](https://github.com/microsoft/mimalloc) diff --git a/src/alejandra_engine/src/builder.rs b/src/alejandra_engine/src/builder.rs index b6a41ae..915f590 100644 --- a/src/alejandra_engine/src/builder.rs +++ b/src/alejandra_engine/src/builder.rs @@ -176,9 +176,7 @@ fn format( // a b rnix::SyntaxKind::NODE_APPLY => crate::rules::apply::rule, // assert a; b - rnix::SyntaxKind::NODE_ASSERT => { - crate::rules::assert_or_with::rule - } + rnix::SyntaxKind::NODE_ASSERT => crate::rules::scoped::rule, // { } rnix::SyntaxKind::NODE_ATTR_SET => crate::rules::attr_set::rule, // a $op b @@ -239,9 +237,7 @@ fn format( // !a rnix::SyntaxKind::NODE_UNARY_OP => crate::rules::default, // with a; b - rnix::SyntaxKind::NODE_WITH => { - crate::rules::assert_or_with::rule - } + rnix::SyntaxKind::NODE_WITH => crate::rules::scoped::rule, kind => { panic!( "Missing rule for {:?} at: {}", diff --git a/src/alejandra_engine/src/parsers/assert_or_with.rs b/src/alejandra_engine/src/parsers/assert_or_with.rs deleted file mode 100644 index 1b99ccc..0000000 --- a/src/alejandra_engine/src/parsers/assert_or_with.rs +++ /dev/null @@ -1,74 +0,0 @@ -use std::collections::LinkedList; - -#[derive(Debug)] -pub(crate) struct AssertOrWith { - pub assert_or_with: rnix::SyntaxElement, - pub comments_after_assert_or_with: LinkedList, - pub has_newlines_after_assert_or_with: bool, - pub first_expression: rnix::SyntaxElement, - pub semicolon: rnix::SyntaxElement, - pub comments_after_semicolon: LinkedList, - pub has_newlines_after_semicolon: bool, - pub second_expression: rnix::SyntaxElement, -} - -impl AssertOrWith { - pub(crate) fn new( - build_ctx: &crate::builder::BuildCtx, - node: &rnix::SyntaxNode, - ) -> AssertOrWith { - let mut children = crate::children::Children::new(build_ctx, node); - - // assert_or_with - let assert_or_with = children.get_next().unwrap(); - - // comments_after_assert_or_with - // has_newlines_after_assert_or_with - let mut comments_after_assert_or_with = LinkedList::new(); - let mut has_newlines_after_assert_or_with = false; - children.drain_trivia(|element| match element { - crate::children::Trivia::Comment(text) => { - comments_after_assert_or_with.push_back(text); - } - crate::children::Trivia::Whitespace(text) => { - has_newlines_after_assert_or_with = - has_newlines_after_assert_or_with - || crate::utils::count_newlines(&text) > 0; - } - }); - - // first_expression - let first_expression = children.get_next().unwrap(); - - // semicolon - let semicolon = children.get_next().unwrap(); - - // comments_after_semicolon - // has_newlines_after_semicolon - let mut comments_after_semicolon = LinkedList::new(); - let mut has_newlines_after_semicolon = false; - children.drain_trivia(|element| match element { - crate::children::Trivia::Comment(text) => { - comments_after_semicolon.push_back(text); - } - crate::children::Trivia::Whitespace(text) => { - has_newlines_after_semicolon = has_newlines_after_semicolon - || crate::utils::count_newlines(&text) > 0; - } - }); - - // second_expression - let second_expression = children.get_next().unwrap(); - - AssertOrWith { - assert_or_with, - comments_after_assert_or_with, - has_newlines_after_assert_or_with, - first_expression, - semicolon, - comments_after_semicolon, - has_newlines_after_semicolon, - second_expression, - } - } -} diff --git a/src/alejandra_engine/src/parsers/mod.rs b/src/alejandra_engine/src/parsers/mod.rs index 8f473f3..4b25b4a 100644 --- a/src/alejandra_engine/src/parsers/mod.rs +++ b/src/alejandra_engine/src/parsers/mod.rs @@ -1,3 +1,2 @@ -pub(crate) mod assert_or_with; pub(crate) mod if_else; pub(crate) mod pattern; diff --git a/src/alejandra_engine/src/rules/assert_or_with.rs b/src/alejandra_engine/src/rules/assert_or_with.rs deleted file mode 100644 index 15c800a..0000000 --- a/src/alejandra_engine/src/rules/assert_or_with.rs +++ /dev/null @@ -1,95 +0,0 @@ -pub(crate) fn rule( - build_ctx: &crate::builder::BuildCtx, - node: &rnix::SyntaxNode, -) -> std::collections::LinkedList { - let mut steps = std::collections::LinkedList::new(); - - let parsed = - crate::parsers::assert_or_with::AssertOrWith::new(build_ctx, node); - - let vertical = build_ctx.vertical - || !parsed.comments_after_assert_or_with.is_empty() - || parsed.has_newlines_after_assert_or_with - || !parsed.comments_after_semicolon.is_empty() - || parsed.has_newlines_after_semicolon; - - // assert_or_with - steps.push_back(crate::builder::Step::Format(parsed.assert_or_with)); - - // comments_after_assert_or_with - if parsed.comments_after_assert_or_with.is_empty() { - steps.push_back(crate::builder::Step::Whitespace); - } else { - steps.push_back(crate::builder::Step::NewLine); - steps.push_back(crate::builder::Step::Pad); - for text in parsed.comments_after_assert_or_with { - steps.push_back(crate::builder::Step::Comment(text)); - steps.push_back(crate::builder::Step::NewLine); - steps.push_back(crate::builder::Step::Pad); - } - } - - // first_expression - if vertical { - steps.push_back(crate::builder::Step::FormatWider( - parsed.first_expression, - )); - } else { - steps.push_back(crate::builder::Step::Format(parsed.first_expression)); - } - - // semicolon - steps.push_back(crate::builder::Step::Format(parsed.semicolon)); - - // comments_after_semicolon - let has_comments_after_semicolon = - !parsed.comments_after_semicolon.is_empty(); - for text in parsed.comments_after_semicolon { - steps.push_back(crate::builder::Step::NewLine); - steps.push_back(crate::builder::Step::Pad); - steps.push_back(crate::builder::Step::Comment(text)); - } - - // second_expression - if vertical { - if matches!( - parsed.second_expression.kind(), - rnix::SyntaxKind::NODE_ASSERT | rnix::SyntaxKind::NODE_WITH - ) { - steps.push_back(crate::builder::Step::NewLine); - steps.push_back(crate::builder::Step::Pad); - steps.push_back(crate::builder::Step::FormatWider( - parsed.second_expression, - )); - } else if has_comments_after_semicolon - || !matches!( - parsed.second_expression.kind(), - rnix::SyntaxKind::NODE_ATTR_SET - | rnix::SyntaxKind::NODE_IDENT - | rnix::SyntaxKind::NODE_PAREN - | rnix::SyntaxKind::NODE_LET_IN - | rnix::SyntaxKind::NODE_LIST - | rnix::SyntaxKind::NODE_LITERAL - | rnix::SyntaxKind::NODE_STRING - ) - { - steps.push_back(crate::builder::Step::Indent); - steps.push_back(crate::builder::Step::NewLine); - steps.push_back(crate::builder::Step::Pad); - steps.push_back(crate::builder::Step::FormatWider( - parsed.second_expression, - )); - steps.push_back(crate::builder::Step::Dedent); - } else { - steps.push_back(crate::builder::Step::Whitespace); - steps.push_back(crate::builder::Step::FormatWider( - parsed.second_expression, - )); - } - } else { - steps.push_back(crate::builder::Step::Whitespace); - steps.push_back(crate::builder::Step::Format(parsed.second_expression)); - } - - steps -} diff --git a/src/alejandra_engine/src/rules/mod.rs b/src/alejandra_engine/src/rules/mod.rs index 48c47a3..f8ed50a 100644 --- a/src/alejandra_engine/src/rules/mod.rs +++ b/src/alejandra_engine/src/rules/mod.rs @@ -1,5 +1,4 @@ pub(crate) mod apply; -pub(crate) mod assert_or_with; pub(crate) mod attr_set; pub(crate) mod bin_op; pub(crate) mod dynamic; @@ -14,6 +13,7 @@ pub(crate) mod pat_bind; pub(crate) mod pat_entry; pub(crate) mod pattern; pub(crate) mod root; +pub(crate) mod scoped; pub(crate) mod select; pub(crate) mod string; pub(crate) mod string_interpol; diff --git a/src/alejandra_engine/src/rules/scoped.rs b/src/alejandra_engine/src/rules/scoped.rs new file mode 100644 index 0000000..bb3fef1 --- /dev/null +++ b/src/alejandra_engine/src/rules/scoped.rs @@ -0,0 +1,115 @@ +pub(crate) fn rule( + build_ctx: &crate::builder::BuildCtx, + node: &rnix::SyntaxNode, +) -> std::collections::LinkedList { + let mut steps = std::collections::LinkedList::new(); + + let mut children = crate::children2::new(build_ctx, node); + + let first = children.next().unwrap(); + let second = children.next().unwrap(); + let third = children.next().unwrap(); + let fourth = children.next().unwrap(); + + let vertical = build_ctx.vertical + || first.has_inline_comment + || first.has_trivialities + || second.has_inline_comment + || second.has_trivialities + || third.has_inline_comment + || third.has_trivialities + || fourth.has_inline_comment + || fourth.has_trivialities; + + // first + steps.push_back(crate::builder::Step::Format(first.element)); + + if let Some(text) = first.inline_comment { + steps.push_back(crate::builder::Step::Whitespace); + steps.push_back(crate::builder::Step::Comment(text)); + steps.push_back(crate::builder::Step::NewLine); + steps.push_back(crate::builder::Step::Pad); + } else if first.has_comments { + steps.push_back(crate::builder::Step::NewLine); + steps.push_back(crate::builder::Step::Pad); + } else { + steps.push_back(crate::builder::Step::Whitespace); + } + + for trivia in first.trivialities { + match trivia { + crate::children2::Trivia::Comment(text) => { + steps.push_back(crate::builder::Step::Comment(text)); + steps.push_back(crate::builder::Step::NewLine); + steps.push_back(crate::builder::Step::Pad); + } + crate::children2::Trivia::Newlines(_) => {} + } + } + + // second + if vertical { + steps.push_back(crate::builder::Step::FormatWider(second.element)); + } else { + steps.push_back(crate::builder::Step::Format(second.element)); + } + + // third + steps.push_back(crate::builder::Step::Format(third.element)); + + if let Some(text) = third.inline_comment { + steps.push_back(crate::builder::Step::Whitespace); + steps.push_back(crate::builder::Step::Comment(text)); + steps.push_back(crate::builder::Step::NewLine); + steps.push_back(crate::builder::Step::Pad); + } + + for trivia in third.trivialities { + match trivia { + crate::children2::Trivia::Comment(text) => { + steps.push_back(crate::builder::Step::NewLine); + steps.push_back(crate::builder::Step::Pad); + steps.push_back(crate::builder::Step::Comment(text)); + } + crate::children2::Trivia::Newlines(_) => {} + } + } + + // fourth + if vertical { + if matches!( + fourth.element.kind(), + rnix::SyntaxKind::NODE_ASSERT | rnix::SyntaxKind::NODE_WITH + ) { + steps.push_back(crate::builder::Step::NewLine); + steps.push_back(crate::builder::Step::Pad); + steps.push_back(crate::builder::Step::FormatWider(fourth.element)); + } else if third.has_inline_comment + || third.has_comments + || !matches!( + fourth.element.kind(), + rnix::SyntaxKind::NODE_ATTR_SET + | rnix::SyntaxKind::NODE_IDENT + | rnix::SyntaxKind::NODE_PAREN + | rnix::SyntaxKind::NODE_LET_IN + | rnix::SyntaxKind::NODE_LIST + | rnix::SyntaxKind::NODE_LITERAL + | rnix::SyntaxKind::NODE_STRING + ) + { + steps.push_back(crate::builder::Step::Indent); + steps.push_back(crate::builder::Step::NewLine); + steps.push_back(crate::builder::Step::Pad); + steps.push_back(crate::builder::Step::FormatWider(fourth.element)); + steps.push_back(crate::builder::Step::Dedent); + } else { + steps.push_back(crate::builder::Step::Whitespace); + steps.push_back(crate::builder::Step::FormatWider(fourth.element)); + } + } else { + steps.push_back(crate::builder::Step::Whitespace); + steps.push_back(crate::builder::Step::Format(fourth.element)); + } + + steps +} diff --git a/src/alejandra_engine/tests/cases/assert/in b/src/alejandra_engine/tests/cases/assert/in index 1e8d1f3..6be19f6 100644 --- a/src/alejandra_engine/tests/cases/assert/in +++ b/src/alejandra_engine/tests/cases/assert/in @@ -1,8 +1,12 @@ [ - (assert b; c) - (assert b; /*b*/ c) - (assert /*a*/ b; c) - (assert /*a*/ b; /*b*/ c) + (assert b ; e) + (assert b ; /*d*/ e) + (assert b /*c*/; e) + (assert b /*c*/; /*d*/ e) + (assert /*a*/ b ; e) + (assert /*a*/ b ; /*d*/ e) + (assert /*a*/ b /*c*/; e) + (assert /*a*/ b /*c*/; /*d*/ e) ( assert b; cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc ) ( assert b; cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc ) diff --git a/src/alejandra_engine/tests/cases/assert/out b/src/alejandra_engine/tests/cases/assert/out index ea3a02a..a69be94 100644 --- a/src/alejandra_engine/tests/cases/assert/out +++ b/src/alejandra_engine/tests/cases/assert/out @@ -1,24 +1,44 @@ [ - (assert b; c) + (assert b; e) (assert b; /* - b + d */ - c) + e) + (assert b; e) + (assert b; + /* + d + */ + e) (assert /* a */ - b; c) + b; e) (assert /* a */ b; /* - b + d */ - c) + e) + (assert + /* + a + */ + b; e) + (assert + /* + a + */ + b; + /* + d + */ + e) (assert b; cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc) (assert b; cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc) ]