Skip to content

Commit

Permalink
FormatTokens: check outside parens for enclosed
Browse files Browse the repository at this point in the history
In scalameta v4.5.6, some enclosed trees do not actually contain the
enclosing parentheses, hence check for these cases.
  • Loading branch information
kitbellew committed May 18, 2022
1 parent 6b81790 commit f72b624
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ object Error {
extends Error("Formatter output does not parse:\n" + msg)

case class UnexpectedTree[Expected <: Tree: ClassTag](obtained: Tree)
extends Error(s"""Expected: ${classTag[Expected].runtimeClass.getClass}
extends Error(s"""Expected: ${classTag[Expected].runtimeClass.getName}
|Obtained: ${log(obtained)}""".stripMargin)

case class CantFormatFile(msg: String)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,7 @@ class FormatOps(
fullInfix: InfixApp,
leftInfix: InfixApp
)(implicit style: ScalafmtConfig) {
private val beforeLhs = ft.left.start < app.all.tokens.head.start
private val beforeLhs = ft.left.start < app.all.pos.start
private val fullExpire = getLastEnclosedToken(fullInfix.all)
private val isFirstOp = beforeLhs || (leftInfix.op eq app.op)

Expand All @@ -586,9 +586,10 @@ class FormatOps(
val prevOwner = prevFt.meta.leftOwner
prevFt.left match {
case _: T.Equals => Some(getLastToken(prevOwner))
case _: T.Comma | _: T.LeftParen | _: T.LeftBracket
if isCallSiteLeft(prevFt) && fullAll.parent.contains(prevOwner) &&
isSeqSingle(getApplyArgs(prevFt, false).args) =>
case lp @ (_: T.LeftParen | _: T.LeftBracket)
if fullAll.parent.contains(prevOwner) && !isInfixApp(prevOwner) &&
Option(getApplyArgs(lp, prevOwner, false, orNull = true))
.exists(x => isSeqSingle(x.args)) =>
Some(getLastToken(fullAll))
case _ => None
}
Expand Down Expand Up @@ -1389,7 +1390,10 @@ class FormatOps(
case fun: Term.FunctionTerm if fun.parent.exists {
case Term.ApplyInfix(_, _, _, List(`fun`)) => true
case _ => false
} =>
} && fun.pos.start == ft.left.start =>
Some(fun)
case Term.ApplyInfix(_, before, _, List(fun: Term.FunctionTerm))
if before.pos.end <= ft.left.start =>
Some(fun)
case t: Init =>
findArgsFor(ft.left, t.argss).collect {
Expand Down Expand Up @@ -1437,6 +1441,15 @@ class FormatOps(
): TreeArgs = {
val paren = if (isRight) ft.right else ft.left
val owner = if (isRight) ft.meta.rightOwner else ft.meta.leftOwner
getApplyArgs(paren, owner, isRight)
}

def getApplyArgs(
paren: T,
owner: Tree,
isRight: Boolean,
orNull: Boolean = false
): TreeArgs = {
def getArgs(argss: Seq[Seq[Tree]]): Seq[Tree] =
findArgsFor(paren, argss).getOrElse(Seq.empty)
owner match {
Expand All @@ -1454,8 +1467,12 @@ class FormatOps(
}
case _ =>
owner.parent match {
case Some(Term.ApplyInfix(_, op, _, rhs @ List(`owner`))) =>
case Some(Term.ApplyInfix(_, op, _, rhs @ List(`owner`))) if {
val ownerTokens = owner.tokens
ownerTokens.head == paren && isEnclosedInMatching(ownerTokens)
} =>
TreeArgs(op, rhs)
case _ if orNull => null
case p =>
logger.debug(s"""getApplyArgs: unknown tree
|Tree: ${log(owner)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,12 @@ class FormatTokens(leftTok2tok: Map[TokenOps.TokenHash, Int])(
last: FormatToken
)(head: FormatToken): Option[FormatToken] =
if (areMatchingParens(last.left)(head.left)) Some(prev(last))
else None
else {
val afterLast = nextNonComment(last)
if (areMatchingParens(afterLast.right)(prevNonCommentBefore(head).left))
Some(afterLast)
else None
}
def getClosingIfInParens(tokens: Tokens): Option[FormatToken] =
getHeadOpt(tokens).flatMap(getClosingIfInParens(getLastNonTrivial(tokens)))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ class Router(formatOps: FormatOps) {
import tokens.{
matching,
matchingOpt,
isEnclosedInMatching,
prev,
next,
tokenBefore,
Expand Down Expand Up @@ -934,7 +933,7 @@ class Router(formatOps: FormatOps) {

val sourceIgnored = style.newlines.sourceIgnored
val isSingleEnclosedArgument =
singleArgument && isEnclosedInMatching(args(0))
singleArgument && tokens.isEnclosedInMatching(args(0))
val useConfigStyle = onlyConfigStyle || (sourceIgnored &&
style.optIn.configStyleArguments && !isSingleEnclosedArgument)

Expand Down Expand Up @@ -2103,12 +2102,13 @@ class Router(formatOps: FormatOps) {
case FormatToken(open: T.LeftParen, right, _) =>
val isConfig = couldUseConfigStyle(formatToken)
val close = matching(open)
val enclosed = findEnclosedBetweenParens(open, close, leftOwner)
def spaceSplitWithoutPolicy(implicit fileLine: FileLine) = {
val indent: Length = right match {
case T.KwIf() => StateColumn
case T.KwFor() if !style.indentYieldKeyword => StateColumn
case _ =>
if (leftOwner.is[Term.ApplyInfix]) Num(0)
if (enclosed.exists(_.is[Term.ApplyInfix])) Num(0)
else {
val closeFt = tokens(close, -1)
val willBreak = closeFt.left.is[T.Comment] &&
Expand Down Expand Up @@ -2139,18 +2139,19 @@ class Router(formatOps: FormatOps) {
case Newlines.keep =>
Seq(if (newlines != 0) newlineSplit(0, isConfig) else spaceSplit)
case _ =>
val singleLine = !isSuperfluousParenthesis(open, leftOwner) ||
val singleLine = enclosed.forall { x =>
style.newlines.source.eq(Newlines.unfold) &&
leftOwner.parent.exists {
x.parent.exists {
case _: Template | _: Defn => false
case InfixApp(_) => false
case _ => true
}
}
Seq(
if (!singleLine) spaceSplit
else {
val singleLineInfixPolicy =
if (!isInfixApp(leftOwner)) None
if (!enclosed.exists(isInfixApp)) None
else Some(getSingleLineInfixPolicy(close))
spaceSplitWithoutPolicy
.withSingleLine(close)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,12 @@ object TreeOps {
}

def isCallSiteLeft(ft: FormatToken)(implicit style: ScalafmtConfig): Boolean =
isCallSite(ft.meta.leftOwner)
ft.meta.leftOwner match {
case Term.ApplyInfix(_, op, _, List(arg))
if op.pos.end <= ft.left.start => // parens used to belong to rhs
isCallSite(arg)
case t => isCallSite(t)
}

def isTuple(tree: Tree): Boolean =
tree match {
Expand Down

0 comments on commit f72b624

Please sign in to comment.