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

Split: switch ignoreIf to tag, allows more control #1737

Merged
merged 4 commits into from
Feb 24, 2020
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 @@ -196,6 +196,7 @@ private class BestFirstSearch private (
curr.policy
.execute(Decision(splitToken, splits))
.splits
.filter(_.isActive)
.sortBy(_.cost)
}
var optimalNotFound = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -946,9 +946,7 @@ class FormatOps(val tree: Tree, val initStyle: ScalafmtConfig) {
(style.verticalMultiline.newlineAfterOpenParen && !isImplicitArgList && isDefinition) ||
mixedParamsWithCtorModifier

val mod =
if (shouldAddNewline) Newline
else NoSplit
val mod = NoSplit.orNL(!shouldAddNewline)

Seq(
Split(mod, 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ case class Provided(code: String) extends Modification {

case object NoSplit extends Modification {
override val newlines: Int = 0
def orNL(flag: Boolean): Modification = if (flag) this else Newline
}

/**
Expand Down Expand Up @@ -51,5 +52,6 @@ object Space extends Modification {
override val newlines: Int = 0
override def toString = "Space"

def apply(flag: Boolean): Modification = if (flag) Space else NoSplit
def apply(flag: Boolean): Modification = if (flag) this else NoSplit
def orNL(flag: Boolean): Modification = if (flag) this else Newline
}
132 changes: 58 additions & 74 deletions scalafmt-core/shared/src/main/scala/org/scalafmt/internal/Router.scala
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,12 @@ class Router(formatOps: FormatOps) {
else penalizeAllNewlines(end, BreakSingleLineInterpolatedString)
Seq(
// statecolumn - 1 because of margin characters |
Split(NoSplit, 0, ignoreIf = !isStripMargin)
Split(NoSplit, 0)
.onlyIf(isStripMargin)
.withPolicy(policy)
.withIndent(StateColumn, end, Left)
.withIndent(-1, end, Left),
Split(NoSplit, 0, ignoreIf = isStripMargin).withPolicy(policy)
Split(NoSplit, 0).notIf(isStripMargin).withPolicy(policy)
)
case FormatToken(
T.Interpolation.Id(_) | T.Interpolation.Part(_) |
Expand Down Expand Up @@ -283,13 +284,12 @@ class Router(formatOps: FormatOps) {

Seq(
singleLineSplit,
Split(
Space,
0,
ignoreIf =
Split(Space, 0)
.notIf(
style.newlines.alwaysBeforeCurlyBraceLambdaParams ||
isSelfAnnotation || lambdaPolicy == null
).withOptimalToken(lambdaArrow)
)
.withOptimalTokenOpt(lambdaArrow)
.withIndent(lambdaIndent, close, Right)
.withPolicy(lambdaPolicy),
Split(nl, 1)
Expand Down Expand Up @@ -331,7 +331,8 @@ class Router(formatOps: FormatOps) {
if (isEmptyFunctionBody(leftOwner) && !right.is[T.Comment]) 0
else 2
val singleLineSplit =
Split(Space, 0, ignoreIf = hasSingleLineComment)
Split(Space, 0)
.notIf(hasSingleLineComment)
.withPolicy(SingleLineBlock(endOfFunction))
def newlineSplit =
Split(Newline, 1 + nestedApplies(leftOwner))
Expand Down Expand Up @@ -377,15 +378,9 @@ class Router(formatOps: FormatOps) {
)
case _ =>
Seq(
Split(
Space,
0,
ignoreIf = newlines != 0
), // Gets killed by `case` policy.
Split(
NewlineT(isDouble = false, noIndent = rhsIsCommentedOut(tok)),
1
)
// Gets killed by `case` policy.
Split(Space, 0).onlyIf(newlines == 0),
Split(NewlineT(noIndent = rhsIsCommentedOut(tok)), 1)
)
}
// New statement
Expand Down Expand Up @@ -424,7 +419,8 @@ class Router(formatOps: FormatOps) {
newlines == 0 && right.is[Keyword]
Seq(
// This split needs to have an optimalAt field.
Split(Space, 0, ignoreIf = !spaceCouldBeOk)
Split(Space, 0)
.onlyIf(spaceCouldBeOk)
.withOptimalToken(expire)
.withPolicy(SingleLineBlock(expire)),
// For some reason, this newline cannot cost 1.
Expand Down Expand Up @@ -523,17 +519,17 @@ class Router(formatOps: FormatOps) {
case _ =>
val rhsIsComment = isSingleLineComment(right)
Seq(
Split(
Space,
0,
ignoreIf = rhsIsComment || newlines > 0 && !rhsIsJsNative,
policy =
Split(Space, 0)
.notIf(rhsIsComment || newlines != 0 && !rhsIsJsNative)
.withPolicy(
if (!style.newlines.alwaysBeforeMultilineDef) NoPolicy
else SingleLineBlock(expire, exclude = exclude)
),
Split(Space, 0, ignoreIf = newlines != 0 || !rhsIsComment)
),
Split(Space, 0)
.onlyIf(newlines == 0 && rhsIsComment)
.withIndent(2, expire, Left),
Split(Newline, 1, ignoreIf = rhsIsJsNative)
Split(Newline, 1)
.notIf(rhsIsJsNative)
.withIndent(2, expire, Left)
)
}
Expand Down Expand Up @@ -581,7 +577,7 @@ class Router(formatOps: FormatOps) {
.onlyIf(noSplitMod != null)
.withOptimalToken(lambdaToken),
Split(Newline, newlinePenalty)
.withPolicy(newlinePolicy)
.withPolicyOpt(newlinePolicy)
.withIndent(style.continuationIndent.callSite, close, Right)
)
}
Expand Down Expand Up @@ -634,8 +630,7 @@ class Router(formatOps: FormatOps) {
if (isBracket)
penalizeAllNewlines(close, Constants.BracketPenalty * penalty + 3)
else NoPolicy
val bracketMultiplier =
if (isBracket) Constants.BracketPenalty else 1
val bracketCoef = if (isBracket) Constants.BracketPenalty else 1
val bracketPenalty = if (isBracket) 1 else 0
val nestingPenalty = nestedApplies(leftOwner)

Expand All @@ -655,14 +650,12 @@ class Router(formatOps: FormatOps) {
else NoSplit

Seq(
Split(noSplitModification, 0 + (nestingPenalty * bracketMultiplier))
Split(noSplitModification, 0 + (nestingPenalty * bracketCoef))
.withPolicy(noSplitPolicy)
.withIndent(indent, close, Left),
Split(
Newline,
(1 + nestingPenalty * nestingPenalty) * bracketMultiplier,
ignoreIf = right.is[T.RightParen]
).withPolicy(penalizeBrackets(1))
Split(Newline, (1 + nestingPenalty * nestingPenalty) * bracketCoef)
.notIf(right.is[T.RightParen])
.withPolicy(penalizeBrackets(1))
.withIndent(indent, close, Left)
)
}
Expand Down Expand Up @@ -694,7 +687,7 @@ class Router(formatOps: FormatOps) {
.andThen(unindent)
Seq(
Split(NoSplit, 0)
.withOptimalToken(optimal)
.withOptimalTokenOpt(optimal)
.withPolicy(noSplitPolicy)
.withIndent(indent, close, Left),
Split(Newline, 2)
Expand Down Expand Up @@ -769,10 +762,7 @@ class Router(formatOps: FormatOps) {

val oneArgOneLine = OneArgOneLineSplit(formatToken)

val newlineMod: Modification =
if (newlines == 0 && isSingleLineComment(right)) Space
else if (right.is[T.LeftBrace]) NoSplit
else Newline
val newlineMod: Modification = NoSplit.orNL(right.is[T.LeftBrace])

val defnSite = isDefnSite(leftOwner)
val closeFormatToken = tokens(close)
Expand Down Expand Up @@ -964,11 +954,7 @@ class Router(formatOps: FormatOps) {
case _ if isInfix =>
Seq(
// Do whatever the user did if infix.
Split(
if (newlines > 0) Newline
else Space,
0
)
Split(Space.orNL(newlines == 0), 0)
)
case _ =>
val indent = leftOwner match {
Expand All @@ -986,8 +972,9 @@ class Router(formatOps: FormatOps) {
}
}
Seq(
Split(Space, 0, ignoreIf = newlines != 0 && singleLineComment),
Split(Newline, 1, ignoreIf = noNewline)
Split(Space, 0).notIf(newlines != 0 && singleLineComment),
Split(Newline, 1)
.notIf(noNewline)
.withIndent(indent, right, ExpiresOn.Right)
)
}
Expand Down Expand Up @@ -1070,10 +1057,6 @@ class Router(formatOps: FormatOps) {
case _ => 0
}

val mod: Modification =
if (isAttachedSingleLineComment(formatToken)) Space
else Newline

val exclude =
insideBlock(formatToken, expire, _.isInstanceOf[T.LeftBrace])
rhs match {
Expand Down Expand Up @@ -1102,10 +1085,12 @@ class Router(formatOps: FormatOps) {
(!jsNative && newlines > 0 && leftOwner.isInstanceOf[Defn])
val spaceIndent = if (isSingleLineComment(right)) 2 else 0
Seq(
Split(Space, 0, policy = spacePolicy, ignoreIf = noSpace)
.withOptimalToken(optimal, killOnFail = false)
Split(Space, 0, policy = spacePolicy)
.notIf(noSpace)
.withOptimalToken(optimal)
.withIndent(spaceIndent, expire, Left),
Split(mod, 1 + penalty, ignoreIf = noNewline)
Split(Newline, 1 + penalty)
.notIf(noNewline)
.withIndent(2, expire, Left)
)
}
Expand All @@ -1126,10 +1111,9 @@ class Router(formatOps: FormatOps) {
val breakOnEveryDot = Policy(expire) {
case Decision(t @ FormatToken(_, _: T.Dot, _), _)
if chain.contains(t.meta.rightOwner) =>
val mod =
if (style.optIn.breaksInsideChains && t.newlinesBetween == 0)
NoSplit
else Newline
val mod = NoSplit.orNL(
style.optIn.breaksInsideChains && t.newlinesBetween == 0
)
Seq(Split(mod, 1))
}
val exclude = getExcludeIf(expire)
Expand Down Expand Up @@ -1162,7 +1146,8 @@ class Router(formatOps: FormatOps) {
}
} else 0
Seq(
Split(NoSplit, 0, ignoreIf = ignoreNoSplit)
Split(NoSplit, 0)
.notIf(ignoreNoSplit)
.withPolicy(noSplitPolicy),
Split(
Newline.copy(acceptNoSplit = true),
Expand Down Expand Up @@ -1311,24 +1296,19 @@ class Router(formatOps: FormatOps) {
case t: Term.ForYield => t.body.tokens.last
case t: Term.While => t.body.tokens.last
}
// Inline comment attached to closing RightParen
val attachedComment = isAttachedSingleLineComment(formatToken)
val newlineModification: Modification =
if (attachedComment)
Space // Inline comment will force newline later.
else Newline
val exclude =
insideBlock(formatToken, expire, _.is[T.LeftBrace]).map(parensRange)
Seq(
Split(Space, 0, ignoreIf = attachedComment || newlines > 0)
Split(Space, 0)
.notIf(isSingleLineComment(formatToken.right) || newlines != 0)
.withPolicy(SingleLineBlock(expire, exclude = exclude)),
Split(newlineModification, 1).withIndent(2, expire, Left)
Split(Newline, 1).withIndent(2, expire, Left)
)
case FormatToken(T.RightBrace(), T.KwElse(), _) =>
val nlOnly = style.newlines.alwaysBeforeElseAfterCurlyIf ||
!leftOwner.is[Term.Block] || !leftOwner.parent.forall(_ == rightOwner)
Seq(
Split(if (nlOnly) Newline else Space, 0)
Split(Space.orNL(!nlOnly), 0)
)

case FormatToken(T.RightBrace(), T.KwYield(), _) =>
Expand All @@ -1340,7 +1320,8 @@ class Router(formatOps: FormatOps) {
val exclude =
insideBlock(formatToken, expire, _.is[T.LeftBrace]).map(parensRange)
Seq(
Split(Space, 0, ignoreIf = newlines > 0)
Split(Space, 0)
.onlyIf(newlines == 0)
.withPolicy(SingleLineBlock(expire, exclude = exclude)),
Split(Newline, 1)
)
Expand All @@ -1351,7 +1332,8 @@ class Router(formatOps: FormatOps) {
}) =>
val expire = leftOwner.asInstanceOf[Term.If].elsep.tokens.last
Seq(
Split(Space, 0, ignoreIf = newlines != 0)
Split(Space, 0)
.onlyIf(newlines == 0)
.withPolicy(SingleLineBlock(expire)),
Split(Newline, 1).withIndent(2, expire, Left)
)
Expand Down Expand Up @@ -1382,10 +1364,12 @@ class Router(formatOps: FormatOps) {
case _ => Num(0)
}
Seq(
Split(Newline, 0, ignoreIf = !isConfig)
Split(Newline, 0)
.onlyIf(isConfig)
.withPolicy(breakOnClose)
.withIndent(style.continuationIndent.callSite, close, Right),
Split(NoSplit, 0, ignoreIf = isConfig)
Split(NoSplit, 0)
.notIf(isConfig)
.withIndent(indent, close, Left)
.withPolicy(penalizeAllNewlines(close, 1))
)
Expand Down Expand Up @@ -1489,7 +1473,7 @@ class Router(formatOps: FormatOps) {
if rightOwner.is[Enumerator.Guard] =>
Seq(
// Either everything fits in one line or break on =>
Split(Space, 0, ignoreIf = newlines > 0),
Split(Space, 0).onlyIf(newlines == 0),
Split(Newline, 1)
)
case tok @ FormatToken(arrow @ T.LeftArrow(), _, _)
Expand Down Expand Up @@ -1638,7 +1622,7 @@ class Router(formatOps: FormatOps) {
cache.getOrElseUpdate(
formatToken, {
val splits =
getSplits(formatToken).filter(!_.ignoreIf).map(_.adapt(formatToken))
getSplits(formatToken).filter(!_.isIgnored).map(_.adapt(formatToken))
formatToken match {
// TODO(olafur) refactor into "global policy"
// Only newlines after inline comments.
Expand Down
Loading