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 0e74487ad4..908c27e061 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 @@ -969,7 +969,7 @@ class FormatOps( ft: FormatToken, allowForce: => Boolean = true )(implicit style: ScalafmtConfig): Boolean = - opensConfigStyle(ft) || allowForce && forceConfigStyle(ft.meta.leftOwner) + opensConfigStyle(ft) || allowForce && forceConfigStyle(hash(ft.left)) def opensConfigStyle( ft: => FormatToken, @@ -1145,26 +1145,34 @@ class FormatOps( } else Seq(Split(Space, 0), Split(Newline, 1)) } - def getForceConfigStyle: (Set[Tree], Set[TokenHash]) = { + def getForceConfigStyle: (Set[TokenHash], Set[TokenHash]) = { val maxDistance = runner.optimizer.forceConfigStyleOnOffset if (maxDistance < 0) (Set.empty, Set.empty) else { val clearQueues = Set.newBuilder[TokenHash] - val forces = Set.newBuilder[Tree] + val forces = Set.newBuilder[TokenHash] val minArgs = runner.optimizer.forceConfigStyleMinArgCount - tokens.foreach { - case FormatToken( - left: T.LeftParen, - _, - FormatToken.LeftOwner(app @ CallArgsForConfigStyle(args)) - ) - if args.lengthCompare(minArgs) >= 0 && - distance(left, matching(left)) > maxDistance => - forces += app + def process(args: Seq[Tree], open: T, close: T): Unit = + if ( + args.lengthCompare(minArgs) >= 0 && + distance(open, close) > maxDistance + ) { + forces += hash(open) args.foreach { arg => clearQueues += hash(tokens.getHead(arg).left) } + } + tokens.foreach { + case FormatToken(left: T.LeftParen, _, meta) => + matchingOpt(left).foreach { close => + (meta.leftOwner match { + case t: Term.Apply => Some(t.args) + case t: Init => TokenOps.findArgsBetween(left, close, t.argss) + case t: Term.ApplyUsing => Some(t.args) + case _ => None + }).foreach(process(_, left, close)) + } case _ => } (forces.result(), clearQueues.result()) diff --git a/scalafmt-core/shared/src/main/scala/org/scalafmt/util/TokenOps.scala b/scalafmt-core/shared/src/main/scala/org/scalafmt/util/TokenOps.scala index 12f9df4e13..1d32920255 100644 --- a/scalafmt-core/shared/src/main/scala/org/scalafmt/util/TokenOps.scala +++ b/scalafmt-core/shared/src/main/scala/org/scalafmt/util/TokenOps.scala @@ -186,13 +186,19 @@ object TokenOps { argss: Seq[Seq[A]], matchingOpt: Token => Option[Token] ): Option[Seq[A]] = - matchingOpt(token).flatMap { other => - // find the arg group starting with given format token - val beg = math.min(token.start, other.start) - argss - .find(_.headOption.exists(_.tokens.head.start >= beg)) - .filter(_.head.tokens.head.start <= math.max(token.end, other.end)) - } + matchingOpt(token).flatMap(findArgsBetween(token, _, argss)) + + def findArgsBetween[A <: Tree]( + token: Token, + other: Token, + argss: Seq[Seq[A]] + ): Option[Seq[A]] = { + // find the arg group starting with given format token + val beg = math.min(token.start, other.start) + argss + .find(_.headOption.exists(_.tokens.head.start >= beg)) + .filter(_.head.tokens.head.start <= math.max(token.end, other.end)) + } def getXmlLastLineIndent(tok: Xml.Part): Option[Int] = { val part = tok.value 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 d72271dabd..f829ea524d 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 @@ -510,15 +510,6 @@ object TreeOps { splitCallIntoParts.lift(tree) } - object CallArgsForConfigStyle { - def unapply(tree: Tree): Option[Seq[Tree]] = Some(tree match { - case t: Term.Apply => t.args - case t: Init => t.argss.flatten - case t: Term.ApplyUsing => t.args - case _ => Seq.empty - }).filter(_.nonEmpty) - } - type DefnParts = (Seq[Mod], Name, Seq[Type.Param], Seq[Seq[Term.Param]]) val splitDefnIntoParts: PartialFunction[Tree, DefnParts] = { // types diff --git a/scalafmt-tests/src/test/resources/default/Apply.stat b/scalafmt-tests/src/test/resources/default/Apply.stat index 0de2a1e8f0..5efabfa669 100644 --- a/scalafmt-tests/src/test/resources/default/Apply.stat +++ b/scalafmt-tests/src/test/resources/default/Apply.stat @@ -1920,9 +1920,7 @@ class a { customDnsResolver = customDnsResolver, retries = 0, maxIdleDuration = Duration.Inf - )( - F - ) + )(F) } <<< #3309 apply preset = default