Skip to content

Commit

Permalink
FormatTokens: add more methods around comments
Browse files Browse the repository at this point in the history
  • Loading branch information
kitbellew committed May 10, 2024
1 parent dc53269 commit f415a54
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ class FormatOps(
case c: T.Comment
if start.noBreak &&
(!start.left.is[T.LeftParen] ||
tokens.isBreakAfterRight(start)) => Some(c)
tokens.hasBreakAfterRightBeforeNonComment(start)) => Some(c)
case _ => Some(start.left)
}
}.fold(_.right, identity)
Expand All @@ -163,8 +163,9 @@ class FormatOps(
case _: T.Comma | _: T.LeftParen | _: T.Semicolon | _: T.RightArrow |
_: T.Equals => None
case _: T.RightParen if start.left.is[T.LeftParen] => None
case c: T.Comment if start.noBreak && tokens.isBreakAfterRight(start) =>
Some(c)
case c: T.Comment
if start.noBreak &&
tokens.hasBreakAfterRightBeforeNonComment(start) => Some(c)
case _ if !style.newlines.formatInfix && start.noBreak && isInfix => None
case _ => Some(start.left)
}
Expand Down Expand Up @@ -1240,7 +1241,7 @@ class FormatOps(
def isDone(x: FormatToken) = x.hasBlankLine || x.right.end >= end
@tailrec
def iter(x: FormatToken): FormatToken = {
val nft = tokens.nextNonCommentSameLine(next(x))
val nft = tokens.nextNonCommentSameLineAfter(x)
if (isDone(nft)) nft
else if (!nft.right.is[T.Comment]) ft // original
else iter(nft)
Expand All @@ -1266,7 +1267,7 @@ class FormatOps(
case _: T.Comment =>
val isDetachedSlc = ft.hasBreak && tokens.isBreakAfterRight(ft)
if (isDetachedSlc || ft.rightHasNewline) null else Space
case _ => Space(style.spaces.inParentheses && spaceOk)
case _ => Space(spaceOk && style.spaces.inParentheses)
}

// look for arrow before body, if any, else after params
Expand Down Expand Up @@ -1636,7 +1637,7 @@ class FormatOps(
if (!ft.right.is[T.Comment]) splitsFunc(ft)
else if (ft.hasBreak) Seq(nlSplitFunc(0).forThisLine)
else {
val nextFt = nextNonCommentSameLine(next(ft))
val nextFt = tokens.nextNonCommentSameLineAfter(ft)
val splits =
if (nextFt.noBreak) splitsFunc(nextFt)
else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,9 @@ class FormatTokens(leftTok2tok: Map[TokenHash, Int])(val arr: Array[FormatToken]
final def nextNonCommentSameLine(curr: FormatToken): FormatToken =
findToken(curr, next)(ft => ft.hasBreak || !ft.right.is[Token.Comment])

final def nextNonCommentSameLineAfter(curr: FormatToken): FormatToken =
nextNonCommentSameLine(next(curr))

final def nextNonComment(curr: FormatToken): FormatToken =
findToken(curr, next)(!_.right.is[Token.Comment])

Expand Down Expand Up @@ -288,13 +291,21 @@ class FormatTokens(leftTok2tok: Map[TokenHash, Int])(val arr: Array[FormatToken]
@inline
def isBreakAfterRight(ft: FormatToken): Boolean = next(ft).hasBreakOrEOF

@inline
def hasBreakAfterRightBeforeNonComment(ft: FormatToken): Boolean =
nextNonCommentSameLineAfter(ft).hasBreakOrEOF

@inline
def hasBreakBeforeNonComment(ft: FormatToken): Boolean = ft.hasBreak ||
hasBreakAfterRightBeforeNonComment(ft)

@inline
def isRightCommentThenBreak(ft: FormatToken): Boolean = ft.right
.is[Token.Comment] && isBreakAfterRight(ft)
.is[Token.Comment] && hasBreakAfterRightBeforeNonComment(ft)

@inline
def isRightLikeSingleLineComment(ft: FormatToken): Boolean =
isRightCommentThenBreak(ft) && !ft.rightHasNewline
def isRightCommentWithBreak(ft: FormatToken): Boolean = ft.right
.is[Token.Comment] && hasBreakBeforeNonComment(ft)

@inline
def isAttachedCommentThenBreak(ft: FormatToken): Boolean = ft.noBreak &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1869,7 +1869,8 @@ object FormatWriter {
case x => x
}

val slc = tokens.isRightLikeSingleLineComment(ft)
val slc = ft.right.is[T.Comment] && tokens.isBreakAfterRight(ft) &&
!ft.rightHasNewline
val code = if (slc) "//" else ft.meta.right.text
floc.style.alignMap.get(code).flatMap { matchers =>
// Corner case when line ends with comment
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1149,8 +1149,7 @@ class Router(formatOps: FormatOps) {
val rightIsComment = right.is[T.Comment]
val mustUseNL = onlyConfigStyle ||
style.newlines.keepBreak(newlines) ||
rightIsComment &&
(newlines != 0 || nextNonCommentSameLine(next(ft)).hasBreak)
tokens.isRightCommentWithBreak(ft)
val noSplitModification =
if (rightIsComment && !mustUseNL) getMod(ft) else baseNoSplitMod
val nlMod = if (rightIsComment && mustUseNL) getMod(ft) else Newline
Expand Down Expand Up @@ -1192,8 +1191,7 @@ class Router(formatOps: FormatOps) {
val nlOnly = flags.dangleForTrailingCommas ||
flags.configStyle != ConfigStyle.None ||
style.newlines.keepBreak(newlines) || scalaJsStyleNL ||
rightIsComment &&
(newlines != 0 || nextNonCommentSameLine(next(ft)).hasBreak)
tokens.isRightCommentWithBreak(ft)

def findComma(ft: FormatToken) = findFirstOnRight[T.Comma](ft, close)

Expand Down Expand Up @@ -1955,7 +1953,7 @@ class Router(formatOps: FormatOps) {
if (style.newlines.getBeforeMultiline eq Newlines.unfold) CtrlBodySplits
.checkComment(ft, nlSplitFunc) { ft =>
if (ft.right.is[T.LeftBrace]) {
val nextFt = nextNonCommentSameLine(next(ft))
val nextFt = tokens.nextNonCommentSameLineAfter(ft)
val policy = decideNewlinesOnlyAfterToken(nextFt.left)
Seq(Split(Space, 0, policy = policy))
} else Seq(nlSplitFunc(0))
Expand Down Expand Up @@ -1987,7 +1985,7 @@ class Router(formatOps: FormatOps) {
case FormatToken(_, _: T.KwThen | _: T.KwDo, _) =>
if (style.newlines.sourceIgnored || noBreak()) Seq(
Split(Space, 0)
.withOptimalToken(nextNonCommentSameLine(next(ft)).left),
.withOptimalToken(tokens.nextNonCommentSameLineAfter(ft).left),
Split(Newline, 1),
)
else Seq(Split(Newline, 0))
Expand Down Expand Up @@ -2120,7 +2118,7 @@ class Router(formatOps: FormatOps) {
val policy =
if (bodyBlock || tokens.isAttachedCommentThenBreak(arrowFt)) NoPolicy
else if (isCaseBodyEnclosedAsBlock(postArrowFt, owner)) {
val postParenFt = nextNonCommentSameLine(next(postArrowFt))
val postParenFt = tokens.nextNonCommentSameLineAfter(postArrowFt)
val lparen = postParenFt.left
val rparen = matching(lparen)
if (postParenFt.right.start >= rparen.start) defaultPolicy
Expand Down Expand Up @@ -2162,7 +2160,7 @@ class Router(formatOps: FormatOps) {
if (style.newlines.keepBreak(newlines)) Seq(Split(Newline, 0))
else {
val arrow = getCaseArrow(rightOwner.asInstanceOf[Case]).left
val afterIf = nextNonCommentSameLine(next(ft))
val afterIf = tokens.nextNonCommentSameLineAfter(ft)
val noSplit =
if (style.newlines.keepBreak(afterIf)) {
val indent = Indent(style.indent.main, arrow, ExpiresOn.Before)
Expand Down Expand Up @@ -2422,13 +2420,14 @@ class Router(formatOps: FormatOps) {
}
ft match {
case FormatToken(_: T.BOF, _, _) => splits
case FormatToken(_, _: T.Comment, _) if tokens.isBreakAfterRight(ft) =>
case FormatToken(_, _: T.Comment, _) if rhsIsCommentedOutIfComment(ft) =>
splitsAsNewlines(splits.map(_.withNoIndent))
case FormatToken(_: T.Comment, _, _) =>
if (ft.noBreak) splits else splitsAsNewlines(splits)
case FormatToken(_, _: T.Comment, _)
if tokens.hasBreakAfterRightBeforeNonComment(ft) =>
if (ft.noBreak) splits.map(_.withMod(Space))
else if (!rhsIsCommentedOut(ft)) splitsAsNewlines(splits)
else splitsAsNewlines(splits.map(_.withNoIndent))
// Only newlines after inline comments.
case FormatToken(_: T.Comment, _, _) if ft.hasBreak =>
splitsAsNewlines(splits)
else splitsAsNewlines(splits)
case ft if ft.meta.formatOff && ft.hasBreak => splitsAsNewlines(splits)
case FormatToken(_: T.Equals, r: T.KwMacro, _)
if dialect.allowSignificantIndentation =>
Expand All @@ -2451,10 +2450,8 @@ class Router(formatOps: FormatOps) {
def expire = getLastToken(body)
if (ft.right.is[T.LeftBrace]) // The block will take care of indenting by 2
Seq(Split(Space, 0).withIndents(spaceIndents))
else if (
ft.right.is[T.Comment] &&
(ft.hasBreak || nextNonCommentSameLine(next(ft)).hasBreak)
) Seq(CtrlBodySplits.withIndent(Split(Space.orNL(ft.noBreak), 0), ft, body))
else if (tokens.isRightCommentWithBreak(ft))
Seq(CtrlBodySplits.withIndent(Split(Space.orNL(ft.noBreak), 0), ft, body))
else if (isJsNative(body)) Seq(Split(Space, 0).withSingleLine(expire))
else if (style.newlines.forceBeforeAssign(ft.meta.leftOwner))
Seq(CtrlBodySplits.withIndent(Split(Newline, 0), ft, body))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,8 @@ private class PreferCurlyFors(implicit val ftoks: FormatTokens)
else null

case _: Token.Semicolon
if !style.rewrite.preferCurlyFors.removeTrailingSemicolonsOnly || {
val next = ftoks.next(ft)
next.hasBreak || ftoks.isRightCommentThenBreak(next)
} =>
if !style.rewrite.preferCurlyFors.removeTrailingSemicolonsOnly ||
ftoks.hasBreakAfterRightBeforeNonComment(ft) =>
ft.meta.rightOwner match {
case _: Term.For | _: Term.ForYield => removeToken
case _ => null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,13 @@ object TokenOps {
def withNoIndent(ft: FormatToken): Boolean = ft.between.lastOption
.exists(_.is[LF])

@inline
def rhsIsCommentedOut(ft: FormatToken): Boolean = ft.right.is[Comment] &&
withNoIndent(ft) && isSingleLineIfComment(ft.right)
rhsIsCommentedOutIfComment(ft)

@inline
def rhsIsCommentedOutIfComment(ft: FormatToken): Boolean = withNoIndent(ft) &&
isSingleLineIfComment(ft.right)

@inline
def isLeftCommentThenBreak(ft: FormatToken): Boolean = ft.left
Expand Down
8 changes: 4 additions & 4 deletions scalafmt-tests/src/test/resources/scala3/Extension.stat
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,9 @@ maxColumn = 40
extension [A](cat: Cat) /* new feature */ // or this
def a = 1
>>>
extension [A](cat: Cat)
/* new feature */ // or this
extension [A](
cat: Cat
) /* new feature */ // or this
def a = 1
<<< extension comments with embedded NL
maxColumn = 40
Expand All @@ -136,8 +137,7 @@ extension [A](cat: Cat) /*
* new feature */ // or this
def a = 1
>>>
extension [A](cat: Cat)
/*
extension [A](cat: Cat) /*
* new feature */ // or this
def a = 1
<<< extension comments brace
Expand Down

0 comments on commit f415a54

Please sign in to comment.