From 07c61a28adc7950e35e9db3972d62e97b0067695 Mon Sep 17 00:00:00 2001 From: Albert Meltzer <7529386+kitbellew@users.noreply.github.com> Date: Thu, 29 Feb 2024 23:14:08 +0100 Subject: [PATCH] `}` could be from a block arg or splice --- .../org/scalafmt/internal/FormatOps.scala | 6 ------ .../scala/org/scalafmt/internal/Router.scala | 14 +++++++++----- .../org/scalafmt/rewrite/RedundantBraces.scala | 15 ++++++++++----- .../scala/org/scalafmt/util/TreeClasses.scala | 18 ------------------ .../main/scala/org/scalafmt/util/TreeOps.scala | 17 ++++++++++------- 5 files changed, 29 insertions(+), 41 deletions(-) delete mode 100644 scalafmt-core/shared/src/main/scala/org/scalafmt/util/TreeClasses.scala 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 2d3bca04ff..a0f2676ae1 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 @@ -1382,12 +1382,6 @@ class FormatOps( if (!ft.right.is[T.Comment] || isDone(ft)) ft else iter(ft) } - def xmlSpace(owner: Tree): Modification = - owner match { - case _: Term.Xml | _: Pat.Xml => NoSplit - case _ => Space - } - def getSpaceAndNewlineAfterCurlyLambda( newlines: Int )(implicit style: ScalafmtConfig): (Boolean, NewlineT) = 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 d26f5e5f1f..2955d1384a 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 @@ -191,14 +191,19 @@ class Router(formatOps: FormatOps) { .withIndents(alignIndents.getOrElse(mainIndents)) .withPolicy(decideNewlinesOnlyBeforeClose(close)) } - def findArg = findInterpolateArgAfter(open.end, leftOwner) + def isSimpleInterpolate = (leftOwner match { + case t: Pat.Interpolate => findArgAfter(open.end, t.args) + case t: Term.Interpolate => findArgAfter(open.end, t.args) + case t: Term.Block => getBlockSingleStat(t) + case _ => None + }).exists(!_.is[Term.If]) + style.newlines.inInterpolation match { case Newlines.InInterpolation.avoid => Seq(spaceSplit) case _ if style.newlines.keepBreak(newlines) => Seq(newlineSplit(0)) case Newlines.InInterpolation.allow - if !dialect.allowSignificantIndentation || - !findArg.exists(_.is[Term.If]) => + if !dialect.allowSignificantIndentation || isSimpleInterpolate => Seq(spaceSplit) case _ => /* sequence of tokens: @@ -216,8 +221,7 @@ class Router(formatOps: FormatOps) { ) } - case FormatToken(_, _: T.RightBrace, _) - if rightOwner.is[SomeInterpolate] => + case FormatToken(_, _: T.RightBrace, _) if isInterpolate(rightOwner) => Seq(Split(Space(style.spaces.inInterpolatedStringCurlyBraces), 0)) // optional braces: block follows diff --git a/scalafmt-core/shared/src/main/scala/org/scalafmt/rewrite/RedundantBraces.scala b/scalafmt-core/shared/src/main/scala/org/scalafmt/rewrite/RedundantBraces.scala index 4ac7e13af9..d024b4cd0c 100644 --- a/scalafmt-core/shared/src/main/scala/org/scalafmt/rewrite/RedundantBraces.scala +++ b/scalafmt-core/shared/src/main/scala/org/scalafmt/rewrite/RedundantBraces.scala @@ -152,6 +152,13 @@ class RedundantBraces(ftoks: FormatTokens) extends FormatTokensRewrite.Rule { session: Session, style: ScalafmtConfig ): Replacement = { + def handleInterpolation = + if ( + style.rewrite.redundantBraces.stringInterpolation && + processInterpolation + ) removeToken + else null + owner match { case t: Term.FunctionTerm if t.tokens.last.is[Token.RightBrace] => if (!okToRemoveFunctionInApplyOrInit(t)) null @@ -167,13 +174,11 @@ class RedundantBraces(ftoks: FormatTokens) extends FormatTokensRewrite.Rule { case Some(f: Term.FunctionTerm) if okToReplaceFunctionInSingleArgApply(f) => replaceWithLeftParen + case Some(_: Term.Interpolate) => handleInterpolation case _ => if (processBlock(t)) removeToken else null } - case _: Term.Interpolate - if style.rewrite.redundantBraces.stringInterpolation && - processInterpolation => - removeToken + case _: Term.Interpolate => handleInterpolation case Importer(_, List(x)) if !(x.is[Importee.Rename] || x.is[Importee.Unimport]) || style.dialect.allowAsForImportRename && @@ -219,7 +224,7 @@ class RedundantBraces(ftoks: FormatTokens) extends FormatTokensRewrite.Rule { def isLiteralIdentifier(arg: Term.Name): Boolean = { val syntax = arg.toString() - syntax.headOption.contains('`') && syntax.lastOption.contains('`') + syntax.nonEmpty && syntax.head == '`' && syntax.last == '`' } /** we need to keep braces diff --git a/scalafmt-core/shared/src/main/scala/org/scalafmt/util/TreeClasses.scala b/scalafmt-core/shared/src/main/scala/org/scalafmt/util/TreeClasses.scala deleted file mode 100644 index f6600a8f34..0000000000 --- a/scalafmt-core/shared/src/main/scala/org/scalafmt/util/TreeClasses.scala +++ /dev/null @@ -1,18 +0,0 @@ -package org.scalafmt.util - -import scala.meta._ -import scala.meta.internal.classifiers.classifier - -@classifier -trait SomeInterpolate -object SomeInterpolate { - def unapply(tree: Tree): Boolean = { - tree.is[Term.Interpolate] || tree.is[Pat.Interpolate] - } -} -@classifier -trait CtorModifier -object CtorModifier { - def unapply(tree: Tree): Boolean = - tree.is[Mod.Private] || tree.is[Mod.Protected] -} 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 22037c0e82..fa4e8929f4 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 @@ -12,6 +12,7 @@ import scala.reflect.ClassTag import org.scalafmt.Error import org.scalafmt.config.{DanglingParentheses, ScalafmtConfig} +import org.scalafmt.internal.{Modification, Space} import org.scalafmt.internal.{FormatToken, FormatTokens} import org.scalafmt.util.InfixApp._ @@ -756,13 +757,6 @@ object TreeOps { } } - def findInterpolateArgAfter(end: Int, tree: Tree): Option[Tree] = - tree match { - case t: Pat.Interpolate => findArgAfter(end, t.args) - case t: Term.Interpolate => findArgAfter(end, t.args) - case _ => None - } - def findArgAfter(end: Int, trees: Seq[Tree]): Option[Tree] = trees.find(_.pos.start >= end) @@ -1067,4 +1061,13 @@ object TreeOps { def isParentAnApply(t: Tree): Boolean = t.parent.exists(_.is[Term.Apply]) + def isTreeOrBlockParent(owner: Tree)(pred: Tree => Boolean): Boolean = + if (owner.is[Term.Block]) owner.parent.exists(pred) else pred(owner) + + def xmlSpace(owner: Tree): Modification = + Space(!isTreeOrBlockParent(owner)(_.isAny[Term.Xml, Pat.Xml])) + + def isInterpolate(tree: Tree): Boolean = + isTreeOrBlockParent(tree)(_.isAny[Term.Interpolate, Pat.Interpolate]) + }