From 62dd8ec60aedd290cada4e01b11eb5900a81e3a2 Mon Sep 17 00:00:00 2001 From: Kevin Amado Date: Mon, 28 Feb 2022 13:44:42 -0500 Subject: [PATCH] feat: support inline comments in if-else --- CHANGELOG.md | 13 +- src/alejandra_engine/src/parsers/if_else.rs | 102 --------- src/alejandra_engine/src/parsers/mod.rs | 1 - src/alejandra_engine/src/rules/if_else.rs | 217 +++++++++++-------- src/alejandra_engine/tests/cases/if_else/in | 16 ++ src/alejandra_engine/tests/cases/if_else/out | 16 ++ 6 files changed, 173 insertions(+), 192 deletions(-) delete mode 100644 src/alejandra_engine/src/parsers/if_else.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index df75384..3cb4b77 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,12 +19,23 @@ Types of changes ### Added -- Binary operators now support inline comments: +- Inline comments support in binary operators: ```diff - ++ - # subsections go last + ++ # subsections go last ``` +- Inline comments support in `with` and `assert` expressions: + ```diff + - assert (libXft != null) -> libpng != null; + - # probably a bug + - assert stdenv.isDarwin -> libXaw != null; + - # fails to link otherwise + + assert (libXft != null) -> libpng != null; # probably a bug + + + + assert stdenv.isDarwin -> libXaw != null; # fails to link otherwise + + + ``` ### Changed diff --git a/src/alejandra_engine/src/parsers/if_else.rs b/src/alejandra_engine/src/parsers/if_else.rs deleted file mode 100644 index 0d3f996..0000000 --- a/src/alejandra_engine/src/parsers/if_else.rs +++ /dev/null @@ -1,102 +0,0 @@ -use std::collections::LinkedList; - -#[derive(Debug)] -pub(crate) struct IfElse { - pub if_: rnix::SyntaxElement, - pub comments_before_if_expr: LinkedList, - pub if_expr: rnix::SyntaxElement, - pub comments_after_if_expr: LinkedList, - pub then_: rnix::SyntaxElement, - pub comments_before_then_expr: LinkedList, - pub then_expr: rnix::SyntaxElement, - pub comments_after_then_expr: LinkedList, - pub else_: rnix::SyntaxElement, - pub comments_before_else_expr: LinkedList, - pub else_expr: rnix::SyntaxElement, -} - -impl IfElse { - pub(crate) fn parse( - build_ctx: &crate::builder::BuildCtx, - node: &rnix::SyntaxNode, - ) -> IfElse { - let mut children = crate::children::Children::new(build_ctx, node); - - // if_ - let if_ = children.get_next().unwrap(); - - // comments_before_if_expr - let mut comments_before_if_expr = LinkedList::new(); - children.drain_trivia(|element| match element { - crate::children::Trivia::Comment(text) => { - comments_before_if_expr.push_back(text); - } - crate::children::Trivia::Whitespace(_) => {} - }); - - // if_expr - let if_expr = children.get_next().unwrap(); - - // comments_after_if_expr - let mut comments_after_if_expr = LinkedList::new(); - children.drain_trivia(|element| match element { - crate::children::Trivia::Comment(text) => { - comments_after_if_expr.push_back(text); - } - crate::children::Trivia::Whitespace(_) => {} - }); - - // then_ - let then_ = children.get_next().unwrap(); - - // comments_before_then_expr - let mut comments_before_then_expr = LinkedList::new(); - children.drain_trivia(|element| match element { - crate::children::Trivia::Comment(text) => { - comments_before_then_expr.push_back(text); - } - crate::children::Trivia::Whitespace(_) => {} - }); - - // then_expr - let then_expr = children.get_next().unwrap(); - - // comments_after_then_expr - let mut comments_after_then_expr = LinkedList::new(); - children.drain_trivia(|element| match element { - crate::children::Trivia::Comment(text) => { - comments_after_then_expr.push_back(text); - } - crate::children::Trivia::Whitespace(_) => {} - }); - - // else_ - let else_ = children.get_next().unwrap(); - - // comments_before_else_expr - let mut comments_before_else_expr = LinkedList::new(); - children.drain_trivia(|element| match element { - crate::children::Trivia::Comment(text) => { - comments_before_else_expr.push_back(text); - } - crate::children::Trivia::Whitespace(_) => {} - }); - - // else_expr - let else_expr = children.get_next().unwrap(); - - IfElse { - if_, - comments_before_if_expr, - if_expr, - comments_after_if_expr, - then_, - comments_before_then_expr, - then_expr, - comments_after_then_expr, - else_, - comments_before_else_expr, - else_expr, - } - } -} diff --git a/src/alejandra_engine/src/parsers/mod.rs b/src/alejandra_engine/src/parsers/mod.rs index 4b25b4a..b13857e 100644 --- a/src/alejandra_engine/src/parsers/mod.rs +++ b/src/alejandra_engine/src/parsers/mod.rs @@ -1,2 +1 @@ -pub(crate) mod if_else; pub(crate) mod pattern; diff --git a/src/alejandra_engine/src/rules/if_else.rs b/src/alejandra_engine/src/rules/if_else.rs index 760753e..50b2996 100644 --- a/src/alejandra_engine/src/rules/if_else.rs +++ b/src/alejandra_engine/src/rules/if_else.rs @@ -4,111 +4,167 @@ pub(crate) fn rule( ) -> std::collections::LinkedList { let mut steps = std::collections::LinkedList::new(); - let parsed = crate::parsers::if_else::IfElse::parse(build_ctx, node); + let mut children = crate::children2::new(build_ctx, node); + + let if_ = children.next().unwrap(); + let if_expr = children.next().unwrap(); + let then_ = children.next().unwrap(); + let then_expr = children.next().unwrap(); + let else_ = children.next().unwrap(); + let else_expr = children.next().unwrap(); // if_ - steps.push_back(crate::builder::Step::Format(parsed.if_)); + steps.push_back(crate::builder::Step::Format(if_.element)); - if parsed.comments_before_if_expr.is_empty() { - // if_expr - if crate::builder::fits_in_single_line( - build_ctx, - parsed.if_expr.clone(), - ) { - steps.push_back(crate::builder::Step::Whitespace); - steps.push_back(crate::builder::Step::FormatWider(parsed.if_expr)); - } else { - 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.if_expr)); - steps.push_back(crate::builder::Step::Dedent); + steps.push_back(crate::builder::Step::Indent); + if let Some(text) = if_.inline_comment { + steps.push_back(crate::builder::Step::Whitespace); + steps.push_back(crate::builder::Step::Comment(text)); + } + + for trivia in if_.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(_) => {} } - steps.push_back(crate::builder::Step::NewLine); - steps.push_back(crate::builder::Step::Pad); + } + steps.push_back(crate::builder::Step::Dedent); + + // if_expr + if !if_.has_inline_comment + && !if_.has_comments + && crate::builder::fits_in_single_line( + build_ctx, + if_expr.element.clone(), + ) + { + steps.push_back(crate::builder::Step::Whitespace); + steps.push_back(crate::builder::Step::FormatWider(if_expr.element)); } else { - // comments_before_if_expr steps.push_back(crate::builder::Step::Indent); steps.push_back(crate::builder::Step::NewLine); steps.push_back(crate::builder::Step::Pad); - for text in parsed.comments_before_if_expr { - steps.push_back(crate::builder::Step::Comment(text)); - steps.push_back(crate::builder::Step::NewLine); - steps.push_back(crate::builder::Step::Pad); - } - // if_expr - steps.push_back(crate::builder::Step::FormatWider(parsed.if_expr)); + steps.push_back(crate::builder::Step::FormatWider(if_expr.element)); steps.push_back(crate::builder::Step::Dedent); - steps.push_back(crate::builder::Step::NewLine); - steps.push_back(crate::builder::Step::Pad); } - // comments_after_if_expr - for text in parsed.comments_after_if_expr { + if let Some(text) = if_expr.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 { + steps.push_back(crate::builder::Step::NewLine); + steps.push_back(crate::builder::Step::Pad); + } + + for trivia in if_expr.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(_) => {} + } } // then_ - steps.push_back(crate::builder::Step::Format(parsed.then_)); + steps.push_back(crate::builder::Step::Format(then_.element)); - if parsed.comments_before_then_expr.is_empty() { - // then_expr - if matches!( - parsed.then_expr.kind(), + steps.push_back(crate::builder::Step::Indent); + if let Some(text) = then_.inline_comment { + steps.push_back(crate::builder::Step::Whitespace); + steps.push_back(crate::builder::Step::Comment(text)); + } + + for trivia in then_.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(_) => {} + } + } + steps.push_back(crate::builder::Step::Dedent); + + // then_expr + if !then_.has_inline_comment + && !then_.has_comments + && (matches!( + then_expr.element.kind(), rnix::SyntaxKind::NODE_ATTR_SET | rnix::SyntaxKind::NODE_LET_IN | rnix::SyntaxKind::NODE_LIST | rnix::SyntaxKind::NODE_STRING ) || crate::builder::fits_in_single_line( build_ctx, - parsed.then_expr.clone(), - ) { - steps.push_back(crate::builder::Step::Whitespace); - steps - .push_back(crate::builder::Step::FormatWider(parsed.then_expr)); - } else { - 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.then_expr)); - steps.push_back(crate::builder::Step::Dedent); - } - steps.push_back(crate::builder::Step::NewLine); - steps.push_back(crate::builder::Step::Pad); + then_expr.element.clone(), + )) + { + steps.push_back(crate::builder::Step::Whitespace); + steps.push_back(crate::builder::Step::FormatWider(then_expr.element)); } else { - // comments_before_then_expr steps.push_back(crate::builder::Step::Indent); steps.push_back(crate::builder::Step::NewLine); steps.push_back(crate::builder::Step::Pad); - for text in parsed.comments_before_then_expr { - steps.push_back(crate::builder::Step::Comment(text)); - steps.push_back(crate::builder::Step::NewLine); - steps.push_back(crate::builder::Step::Pad); - } - // then_expr - steps.push_back(crate::builder::Step::FormatWider(parsed.then_expr)); + steps.push_back(crate::builder::Step::FormatWider(then_expr.element)); steps.push_back(crate::builder::Step::Dedent); - steps.push_back(crate::builder::Step::NewLine); - steps.push_back(crate::builder::Step::Pad); } - // comments_after_then_expr - for text in parsed.comments_after_then_expr { + if let Some(text) = then_expr.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 { + steps.push_back(crate::builder::Step::NewLine); + steps.push_back(crate::builder::Step::Pad); + } + + for trivia in then_expr.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(_) => {} + } } // else_ - steps.push_back(crate::builder::Step::Format(parsed.else_)); + steps.push_back(crate::builder::Step::Format(else_.element)); - if parsed.comments_before_else_expr.is_empty() { - // else_expr - if matches!( - parsed.else_expr.kind(), + steps.push_back(crate::builder::Step::Indent); + if let Some(text) = else_.inline_comment { + steps.push_back(crate::builder::Step::Whitespace); + steps.push_back(crate::builder::Step::Comment(text)); + } + + for trivia in else_.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(_) => {} + } + } + steps.push_back(crate::builder::Step::Dedent); + + // else_expr + if !else_.has_inline_comment + && !else_.has_comments + && (matches!( + else_expr.element.kind(), rnix::SyntaxKind::NODE_ATTR_SET | rnix::SyntaxKind::NODE_IF_ELSE | rnix::SyntaxKind::NODE_LET_IN @@ -116,31 +172,16 @@ pub(crate) fn rule( | rnix::SyntaxKind::NODE_STRING ) || crate::builder::fits_in_single_line( build_ctx, - parsed.else_expr.clone(), - ) { - steps.push_back(crate::builder::Step::Whitespace); - steps - .push_back(crate::builder::Step::FormatWider(parsed.else_expr)); - } else { - 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.else_expr)); - steps.push_back(crate::builder::Step::Dedent); - } + else_expr.element.clone(), + )) + { + steps.push_back(crate::builder::Step::Whitespace); + steps.push_back(crate::builder::Step::FormatWider(else_expr.element)); } else { - // comments_before_else_expr steps.push_back(crate::builder::Step::Indent); steps.push_back(crate::builder::Step::NewLine); steps.push_back(crate::builder::Step::Pad); - for text in parsed.comments_before_else_expr { - steps.push_back(crate::builder::Step::Comment(text)); - steps.push_back(crate::builder::Step::NewLine); - steps.push_back(crate::builder::Step::Pad); - } - // else_expr - steps.push_back(crate::builder::Step::FormatWider(parsed.else_expr)); + steps.push_back(crate::builder::Step::FormatWider(else_expr.element)); steps.push_back(crate::builder::Step::Dedent); } diff --git a/src/alejandra_engine/tests/cases/if_else/in b/src/alejandra_engine/tests/cases/if_else/in index 4918f05..5212aa7 100644 --- a/src/alejandra_engine/tests/cases/if_else/in +++ b/src/alejandra_engine/tests/cases/if_else/in @@ -15,6 +15,22 @@ '') (if ./a then b else c) (if /**/ a /**/ then /**/ b /**/ else /**/ c) + (if # test + a # test + then # test + b # test + else # test + c) + (if # test + /**/ + a # test + /**/ + then # test + b # test + /**/ + else # test + /**/ + c) (if if a then b else c then b else if a then b else if a then b else c) (if if a then b else c then b else if a then b else /*x*/ if a then b else c) (if diff --git a/src/alejandra_engine/tests/cases/if_else/out b/src/alejandra_engine/tests/cases/if_else/out index 772ce5c..0ab6887 100644 --- a/src/alejandra_engine/tests/cases/if_else/out +++ b/src/alejandra_engine/tests/cases/if_else/out @@ -27,6 +27,22 @@ else /**/ c) + (if # test + a # test + then # test + b # test + else # test + c) + (if # test + /**/ + a # test + /**/ + then # test + b # test + /**/ + else # test + /**/ + c) (if if a then b