From 04e50443d01019b5f2a1d55e18f686d37576e15a Mon Sep 17 00:00:00 2001 From: Albert Meltzer <7529386+kitbellew@users.noreply.github.com> Date: Mon, 26 Aug 2024 11:37:54 -0700 Subject: [PATCH] Use new tree/token implicit extensions --- .../main/scala/org/scalafmt/config/Newlines.scala | 2 +- .../src/main/scala/org/scalafmt/config/Spaces.scala | 2 +- .../org/scalafmt/internal/BestFirstSearch.scala | 2 +- .../scala/org/scalafmt/internal/FormatOps.scala | 10 ++++------ .../scala/org/scalafmt/internal/FormatWriter.scala | 2 +- .../main/scala/org/scalafmt/internal/Router.scala | 8 ++++---- .../main/scala/org/scalafmt/internal/State.scala | 2 +- .../scalafmt/rewrite/ConvertToNewScala3Syntax.scala | 5 ++--- .../main/scala/org/scalafmt/rewrite/Imports.scala | 3 +-- .../org/scalafmt/rewrite/RedundantBraces.scala | 10 ++++------ .../org/scalafmt/rewrite/RedundantParens.scala | 7 +++---- .../main/scala/org/scalafmt/util/TokenClasses.scala | 4 ++-- .../src/main/scala/org/scalafmt/util/TokenOps.scala | 3 +-- .../src/main/scala/org/scalafmt/util/TreeOps.scala | 13 ++++++------- 14 files changed, 32 insertions(+), 41 deletions(-) diff --git a/scalafmt-core/shared/src/main/scala/org/scalafmt/config/Newlines.scala b/scalafmt-core/shared/src/main/scala/org/scalafmt/config/Newlines.scala index 455401209d..8e33217302 100644 --- a/scalafmt-core/shared/src/main/scala/org/scalafmt/config/Newlines.scala +++ b/scalafmt-core/shared/src/main/scala/org/scalafmt/config/Newlines.scala @@ -461,7 +461,7 @@ object Newlines { } } case object anyMember extends ForceBeforeMultilineAssign { - def apply(tree: Tree): Boolean = tree.parent.exists(_.is[Template.Body]) + def apply(tree: Tree): Boolean = tree.parent.is[Template.Body] } case object topMember extends ForceBeforeMultilineAssign { def apply(tree: Tree): Boolean = { diff --git a/scalafmt-core/shared/src/main/scala/org/scalafmt/config/Spaces.scala b/scalafmt-core/shared/src/main/scala/org/scalafmt/config/Spaces.scala index c46669abb2..61a893da38 100644 --- a/scalafmt-core/shared/src/main/scala/org/scalafmt/config/Spaces.scala +++ b/scalafmt-core/shared/src/main/scala/org/scalafmt/config/Spaces.scala @@ -73,7 +73,7 @@ case class Spaces( case Spaces.AfterColonInMatchPattern.Never => true case Spaces.AfterColonInMatchPattern.Always => false case Spaces.AfterColonInMatchPattern.NoAlternatives => x.parent - .exists(_.is[meta.Pat.Alternative]) + .is[meta.Pat.Alternative] } case _ => false } diff --git a/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/BestFirstSearch.scala b/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/BestFirstSearch.scala index 7efa17e112..7d64122a28 100644 --- a/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/BestFirstSearch.scala +++ b/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/BestFirstSearch.scala @@ -327,7 +327,7 @@ object BestFirstSearch { if (x eq expire) expire = null else result += x case FormatToken(t: Token.LeftParen, _, m) if (m.leftOwner match { // TODO(olafur) https://github.com/scalameta/scalameta/issues/345 - case lo: Term.ArgClause => !lo.parent.exists(_.is[Term.ApplyInfix]) + case lo: Term.ArgClause => !lo.parent.is[Term.ApplyInfix] case _: Term.Apply => true // legacy: when enclosed in parens case _ => false }) => expire = tokens.matching(t) 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 820b61f701..2ca603908e 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 @@ -1056,7 +1056,7 @@ class FormatOps( tokens.foreach { case ft @ FormatToken(_: T.LeftParen | _: T.LeftBracket, _, m) => m.leftOwner match { - case t: Member.ArgClause if !t.parent.exists(_.is[Member.Infix]) => + case t: Member.ArgClause if !t.parent.is[Member.Infix] => process(t, ft)(callSite) case t: Member.ParamClause => process(t, ft)(defnSite) case t: Type.FuncParamClause => process(t, ft)(defnSite) @@ -1387,9 +1387,7 @@ class FormatOps( ok && (thisTree match { case _: Term.Match => // like select and apply in one - val hasBrace = nextNonComment(tokens(thisSelectLike.nameToken)).right - .is[T.LeftBrace] - !hasBrace || + !tokenAfter(thisSelectLike.nameToken).right.is[T.LeftBrace] || style.includeCurlyBraceInSelectChains && nextSelect.isDefined && !nextSelect.contains(lastApply) case _ => checkParent @@ -1983,7 +1981,7 @@ class FormatOps( case Indents.FewerBraces.never => true case Indents.FewerBraces.always => false case Indents.FewerBraces.beforeSelect => - !p.parent.exists(_.is[Term.Select]) + !p.parent.is[Term.Select] }) || isSelect(p) if (ok) None // select is taken care off elsewhere else Some(style.indent.main + style.indent.getSignificant) @@ -2692,7 +2690,7 @@ class FormatOps( // take last arg when multiple case x => getArgsOrNil(x).view.drop(1).lastOption match { case None | Some(_: Term.Repeated) => false - case Some(t: Term.Param) => !t.decltpe.exists(_.is[Type.Repeated]) + case Some(t: Term.Param) => !t.decltpe.is[Type.Repeated] case _ => true } } diff --git a/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/FormatWriter.scala b/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/FormatWriter.scala index ffdd2e9bb3..70d2169a3b 100644 --- a/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/FormatWriter.scala +++ b/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/FormatWriter.scala @@ -364,7 +364,7 @@ class FormatWriter(formatOps: FormatOps) { @tailrec def noAnnoFor(tree: Tree): Boolean = tree.parent match { case Some(p @ (_: Term | _: Term.ArgClause)) => noAnnoFor(p) - case Some(p: Init) => !p.parent.exists(_.is[Mod.Annot]) + case Some(p: Init) => !p.parent.is[Mod.Annot] case _ => true } val style = floc.style 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 7df40c5135..3c46291797 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 @@ -182,12 +182,12 @@ class Router(formatOps: FormatOps) { Split(Newline, cost).withIndents(alignIndents.getOrElse(mainIndents)) .withPolicy(decideNewlinesOnlyBeforeClose(close)) } - def isSimpleInterpolate = (leftOwner match { + 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]) + }).isOpt[Term.If] style.newlines.inInterpolation match { case Newlines.InInterpolation.avoid => Seq(spaceSplit) @@ -639,7 +639,7 @@ class Router(formatOps: FormatOps) { // see: // https://github.com/scalameta/scalafmt/pull/1516 // https://github.com/scalameta/scalafmt/issues/1528 - case t: Init => t.parent.forall(_.is[Mod.Annot]) + case t: Init => t.parent.isOpt[Mod.Annot] case Term.Name(name) => style.spaces.afterTripleEquals && name == "===" || (rightOwner match { @@ -649,7 +649,7 @@ class Router(formatOps: FormatOps) { case _ => false }) case _: Defn.ExtensionGroup => style.spaces.afterKeywordBeforeParen && - soft.KwExtension.unapply(left) + soft.KwExtension.matches(left) case _ => false }) def baseNoSplit(implicit fileLine: FileLine) = Split(modification, 0) diff --git a/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/State.scala b/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/State.scala index a12bb576ef..5bcae6a6d0 100644 --- a/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/State.scala +++ b/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/State.scala @@ -299,7 +299,7 @@ final case class State( case _: Token.KwMatch => tok.meta.rightOwner.is[Term.Match] && allowed.contains(Indents.RelativeToLhs.`match`) case _: Token.Ident => tok.meta.rightOwner.parent - .exists(_.is[Term.ApplyInfix]) && + .is[Term.ApplyInfix] && allowed.contains(Indents.RelativeToLhs.`infix`) case _ => false }) diff --git a/scalafmt-core/shared/src/main/scala/org/scalafmt/rewrite/ConvertToNewScala3Syntax.scala b/scalafmt-core/shared/src/main/scala/org/scalafmt/rewrite/ConvertToNewScala3Syntax.scala index 6460b32201..2395d18e7c 100644 --- a/scalafmt-core/shared/src/main/scala/org/scalafmt/rewrite/ConvertToNewScala3Syntax.scala +++ b/scalafmt-core/shared/src/main/scala/org/scalafmt/rewrite/ConvertToNewScala3Syntax.scala @@ -65,14 +65,13 @@ private class ConvertToNewScala3Syntax(implicit val ftoks: FormatTokens) replaceTokenIdent("*", ft.right) case t: Type.Wildcard if dialect.allowQuestionMarkAsTypeWildcard && - t.parent.exists(_.is[Type.ArgClause]) => - replaceTokenIdent("?", ft.right) + t.parent.is[Type.ArgClause] => replaceTokenIdent("?", ft.right) case t: Term.Repeated if dialect.allowPostfixStarVarargSplices && isSimpleRepeated(t) => removeToken // see above, under Colon case t: Pat.SeqWildcard if dialect.allowPostfixStarVarargSplices && - t.parent.exists(_.is[Pat.Bind]) => removeToken // see above, under At + t.parent.is[Pat.Bind] => removeToken // see above, under At case _ => null } diff --git a/scalafmt-core/shared/src/main/scala/org/scalafmt/rewrite/Imports.scala b/scalafmt-core/shared/src/main/scala/org/scalafmt/rewrite/Imports.scala index 869f1e3878..3220d3f4ea 100644 --- a/scalafmt-core/shared/src/main/scala/org/scalafmt/rewrite/Imports.scala +++ b/scalafmt-core/shared/src/main/scala/org/scalafmt/rewrite/Imports.scala @@ -368,9 +368,8 @@ object Imports extends RewriteFactory { case t: Importee.Unimport => Some(t.name) case _ => None }).exists { x => - val tokenAfter = ctx.tokenTraverser.nextNonTrivialToken(x.tokens.last) // in scala3, `as` doesn't need braces - tokenAfter.exists(_.is[Token.RightArrow]) + ctx.tokenTraverser.nextNonTrivialToken(x.tokens.last).is[Token.RightArrow] } protected final def getCommentsAround( 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 b9c9cca3a5..040c1223ea 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 @@ -139,8 +139,7 @@ class RedundantBraces(implicit val ftoks: FormatTokens) // single-arg apply of a partial function // a({ case b => c; d }) change to a { case b => c; d } def lpPartialFunction = rtOwner match { - case ta @ Term.ArgClause(arg :: Nil, _) - if !ta.parent.exists(_.is[Init]) => + case ta @ Term.ArgClause(arg :: Nil, _) if !ta.parent.is[Init] => getOpeningParen(ta).map { lp => if (lp.ne(rt) || getBlockNestedPartialFunction(arg).isEmpty) null else ftoks.nextNonCommentAfter(ft) match { @@ -469,9 +468,8 @@ class RedundantBraces(implicit val ftoks: FormatTokens) case t: Term.NewAnonymous => // can't allow: new A with B .foo // can allow if: no ".foo", no "with B", or has braces - !b.parent.exists(_.is[Term.Select]) || - t.templ.inits.lengthCompare(1) <= 0 || t.templ.stats.nonEmpty || - t.tokens.last.is[Token.RightBrace] + !b.parent.is[Term.Select] || t.templ.inits.lengthCompare(1) <= 0 || + t.templ.body.stats.nonEmpty || t.tokens.last.is[Token.RightBrace] case _: Term => true case _ => false } @@ -484,7 +482,7 @@ class RedundantBraces(implicit val ftoks: FormatTokens) !fb.is[Term.Block] || // don't rewrite block if the inner block will be rewritten, too // sometimes a function body block doesn't have braces - fb.tokens.headOption.exists(_.is[Token.LeftBrace]) && + fb.tokens.headOption.is[Token.LeftBrace] && !okToRemoveAroundFunctionBody(fb, true) } case _: Term.Assign => false // f({ a = b }) is not the same as f(a = b) 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 c1b34da0cd..8fc4b6f6d4 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 @@ -144,8 +144,8 @@ class RedundantParens(implicit val ftoks: FormatTokens) private def okToReplaceOther( t: Tree, )(implicit style: ScalafmtConfig): Boolean = t match { - case _: Lit => t.tokens.length == 1 || !t.parent.exists(_.is[Term.Ref]) - case _: Term.ApplyUnary => !t.parent.exists(_.is[Term.Ref]) + case _: Lit => t.tokens.length == 1 || !t.parent.is[Term.Ref] + case _: Term.ApplyUnary => !t.parent.is[Term.Ref] case _: Member.Apply | _: Term.Interpolate | _: Term.PartialFunction => true case t: Term.Select => isSelectWithDot(t) case _: Ref => true // Ref must be after Select and ApplyUnary @@ -159,8 +159,7 @@ class RedundantParens(implicit val ftoks: FormatTokens) t: Member.ArgClause, )(implicit style: ScalafmtConfig): Boolean = t.values match { case arg :: Nil => arg match { - case _: Term.Block | _: Term.PartialFunction => t.parent - .exists(!_.is[Init]) + case _: Term.Block | _: Term.PartialFunction => !t.parent.isOpt[Init] case _: Lit.Unit | _: Member.Tuple => false case t: Term.Select if !isSelectWithDot(t) => false case _ => t.parent.exists { diff --git a/scalafmt-core/shared/src/main/scala/org/scalafmt/util/TokenClasses.scala b/scalafmt-core/shared/src/main/scala/org/scalafmt/util/TokenClasses.scala index c367ffe8fc..eee5ea22db 100644 --- a/scalafmt-core/shared/src/main/scala/org/scalafmt/util/TokenClasses.scala +++ b/scalafmt-core/shared/src/main/scala/org/scalafmt/util/TokenClasses.scala @@ -32,11 +32,11 @@ object LeftParenOrBrace extends TokenClassifier { class SoftKeywordClasses(dialect: Dialect) extends SoftKeywords(dialect) { object ImplicitOrUsing extends TokenClassifier { - def matches(tok: Token): Boolean = tok.is[KwImplicit] || KwUsing.unapply(tok) + def matches(tok: Token): Boolean = tok.is[KwImplicit] || KwUsing.matches(tok) } object ExtendsOrDerives extends TokenClassifier { def matches(tok: Token): Boolean = tok.is[KwExtends] || - KwDerives.unapply(tok) + KwDerives.matches(tok) } } 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 5b59b6019f..eeb5d44c17 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 @@ -64,8 +64,7 @@ object TokenOps { findLastVisibleTokenOpt(tokens).getOrElse(tokens.last) @inline - def withNoIndent(ft: FormatToken): Boolean = ft.between.lastOption - .exists(_.is[AtEOL]) + def withNoIndent(ft: FormatToken): Boolean = ft.between.lastOption.is[AtEOL] @inline def rhsIsCommentedOut(ft: FormatToken): Boolean = ft.right.is[Comment] && 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 ba9e2c0bc6..ecf6124e0f 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 @@ -375,7 +375,7 @@ object TreeOps { new FormatToken.ExtractFromMeta(x => colonDeclType(x.rightOwner)) def isParamClauseSite(tree: Tree): Boolean = tree match { - case _: Type.ParamClause => !tree.parent.exists(_.is[Type.Lambda]) + case _: Type.ParamClause => !tree.parent.is[Type.Lambda] case _: Term.ParamClause => tree.parent match { case Some(p: Term.FunctionTerm) => !isSeqSingle(p.paramClause.values) case _ => true @@ -402,7 +402,7 @@ object TreeOps { token.end def isArgClauseSite(tree: Tree): Boolean = tree match { - case t: Member.ArgClause => !t.parent.exists(_.is[Member.Infix]) || + case t: Member.ArgClause => !t.parent.is[Member.Infix] || (t.values match { case (_: Term.Assign | _: Lit.Unit) :: Nil => true case Nil | _ :: Nil => false @@ -416,7 +416,7 @@ object TreeOps { def noSpaceBeforeOpeningParen(tree: Tree): Boolean = tree match { case _: Term.Super => true - case t: Member.ArgClause => !t.parent.exists(_.is[Member.Infix]) + case t: Member.ArgClause => !t.parent.is[Member.Infix] case _: Member.ParamClause => tree.parent.exists { case _: Term.FunctionTerm => false case t: Ctor.Primary => t.mods.isEmpty || @@ -534,7 +534,7 @@ object TreeOps { def isXmlBrace(owner: Tree): Boolean = owner match { case _: Term.Xml | _: Pat.Xml => true - case b: Term.Block => b.parent.exists(_.isInstanceOf[Term.Xml]) + case b: Term.Block => b.parent.is[Term.Xml] case _ => false } @@ -620,8 +620,7 @@ object TreeOps { def getTreeLineSpan(pos: Position): Int = if (pos.isEmpty) 0 else pos.endLine - pos.startLine - def hasSingleTermStat(t: Term.Block): Boolean = getBlockSingleStat(t) - .exists(_.is[Term]) + def hasSingleTermStat(t: Term.Block): Boolean = getBlockSingleStat(t).is[Term] def hasSingleTermStatIfBlock(t: Tree): Boolean = t match { case b: Term.Block => hasSingleTermStat(b) @@ -1011,7 +1010,7 @@ object TreeOps { case _ => false }) - def isParentAnApply(t: Tree): Boolean = t.parent.exists(_.is[Term.Apply]) + 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)