From 2d14af977b5522beda95264659ba1c1a0c5d21cf Mon Sep 17 00:00:00 2001 From: Albert Meltzer <7529386+kitbellew@users.noreply.github.com> Date: Thu, 16 Jan 2025 08:54:41 -0800 Subject: [PATCH] Router: break before `=>` in new given Apparently, break after forces an indented region and fails to compile. --- .../org/scalafmt/internal/FormatOps.scala | 4 +++- .../scala/org/scalafmt/internal/Router.scala | 18 +++++++-------- .../test/resources/scala3/OptionalBraces.stat | 22 +++++++++---------- .../resources/scala3/OptionalBraces_fold.stat | 16 +++++++------- .../resources/scala3/OptionalBraces_keep.stat | 22 +++++++++---------- .../scala3/OptionalBraces_unfold.stat | 22 ++++++++++++------- .../test/scala/org/scalafmt/FormatTests.scala | 2 +- 7 files changed, 57 insertions(+), 49 deletions(-) diff --git a/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/FormatOps.scala b/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/FormatOps.scala index ed2cc5ec7b..c6e01b5f58 100644 --- a/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/FormatOps.scala +++ b/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/FormatOps.scala @@ -65,10 +65,12 @@ class FormatOps( final def getSlbEndOnLeft(start: FT)(implicit style: ScalafmtConfig): FT = { val nft = start.right match { case _: T.EOF => start - case _: T.Comma | _: T.Semicolon | _: T.RightArrow | _: T.Equals | + case _: T.Comma | _: T.Semicolon | _: T.Equals | _: T.Interpolation.Start | _: T.Interpolation.SpliceEnd | _: T.Interpolation.End | _: T.Interpolation.SpliceStart | _: T.Interpolation.Part => null + case _: T.RightArrow => // given breaks before `=>` + if (start.rightOwner.is[Member.ParamClauseGroup]) start else null case _ if start.hasBlankLine => start case _ if AsInfixOp(start.rightOwner) diff --git a/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/Router.scala b/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/Router.scala index ae95ebeb2b..406cd95e5e 100644 --- a/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/Router.scala +++ b/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/Router.scala @@ -630,9 +630,9 @@ class Router(formatOps: FormatOps) { if (pcg.tparamClause.values.isEmpty) pcg.paramClauses else pcg.tparamClause +: pcg.paramClauses, ).foldLeft(Policy.noPolicy) { case (policy, pc) => - val pcLast = getLast(pc) - val pcPolicy = Policy ? pcLast.left.is[T.RightArrow] && - decideNewlinesOnlyAfterToken(nextNonCommentSameLine(pcLast)) + val afterpc = tokenAfter(pc) + val pcPolicy = Policy ? afterpc.right.is[T.RightArrow] && + decideNewlinesOnlyAfterToken(afterpc) policy ==> pcPolicy } if (nonSlbPolicy.isEmpty) Seq(Split(Space, 0)) @@ -645,16 +645,17 @@ class Router(formatOps: FormatOps) { // Given conditional arrow case FT( - left: T.RightArrow, _, - FT.LeftOwnerParent( + right: T.RightArrow, + FT.RightOwnerParent( pcg: Member.ParamClauseGroup, Some(gvn: Stat.GivenLike), ), ) => val nlOnly = !style.newlines.sourceIgnored && hasBreak() def spaceSplit(implicit fl: FileLine) = Split(nlOnly, 0)(Space) - val nextParamClause = pcg.paramClauses.find(_.pos.start > left.start) + val nextParamClause = (pcg.tparamClause +: pcg.paramClauses) + .find(_.pos.end > right.end) .orElse(gvn.paramClauseGroups.dropWhile(_ ne pcg) match { case `pcg` :: pcgNext :: _ => val tpc = pcgNext.tparamClause @@ -690,13 +691,12 @@ class Router(formatOps: FormatOps) { ) } } { npc => - val nextArrow = - getSlbEndOnLeft(nextAfterNonCommentSameLine(getLast(npc))) + val nextArrow = getSlbEndOnLeft(nextNonCommentSameLine(getLast(npc))) val noSlb = npc.values.lengthCompare(1) != 0 Seq( spaceSplit.withSingleLine(nextArrow, ignore = noSlb), Split(Newline, 1) - .withIndent(style.indent.main, nextArrow, ExpiresOn.After), + .withIndent(style.indent.main, nextArrow, ExpiresOn.Before), ) } diff --git a/scalafmt-tests/shared/src/test/resources/scala3/OptionalBraces.stat b/scalafmt-tests/shared/src/test/resources/scala3/OptionalBraces.stat index c734513457..92c0fdabae 100644 --- a/scalafmt-tests/shared/src/test/resources/scala3/OptionalBraces.stat +++ b/scalafmt-tests/shared/src/test/resources/scala3/OptionalBraces.stat @@ -7974,9 +7974,9 @@ given [A] => given [A] => Seq[A] = foo >>> -given [A] => - Seq[A] = foo given [A] => Seq[A] = foo +given [A] + => Seq[A] = foo <<< scala-3.6 given 2 maxColumn = 40 runner.parser = source @@ -7986,10 +7986,10 @@ given [A] => (Seq[A] => given [A] => (Seq[A] => List[A]) => List[A] = foo >>> -given [A] => (Seq[A] => List[A]) => - List[A] = foo -given [A] => (Seq[A] => List[A]) => - List[A] = foo +given [A] => (Seq[A] => List[A]) + => List[A] = foo +given [A] => (Seq[A] => List[A]) + => List[A] = foo <<< scala-3.6 given 3 maxColumn = 40 runner.parser = source @@ -7999,11 +7999,11 @@ given foo: (a: A) => given foo: (a: A) => [B, C <: AnyRef] => (b: B[A], C) => List[A] = foo >>> -given foo: (a: A) => - [B, C <: AnyRef] => (b: B[A], C) => - List[A] = foo -given foo: (a: A) => [B, C <: AnyRef] => - (b: B[A], C) => List[A] = foo +given foo: (a: A) => [B, C <: AnyRef] + => (b: B[A], C) => List[A] = foo +given foo: (a: A) + => [B, C <: AnyRef] => (b: B[A], C) + => List[A] = foo <<< don't rewrite complex infix to braces rewrite.redundantBraces.oneStatApply.bracesMinSpan = 1 rewrite.rules = [RedundantBraces, RedundantParens] diff --git a/scalafmt-tests/shared/src/test/resources/scala3/OptionalBraces_fold.stat b/scalafmt-tests/shared/src/test/resources/scala3/OptionalBraces_fold.stat index e0936afea4..82bab677da 100644 --- a/scalafmt-tests/shared/src/test/resources/scala3/OptionalBraces_fold.stat +++ b/scalafmt-tests/shared/src/test/resources/scala3/OptionalBraces_fold.stat @@ -7665,10 +7665,10 @@ given [A] => (Seq[A] => given [A] => (Seq[A] => List[A]) => List[A] = foo >>> -given [A] => (Seq[A] => List[A]) => - List[A] = foo -given [A] => (Seq[A] => List[A]) => - List[A] = foo +given [A] => (Seq[A] => List[A]) + => List[A] = foo +given [A] => (Seq[A] => List[A]) + => List[A] = foo <<< scala-3.6 given 3 maxColumn = 40 runner.parser = source @@ -7678,10 +7678,10 @@ given foo: (a: A) => given foo: (a: A) => [B, C <: AnyRef] => (b: B[A], C) => List[A] = foo >>> -given foo: (a: A) => [B, C <: AnyRef] => - (b: B[A], C) => List[A] = foo -given foo: (a: A) => [B, C <: AnyRef] => - (b: B[A], C) => List[A] = foo +given foo: (a: A) => [B, C <: AnyRef] + => (b: B[A], C) => List[A] = foo +given foo: (a: A) => [B, C <: AnyRef] + => (b: B[A], C) => List[A] = foo <<< don't rewrite complex infix to braces rewrite.redundantBraces.oneStatApply.bracesMinSpan = 1 rewrite.rules = [RedundantBraces, RedundantParens] diff --git a/scalafmt-tests/shared/src/test/resources/scala3/OptionalBraces_keep.stat b/scalafmt-tests/shared/src/test/resources/scala3/OptionalBraces_keep.stat index 9b43c04db4..9069b5ffcb 100644 --- a/scalafmt-tests/shared/src/test/resources/scala3/OptionalBraces_keep.stat +++ b/scalafmt-tests/shared/src/test/resources/scala3/OptionalBraces_keep.stat @@ -7997,9 +7997,9 @@ given [A] => given [A] => Seq[A] = foo >>> -given [A] => - Seq[A] = foo given [A] => Seq[A] = foo +given [A] + => Seq[A] = foo <<< scala-3.6 given 2 maxColumn = 40 runner.parser = source @@ -8009,10 +8009,10 @@ given [A] => (Seq[A] => given [A] => (Seq[A] => List[A]) => List[A] = foo >>> -given [A] => (Seq[A] => List[A]) => - List[A] = foo -given [A] => (Seq[A] => List[A]) => - List[A] = foo +given [A] => (Seq[A] => List[A]) + => List[A] = foo +given [A] => (Seq[A] => List[A]) + => List[A] = foo <<< scala-3.6 given 3 maxColumn = 40 runner.parser = source @@ -8022,11 +8022,11 @@ given foo: (a: A) => given foo: (a: A) => [B, C <: AnyRef] => (b: B[A], C) => List[A] = foo >>> -given foo: (a: A) => - [B, C <: AnyRef] => (b: B[A], C) => - List[A] = foo -given foo: (a: A) => [B, C <: AnyRef] => - (b: B[A], C) => List[A] = foo +given foo: (a: A) => [B, C <: AnyRef] + => (b: B[A], C) => List[A] = foo +given foo: (a: A) + => [B, C <: AnyRef] => (b: B[A], C) + => List[A] = foo <<< don't rewrite complex infix to braces rewrite.redundantBraces.oneStatApply.bracesMinSpan = 1 rewrite.rules = [RedundantBraces, RedundantParens] diff --git a/scalafmt-tests/shared/src/test/resources/scala3/OptionalBraces_unfold.stat b/scalafmt-tests/shared/src/test/resources/scala3/OptionalBraces_unfold.stat index d9a9cf43e8..c3525578ed 100644 --- a/scalafmt-tests/shared/src/test/resources/scala3/OptionalBraces_unfold.stat +++ b/scalafmt-tests/shared/src/test/resources/scala3/OptionalBraces_unfold.stat @@ -8306,10 +8306,12 @@ given [A] => (Seq[A] => given [A] => (Seq[A] => List[A]) => List[A] = foo >>> -given [A] => (Seq[A] => List[A]) => - List[A] = foo -given [A] => (Seq[A] => List[A]) => - List[A] = foo +given [A] + => (Seq[A] => List[A]) + => List[A] = foo +given [A] + => (Seq[A] => List[A]) + => List[A] = foo <<< scala-3.6 given 3 maxColumn = 40 runner.parser = source @@ -8319,10 +8321,14 @@ given foo: (a: A) => given foo: (a: A) => [B, C <: AnyRef] => (b: B[A], C) => List[A] = foo >>> -given foo: (a: A) => [B, C <: AnyRef] => - (b: B[A], C) => List[A] = foo -given foo: (a: A) => [B, C <: AnyRef] => - (b: B[A], C) => List[A] = foo +given foo: (a: A) + => [B, C <: AnyRef] + => (b: B[A], C) + => List[A] = foo +given foo: (a: A) + => [B, C <: AnyRef] + => (b: B[A], C) + => List[A] = foo <<< don't rewrite complex infix to braces rewrite.redundantBraces.oneStatApply.bracesMinSpan = 1 rewrite.rules = [RedundantBraces, RedundantParens] diff --git a/scalafmt-tests/shared/src/test/scala/org/scalafmt/FormatTests.scala b/scalafmt-tests/shared/src/test/scala/org/scalafmt/FormatTests.scala index 56b13f408e..b6a2eb9584 100644 --- a/scalafmt-tests/shared/src/test/scala/org/scalafmt/FormatTests.scala +++ b/scalafmt-tests/shared/src/test/scala/org/scalafmt/FormatTests.scala @@ -144,7 +144,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, 1253729, "total explored") + assertEquals(explored, 1253916, "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 :'(