Skip to content

Commit

Permalink
Router: no break after => in lambda w/ type
Browse files Browse the repository at this point in the history
Otherwise, it looks like a "fewer braces" invocation and will be parsed
as such.
  • Loading branch information
kitbellew committed Nov 10, 2024
1 parent e9ac8b6 commit d3dc445
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ class Router(formatOps: FormatOps) {
else Some(false)
(arrow, 0, nlOnly)
case (t: Term.FunctionTerm) :: Nil =>
val arrow = getFuncArrow(lastLambda(t)).getOrElse(getLast(t))
val arrow = lastLambda(t).flatMap(getFuncArrow).getOrElse(getLast(t))
val nlOnly =
if (style.newlines.alwaysBeforeCurlyLambdaParams) Some(true)
else if (
Expand Down Expand Up @@ -527,27 +527,29 @@ class Router(formatOps: FormatOps) {
case _ => false
}) =>
val leftFunc = leftOwner.asInstanceOf[Term.FunctionTerm]
val (afterCurlySpace, afterCurlyNewlines) =
getSpaceAndNewlineAfterCurlyLambda(newlines)
def spaceSplitBase(implicit line: FileLine): Split = Split(Space, 0)
val spaceSplit = leftFunc.body match {
case _: Term.FunctionTerm => spaceSplitBase
case Term.Block((_: Term.FunctionTerm) :: Nil)
if !nextNonComment(ft).right.is[T.LeftBrace] => spaceSplitBase
case _ if afterCurlySpace && {
style.newlines.fold || !rightOwner.is[Defn]
} =>
val exp = nextNonCommentSameLine(getLastNonTrivial(leftFunc.body))
.left
spaceSplitBase.withSingleLine(exp, noSyntaxNL = true)
case _ => Split.ignored
}
val (endIndent, expiresOn) = functionExpire(leftFunc)
Seq(
spaceSplit,
Split(afterCurlyNewlines, 1)
.withIndent(style.indent.main, endIndent, expiresOn),
)
if (canBreakAfterFuncArrow(leftFunc)) {
val (afterCurlySpace, afterCurlyNewlines) =
getSpaceAndNewlineAfterCurlyLambda(newlines)
val spaceSplit = leftFunc.body match {
case _: Term.FunctionTerm => spaceSplitBase
case Term.Block((_: Term.FunctionTerm) :: Nil)
if !nextNonComment(ft).right.is[T.LeftBrace] => spaceSplitBase
case _ if afterCurlySpace && {
style.newlines.fold || !rightOwner.is[Defn]
} =>
val exp = nextNonCommentSameLine(getLastNonTrivial(leftFunc.body))
.left
spaceSplitBase.withSingleLine(exp, noSyntaxNL = true)
case _ => Split.ignored
}
val (endIndent, expiresOn) = functionExpire(leftFunc)
Seq(
spaceSplit,
Split(afterCurlyNewlines, 1)
.withIndent(style.indent.main, endIndent, expiresOn),
)
} else Seq(spaceSplitBase)

case FormatToken(_: T.RightArrow | _: T.ContextArrow, right, _)
if (leftOwner match {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -351,14 +351,36 @@ object TreeOps {
math.max(res, treeDepth(t))
}

final def canBreakAfterFuncArrow(func: Term.FunctionTerm)(implicit
ftoks: FormatTokens,
style: ScalafmtConfig,
): Boolean = !style.dialect.allowFewerBraces || {
val params = func.paramClause
params.values match {
case param :: Nil => param.decltpe match {
case Some(_: Type.Name) => ftoks.isEnclosedInMatching(params)
case _ => true
}
case _ => true
}
}

@tailrec
final def lastLambda(
first: Term.FunctionTerm,
)(implicit ftoks: FormatTokens): Term.FunctionTerm = first.body match {
case child: Term.FunctionTerm => lastLambda(child)
case b @ Term.Block((child: Term.FunctionTerm) :: Nil)
if !ftoks.getHead(b).left.is[Token.LeftBrace] => lastLambda(child)
case _ => first
res: Option[Term.FunctionTerm] = None,
)(implicit
ftoks: FormatTokens,
style: ScalafmtConfig,
): Option[Term.FunctionTerm] = {
val nextres = if (canBreakAfterFuncArrow(first)) Some(first) else res
first.body match {
case child: Term.FunctionTerm => lastLambda(child, nextres)
case b @ Term.Block((child: Term.FunctionTerm) :: Nil)
if !ftoks.getHead(b).left.is[Token.LeftBrace] =>
lastLambda(child, nextres)
case _ => nextres
}
}

@inline
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class CommunityScala3_2Suite extends CommunityScala3Suite("scala-3.2") {

class CommunityScala3_3Suite extends CommunityScala3Suite("scala-3.3") {

override protected def totalStatesVisited: Option[Int] = Some(34839832)
override protected def totalStatesVisited: Option[Int] = Some(34839737)

override protected def builds = Seq(getBuild("3.3.3", dialects.Scala33, 861))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7556,11 +7556,11 @@ object Build:
.settings(
generateScalaDocumentation := Def.inputTaskDyn {
val outputDirOverride =
extraArgs.headOption.fold(identity[GenerationConfig](_)) {
newDir => config: GenerationConfig => config.add(OutputDir(newDir))
extraArgs.headOption.fold(identity[GenerationConfig](_)) { newDir =>
config: GenerationConfig => config.add(OutputDir(newDir))
}
val justAPI = justAPIArg.fold(identity[GenerationConfig](_)) {
_ => config: GenerationConfig => config.remove[SiteRoot]
val justAPI = justAPIArg.fold(identity[GenerationConfig](_)) { _ =>
config: GenerationConfig => config.remove[SiteRoot]
}
}.evaluated
)
Original file line number Diff line number Diff line change
Expand Up @@ -7264,15 +7264,14 @@ object Build {
)
}
>>>
Idempotency violated
=> Diff (- obtained, + expected)
}
- val justAPI = justAPIArg.fold(identity[GenerationConfig](_)) { _ =>
- config: GenerationConfig =>
- config.remove[SiteRoot]
- }
+ val justAPI = justAPIArg
+ .fold(identity[GenerationConfig](_)) { _ => config: GenerationConfig =>
+ config.remove[SiteRoot]
+ }
}.evaluated)
object Build:
lazy val scaladoc = project.in(file("scaladoc"))
.settings(generateScalaDocumentation := Def.inputTaskDyn {
val outputDirOverride = extraArgs.headOption
.fold(identity[GenerationConfig](_)) { newDir =>
config: GenerationConfig => config.add(OutputDir(newDir))
}
val justAPI = justAPIArg.fold(identity[GenerationConfig](_)) { _ =>
config: GenerationConfig => config.remove[SiteRoot]
}
}.evaluated)
Original file line number Diff line number Diff line change
Expand Up @@ -7584,11 +7584,11 @@ object Build:
settings(
generateScalaDocumentation := Def.inputTaskDyn {
val outputDirOverride =
extraArgs.headOption.fold(identity[GenerationConfig](_)) {
newDir => config: GenerationConfig => config.add(OutputDir(newDir))
extraArgs.headOption.fold(identity[GenerationConfig](_)) { newDir =>
config: GenerationConfig => config.add(OutputDir(newDir))
}
val justAPI = justAPIArg.fold(identity[GenerationConfig](_)) {
_ => config: GenerationConfig => config.remove[SiteRoot]
val justAPI = justAPIArg.fold(identity[GenerationConfig](_)) { _ =>
config: GenerationConfig => config.remove[SiteRoot]
}
}.evaluated
)
Original file line number Diff line number Diff line change
Expand Up @@ -7859,21 +7859,23 @@ object Build {
)
}
>>>
Idempotency violated
=> Diff (- obtained, + expected)
.headOption
- .fold(identity[GenerationConfig](_)) { newDir =>
- config: GenerationConfig =>
- config.add(OutputDir(newDir))
+ .fold(identity[GenerationConfig](_)) {
+ newDir => config: GenerationConfig =>
+ config.add(OutputDir(newDir))
}
val justAPI =
- justAPIArg.fold(identity[GenerationConfig](_)) { _ =>
- config: GenerationConfig =>
- config.remove[SiteRoot]
+ justAPIArg.fold(identity[GenerationConfig](_)) {
+ _ => config: GenerationConfig =>
+ config.remove[SiteRoot]
}
object Build:
lazy val scaladoc = project
.in(file("scaladoc"))
.settings(
generateScalaDocumentation :=
Def
.inputTaskDyn {
val outputDirOverride =
extraArgs
.headOption
.fold(identity[GenerationConfig](_)) { newDir =>
config: GenerationConfig => config.add(OutputDir(newDir))
}
val justAPI =
justAPIArg.fold(identity[GenerationConfig](_)) { _ =>
config: GenerationConfig => config.remove[SiteRoot]
}
}
.evaluated
)
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ class FormatTests extends FunSuite with CanRunTests with FormatAssertions {
val explored = Debug.explored.get()
logger.debug(s"Total explored: $explored")
if (!onlyUnit && !onlyManual)
assertEquals(explored, 1119018, "total explored")
assertEquals(explored, 1116417, "total explored")
val results = debugResults.result()
// TODO(olafur) don't block printing out test results.
// I don't want to deal with scalaz's Tasks :'(
Expand Down

0 comments on commit d3dc445

Please sign in to comment.