1
Fork 0
mirror of https://github.com/RGBCube/alejandra synced 2025-07-30 12:07:46 +00:00

feat: support inline comments in if-else

This commit is contained in:
Kevin Amado 2022-02-28 13:44:42 -05:00
parent 8ed23bf620
commit 62dd8ec60a
6 changed files with 173 additions and 192 deletions

View file

@ -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

View file

@ -1,102 +0,0 @@
use std::collections::LinkedList;
#[derive(Debug)]
pub(crate) struct IfElse {
pub if_: rnix::SyntaxElement,
pub comments_before_if_expr: LinkedList<String>,
pub if_expr: rnix::SyntaxElement,
pub comments_after_if_expr: LinkedList<String>,
pub then_: rnix::SyntaxElement,
pub comments_before_then_expr: LinkedList<String>,
pub then_expr: rnix::SyntaxElement,
pub comments_after_then_expr: LinkedList<String>,
pub else_: rnix::SyntaxElement,
pub comments_before_else_expr: LinkedList<String>,
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,
}
}
}

View file

@ -1,2 +1 @@
pub(crate) mod if_else;
pub(crate) mod pattern;

View file

@ -4,111 +4,167 @@ pub(crate) fn rule(
) -> std::collections::LinkedList<crate::builder::Step> {
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);
}

View file

@ -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

View file

@ -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