Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TreeOps: replace SplitCallIntoParts with new Tree interfaces #3424

Merged
merged 1 commit into from
Dec 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -611,15 +611,15 @@ class FormatOps(
case p: Term.Block => isSingleElement(p.stats, child)
case p: Term.FunctionTerm => isBlockFunction(p)
case p @ Member.ArgClause(`child` :: Nil) => isEnclosedInMatching(p)
case SplitCallIntoParts(_, Left(Seq(`child`))) => true
case Member.Tuple(`child` :: Nil) => true
case _ => false
}
def isAloneArgOrBody(child: Tree) = child.parent.exists {
case t: Case => t.pat.eq(child) || t.body.eq(child)
case _: Term.If | _: Term.While | _: Term.Do => true
case _: Member.ArgClause => true
case p: Term.Block => isSingleElement(p.stats, child)
case SplitCallIntoParts(_) => true
case _: Init | _: Term.Super | _: Member.Tuple => true
case t: Tree.WithBody => t.body eq child
case t: Term.Param => t.default.contains(child)
case _ => false
Expand Down Expand Up @@ -1426,8 +1426,8 @@ class FormatOps(
tree match {
case GetSelectLike(t) =>
if (isEnclosed) None else Some(t)
case SplitCallIntoParts(fun, _) if tree ne fun =>
if (isEnclosed) None else findPrevSelect(fun, enclosed)
case t: Member.Apply =>
if (isEnclosed) None else findPrevSelect(t.fun, enclosed)
case Term.AnonymousFunction(body) =>
if (enclosed) None else findPrevSelect(body, false)
case _ => None
Expand All @@ -1450,7 +1450,7 @@ class FormatOps(
tree.parent match {
case Some(GetSelectLike(p)) =>
findLastApplyAndNextSelectEnclosed(p.tree, select.orElse(Some(p)))
case Some(p @ SplitCallIntoParts(`tree`, _)) =>
case Some(p: Member.Apply) if p.fun eq tree =>
findLastApplyAndNextSelectEnclosed(p, select)
case _ => (tree, select)
}
Expand All @@ -1464,7 +1464,7 @@ class FormatOps(
tree.parent match {
case Some(GetSelectLike(p)) =>
findLastApplyAndNextSelectPastEnclosed(p.tree, select.orElse(Some(p)))
case Some(p @ SplitCallIntoParts(`tree`, _)) =>
case Some(p: Member.Apply) if p.fun eq tree =>
prevEnclosed match {
case Some(t) => (t, select)
case _ =>
Expand Down Expand Up @@ -1497,7 +1497,7 @@ class FormatOps(
if tokens.getHead(p.argClause).left.is[T.LeftBrace] =>
style.includeCurlyBraceInSelectChains &&
!nextSelect.contains(lastApply) // exclude short curly
case Some(SplitCallIntoParts(`thisTree`, _)) => true
case Some(p: Member.Apply) => p.fun eq thisTree
case _ => false
})
}
Expand Down Expand Up @@ -1563,17 +1563,17 @@ class FormatOps(
@tailrec
private def getOpenNLByArgs(
ft: FormatToken,
argss: Seq[Seq[Tree]],
argClauses: Seq[Member.ArgClause],
penalty: Int,
policies: Seq[Policy]
): Seq[Policy] = {
if (argss.isEmpty) policies
if (argClauses.isEmpty) policies
else {
val args = argss.head
val args = argClauses.head.values
val openFt = nextNonComment(ft)
if (args.isEmpty) {
val nextFt = next(nextNonComment(next(openFt)))
getOpenNLByArgs(nextFt, argss.tail, penalty, policies)
getOpenNLByArgs(nextFt, argClauses.tail, penalty, policies)
} else {
val endPolicy = tokens.getHead(args.head).left match {
case t: T.LeftBrace => Policy.End.After(t)
Expand All @@ -1585,27 +1585,23 @@ class FormatOps(
Policy.End.On(openFt.right)
) +: policies
val nextPolicies = args match {
case Seq(SplitCallIntoParts(f, a)) =>
getOpenNLByTree(f, a, withPnl, penalty)
case (t: Member.Apply) :: Nil =>
getOpenNLByTree(t.fun, Seq(t.argClause), withPnl, penalty)
case _ => withPnl
}
getOpenNLByArgs(argLastFt, argss.tail, penalty, nextPolicies)
getOpenNLByArgs(argLastFt, argClauses.tail, penalty, nextPolicies)
}
}
}

private def getOpenNLByTree(
fun: Tree,
argsOrArgss: CallArgs,
argClauses: Seq[Member.ArgClause],
policies: Seq[Policy],
penalty: Int
): Seq[Policy] = {
val argss = argsOrArgss match {
case Left(x) => Seq(x)
case Right(x) => x
}
val funLastFt = tokens.getLast(fun)
getOpenNLByArgs(funLastFt, argss, penalty, policies)
getOpenNLByArgs(funLastFt, argClauses, penalty, policies)
}

@tailrec
Expand All @@ -1614,10 +1610,13 @@ class FormatOps(
policy: Policy = Policy.NoPolicy
): Policy =
body match {
case SplitCallIntoParts(fun, args) if fun ne body =>
val nextPolicy = getOpenNLByTree(fun, args, Nil, 1)
case t: Member.Apply if t.fun ne body =>
val nextPolicy = getOpenNLByTree(t.fun, t.argClause :: Nil, Nil, 1)
.foldLeft(policy) { case (res, x) => Policy.Relay(x, res) }
getFoldedPolicy(t.fun, nextPolicy)
case t: Init =>
getOpenNLByTree(t.tpe, t.argClauses, Nil, 1)
.foldLeft(policy) { case (res, x) => Policy.Relay(x, res) }
getFoldedPolicy(fun, nextPolicy)
case t: Term.Select => getFoldedPolicy(t.qual, policy)
case _ => policy
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1698,7 +1698,7 @@ class Router(formatOps: FormatOps) {
rightOwner.is[Term.Select] && findTreeWithParent(rightOwner) {
case _: Term.ArgClause => None
case _: Type.Select | _: Importer | _: Pkg => Some(true)
case _: Term.Select | SplitCallIntoParts(_, _) => None
case _: Term.Select | _: Member.Apply => None
case _ => Some(false)
}.isDefined =>
Seq(Split(NoSplit, 0))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ class RedundantParens(ftoks: FormatTokens) extends FormatTokensRewrite.Rule {
): Boolean =
t match {
case _: Lit | _: Name | _: Term.Interpolate => true
case _: Term.PartialFunction | _: Term.Apply => true
case _: Term.PartialFunction | _: Member.Apply => true
case t: Term.Select =>
ftoks.tokenBefore(t.name).left.is[Token.Dot]
case t: Term.Match
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -443,29 +443,6 @@ object TreeOps {
case _ => false
}

type CallArgs = Either[Seq[Tree], Seq[Seq[Tree]]]
type CallParts = (Tree, CallArgs)
val splitCallIntoParts: PartialFunction[Tree, CallParts] = {
case t: Term.Apply => (t.fun, Left(t.args))
case t: Term.Super => (t, Left(Seq(t.superp)))
case t: Pat.Extract => (t.fun, Left(t.args))
case t: Pat.Tuple => (t, Left(t.args))
case t: Type.Apply => (t.tpe, Left(t.args))
case t: Term.ApplyType => (t.fun, Left(t.targs))
case t: Term.Tuple => (t, Left(t.args))
case t: Term.FunctionTerm => (t, Left(t.params))
case t: Term.PolyFunction => (t, Left(t.tparams))
case t: Type.FunctionType => (t, Left(t.params))
case t: Type.PolyFunction => (t, Left(t.tparams))
case t: Type.Tuple => (t, Left(t.args))
case t: Init => (t.tpe, Right(t.argss))
case t: Term.ApplyUsing => (t.fun, Left(t.args))
}
object SplitCallIntoParts {
def unapply(tree: Tree): Option[CallParts] =
splitCallIntoParts.lift(tree)
}

val DefValAssignLeft =
new FormatToken.ExtractFromMeta(_.leftOwner match {
case _: Enumerator => None // it's WithBody
Expand Down Expand Up @@ -706,8 +683,8 @@ object TreeOps {
tree match {
case t: Term.Select if res.isDefined => traverse(t.qual, Some(t.qual))
case t: Term.ApplyType => traverse(t.fun, Some(t))
case SplitCallIntoParts(fun, _) if fun ne tree =>
traverse(fun, Some(fun))
case t: Member.Apply => traverse(t.fun, Some(t.fun))
case t: Init => traverse(t.tpe, Some(t.tpe))
case _ => res
}
}
Expand All @@ -718,14 +695,11 @@ object TreeOps {
@tailrec
private def getLastCall(tree: Tree, lastCall: Tree): Tree = {
// this is to cover types which include one parameter group at a time
def body = tree match {
case t: Term.Apply => t.fun
case t: Pat.Extract => t.fun
case t: Term.ApplyType => t.fun
case t: Term.ApplyUsing => t.fun
case _ => tree
val matches = tree match {
case t: Member.Apply if t.fun eq lastCall => true
case _ => tree eq lastCall
}
if (lastCall.eq(tree) || lastCall.eq(body))
if (matches)
tree.parent match {
case Some(p) => getLastCall(p, tree)
case _ => tree
Expand Down Expand Up @@ -835,9 +809,9 @@ object TreeOps {
case Some(p: Term.New) => followedBySelectOrApply(p)
case Some(_: Term.Select) => true
case Some(p: Member.Infix) => p.lhs.eq(tree) || followedBySelectOrApply(p)
case Some(SplitCallIntoParts(`tree`, args)) =>
args match {
case Left(Seq(_: Term.Block | _: Term.PartialFunction)) => false
case Some(p: Member.Apply) if p.fun eq tree =>
p.argClause.values match {
case (_: Term.Block | _: Term.PartialFunction) :: Nil => false
case _ => true
}
case _ => false
Expand Down