Skip to content

Commit

Permalink
refactor: decouple retrieving comments and formatting comments
Browse files Browse the repository at this point in the history
  • Loading branch information
g-plane committed Jul 28, 2024
1 parent 12ad555 commit a80bcbf
Show file tree
Hide file tree
Showing 17 changed files with 569 additions and 304 deletions.
44 changes: 15 additions & 29 deletions malva/src/ctx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,18 @@ impl<'a, 's> Ctx<'a, 's> {
start: usize,
end: usize,
) -> impl Iterator<Item = &Comment<'s>> + Clone {
debug_assert!(start <= end);

self.comments
.iter()
.filter(move |comment| comment.span.start >= start && comment.span.end <= end)
}

pub(crate) fn start_spaced_comments(
&'a self,
start: usize,
end: usize,
comments: impl Iterator<Item = &'a Comment<'s>> + 'a,
) -> impl Iterator<Item = Doc<'s>> + 'a {
debug_assert!(start <= end);

self.get_comments_between(start, end)
comments
.scan(CommentKind::Block, |prev_kind, comment| {
Some(
[
Expand All @@ -56,15 +55,12 @@ impl<'a, 's> Ctx<'a, 's> {

pub(crate) fn start_spaced_comments_without_last_hard_line(
&'a self,
start: usize,
end: usize,
comments: impl Iterator<Item = &'a Comment<'s>> + 'a,
has_last_line_comment: &'a mut bool,
) -> impl Iterator<Item = Doc<'s>> + 'a {
debug_assert!(start <= end);

StartSpacedCommentsWithoutLastHardLine {
ctx: self,
iter: self.get_comments_between(start, end).peekable(),
iter: comments.peekable(),
prev_kind: CommentKind::Block,
has_last_line_comment,
}
Expand All @@ -73,12 +69,9 @@ impl<'a, 's> Ctx<'a, 's> {

pub(crate) fn end_spaced_comments(
&'a self,
start: usize,
end: usize,
comments: impl Iterator<Item = &'a Comment<'s>> + 'a,
) -> impl Iterator<Item = Doc<'s>> + 'a {
debug_assert!(start <= end);

self.get_comments_between(start, end).flat_map(|comment| {
comments.flat_map(|comment| {
[
comment.doc(self),
match comment.kind {
Expand All @@ -92,32 +85,25 @@ impl<'a, 's> Ctx<'a, 's> {

pub(crate) fn end_spaced_comments_without_last_space(
&'a self,
start: usize,
end: usize,
comments: impl Iterator<Item = &'a Comment<'s>> + 'a,
comment_end: &'a mut Option<usize>,
) -> impl Iterator<Item = Doc<'s>> + 'a {
debug_assert!(start <= end);

EndSpacedCommentsWithoutLastSpace {
ctx: self,
iter: self.get_comments_between(start, end).peekable(),
iter: comments.peekable(),
comment_end,
}
.flatten()
}

pub(crate) fn unspaced_comments(
&'a self,
start: usize,
end: usize,
comments: impl Iterator<Item = &'a Comment<'s>> + 'a,
) -> impl Iterator<Item = Doc<'s>> + 'a {
debug_assert!(start <= end);

self.get_comments_between(start, end)
.filter_map(|comment| match comment.kind {
CommentKind::Block => Some(comment.doc(self)),
CommentKind::Line => None,
})
comments.filter_map(|comment| match comment.kind {
CommentKind::Block => Some(comment.doc(self)),
CommentKind::Line => None,
})
}

pub(crate) fn with_state(
Expand Down
88 changes: 59 additions & 29 deletions malva/src/doc_gen/at_rule/container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ impl<'s> DocGen<'s> for ContainerCondition<'s> {
(Vec::with_capacity(self.conditions.len()), self.span.start),
|(mut docs, pos), condition| {
let span = condition.span();
docs.extend(ctx.start_spaced_comments(pos, span.start));
docs.extend(
ctx.start_spaced_comments(ctx.get_comments_between(pos, span.start)),
);
docs.push(condition.doc(ctx));
(docs, span.end)
},
Expand All @@ -30,9 +32,9 @@ impl<'s> DocGen<'s> for ContainerConditionAnd<'s> {
OperatorLineBreak::Before => vec![Doc::line_or_space(), Doc::text("and"), Doc::space()],
OperatorLineBreak::After => vec![Doc::space(), Doc::text("and"), Doc::line_or_space()],
};
docs.extend(
ctx.end_spaced_comments(self.keyword.span.end, self.query_in_parens.span.start),
);
docs.extend(ctx.end_spaced_comments(
ctx.get_comments_between(self.keyword.span.end, self.query_in_parens.span.start),
));
docs.push(self.query_in_parens.doc(ctx));

Doc::list(docs).group().nest(ctx.indent_width)
Expand All @@ -58,9 +60,9 @@ impl<'s> DocGen<'s> for ContainerConditionNot<'s> {
OperatorLineBreak::Before => vec![Doc::line_or_nil(), Doc::text("not"), Doc::space()],
OperatorLineBreak::After => vec![Doc::text("not"), Doc::line_or_space()],
};
docs.extend(
ctx.end_spaced_comments(self.keyword.span.end, self.query_in_parens.span.start),
);
docs.extend(ctx.end_spaced_comments(
ctx.get_comments_between(self.keyword.span.end, self.query_in_parens.span.start),
));
docs.push(self.query_in_parens.doc(ctx));

Doc::list(docs).group().nest(ctx.indent_width)
Expand All @@ -75,9 +77,9 @@ impl<'s> DocGen<'s> for ContainerConditionOr<'s> {
OperatorLineBreak::Before => vec![Doc::line_or_space(), Doc::text("or"), Doc::space()],
OperatorLineBreak::After => vec![Doc::space(), Doc::text("or"), Doc::line_or_space()],
};
docs.extend(
ctx.end_spaced_comments(self.keyword.span.end, self.query_in_parens.span.start),
);
docs.extend(ctx.end_spaced_comments(
ctx.get_comments_between(self.keyword.span.end, self.query_in_parens.span.start),
));
docs.push(self.query_in_parens.doc(ctx));

Doc::list(docs).group().nest(ctx.indent_width)
Expand All @@ -90,7 +92,9 @@ impl<'s> DocGen<'s> for ContainerPrelude<'s> {
if let Some(name) = &self.name {
docs.push(name.doc(ctx));
docs.push(Doc::space());
docs.extend(ctx.end_spaced_comments(name.span().start, self.condition.span.start));
docs.extend(ctx.end_spaced_comments(
ctx.get_comments_between(name.span().start, self.condition.span.start),
));
}
docs.push(self.condition.doc(ctx));
Doc::list(docs)
Expand All @@ -101,24 +105,44 @@ impl<'s> DocGen<'s> for QueryInParens<'s> {
fn doc(&self, ctx: &Ctx<'_, 's>) -> Doc<'s> {
match &self.kind {
QueryInParensKind::ContainerCondition(condition) => Doc::text("(")
.concat(ctx.end_spaced_comments(self.span.start, condition.span.start))
.concat(ctx.end_spaced_comments(
ctx.get_comments_between(self.span.start, condition.span.start),
))
.append(condition.doc(ctx))
.concat(ctx.start_spaced_comments(condition.span.end, self.span.end))
.concat(ctx.start_spaced_comments(
ctx.get_comments_between(condition.span.end, self.span.end),
))
.append(Doc::text(")")),
QueryInParensKind::SizeFeature(size_feature) => {
let span = size_feature.span();
Doc::text("(")
.concat(ctx.end_spaced_comments(self.span.start, span.start))
.concat(
ctx.end_spaced_comments(
ctx.get_comments_between(self.span.start, span.start),
),
)
.append(size_feature.doc(ctx))
.concat(ctx.start_spaced_comments(span.end, self.span.end))
.concat(
ctx.start_spaced_comments(
ctx.get_comments_between(span.end, self.span.end),
),
)
.append(Doc::text(")"))
}
QueryInParensKind::StyleQuery(style_query) => {
let span = style_query.span();
Doc::text("style(")
.concat(ctx.end_spaced_comments(self.span.start, span.start))
.concat(
ctx.end_spaced_comments(
ctx.get_comments_between(self.span.start, span.start),
),
)
.append(style_query.doc(ctx))
.concat(ctx.start_spaced_comments(span.end, self.span.end))
.concat(
ctx.start_spaced_comments(
ctx.get_comments_between(span.end, self.span.end),
),
)
.append(Doc::text(")"))
}
}
Expand All @@ -134,7 +158,9 @@ impl<'s> DocGen<'s> for StyleCondition<'s> {
(Vec::with_capacity(self.conditions.len()), self.span.start),
|(mut docs, pos), condition| {
let span = condition.span();
docs.extend(ctx.start_spaced_comments(pos, span.start));
docs.extend(
ctx.start_spaced_comments(ctx.get_comments_between(pos, span.start)),
);
docs.push(condition.doc(ctx));
(docs, span.end)
},
Expand All @@ -152,9 +178,9 @@ impl<'s> DocGen<'s> for StyleConditionAnd<'s> {
OperatorLineBreak::Before => vec![Doc::line_or_space(), Doc::text("and"), Doc::space()],
OperatorLineBreak::After => vec![Doc::space(), Doc::text("and"), Doc::line_or_space()],
};
docs.extend(
ctx.end_spaced_comments(self.keyword.span.end, self.style_in_parens.span.start),
);
docs.extend(ctx.end_spaced_comments(
ctx.get_comments_between(self.keyword.span.end, self.style_in_parens.span.start),
));
docs.push(self.style_in_parens.doc(ctx));

Doc::list(docs).group().nest(ctx.indent_width)
Expand All @@ -180,9 +206,9 @@ impl<'s> DocGen<'s> for StyleConditionNot<'s> {
OperatorLineBreak::Before => vec![Doc::line_or_nil(), Doc::text("not"), Doc::space()],
OperatorLineBreak::After => vec![Doc::text("not"), Doc::line_or_space()],
};
docs.extend(
ctx.end_spaced_comments(self.keyword.span.end, self.style_in_parens.span.start),
);
docs.extend(ctx.end_spaced_comments(
ctx.get_comments_between(self.keyword.span.end, self.style_in_parens.span.start),
));
docs.push(self.style_in_parens.doc(ctx));

Doc::list(docs).group().nest(ctx.indent_width)
Expand All @@ -197,9 +223,9 @@ impl<'s> DocGen<'s> for StyleConditionOr<'s> {
OperatorLineBreak::Before => vec![Doc::line_or_space(), Doc::text("or"), Doc::space()],
OperatorLineBreak::After => vec![Doc::space(), Doc::text("or"), Doc::line_or_space()],
};
docs.extend(
ctx.end_spaced_comments(self.keyword.span.end, self.style_in_parens.span.start),
);
docs.extend(ctx.end_spaced_comments(
ctx.get_comments_between(self.keyword.span.end, self.style_in_parens.span.start),
));
docs.push(self.style_in_parens.doc(ctx));

Doc::list(docs).group().nest(ctx.indent_width)
Expand All @@ -210,9 +236,13 @@ impl<'s> DocGen<'s> for StyleInParens<'s> {
fn doc(&self, ctx: &Ctx<'_, 's>) -> Doc<'s> {
let kind_span = self.kind.span();
Doc::text("(")
.concat(ctx.end_spaced_comments(self.span.start, kind_span.start))
.concat(
ctx.end_spaced_comments(ctx.get_comments_between(self.span.start, kind_span.start)),
)
.append(self.kind.doc(ctx))
.concat(ctx.start_spaced_comments(kind_span.end, self.span.end))
.concat(
ctx.start_spaced_comments(ctx.get_comments_between(kind_span.end, self.span.end)),
)
.append(Doc::text(")"))
}
}
Expand Down
4 changes: 3 additions & 1 deletion malva/src/doc_gen/at_rule/custom_media.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ impl<'s> DocGen<'s> for CustomMedia<'s> {
self.name
.doc(ctx)
.append(Doc::space())
.concat(ctx.end_spaced_comments(self.name.span().end, self.value.span().start))
.concat(ctx.end_spaced_comments(
ctx.get_comments_between(self.name.span().end, self.value.span().start),
))
.append(self.value.doc(ctx))
}
}
Expand Down
6 changes: 3 additions & 3 deletions malva/src/doc_gen/at_rule/custom_selector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ impl<'s> DocGen<'s> for CustomSelectorPrelude<'s> {
self.custom_selector
.doc(ctx)
.append(Doc::line_or_space().nest(ctx.indent_width))
.concat(
ctx.end_spaced_comments(self.custom_selector.span.end, self.selector.span.start),
)
.concat(ctx.end_spaced_comments(
ctx.get_comments_between(self.custom_selector.span.end, self.selector.span.start),
))
.append(self.selector.doc(ctx))
.group()
}
Expand Down
14 changes: 9 additions & 5 deletions malva/src/doc_gen/at_rule/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,22 @@ impl<'s> DocGen<'s> for ImportPrelude<'s> {
if let Some(layer) = &self.layer {
let span = layer.span();
docs.push(Doc::line_or_space());
docs.extend(ctx.end_spaced_comments(pos, span.start));
docs.extend(ctx.end_spaced_comments(ctx.get_comments_between(pos, span.start)));
docs.push(layer.doc(ctx));
pos = span.end;
}

if let Some(supports) = &self.supports {
let span = supports.span();
docs.push(Doc::line_or_space());
docs.extend(ctx.end_spaced_comments(pos, span.start));
docs.extend(ctx.end_spaced_comments(ctx.get_comments_between(pos, span.start)));
docs.push(supports.doc(ctx));
pos = span.end;
}

if let Some(media) = &self.media {
docs.push(Doc::line_or_space());
docs.extend(ctx.end_spaced_comments(pos, media.span.start));
docs.extend(ctx.end_spaced_comments(ctx.get_comments_between(pos, media.span.start)));
docs.push(media.doc(ctx));
}

Expand Down Expand Up @@ -57,14 +57,18 @@ impl<'s> DocGen<'s> for ImportPreludeSupports<'s> {
fn doc(&self, ctx: &Ctx<'_, 's>) -> Doc<'s> {
let kind_span = self.kind.span();
Doc::text("supports(")
.concat(ctx.end_spaced_comments(self.span.start, kind_span.start))
.concat(
ctx.end_spaced_comments(ctx.get_comments_between(self.span.start, kind_span.start)),
)
.append(match &self.kind {
ImportPreludeSupportsKind::SupportsCondition(supports_condition) => {
supports_condition.doc(ctx)
}
ImportPreludeSupportsKind::Declaration(declaration) => declaration.doc(ctx),
})
.concat(ctx.start_spaced_comments(kind_span.end, self.span.end))
.concat(
ctx.start_spaced_comments(ctx.get_comments_between(kind_span.end, self.span.end)),
)
.append(Doc::text(")"))
}
}
Loading

0 comments on commit a80bcbf

Please sign in to comment.