in lib/src/chunk_builder.dart [207:342]
void writeComments(
List<SourceComment> comments, int linesBeforeToken, String token) {
// Edge case: if we require a blank line, but there exists one between
// some of the comments, or after the last one, then we don't need to
// enforce one before the first comment. Example:
//
// library foo;
// // comment
//
// class Bar {}
//
// Normally, a blank line is required after `library`, but since there is
// one after the comment, we don't need one before it. This is mainly so
// that commented out directives stick with their preceding group.
if (_pendingWhitespace == Whitespace.twoNewlines &&
comments.first.linesBefore < 2) {
if (linesBeforeToken > 1) {
_pendingWhitespace = Whitespace.newline;
} else {
for (var i = 1; i < comments.length; i++) {
if (comments[i].linesBefore > 1) {
_pendingWhitespace = Whitespace.newline;
break;
}
}
}
}
// Edge case: if the previous output was also from a call to
// [writeComments()] which ended with a line comment, force a newline.
// Normally, comments are strictly interleaved with tokens and you never
// get two sequences of comments in a row. However, when applying a fix
// that removes a token (like `new`), it's possible to get two sets of
// comments in a row, as in:
//
// // a
// new // b
// Foo();
//
// When that happens, we need to make sure to preserve the split at the end
// of the first sequence of comments if there is one.
if (_pendingWhitespace == Whitespace.afterHardSplit) {
comments.first.linesBefore = 1;
_pendingWhitespace = Whitespace.none;
}
// Edge case: if the comments are completely inline (i.e. just a series of
// block comments with no newlines before, after, or between them), then
// they will eat any pending newlines. Make sure that doesn't happen by
// putting the pending whitespace before the first comment. Turns this:
//
// library foo; /* a */ /* b */ import 'a.dart';
//
// into:
//
// library foo;
//
// /* a */ /* b */ import 'a.dart';
if (linesBeforeToken == 0 &&
_pendingWhitespace.minimumLines > comments.first.linesBefore &&
comments.every((comment) => comment.type == CommentType.inlineBlock)) {
comments.first.linesBefore = _pendingWhitespace.minimumLines;
}
// Write each comment and the whitespace between them.
for (var i = 0; i < comments.length; i++) {
var comment = comments[i];
preserveNewlines(comment.linesBefore);
// Don't emit a space because we'll handle it below. If we emit it here,
// we may get a trailing space if the comment needs a line before it.
if (_pendingWhitespace == Whitespace.space) {
_pendingWhitespace = Whitespace.none;
}
_emitPendingWhitespace();
// See if the comment should follow text on the current line.
if (comment.linesBefore == 0 || comment.type == CommentType.inlineBlock) {
// If we're sitting on a split, move the comment before it to adhere it
// to the preceding text.
if (_shouldMoveCommentBeforeSplit(comment)) {
_chunks.last.allowText();
}
// The comment follows other text, so we need to decide if it gets a
// space before it or not.
if (_needsSpaceBeforeComment(comment)) _writeText(' ');
} else {
// The comment is not inline, so start a new line.
_writeHardSplit(
flushLeft: comment.flushLeft,
isDouble: comment.linesBefore > 1,
nest: true);
}
_writeCommentText(comment);
if (comment.selectionStart != null) {
startSelectionFromEnd(comment.text.length - comment.selectionStart!);
}
if (comment.selectionEnd != null) {
endSelectionFromEnd(comment.text.length - comment.selectionEnd!);
}
// Make sure there is at least one newline after a line comment and allow
// one or two after a block comment that has nothing after it.
int linesAfter;
if (i < comments.length - 1) {
linesAfter = comments[i + 1].linesBefore;
} else {
linesAfter = linesBeforeToken;
// Always force a newline after multi-line block comments. Prevents
// mistakes like:
//
// /**
// * Some doc comment.
// */ someFunction() { ... }
if (linesAfter == 0 && comments.last.text.contains('\n')) {
linesAfter = 1;
}
}
if (linesAfter > 0) _writeHardSplit(isDouble: linesAfter > 1, nest: true);
}
// If the comment has text following it (aside from a grouping character),
// it needs a trailing space.
if (_needsSpaceAfterLastComment(comments, token)) {
_pendingWhitespace = Whitespace.space;
}
preserveNewlines(linesBeforeToken);
}