From 537baef8c1646de2e2330fd6aa1a92b2284ac89a Mon Sep 17 00:00:00 2001 From: Albert Meltzer <7529386+kitbellew@users.noreply.github.com> Date: Wed, 20 Nov 2024 23:19:53 -0800 Subject: [PATCH 1/2] Test `into`, pure functions, capture checking --- .../test/resources/scala3/OptionalBraces.stat | 144 +++++++++++++++ .../resources/scala3/OptionalBraces_fold.stat | 144 +++++++++++++++ .../resources/scala3/OptionalBraces_keep.stat | 144 +++++++++++++++ .../scala3/OptionalBraces_unfold.stat | 165 ++++++++++++++++++ .../test/scala/org/scalafmt/FormatTests.scala | 2 +- 5 files changed, 598 insertions(+), 1 deletion(-) diff --git a/scalafmt-tests/shared/src/test/resources/scala3/OptionalBraces.stat b/scalafmt-tests/shared/src/test/resources/scala3/OptionalBraces.stat index 703f0ad39e..c5dc75ea58 100644 --- a/scalafmt-tests/shared/src/test/resources/scala3/OptionalBraces.stat +++ b/scalafmt-tests/shared/src/test/resources/scala3/OptionalBraces.stat @@ -7696,3 +7696,147 @@ object a: b.c match case d if e => f // comment +<<< implicit parameter type conversion with "into" modifier 1 +runner.dialect = scala3future +=== +object a: + def ++ (elems: into IterableOnce[A]): List[A] +>>> +object a: + def ++(elems: into IterableOnce[A]): List[A] +<<< implicit parameter type conversion with "into" modifier 2 +runner.dialect = scala3future +=== +object a: + def ++ (elems: => into IterableOnce[A]): List[A] +>>> +object a: + def ++(elems: => into IterableOnce[A]): List[A] +<<< implicit parameter type conversion with "into" modifier 3 +runner.dialect = scala3future +=== +object a: + def flatMap[B](f: into A => IterableOnce[B]): List[B] +>>> +object a: + def flatMap[B](f: into A => IterableOnce[B]): List[B] +<<< implicit parameter type conversion with "into" modifier 4 +runner.dialect = scala3future +=== +object a: + def flatMap[B](f: A => into IterableOnce[B]): List[B] +>>> +object a: + def flatMap[B](f: A => into IterableOnce[B]): List[B] +<<< implicit parameter type conversion with "into" modifier 5 +runner.dialect = scala3future +=== +object a: + def concatAll(xss: (into IterableOnce[Char])*): List[Char] +>>> +object a: + def concatAll(xss: (into IterableOnce[Char])*): List[Char] +<<< pure type functions 1 +runner.dialect = scala3future +=== +object a: + val func: A -> B = foo +>>> +object a: + val func: A -> B = foo +<<< pure type functions 2 +runner.dialect = scala3future +=== +object a: + def func(f: A -> B): Unit +>>> +object a: + def func(f: A -> B): Unit +<<< pure type functions 3 +runner.dialect = scala3future +=== +object a: + def map[T <: (A -> B)](f: T): A -> B = ??? +>>> +object a: + def map[T <: (A -> B)](f: T): A -> B = ??? +<<< pure type functions 4 +runner.dialect = scala3future +=== +object a: + val func: A ?-> B = foo +>>> +object a: + val func: A ?-> B = foo +<<< pure type functions 5 +runner.dialect = scala3future +=== +object a: + def func(f: A ?-> B): Unit +>>> +object a: + def func(f: A ?-> B): Unit +<<< pure type functions 6 +runner.dialect = scala3future +=== +object a: + def map[T <: (A ?-> B)](f: T): A ?-> B = ??? +>>> +object a: + def map[T <: (A ?-> B)](f: T): A ?-> B = ??? +<<< pure type functions 7 +runner.dialect = scala3future +=== +object a: + def func(f: -> B): Unit +>>> +object a: + def func(f: -> B): Unit +<<< capability capture checking 1 +runner.dialect = scala3future +=== +object a: + class Logger(fs: FileSystem^) +>>> +object a: + class Logger(fs: FileSystem ^) +<<< capability capture checking 2 +runner.dialect = scala3future +=== +object a: + val l: Logger^{fs} = Logger(fs) +>>> +object a: + val l: Logger ^ { fs } = Logger(fs) +<<< capability capture checking 3 +runner.dialect = scala3future +=== +object a: + def tail: LazyList[A]^{this} +>>> +object a: + def tail: LazyList[A] ^ { this } +<<< capability capture checking 4 +runner.dialect = scala3future +=== +object a: + def p: Pair[Int ->{ct} String, Logger^{fs}] = Pair(x, y) +>>> +object a: + def p: Pair[Int -> { ct } String, Logger ^ { fs }] = Pair(x, y) +<<< capability capture checking 5 +runner.dialect = scala3future +=== +object a: + def map[T <: (A ?->{a, c} B)](f: T): A ?-> B = ??? +>>> +object a: + def map[T <: (A ?-> { a, c } B)](f: T): A ?-> B = ??? +<<< capability capture checking 6 +runner.dialect = scala3future +=== +object a: + def func(f: ->{a, b, c} B): Unit +>>> +object a: + def func(f: -> { a, b, c } B): Unit 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 e49f5e5ed9..b7e03efac4 100644 --- a/scalafmt-tests/shared/src/test/resources/scala3/OptionalBraces_fold.stat +++ b/scalafmt-tests/shared/src/test/resources/scala3/OptionalBraces_fold.stat @@ -7395,3 +7395,147 @@ object a: b.c match case d if e => f // comment +<<< implicit parameter type conversion with "into" modifier 1 +runner.dialect = scala3future +=== +object a: + def ++ (elems: into IterableOnce[A]): List[A] +>>> +object a: + def ++(elems: into IterableOnce[A]): List[A] +<<< implicit parameter type conversion with "into" modifier 2 +runner.dialect = scala3future +=== +object a: + def ++ (elems: => into IterableOnce[A]): List[A] +>>> +object a: + def ++(elems: => into IterableOnce[A]): List[A] +<<< implicit parameter type conversion with "into" modifier 3 +runner.dialect = scala3future +=== +object a: + def flatMap[B](f: into A => IterableOnce[B]): List[B] +>>> +object a: + def flatMap[B](f: into A => IterableOnce[B]): List[B] +<<< implicit parameter type conversion with "into" modifier 4 +runner.dialect = scala3future +=== +object a: + def flatMap[B](f: A => into IterableOnce[B]): List[B] +>>> +object a: + def flatMap[B](f: A => into IterableOnce[B]): List[B] +<<< implicit parameter type conversion with "into" modifier 5 +runner.dialect = scala3future +=== +object a: + def concatAll(xss: (into IterableOnce[Char])*): List[Char] +>>> +object a: + def concatAll(xss: (into IterableOnce[Char])*): List[Char] +<<< pure type functions 1 +runner.dialect = scala3future +=== +object a: + val func: A -> B = foo +>>> +object a: + val func: A -> B = foo +<<< pure type functions 2 +runner.dialect = scala3future +=== +object a: + def func(f: A -> B): Unit +>>> +object a: + def func(f: A -> B): Unit +<<< pure type functions 3 +runner.dialect = scala3future +=== +object a: + def map[T <: (A -> B)](f: T): A -> B = ??? +>>> +object a: + def map[T <: (A -> B)](f: T): A -> B = ??? +<<< pure type functions 4 +runner.dialect = scala3future +=== +object a: + val func: A ?-> B = foo +>>> +object a: + val func: A ?-> B = foo +<<< pure type functions 5 +runner.dialect = scala3future +=== +object a: + def func(f: A ?-> B): Unit +>>> +object a: + def func(f: A ?-> B): Unit +<<< pure type functions 6 +runner.dialect = scala3future +=== +object a: + def map[T <: (A ?-> B)](f: T): A ?-> B = ??? +>>> +object a: + def map[T <: (A ?-> B)](f: T): A ?-> B = ??? +<<< pure type functions 7 +runner.dialect = scala3future +=== +object a: + def func(f: -> B): Unit +>>> +object a: + def func(f: -> B): Unit +<<< capability capture checking 1 +runner.dialect = scala3future +=== +object a: + class Logger(fs: FileSystem^) +>>> +object a: + class Logger(fs: FileSystem ^) +<<< capability capture checking 2 +runner.dialect = scala3future +=== +object a: + val l: Logger^{fs} = Logger(fs) +>>> +object a: + val l: Logger ^ { fs } = Logger(fs) +<<< capability capture checking 3 +runner.dialect = scala3future +=== +object a: + def tail: LazyList[A]^{this} +>>> +object a: + def tail: LazyList[A] ^ { this } +<<< capability capture checking 4 +runner.dialect = scala3future +=== +object a: + def p: Pair[Int ->{ct} String, Logger^{fs}] = Pair(x, y) +>>> +object a: + def p: Pair[Int -> { ct } String, Logger ^ { fs }] = Pair(x, y) +<<< capability capture checking 5 +runner.dialect = scala3future +=== +object a: + def map[T <: (A ?->{a, c} B)](f: T): A ?-> B = ??? +>>> +object a: + def map[T <: (A ?-> { a, c } B)](f: T): A ?-> B = ??? +<<< capability capture checking 6 +runner.dialect = scala3future +=== +object a: + def func(f: ->{a, b, c} B): Unit +>>> +object a: + def func(f: -> { a, b, c } B): Unit 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 606a66c147..e3c1c0a9ce 100644 --- a/scalafmt-tests/shared/src/test/resources/scala3/OptionalBraces_keep.stat +++ b/scalafmt-tests/shared/src/test/resources/scala3/OptionalBraces_keep.stat @@ -7720,3 +7720,147 @@ object a: b.c match case d if e => f // comment +<<< implicit parameter type conversion with "into" modifier 1 +runner.dialect = scala3future +=== +object a: + def ++ (elems: into IterableOnce[A]): List[A] +>>> +object a: + def ++(elems: into IterableOnce[A]): List[A] +<<< implicit parameter type conversion with "into" modifier 2 +runner.dialect = scala3future +=== +object a: + def ++ (elems: => into IterableOnce[A]): List[A] +>>> +object a: + def ++(elems: => into IterableOnce[A]): List[A] +<<< implicit parameter type conversion with "into" modifier 3 +runner.dialect = scala3future +=== +object a: + def flatMap[B](f: into A => IterableOnce[B]): List[B] +>>> +object a: + def flatMap[B](f: into A => IterableOnce[B]): List[B] +<<< implicit parameter type conversion with "into" modifier 4 +runner.dialect = scala3future +=== +object a: + def flatMap[B](f: A => into IterableOnce[B]): List[B] +>>> +object a: + def flatMap[B](f: A => into IterableOnce[B]): List[B] +<<< implicit parameter type conversion with "into" modifier 5 +runner.dialect = scala3future +=== +object a: + def concatAll(xss: (into IterableOnce[Char])*): List[Char] +>>> +object a: + def concatAll(xss: (into IterableOnce[Char])*): List[Char] +<<< pure type functions 1 +runner.dialect = scala3future +=== +object a: + val func: A -> B = foo +>>> +object a: + val func: A -> B = foo +<<< pure type functions 2 +runner.dialect = scala3future +=== +object a: + def func(f: A -> B): Unit +>>> +object a: + def func(f: A -> B): Unit +<<< pure type functions 3 +runner.dialect = scala3future +=== +object a: + def map[T <: (A -> B)](f: T): A -> B = ??? +>>> +object a: + def map[T <: (A -> B)](f: T): A -> B = ??? +<<< pure type functions 4 +runner.dialect = scala3future +=== +object a: + val func: A ?-> B = foo +>>> +object a: + val func: A ?-> B = foo +<<< pure type functions 5 +runner.dialect = scala3future +=== +object a: + def func(f: A ?-> B): Unit +>>> +object a: + def func(f: A ?-> B): Unit +<<< pure type functions 6 +runner.dialect = scala3future +=== +object a: + def map[T <: (A ?-> B)](f: T): A ?-> B = ??? +>>> +object a: + def map[T <: (A ?-> B)](f: T): A ?-> B = ??? +<<< pure type functions 7 +runner.dialect = scala3future +=== +object a: + def func(f: -> B): Unit +>>> +object a: + def func(f: -> B): Unit +<<< capability capture checking 1 +runner.dialect = scala3future +=== +object a: + class Logger(fs: FileSystem^) +>>> +object a: + class Logger(fs: FileSystem ^) +<<< capability capture checking 2 +runner.dialect = scala3future +=== +object a: + val l: Logger^{fs} = Logger(fs) +>>> +object a: + val l: Logger ^ { fs } = Logger(fs) +<<< capability capture checking 3 +runner.dialect = scala3future +=== +object a: + def tail: LazyList[A]^{this} +>>> +object a: + def tail: LazyList[A] ^ { this } +<<< capability capture checking 4 +runner.dialect = scala3future +=== +object a: + def p: Pair[Int ->{ct} String, Logger^{fs}] = Pair(x, y) +>>> +object a: + def p: Pair[Int -> { ct } String, Logger ^ { fs }] = Pair(x, y) +<<< capability capture checking 5 +runner.dialect = scala3future +=== +object a: + def map[T <: (A ?->{a, c} B)](f: T): A ?-> B = ??? +>>> +object a: + def map[T <: (A ?-> { a, c } B)](f: T): A ?-> B = ??? +<<< capability capture checking 6 +runner.dialect = scala3future +=== +object a: + def func(f: ->{a, b, c} B): Unit +>>> +object a: + def func(f: -> { a, b, c } B): Unit 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 f553bec717..5ee70821a1 100644 --- a/scalafmt-tests/shared/src/test/resources/scala3/OptionalBraces_unfold.stat +++ b/scalafmt-tests/shared/src/test/resources/scala3/OptionalBraces_unfold.stat @@ -8014,3 +8014,168 @@ object a: case d if e => f // comment +<<< implicit parameter type conversion with "into" modifier 1 +runner.dialect = scala3future +=== +object a: + def ++ (elems: into IterableOnce[A]): List[A] +>>> +object a: + def ++(elems: into IterableOnce[A]): List[A] +<<< implicit parameter type conversion with "into" modifier 2 +runner.dialect = scala3future +=== +object a: + def ++ (elems: => into IterableOnce[A]): List[A] +>>> +object a: + def ++(elems: => into IterableOnce[A]): List[A] +<<< implicit parameter type conversion with "into" modifier 3 +runner.dialect = scala3future +=== +object a: + def flatMap[B](f: into A => IterableOnce[B]): List[B] +>>> +object a: + def flatMap[B](f: into A => IterableOnce[B]): List[B] +<<< implicit parameter type conversion with "into" modifier 4 +runner.dialect = scala3future +=== +object a: + def flatMap[B](f: A => into IterableOnce[B]): List[B] +>>> +object a: + def flatMap[B](f: A => into IterableOnce[B]): List[B] +<<< implicit parameter type conversion with "into" modifier 5 +runner.dialect = scala3future +=== +object a: + def concatAll(xss: (into IterableOnce[Char])*): List[Char] +>>> +object a: + def concatAll(xss: (into IterableOnce[Char])*): List[Char] +<<< pure type functions 1 +runner.dialect = scala3future +=== +object a: + val func: A -> B = foo +>>> +object a: + val func: A -> B = foo +<<< pure type functions 2 +runner.dialect = scala3future +=== +object a: + def func(f: A -> B): Unit +>>> +object a: + def func(f: A -> B): Unit +<<< pure type functions 3 +runner.dialect = scala3future +=== +object a: + def map[T <: (A -> B)](f: T): A -> B = ??? +>>> +object a: + def map[T <: (A -> B)](f: T): A -> B = ??? +<<< pure type functions 4 +runner.dialect = scala3future +=== +object a: + val func: A ?-> B = foo +>>> +object a: + val func: A ?-> B = foo +<<< pure type functions 5 +runner.dialect = scala3future +=== +object a: + def func(f: A ?-> B): Unit +>>> +object a: + def func(f: A ?-> B): Unit +<<< pure type functions 6 +runner.dialect = scala3future +=== +object a: + def map[T <: (A ?-> B)](f: T): A ?-> B = ??? +>>> +object a: + def map[T <: (A ?-> B)](f: T): A ?-> B = ??? +<<< pure type functions 7 +runner.dialect = scala3future +=== +object a: + def func(f: -> B): Unit +>>> +object a: + def func(f: -> B): Unit +<<< capability capture checking 1 +runner.dialect = scala3future +=== +object a: + class Logger(fs: FileSystem^) +>>> +object a: + class Logger(fs: FileSystem ^) +<<< capability capture checking 2 +runner.dialect = scala3future +=== +object a: + val l: Logger^{fs} = Logger(fs) +>>> +object a: + val l: Logger ^ { + fs + } = Logger(fs) +<<< capability capture checking 3 +runner.dialect = scala3future +=== +object a: + def tail: LazyList[A]^{this} +>>> +object a: + def tail: LazyList[A] ^ { + this + } +<<< capability capture checking 4 +runner.dialect = scala3future +=== +object a: + def p: Pair[Int ->{ct} String, Logger^{fs}] = Pair(x, y) +>>> +object a: + def p: Pair[ + Int -> { + ct + } String, + Logger ^ { + fs + } + ] = Pair(x, y) +<<< capability capture checking 5 +runner.dialect = scala3future +=== +object a: + def map[T <: (A ?->{a, c} B)](f: T): A ?-> B = ??? +>>> +object a: + def map[ + T <: ( + A ?-> { + a, c + } B + ) + ](f: T): A ?-> B = ??? +<<< capability capture checking 6 +runner.dialect = scala3future +=== +object a: + def func(f: ->{a, b, c} B): Unit +>>> +object a: + def func( + f: -> { + a, b, c + } B + ): Unit 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 1452813ab0..2affbff611 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, 1085954, "total explored") + assertEquals(explored, 1089084, "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 :'( From 0fdd57e8f1d8459f76c6c53a1f5013ded0574959 Mon Sep 17 00:00:00 2001 From: Albert Meltzer <7529386+kitbellew@users.noreply.github.com> Date: Thu, 21 Nov 2024 18:22:08 -0800 Subject: [PATCH 2/2] Support pure functions and capture checking --- .../org/scalafmt/internal/FormatOps.scala | 4 +-- .../scala/org/scalafmt/internal/Router.scala | 23 +++++++++---- .../internal/TreeSyntacticGroup.scala | 4 +-- .../scalafmt/rewrite/RedundantParens.scala | 2 +- .../scala/org/scalafmt/util/TreeOps.scala | 16 ++++++--- .../test/resources/scala3/OptionalBraces.stat | 12 +++---- .../resources/scala3/OptionalBraces_fold.stat | 12 +++---- .../resources/scala3/OptionalBraces_keep.stat | 12 +++---- .../scala3/OptionalBraces_unfold.stat | 33 ++++--------------- .../test/scala/org/scalafmt/FormatTests.scala | 2 +- 10 files changed, 59 insertions(+), 61 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 7f58c01752..75fdb97b81 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 @@ -193,8 +193,8 @@ class FormatOps( // invoked on closing paren, part of ParamClause @tailrec final def defnSiteLastToken(t: Tree): Option[FT] = t match { - case _: Term.ParamClause | _: Type.FuncParamClause | _: Type.FunctionType | - _: Member.ParamClauseGroup => t.parent match { + case _: Member.SyntaxValuesClause | _: Member.ParamClauseGroup | + _: Type.ParamFunctionType => t.parent match { case Some(p) => defnSiteLastToken(p) case _ => None } 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 3e115db1b8..c1485ec6a2 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 @@ -247,6 +247,14 @@ class Router(formatOps: FormatOps) { // { ... } Blocks case FT(_: T.LeftBrace, _: T.RightBrace, _) => Seq(Split(NoSplit, 0)) + + // Capture checking + case FT(_, _: T.LeftBrace, _) if isCapturingBrace(rightOwner) => + Seq(Split(NoSplit, 0)) + case FT(_: T.LeftBrace, _, _) if isCapturingBrace(leftOwner) => + val close = matchingLeft(ft) + Seq(Split(NoSplit, 0).withIndent(style.indent.main, close, Before)) + case FT(_: T.LeftBrace, right, _) => val close = matchingLeft(ft) val isSelfAnnotationNL = style.optIn.selfAnnotationNewline && @@ -355,7 +363,7 @@ class Router(formatOps: FormatOps) { else getSingleLineLambdaDecisionOpt } - val noSplitMod = xmlSpace(leftOwner) + val noSplitMod = braceSpace(leftOwner) val (slbMod, slbParensExclude) = if (singleLineDecisionOpt.isEmpty) (noSplitMod, None) else getBracesToParensMod(close, noSplitMod, isWithinBraces = true) @@ -717,7 +725,7 @@ class Router(formatOps: FormatOps) { } case FT(_, _: T.RightBrace, _) => - Seq(Split(if (ft.hasBlankLine) Newline2x else xmlSpace(rightOwner), 0)) + Seq(Split(if (ft.hasBlankLine) Newline2x else braceSpace(rightOwner), 0)) case FT(_: T.KwPackage, _, _) if leftOwner.is[Pkg] => Seq(Split(Space, 0)) // Opening [ with no leading space. @@ -1586,9 +1594,8 @@ class Router(formatOps: FormatOps) { .exists(x => isTokenLastOrAfter(x.left, roPos)) } } => - val mod = - getBracesToParensMod(matchingRight(ft), Space, isWithinBraces = false) - ._1 + val rb = matchingRight(ft) + val mod = getBracesToParensMod(rb, Space, isWithinBraces = false)._1 Seq(Split(mod, 0)) // Delim @@ -2549,6 +2556,9 @@ class Router(formatOps: FormatOps) { if rightOwner.isAny[Tree.Repeated, Pat.SeqWildcard] => Seq(Split(NoSplit, 0)) + case FT(_, T.Ident("^"), _) if rightOwner.is[Type.Capturing] => + Seq(Split(NoSplit, 0)) + case FT( _: T.Ident | _: T.Literal | _: T.Interpolation.End | _: T.Xml.End, _: T.Ident | _: T.Literal, @@ -2658,7 +2668,8 @@ class Router(formatOps: FormatOps) { case FT(Reserved(), _, _) => Seq(Split(Space, 0)) case FT(_, _: T.Symbolic, _) => Seq(Split(Space, 0)) - case FT(_: T.RightArrow, _, _) if leftOwner.is[Type.ByName] => + case FT(_: T.RightArrow | soft.KwPureFunctionArrow(), _, _) + if leftOwner.is[Type.ByNameType] => val mod = Space(style.spaces.inByNameTypes) Seq(Split(mod, 0)) case FT(_: T.Colon, _, _) if style.spaces.notAfterColon(leftOwner) => diff --git a/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/TreeSyntacticGroup.scala b/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/TreeSyntacticGroup.scala index 5370d5e47a..2cf91c6299 100644 --- a/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/TreeSyntacticGroup.scala +++ b/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/TreeSyntacticGroup.scala @@ -52,7 +52,7 @@ object TreeSyntacticGroup { case _: Type.Singleton => g.Type.SimpleTyp case _: Type.Apply => g.Type.SimpleTyp case t: Type.ApplyInfix => g.Type.InfixTyp(t.op.value) - case _: Type.FunctionType => g.Type.Typ + case _: Type.ParamFunctionType => g.Type.Typ case _: Type.PolyFunction => g.Type.Typ case _: Type.Tuple => g.Type.SimpleTyp case _: Type.With => g.Type.WithTyp @@ -64,7 +64,7 @@ object TreeSyntacticGroup { case _: Type.Wildcard => g.Type.SimpleTyp case _: Type.Bounds => g.Path // ??? case _: Type.Repeated => g.Type.ParamTyp - case _: Type.ByName => g.Type.ParamTyp + case _: Type.ByNameType => g.Type.ParamTyp case _: Type.Var => g.Type.ParamTyp case _: Type.Param => g.Path // ??? case _: Type.Match => g.Type.Typ diff --git a/scalafmt-core/shared/src/main/scala/org/scalafmt/rewrite/RedundantParens.scala b/scalafmt-core/shared/src/main/scala/org/scalafmt/rewrite/RedundantParens.scala index 850b1477db..8e9c688f75 100644 --- a/scalafmt-core/shared/src/main/scala/org/scalafmt/rewrite/RedundantParens.scala +++ b/scalafmt-core/shared/src/main/scala/org/scalafmt/rewrite/RedundantParens.scala @@ -97,7 +97,7 @@ class RedundantParens(implicit val ftoks: FormatTokens) case _ if numParens >= 2 => true case _: Term.AnonymousFunction | _: Term.Param => false - case _: Type.FunctionType => false + case _: Type.ParamFunctionType => false case _: Init => false case t: Member.ArgClause => okToReplaceArgClause(t) diff --git a/scalafmt-core/shared/src/main/scala/org/scalafmt/util/TreeOps.scala b/scalafmt-core/shared/src/main/scala/org/scalafmt/util/TreeOps.scala index 55d51d9084..902c1a61cb 100644 --- a/scalafmt-core/shared/src/main/scala/org/scalafmt/util/TreeOps.scala +++ b/scalafmt-core/shared/src/main/scala/org/scalafmt/util/TreeOps.scala @@ -911,11 +911,19 @@ object TreeOps { def isParentAnApply(t: Tree): Boolean = t.parent.is[Term.Apply] - def isTreeOrBlockParent(owner: Tree)(pred: Tree => Boolean): Boolean = - if (owner.is[Term.Block]) owner.parent.exists(pred) else pred(owner) + def isCapturingBrace(owner: Tree): Boolean = owner match { + case _: Type.Capturing => true + case t: Type.FunctionLikeType => t.parent.is[Type.Capturing] + case _ => false + } - def xmlSpace(owner: Tree): Modification = - Space(!isTreeOrBlockParent(owner)(_.isAny[Term.Xml, Pat.Xml])) + def braceSpace(owner: Tree): Modification = Space { + def isXml(t: Tree) = t.isAny[Term.Xml, Pat.Xml] + owner match { + case t: Term.Block => !t.parent.exists(isXml) + case t => !isXml(t) && !isCapturingBrace(t) + } + } def isEmptyTree(tree: Tree): Boolean = tree match { case t: Term.Block => t.stats.isEmpty diff --git a/scalafmt-tests/shared/src/test/resources/scala3/OptionalBraces.stat b/scalafmt-tests/shared/src/test/resources/scala3/OptionalBraces.stat index c5dc75ea58..b4a0d0faa7 100644 --- a/scalafmt-tests/shared/src/test/resources/scala3/OptionalBraces.stat +++ b/scalafmt-tests/shared/src/test/resources/scala3/OptionalBraces.stat @@ -7799,7 +7799,7 @@ object a: class Logger(fs: FileSystem^) >>> object a: - class Logger(fs: FileSystem ^) + class Logger(fs: FileSystem^) <<< capability capture checking 2 runner.dialect = scala3future === @@ -7807,7 +7807,7 @@ object a: val l: Logger^{fs} = Logger(fs) >>> object a: - val l: Logger ^ { fs } = Logger(fs) + val l: Logger^{fs} = Logger(fs) <<< capability capture checking 3 runner.dialect = scala3future === @@ -7815,7 +7815,7 @@ object a: def tail: LazyList[A]^{this} >>> object a: - def tail: LazyList[A] ^ { this } + def tail: LazyList[A]^{this} <<< capability capture checking 4 runner.dialect = scala3future === @@ -7823,7 +7823,7 @@ object a: def p: Pair[Int ->{ct} String, Logger^{fs}] = Pair(x, y) >>> object a: - def p: Pair[Int -> { ct } String, Logger ^ { fs }] = Pair(x, y) + def p: Pair[Int ->{ct} String, Logger^{fs}] = Pair(x, y) <<< capability capture checking 5 runner.dialect = scala3future === @@ -7831,7 +7831,7 @@ object a: def map[T <: (A ?->{a, c} B)](f: T): A ?-> B = ??? >>> object a: - def map[T <: (A ?-> { a, c } B)](f: T): A ?-> B = ??? + def map[T <: (A ?->{a, c} B)](f: T): A ?-> B = ??? <<< capability capture checking 6 runner.dialect = scala3future === @@ -7839,4 +7839,4 @@ object a: def func(f: ->{a, b, c} B): Unit >>> object a: - def func(f: -> { a, b, c } B): Unit + def func(f: ->{a, b, c} B): Unit 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 b7e03efac4..56b90c844b 100644 --- a/scalafmt-tests/shared/src/test/resources/scala3/OptionalBraces_fold.stat +++ b/scalafmt-tests/shared/src/test/resources/scala3/OptionalBraces_fold.stat @@ -7498,7 +7498,7 @@ object a: class Logger(fs: FileSystem^) >>> object a: - class Logger(fs: FileSystem ^) + class Logger(fs: FileSystem^) <<< capability capture checking 2 runner.dialect = scala3future === @@ -7506,7 +7506,7 @@ object a: val l: Logger^{fs} = Logger(fs) >>> object a: - val l: Logger ^ { fs } = Logger(fs) + val l: Logger^{fs} = Logger(fs) <<< capability capture checking 3 runner.dialect = scala3future === @@ -7514,7 +7514,7 @@ object a: def tail: LazyList[A]^{this} >>> object a: - def tail: LazyList[A] ^ { this } + def tail: LazyList[A]^{this} <<< capability capture checking 4 runner.dialect = scala3future === @@ -7522,7 +7522,7 @@ object a: def p: Pair[Int ->{ct} String, Logger^{fs}] = Pair(x, y) >>> object a: - def p: Pair[Int -> { ct } String, Logger ^ { fs }] = Pair(x, y) + def p: Pair[Int ->{ct} String, Logger^{fs}] = Pair(x, y) <<< capability capture checking 5 runner.dialect = scala3future === @@ -7530,7 +7530,7 @@ object a: def map[T <: (A ?->{a, c} B)](f: T): A ?-> B = ??? >>> object a: - def map[T <: (A ?-> { a, c } B)](f: T): A ?-> B = ??? + def map[T <: (A ?->{a, c} B)](f: T): A ?-> B = ??? <<< capability capture checking 6 runner.dialect = scala3future === @@ -7538,4 +7538,4 @@ object a: def func(f: ->{a, b, c} B): Unit >>> object a: - def func(f: -> { a, b, c } B): Unit + def func(f: ->{a, b, c} B): Unit 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 e3c1c0a9ce..ce1de549ad 100644 --- a/scalafmt-tests/shared/src/test/resources/scala3/OptionalBraces_keep.stat +++ b/scalafmt-tests/shared/src/test/resources/scala3/OptionalBraces_keep.stat @@ -7823,7 +7823,7 @@ object a: class Logger(fs: FileSystem^) >>> object a: - class Logger(fs: FileSystem ^) + class Logger(fs: FileSystem^) <<< capability capture checking 2 runner.dialect = scala3future === @@ -7831,7 +7831,7 @@ object a: val l: Logger^{fs} = Logger(fs) >>> object a: - val l: Logger ^ { fs } = Logger(fs) + val l: Logger^{fs} = Logger(fs) <<< capability capture checking 3 runner.dialect = scala3future === @@ -7839,7 +7839,7 @@ object a: def tail: LazyList[A]^{this} >>> object a: - def tail: LazyList[A] ^ { this } + def tail: LazyList[A]^{this} <<< capability capture checking 4 runner.dialect = scala3future === @@ -7847,7 +7847,7 @@ object a: def p: Pair[Int ->{ct} String, Logger^{fs}] = Pair(x, y) >>> object a: - def p: Pair[Int -> { ct } String, Logger ^ { fs }] = Pair(x, y) + def p: Pair[Int ->{ct} String, Logger^{fs}] = Pair(x, y) <<< capability capture checking 5 runner.dialect = scala3future === @@ -7855,7 +7855,7 @@ object a: def map[T <: (A ?->{a, c} B)](f: T): A ?-> B = ??? >>> object a: - def map[T <: (A ?-> { a, c } B)](f: T): A ?-> B = ??? + def map[T <: (A ?->{a, c} B)](f: T): A ?-> B = ??? <<< capability capture checking 6 runner.dialect = scala3future === @@ -7863,4 +7863,4 @@ object a: def func(f: ->{a, b, c} B): Unit >>> object a: - def func(f: -> { a, b, c } B): Unit + def func(f: ->{a, b, c} B): Unit 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 5ee70821a1..711cc3daaf 100644 --- a/scalafmt-tests/shared/src/test/resources/scala3/OptionalBraces_unfold.stat +++ b/scalafmt-tests/shared/src/test/resources/scala3/OptionalBraces_unfold.stat @@ -8117,7 +8117,7 @@ object a: class Logger(fs: FileSystem^) >>> object a: - class Logger(fs: FileSystem ^) + class Logger(fs: FileSystem^) <<< capability capture checking 2 runner.dialect = scala3future === @@ -8125,9 +8125,7 @@ object a: val l: Logger^{fs} = Logger(fs) >>> object a: - val l: Logger ^ { - fs - } = Logger(fs) + val l: Logger^{fs} = Logger(fs) <<< capability capture checking 3 runner.dialect = scala3future === @@ -8135,9 +8133,7 @@ object a: def tail: LazyList[A]^{this} >>> object a: - def tail: LazyList[A] ^ { - this - } + def tail: LazyList[A]^{this} <<< capability capture checking 4 runner.dialect = scala3future === @@ -8145,14 +8141,7 @@ object a: def p: Pair[Int ->{ct} String, Logger^{fs}] = Pair(x, y) >>> object a: - def p: Pair[ - Int -> { - ct - } String, - Logger ^ { - fs - } - ] = Pair(x, y) + def p: Pair[Int ->{ct} String, Logger^{fs}] = Pair(x, y) <<< capability capture checking 5 runner.dialect = scala3future === @@ -8160,13 +8149,7 @@ object a: def map[T <: (A ?->{a, c} B)](f: T): A ?-> B = ??? >>> object a: - def map[ - T <: ( - A ?-> { - a, c - } B - ) - ](f: T): A ?-> B = ??? + def map[T <: (A ?->{a, c} B)](f: T): A ?-> B = ??? <<< capability capture checking 6 runner.dialect = scala3future === @@ -8174,8 +8157,4 @@ object a: def func(f: ->{a, b, c} B): Unit >>> object a: - def func( - f: -> { - a, b, c - } B - ): Unit + def func(f: ->{a, b, c} B): Unit 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 2affbff611..104104fbc3 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, 1089084, "total explored") + assertEquals(explored, 1089000, "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 :'(