From 87846179b8499d9392ac2002e0cceb08ef5157b9 Mon Sep 17 00:00:00 2001 From: Albert Meltzer <7529386+kitbellew@users.noreply.github.com> Date: Sun, 5 May 2024 17:40:41 -0700 Subject: [PATCH] {Format,Tree}Ops: use token index instead of hash --- .../scalafmt/internal/BestFirstSearch.scala | 10 ++--- .../org/scalafmt/internal/FormatOps.scala | 37 ++++++++++--------- .../scala/org/scalafmt/internal/Router.scala | 4 +- .../scala/org/scalafmt/util/TreeOps.scala | 6 +-- 4 files changed, 27 insertions(+), 30 deletions(-) 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 58f35701e9..7b86641abe 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 @@ -7,7 +7,6 @@ import org.scalafmt.config.FormatEvent.Explored import org.scalafmt.config.FormatEvent.VisitToken import org.scalafmt.config.ScalafmtConfig import org.scalafmt.util.LoggerOps -import org.scalafmt.util.TokenOps import org.scalafmt.util.TreeOps import scala.meta.Term @@ -25,7 +24,6 @@ private class BestFirstSearch private ( )(implicit val formatOps: FormatOps) { import BestFirstSearch._ import LoggerOps._ - import TokenOps._ import TreeOps._ import formatOps._ @@ -132,15 +130,13 @@ private class BestFirstSearch private ( tokens(deepestYet.depth), ) - if (curr.split != null && curr.split.isNL) { - val tokenHash = hash(leftTok) + if (curr.split != null && curr.split.isNL) if ( - emptyQueueSpots.contains(tokenHash) || + emptyQueueSpots.contains(curr.depth) || dequeueOnNewStatements && curr.allAltAreNL && !(depth == 0 && noOptZone) && - (leftTok.is[Token.KwElse] || statementStarts.contains(tokenHash)) + (leftTok.is[Token.KwElse] || statementStarts.contains(curr.depth)) ) addGeneration() - } val blockClose = if (start == curr && 0 != maxCost || !noOptZone) None 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 708873f0bb..123ce0c88e 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 @@ -208,11 +208,8 @@ class FormatOps( case _ => false }) - @inline - final def startsStatement(token: T): Option[Tree] = statementStarts - .get(hash(token)) val StartsStatementRight = - new ExtractFromMeta[Tree](meta => startsStatement(tokens(meta.idx).right)) + new ExtractFromMeta[Tree](meta => statementStarts.get(meta.idx + 1)) def parensTuple(token: T): TokenRanges = matchingOpt(token) .fold(TokenRanges.empty)(other => TokenRanges(TokenRange(token, other))) @@ -879,7 +876,7 @@ class FormatOps( opensConfigStyleImplicitParamList(ft) def opensConfigStyle = !style.newlines.sourceIgnored && // classic (ft.hasBreak || opensImplicit) && beforeCloseFt.hasBreak - if (allowForce && forceConfigStyle(hash(ft.left))) ConfigStyle.Forced + if (allowForce && forceConfigStyle(ft.meta.idx)) ConfigStyle.Forced else if (opensConfigStyle) ConfigStyle.Source else ConfigStyle.None } @@ -1028,30 +1025,34 @@ class FormatOps( } else Seq(Split(Space, 0), Split(Newline, 1)) } - def getForceConfigStyle: (Set[TokenHash], Set[TokenHash]) = { + def getForceConfigStyle: (Set[Int], Set[Int]) = { val maxDistance = initStyle.runner.optimizer.forceConfigStyleMinSpan if (maxDistance < 0) (Set.empty, Set.empty) else { - val clearQueues = Set.newBuilder[TokenHash] - val forces = Set.newBuilder[TokenHash] + val clearQueues = Set.newBuilder[Int] + val forces = Set.newBuilder[Int] val minArgs = initStyle.runner.optimizer.forceConfigStyleMinArgCount - def process(args: Seq[Tree], open: T, close: T): Unit = + def process( + clause: Member.SyntaxValuesClause, + ftOpen: FormatToken, + ): Unit = matchingOpt(ftOpen.left).foreach { close => + val values = clause.values if ( - args.lengthCompare(minArgs) >= 0 && - distance(open, close) > maxDistance + values.lengthCompare(minArgs) >= 0 && + distance(ftOpen.left, close) > maxDistance ) { - forces += hash(open) - args.foreach(arg => clearQueues += hash(getHeadToken(arg))) + forces += ftOpen.meta.idx + values.foreach(x => clearQueues += tokens.getHead(x).meta.idx) } + } tokens.foreach { - case FormatToken(left: T.LeftParen, _, meta) => meta.leftOwner match { + case ft @ FormatToken(_: T.LeftParen, _, m) => m.leftOwner match { case t: Term.ArgClause if !t.parent.exists(_.is[Term.ApplyInfix]) => - matchingOpt(left).foreach(process(t.values, left, _)) + process(t, ft) case _ => } - case FormatToken(left: T.LeftBracket, _, meta) => meta.leftOwner match { - case t: Type.ArgClause => matchingOpt(left) - .foreach(process(t.values, left, _)) + case ft @ FormatToken(_: T.LeftBracket, _, m) => m.leftOwner match { + case t: Type.ArgClause => process(t, ft) case _ => } case _ => 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 556a795415..731d37973b 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 @@ -221,7 +221,7 @@ class Router(formatOps: FormatOps) { ) if dialect.allowSignificantIndentation => splits // { ... } Blocks - case tok @ FormatToken(open @ T.LeftBrace(), right, _) => + case tok @ FormatToken(open @ T.LeftBrace(), right, m) => val close = matching(open) val closeFT = tokens(close) val newlineBeforeClosingCurly = decideNewlinesOnlyBeforeClose(close) @@ -246,7 +246,7 @@ class Router(formatOps: FormatOps) { // lambdaNLOnly: None for single line only val (lambdaExpire, lambdaArrow, lambdaIndent, lambdaNLOnly) = - startsStatement(right) match { + statementStarts.get(m.idx + 1) match { case Some(owner: Term.FunctionTerm) if (leftOwner match { case t: Template => t.parent .exists(_.is[Term.NewAnonymous]) && 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 468fe94d27..24eee07165 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 @@ -129,11 +129,11 @@ object TreeOps { def getStatementStarts(tree: Tree, soft: SoftKeywordClasses)(implicit ftoks: FormatTokens, - ): Map[TokenHash, Tree] = { - val ret = Map.newBuilder[TokenHash, Tree] + ): Map[Int, Tree] = { + val ret = Map.newBuilder[Int, Tree] ret.sizeHint(tree.tokens.length) - def addFT(ft: FormatToken, tree: Tree): Unit = ret += hash(ft.left) -> tree + def addFT(ft: FormatToken, tree: Tree): Unit = ret += ft.meta.idx -> tree def addTok(token: Token, tree: Tree) = addFT(ftoks.after(token), tree) def addTree(t: Tree, o: Tree) = ftoks.getHeadOpt(t).foreach(addFT(_, o)) def addOne(t: Tree) = addTree(t, t)