Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Router: merge rhsOptimalToken+endOfSingleLineBlock #4319

Merged
merged 1 commit into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -118,52 +118,43 @@ class FormatOps(
classifier: Classifier[T, A],
): Option[FormatToken] = findFirst(start, end.start)(x => classifier(x.right))

final def rhsOptimalToken(start: FormatToken, end: Int = Int.MaxValue)(
implicit style: ScalafmtConfig,
): T = findTokenWith(start, next) { start =>
start.right match {
case t if t.end >= end => Some(start.left)
case _ if start.hasBlankLine => Some(start.left)
case _: T.RightParen
if start.left.is[T.RightParen] || start.left.is[T.LeftParen] => None
case _: T.RightBracket if start.left.is[T.RightBracket] => None
case _: T.LeftParen if !leftParenStartsNewBlockOnRight(start) => None
case _: T.Comma | _: T.Semicolon | _: T.RightArrow | _: T.Equals => None
case c: T.Comment
if start.noBreak &&
(!start.left.is[T.LeftParen] ||
hasBreakAfterRightBeforeNonComment(start)) => Some(c)
case _ => Some(start.left)
}
}.fold(_.right, identity)

@tailrec
final def endOfSingleLineBlockOnLeft(
start: FormatToken,
)(implicit style: ScalafmtConfig): FormatToken = {
final def getSlbEndOnLeft(start: FormatToken, end: Int = Int.MaxValue)(
implicit style: ScalafmtConfig,
): FormatToken = {
val endFound = start.right match {
case t if t.end >= end => true
case _: T.EOF => true
case _: T.Comma | _: T.Semicolon | _: T.RightArrow | _: T.Equals => false
case _ if start.hasBlankLine => true
case _: T.LeftParen => leftParenStartsNewBlockOnRight(start)
case _: T.RightParen => !start.left.is[T.LeftParen]
case _
if !style.newlines.formatInfix &&
(isInfixOp(start.rightOwner) || isInfixOpOnLeft(start)) =>
start.hasBreak
case _: T.LeftParen if !leftParenStartsNewBlockOnRight(start) => false
case _: T.RightBracket if start.left.is[T.RightBracket] => false
case _: T.RightParen => start.left match {
case _: T.LeftParen => false
case _: T.RightParen => !style.newlines.fold &&
style.danglingParentheses.atSite(start.rightOwner, orElse = true)
case _ => true
}
case _: T.Comment =>
if (start.noBreak) {
val nft = next(start)
if (!start.left.is[T.LeftParen] || hasBreakBeforeNonComment(nft))
return nft // RETURN!!!
}
true
case _ => style.newlines.formatInfix || start.hasBreak ||
!(isInfixOp(start.rightOwner) || isInfixOpOnLeft(start))
case _ => true
}

if (endFound) start else endOfSingleLineBlockOnLeft(next(start))
if (endFound) start else getSlbEndOnLeft(next(start))
}

final def endOfSingleLineBlock(start: FormatToken)(implicit
style: ScalafmtConfig,
): T = endOfSingleLineBlockOnLeft(start).left
): T = getSlbEndOnLeft(start).left

final def isInfixOpOnLeft(ft: FormatToken): Boolean =
isInfixOp(prevNonComment(ft).leftOwner)
Expand Down Expand Up @@ -1535,7 +1526,7 @@ class FormatOps(
fileLine: FileLine,
) = {
val spacePolicy = policy | penalize(penalty)
val miniSlbEnd = rhsOptimalToken(next(ft), blastFT.right.end)
val miniSlbEnd = getSlbEndOnLeft(next(ft), blastFT.right.end).left
val slbLite = style.newlines.keep
val opt = if (slbLite) miniSlbEnd else blast
Split(Space, 0).withSingleLineNoOptimal(miniSlbEnd, noSyntaxNL = true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,8 @@ class Router(formatOps: FormatOps) {
// copy logic from `( ...`, binpack=never, defining `slbSplit`
val isBeforeOpenParen = style.newlines.isBeforeOpenParenCallSite
Split(NoSplit, 0).withSingleLine(
if (isBeforeOpenParen) closeFT.left else rhsOptimalToken(closeFT),
if (isBeforeOpenParen) closeFT.left
else endOfSingleLineBlock(closeFT),
noSyntaxNL = true,
killOnFail = true,
noOptimal = style.newlines.keep,
Expand Down Expand Up @@ -914,7 +915,7 @@ class Router(formatOps: FormatOps) {
else style.newlines.isBeforeOpenParenCallSite
val optimal: T =
if (isBeforeOpenParen) close
else if (!defnSite || isBracket) rhsOptimalToken(afterClose)
else if (!defnSite || isBracket) endOfSingleLineBlock(afterClose)
else defnSiteLastToken(afterClose, leftOwner)

val wouldDangle = onlyConfigStyle || mustDangleForTrailingCommas ||
Expand Down Expand Up @@ -1409,7 +1410,8 @@ class Router(formatOps: FormatOps) {
.Block(List(_: Term.FunctionTerm | _: Term.PartialFunction)) =>
Seq(Split(Newline, 0))
case _ =>
val breakAfter = rhsOptimalToken(next(nextNonCommentSameLine(ft)))
val breakAfter =
endOfSingleLineBlock(next(nextNonCommentSameLine(ft)))
val multiLine = decideNewlinesOnlyAfterToken(breakAfter) ==>
decideNewlinesOnlyBeforeClose(close)
Seq(
Expand Down Expand Up @@ -1455,7 +1457,7 @@ class Router(formatOps: FormatOps) {
// copy logic from `( ...`, binpack=never, defining `slbSplit`
val isBeforeOpenParen = style.newlines.isBeforeOpenParenCallSite
val optimal: T =
if (isBeforeOpenParen) rbft.left else rhsOptimalToken(rbft)
if (isBeforeOpenParen) rbft.left else endOfSingleLineBlock(rbft)
val noOptimal = style.newlines.keep
Split(NoSplit, 0).withSingleLine(optimal, noOptimal = noOptimal)
}
Expand Down Expand Up @@ -1681,7 +1683,7 @@ class Router(formatOps: FormatOps) {
def getSlbEnd() = {
val nft = nextNonCommentSameLineAfter(ft)
val eft = if (nft.noBreak) nextNonCommentSameLineAfter(nft) else nft
rhsOptimalToken(eft)
endOfSingleLineBlock(eft)
}
def shouldKillOnFail() =
(style.binPack.callSite ne BinPack.Site.Never) &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,9 @@ object a {
>>>
object a {
lowClass.isJavaDefined && highClass.isJavaDefined && { // skip if both are java-defined, and
lowClass
.isNonBottomSubClass(highClass) || { // - low <:< high, which means they are overrides in Java and javac is doing the check; or
lowClass.isNonBottomSubClass(
highClass
) || { // - low <:< high, which means they are overrides in Java and javac is doing the check; or
base.info.parents.tail.forall {
p => // - every mixin parent is unrelated to (not a subclass of) low and high, i.e.,
val psym =
Expand Down
Loading