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: consolidate splits around lambda #4363

Merged
merged 1 commit into from
Sep 29, 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 @@ -257,7 +257,7 @@ class Router(formatOps: FormatOps) {
)

// lambdaNLOnly: None for single line only
val (lambdaExpire, lambdaArrow, lambdaIndent, lambdaNLOnly) =
val (lambdaExpire, lambdaIndent, lambdaNLOnly) =
statementStarts.get(m.idx + 1) match {
case Some(owner: Term.FunctionTerm) if (leftOwner match {
case t: Template.Body => hasSingleElement(t, owner) &&
Expand All @@ -273,7 +273,7 @@ class Router(formatOps: FormatOps) {
Newlines.BeforeCurlyLambdaParams.multiline
) None
else Some(false)
(expire, arrow.map(_.left), 0, nlOnly)
(expire, 0, nlOnly)
case Some(t: Case)
if t.cond.isEmpty &&
(leftOwner match {
Expand All @@ -295,23 +295,16 @@ class Router(formatOps: FormatOps) {
Newlines.BeforeCurlyLambdaParams.never
) None
else Some(false)
(arrow, Some(arrow.left), 0, nlOnly)
(arrow, 0, nlOnly)
case _ =>
val annoOpt = selfAnnotationLast.map { anno =>
val indent = style.indent.main
val annoFT = tokens(anno)
val arrow = annoFT.left.is[T.RightArrow]
val expire = if (arrow) annoFT else nextAfterNonComment(annoFT)
(expire, Some(expire.left), indent, Some(isSelfAnnotationNL))
(expire, indent, Some(isSelfAnnotationNL))
}
annoOpt.getOrElse((null, None, 0, None))
}
val lambdaPolicy =
if (lambdaExpire == null) null
else {
val arrowOptimal = getOptimalTokenFor(lambdaExpire)
newlineBeforeClosingCurly & SingleLineBlock(arrowOptimal) &
decideNewlinesOnlyAfterToken(arrowOptimal)
annoOpt.getOrElse((null, 0, None))
}

def getSingleLinePolicy = {
Expand Down Expand Up @@ -365,11 +358,11 @@ class Router(formatOps: FormatOps) {

// do not fold top-level blocks
if (isTopLevelBlock) None
else if (lambdaPolicy != null) getSingleLineLambdaDecisionOpt
else if (lambdaExpire != null) getSingleLineLambdaDecisionOpt
else Some(false)
// old behaviour
case _ =>
if (lambdaPolicy == null) getClassicSingleLineDecisionOpt
if (lambdaExpire == null) getClassicSingleLineDecisionOpt
else getSingleLineLambdaDecisionOpt
}

Expand Down Expand Up @@ -404,15 +397,23 @@ class Router(formatOps: FormatOps) {
.andPolicy(sldPolicy)
}

val splits = Seq(
singleLineSplit,
Split(nl, 1).withPolicy(newlineBeforeClosingCurly)
.withIndent(style.indent.main, close, Before),
Split(style.newlines.keepBreak(newlines), 0)(Space)
.onlyIf(lambdaNLOnly.contains(false) && lambdaPolicy != null)
.withOptimalTokenOpt(lambdaArrow)
.withIndent(lambdaIndent, close, Before).withPolicy(lambdaPolicy),
)
val nlSplit = Split(nl, 1).withPolicy(newlineBeforeClosingCurly)
.withIndent(style.indent.main, close, Before)

// must be after nlSplit
val noLambdaSplit = style.newlines.keepBreak(newlines) ||
lambdaExpire == null || !lambdaNLOnly.contains(false)
val lambdaSplit =
if (noLambdaSplit) Split.ignored
else {
val arrowOptimal = getOptimalTokenFor(lambdaExpire)
val policy = newlineBeforeClosingCurly &
decideNewlinesOnlyAfterToken(arrowOptimal)
Split(Space, 0).withSingleLine(arrowOptimal).andPolicy(policy)
.withIndent(lambdaIndent, close, Before)
}

val splits = Seq(singleLineSplit, lambdaSplit, nlSplit)
right match {
case t: T.Xml.Start => withIndentOnXmlStart(t, splits)
case _ => splits
Expand Down Expand Up @@ -490,32 +491,26 @@ class Router(formatOps: FormatOps) {
case Newlines.classic => isCurlyLambda && hasBreak() && noSquash
}
}
val singleLineSplit = Split(Space, 0)
.notIf(hasSingleLineComment || noSingleLine)
.withSingleLineNoOptimal(endOfFunction)
def newlineSplit = Split(Newline, 1 + nestedApplies(leftOwner))
.withIndent(indent, endOfFunction, expiresOn)
val multiLineSplits =
if (hasSingleLineComment) Seq(newlineSplit)
else {
// 2020-01: break after same-line comments, and any open brace
val nonComment = nextNonCommentSameLine(ft)
val hasBlock = nonComment.right.is[T.LeftBrace] &&
(matching(nonComment.right) eq endOfFunction)
if (!hasBlock && (nonComment eq ft)) Seq(newlineSplit)
else {
def newlineSplit(implicit fileLine: FileLine) =
Split(Newline, 1 + nestedApplies(leftOwner))
.withIndent(indent, endOfFunction, expiresOn)
if (hasSingleLineComment) Seq(newlineSplit)
else {
// 2020-01: break after same-line comments, and any open brace
val nonComment = nextNonCommentSameLine(ft)
val hasBlock = nonComment.right.is[T.LeftBrace] &&
(matching(nonComment.right) eq endOfFunction)
val noSplit =
if (!hasBlock && (nonComment eq ft)) Split(noSingleLine, 0)(Space)
.withSingleLine(endOfFunction)
else
// break after the brace or comment if fits, or now if doesn't
// if brace, don't add indent, the LeftBrace rule will do that
val spaceIndent = if (hasBlock) 0 else indent
Seq(
Split(Space, 0)
.withIndent(spaceIndent, endOfFunction, expiresOn)
.withOptimalToken(getOptimalTokenFor(next(nonComment))),
newlineSplit,
)
}
}
singleLineSplit +: multiLineSplits
Split(Space, 0)
.withIndent(indent, endOfFunction, expiresOn, hasBlock)
.withOptimalToken(getOptimalTokenFor(next(nonComment)))
Seq(noSplit, newlineSplit)
}

// Case arrow
case FormatToken(_: T.RightArrow, rt, _)
Expand Down Expand Up @@ -824,8 +819,8 @@ class Router(formatOps: FormatOps) {
val noMultiline = style.newlines.beforeCurlyLambdaParams eq
Newlines.BeforeCurlyLambdaParams.multiline
Seq(
Split(noSplitMod, 0).withSingleLine(close),
if (noMultiline) Split.ignored else multilineSpaceSplit,
if (noMultiline) Split(noSplitMod, 0).withSingleLine(close)
else multilineSpaceSplit,
Split(Newline, newlinePenalty, policy = newlinePolicy)
.withIndent(style.indent.callSite, close, Before),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,14 @@ case class Split(
else copy(penalty = this.penalty + penalty)

def withIndent(length: => Length, expire: => Token, when: ExpiresOn): Split =
withMod(modExt.withIndent(length, expire, when))
withIndent(length, expire, when, ignore = false)

def withIndent(
length: => Length,
expire: => Token,
when: ExpiresOn,
ignore: Boolean,
): Split = withMod(modExt.withIndent(length, expire, when), ignore)

def withIndentOpt(
length: => Length,
Expand Down
Loading