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

Spaces: add new IfMultipleContextBounds label #4726

Merged
merged 1 commit into from
Jan 17, 2025
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
16 changes: 16 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -4672,6 +4672,12 @@ The parameter also allows the following shortcuts:

### `spaces.beforeContextBoundColon`

This parameter controls if a space should be used before a colon that precedes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need a separate setting here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i am planning to use this same set of values for spaces within braces, and it makes little sense to add those spaces after looking at some other bound which is not within those braces. or to add a completely new set of values which are likely named the same but carry a slightly different meaning. just for consistency.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, thanks for explaining!

type context bounds and takes values 'never', 'always', 'ifMultipleBounds', and
'ifMultipleContextBounds'. The difference between the latter two is: the first
considers all bounds (including subtype and supertype), whereas the second only
the context bounds.

```scala mdoc:defaults
spaces.beforeContextBoundColon
```
Expand All @@ -4698,6 +4704,16 @@ spaces.beforeContextBoundColon=IfMultipleBounds
def method[A: Bound]: B
def method[A : Bound]: B
def method[A: Bound: Bound2]: B
def method[A <: Bound: Bound2]: B
```

```scala mdoc:scalafmt
spaces.beforeContextBoundColon=IfMultipleContextBounds
---
def method[A: Bound]: B
def method[A : Bound]: B
def method[A: Bound: Bound2]: B
def method[A <: Bound: Bound2]: B
```

### `spaces.inImportCurlyBraces`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package org.scalafmt.config

import org.scalafmt.util.TokenOps

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

import metaconfig._
Expand Down Expand Up @@ -85,17 +86,34 @@ object Spaces {
implicit lazy val codec: ConfCodecEx[Spaces] = generic.deriveCodecEx(Spaces())
.noTypos

sealed abstract class BeforeContextBound
sealed abstract class BeforeContextBound {
def apply(tb: Type.Bounds): Boolean
}
object BeforeContextBound {
implicit val codec: ConfCodecEx[BeforeContextBound] = ReaderUtil
.oneOfCustom[BeforeContextBound](Always, Never, IfMultipleBounds) {
.oneOfCustom[BeforeContextBound](
Always,
Never,
IfMultipleBounds,
IfMultipleContextBounds,
) {
case Conf.Bool(true) => Configured.ok(Always)
case Conf.Bool(false) => Configured.ok(Never)
}

case object Always extends BeforeContextBound
case object Never extends BeforeContextBound
case object IfMultipleBounds extends BeforeContextBound
case object Always extends BeforeContextBound {
def apply(tb: Type.Bounds): Boolean = true
}
case object Never extends BeforeContextBound {
def apply(tb: Type.Bounds): Boolean = false
}
case object IfMultipleBounds extends BeforeContextBound {
def apply(tb: Type.Bounds): Boolean =
tb.context.length + tb.view.length + tb.lo.size + tb.hi.size > 1
}
case object IfMultipleContextBounds extends BeforeContextBound {
def apply(tb: Type.Bounds): Boolean = tb.context.lengthCompare(1) > 0
}
}

sealed abstract class AfterColonInMatchPattern
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import org.scalafmt.config.ImportSelectors
import org.scalafmt.config.Indents
import org.scalafmt.config.Newlines
import org.scalafmt.config.ScalafmtConfig
import org.scalafmt.config.Spaces
import org.scalafmt.internal.ExpiresOn.After
import org.scalafmt.internal.ExpiresOn.Before
import org.scalafmt.internal.Length.StateColumn
Expand Down Expand Up @@ -1762,12 +1761,7 @@ class Router(formatOps: FormatOps) {
*/

case FT(_, _: T.Colon, FT.RightOwner(tp: Type.Bounds)) =>
def noNLMod = Space(style.spaces.beforeContextBoundColon match {
case Spaces.BeforeContextBound.Always => true
case Spaces.BeforeContextBound.IfMultipleBounds => 1 <
tp.context.length + tp.view.length + tp.lo.size + tp.hi.size
case _ => false
})
def noNLMod = Space(style.spaces.beforeContextBoundColon(tp))
getSplitsForTypeBounds(noNLMod, tp, tp.context)
case FT(_, _: T.Viewbound, FT.RightOwner(tp: Type.Bounds)) =>
getSplitsForTypeBounds(Space, tp, tp.view)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,26 @@ def myMethod[F[_]: Functor](): Foo
<<< space before colon with subtype bound #1391
final class Test[A <: B: ClassTag]
>>>
final class Test[A <: B : ClassTag]
final class Test[A <: B : ClassTag]
<<< single or multiple context bounds, ifMultipleBounds
runner.parser = source
spaces.beforeContextBoundColon = ifMultipleBounds
===
final class Test[B: ClassTag]
final class Test[A <: B: ClassTag]
final class Test[A <: B: ClassTag: Seq]
>>>
final class Test[B: ClassTag]
final class Test[A <: B : ClassTag]
final class Test[A <: B : ClassTag : Seq]
<<< single or multiple context bounds, ifMultipleContextBounds
runner.parser = source
spaces.beforeContextBoundColon = ifMultipleContextBounds
===
final class Test[B: ClassTag]
final class Test[A <: B: ClassTag]
final class Test[A <: B: ClassTag: Seq]
>>>
final class Test[B: ClassTag]
final class Test[A <: B: ClassTag]
final class Test[A <: B : ClassTag : Seq]
Original file line number Diff line number Diff line change
Expand Up @@ -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, 1256164, "total explored")
assertEquals(explored, 1256300, "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
Loading