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

ModExt: move alt centrally from NewlineT #4583

Merged
merged 1 commit into from
Nov 23, 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 @@ -932,7 +932,7 @@ class FormatOps(
indentLen: Int,
extendsThenWith: => Boolean = false,
)(implicit fileLine: FileLine, ft: FT, style: ScalafmtConfig): Seq[Split] = {
val nlMod = NewlineT(alt = Some(Space))
val nlMod = Newline.withAlt(Space)
def nlPolicy(ignore: Boolean) = Policy ? (ignore || owners.isEmpty) ||
Policy.onRight(lastFt, prefix = "WITH") {
case d @ Decision(FT(_, _: T.KwWith, m), _) if owners(m.rightOwner) =>
Expand Down Expand Up @@ -1161,7 +1161,7 @@ class FormatOps(
style.newlines.forceAfterImplicitParamListModifier
val nlNoAlt = implicitNL ||
!rightIsImplicit && style.verticalMultiline.newlineAfterOpenParen
val nlMod = NewlineT(alt = if (nlNoAlt) None else Some(slbSplit.modExt))
val nlMod = Newline.withAltIf(!nlNoAlt)(slbSplit.modExt)
val spaceImplicit = !implicitNL && implicitParams.lengthCompare(1) > 0 &&
style.newlines.notBeforeImplicitParamListModifier
Seq(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,46 @@ package org.scalafmt.internal

import scala.meta.tokens.{Token => T}

import scala.language.implicitConversions
import scala.annotation.tailrec

/** @param mod
* Is this a space, no space, newline or 2 newlines?
* @param indents
* Does this add indentation?
*/
case class ModExt(mod: Modification, indents: Seq[Indent] = Seq.empty) {
lazy val indentation = indents.mkString("[", ", ", "]")

case class ModExt(
mod: Modification,
indents: Seq[Indent] = Nil,
altOpt: Option[ModExt] = None,
) {
@inline
def isNL: Boolean = mod.isNL

@tailrec
private def toString(prefix: String, indentPrefix: String): String = {
@inline
def res(suffix: String) = {
val ind = if (indents.isEmpty) "" else indents.mkString("[", ", ", "]")
s"$prefix$mod($indentPrefix$ind)$suffix"
}

altOpt match {
case None => res("")
case Some(x) => x.toString(res("|"), "+")
}
}

override def toString: String = toString("", "")

def withAlt(alt: ModExt): ModExt =
if (altOpt.contains(alt)) this else copy(altOpt = Some(alt))

@inline
def withAltIf(ok: Boolean)(alt: => ModExt): ModExt =
if (ok) withAlt(alt) else this

def orMod(flag: Boolean, mod: => ModExt): ModExt = if (flag) this else mod

def withIndent(length: => Length, expire: => FT, when: ExpiresOn): ModExt =
length match {
case Length.Num(0, _) => this
Expand Down Expand Up @@ -75,9 +102,3 @@ case class ModExt(mod: Modification, indents: Seq[Indent] = Seq.empty) {
.flatMap(_.withStateOffset(offset + mod.length))

}

object ModExt {

implicit def implicitModToModExt(mod: Modification): ModExt = ModExt(mod)

}
Original file line number Diff line number Diff line change
Expand Up @@ -34,25 +34,18 @@ case object NoSplit extends Modification {
* optional additional set of indents) if the newline will indent beyond the
* current column? For example, used by select chains in [[Router]].
*/
case class NewlineT(
isDouble: Boolean = false,
noIndent: Boolean = false,
alt: Option[ModExt] = None,
) extends Modification {
case class NewlineT(isDouble: Boolean = false, noIndent: Boolean = false)
extends Modification {
override def toString = {
val double = if (isDouble) "x2" else ""
val indent = if (noIndent) "[NoIndent]" else ""
val altStr = alt.fold("")(x => "|" + x.mod.toString)
"NL" + double + indent + altStr
"NL" + double + indent
}
override val newlines: Int = if (isDouble) 2 else 1
override val length: Int = 0
}

object Newline extends NewlineT {
def orMod(flag: Boolean, mod: => Modification): Modification =
if (flag) this else mod
}
object Newline extends NewlineT

object Newline2x extends NewlineT(isDouble = true) {
def apply(isDouble: Boolean): NewlineT = if (isDouble) this else Newline
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1474,11 +1474,11 @@ class Router(formatOps: FormatOps) {
val nlIndentLen =
if (nlClosedOnOpenEffective eq NlClosedOnOpen.Cfg) indentLen
else bpIndentLen
val nlMod =
if (nlOnly && noBreak() && right.is[T.Comment]) Space
else NewlineT(alt = if (singleLineOnly) Some(NoSplit) else None)
val nlMod = {
if (nlOnly && noBreak() && right.is[T.Comment]) Space.toExt
else Newline.withAltIf(singleLineOnly)(NoSplit)
}.withIndent(nlIndentLen, close, Before)
val nlSplit = Split(nlMod, bracketPenalty * (if (oneline) 4 else 2))
.withIndent(nlIndentLen, close, Before)
.withSingleLineNoOptimal(close, ignore = !singleLineOnly).andPolicy(
Policy ? singleLineOnly || nlPolicy & penalizeNewlinesPolicy,
).andPolicy(singleArgAsInfix.map(InfixSplits(_, ft).nlPolicy))
Expand Down Expand Up @@ -1850,7 +1850,7 @@ class Router(formatOps: FormatOps) {
if (ok) Some(nd) else None
}
val altIndent = endSelect.map(Indent(-indentLen, _, After))
NewlineT(alt = Some(ModExt(modSpace).withIndentOpt(altIndent)))
Newline.withAlt(modSpace.withIndentOpt(altIndent))
}

val prevChain = inSelectChain(prevSelect, thisSelect, expireTree)
Expand Down Expand Up @@ -1889,9 +1889,8 @@ class Router(formatOps: FormatOps) {
val nlCost = nlBaseCost + nestedPenalty + chainLengthPenalty
val nlMod = getNlMod
val legacySplit = Split(!prevChain, 1) { // must come first, for backwards compat
if (style.optIn.breaksInsideChains) Newline
.orMod(hasBreak(), modSpace)
else nlMod
if (!style.optIn.breaksInsideChains) nlMod
else Newline.orMod(hasBreak(), modSpace)
}.withPolicy(newlinePolicy).onlyFor(SplitTag.SelectChainSecondNL)
val slbSplit =
if (ignoreNoSplit) Split.ignored
Expand All @@ -1907,7 +1906,7 @@ class Router(formatOps: FormatOps) {
.withSingleLineNoOptimal(chainExpire, noSyntaxNL = true)
}
}.andPolicy(penalizeBreaks)
val nlSplit = Split(if (ignoreNoSplit) Newline else nlMod, nlCost)
val nlSplit = Split(Newline.orMod(ignoreNoSplit, nlMod), nlCost)
.withPolicy(newlinePolicy)
Seq(legacySplit, slbSplit, nlSplit)
} else {
Expand Down Expand Up @@ -1945,14 +1944,14 @@ class Router(formatOps: FormatOps) {
else Seq(
Split(nlOnly, 0)(modSpace)
.withSingleLine(expire, noSyntaxNL = true),
Split(NewlineT(alt = Some(modSpace)), nlCost)
Split(Newline.withAlt(modSpace), nlCost)
.withPolicy(forcedBreakOnNextDotPolicy),
)

case Newlines.fold =>
def nlSplitBase(cost: Int, policy: Policy = NoPolicy)(implicit
fileLine: FileLine,
) = Split(NewlineT(alt = Some(modSpace)), cost, policy = policy)
) = Split(Newline.withAlt(modSpace), cost, policy = policy)
if (nextDotIfSig.isEmpty)
if (nlOnly) Seq(nlSplitBase(0))
else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ case class Split(
import PolicyOps._

def withNoIndent: Split = mod match {
case x @ NewlineT(_, false, _) =>
case x: NewlineT if !x.noIndent =>
copy(modExt = modExt.copy(mod = x.copy(noIndent = true)))
case _ => this
}
Expand All @@ -70,9 +70,6 @@ case class Split(
@inline
def fileLine: FileLine = fileLineStack.fileLineLast

@inline
def indentation: String = modExt.indentation

@inline
def isNL: Boolean = modExt.isNL

Expand Down Expand Up @@ -318,7 +315,7 @@ case class Split(
else ""
}
val opt = optimalAt.fold("")(", opt=" + _)
s"""${prefix}c=$cost[$penalty] $mod:[$fileLineStack](indents=$indentation, $policy$opt)"""
s"""${prefix}c=$cost[$penalty] $modExt:[$fileLineStack]($policy$opt)"""
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ final class State(
if (right.is[T.EOF]) (initialNextSplit, 0, Seq.empty)
else {
val offset = column - indentation
def getUnexpired(modExt: ModExt, indents: Seq[ActualIndent] = Nil) = {
def getUnexpired(modExt: ModExt, indents: Seq[ActualIndent]) = {
val extendedEnd = getRelativeToLhsLastLineEnd(modExt.isNL)
(modExt.getActualIndents(offset) ++ indents).flatMap { x =>
if (x.notExpiredBy(tok)) Some(x)
Expand All @@ -80,19 +80,17 @@ final class State(
}

val initialModExt = initialNextSplit.modExt
val indents = initialModExt.indents
val nextPushes = getUnexpired(initialModExt, pushes)
val nextIndent = Indent.getIndent(nextPushes)
initialNextSplit.mod match {
case m: NewlineT
if !tok.left.is[T.Comment] && m.alt.isDefined &&
nextIndent >= m.alt.get.mod.length + column =>
val alt = m.alt.get
val altPushes = getUnexpired(alt)
val altIndent = Indent.getIndent(altPushes)
val split = initialNextSplit.withMod(alt.withIndents(indents))
(split, nextIndent + altIndent, nextPushes ++ altPushes)
case _ => (initialNextSplit, nextIndent, nextPushes)
initialModExt.altOpt.flatMap { alt =>
if (tok.left.is[T.Comment]) None
else if (nextIndent < alt.mod.length + column) None
else Some(alt.withIndents(initialModExt.indents))
}.fold((initialNextSplit, nextIndent, nextPushes)) { alt =>
val altPushes = getUnexpired(alt, pushes)
val altIndent = Indent.getIndent(altPushes)
val split = initialNextSplit.withMod(alt)
(split, altIndent, altPushes)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
package org.scalafmt

import scala.language.implicitConversions

package object internal {

private[scalafmt] type FT = FormatToken
private[scalafmt] val FT = FormatToken

private[scalafmt] implicit def implicitModToModExt(
mod: Modification,
): ModExt = ModExt(mod)

private[scalafmt] implicit class ImplicitModification(
private val mod: Modification,
) extends AnyVal {
def toExt: ModExt = mod
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ object LoggerOps {
s"d=${s.depth} w=${s.cost}[${s.appliedPenalty}] i=${s.indentation} col=${s
.column} #nl=${s.lineId}$policies;${delim}s=${log(s.split)}$nls"
}
def log(split: Split): String = s"$split"
def log(split: Split): String = split.toString

def log(formatToken: FT): String =
s"""|${log(formatToken.left)}
Expand Down