Skip to content

Commit

Permalink
FormatOps: enclosing parens owned by enclosed tree
Browse files Browse the repository at this point in the history
  • Loading branch information
kitbellew committed Nov 29, 2022
1 parent e9495ee commit cdee46b
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2063,14 +2063,14 @@ class FormatOps(
indentOpt: Option[Int] = None
)(implicit fileLine: FileLine, style: ScalafmtConfig): Seq[Split] = {
val treeTokens = tree.tokens
val end = tokens.getLast(treeTokens)
val end = tokens.getLast(treeTokens, tree)
val slbExpire = nextNonCommentSameLine(end).left
val closeOpt =
if (isTuple(tree)) None
else {
val maybeClose = prevNonComment(end)
tokens
.getClosingIfInParens(maybeClose)(tokens.getHead(treeTokens))
.getClosingIfInParens(maybeClose)(tokens.getHead(treeTokens, tree))
.map(prevNonComment(_).left)
}
def nlPolicy(implicit fileLine: FileLine) =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ class FormatTokens(leftTok2tok: Map[TokenOps.TokenHash, Int])(
}
def getClosingIfInParens(tree: Tree): Option[FormatToken] = {
val tokens = tree.tokens
getHeadOpt(tokens).flatMap(getClosingIfInParens(getLastNonTrivial(tokens)))
getHeadOpt(tokens, tree)
.flatMap(getClosingIfInParens(getLastNonTrivial(tokens, tree)))
}

def getLastExceptParen(tokens: Tokens): FormatToken = {
Expand Down Expand Up @@ -159,35 +160,61 @@ class FormatTokens(leftTok2tok: Map[TokenOps.TokenHash, Int])(
final def prevNonCommentBefore(curr: FormatToken): FormatToken =
prevNonComment(prev(curr))

def getHead(tokens: Tokens): FormatToken =
@tailrec
final def getOnOrBeforeOwned(ft: FormatToken, tree: Tree): FormatToken = {
val prevFt = prevNonCommentBefore(ft)
if (prevFt == ft || prevFt.meta.leftOwner != tree) ft
else getOnOrBeforeOwned(prevFt, tree)
}

@tailrec
final def getOnOrAfterOwned(ft: FormatToken, tree: Tree): FormatToken = {
val nextFt = next(nextNonComment(ft))
if (nextFt == ft || nextFt.meta.leftOwner != tree) ft
else getOnOrAfterOwned(nextFt, tree)
}

private def getHead(tokens: Tokens): FormatToken =
after(tokens.head)
def getHead(tree: Tree): FormatToken =
getHead(tree.tokens)
def getHead(tokens: Tokens, tree: Tree): FormatToken =
getOnOrBeforeOwned(getHead(tokens), tree)
@inline def getHead(tree: Tree): FormatToken =
getHead(tree.tokens, tree)

def getHeadOpt(tokens: Tokens): Option[FormatToken] =
private def getHeadOpt(tokens: Tokens): Option[FormatToken] =
tokens.headOption.map(after)
def getHeadOpt(tree: Tree): Option[FormatToken] =
getHeadOpt(tree.tokens)
def getHeadOpt(tokens: Tokens, tree: Tree): Option[FormatToken] =
getHeadOpt(tokens).map(getOnOrBeforeOwned(_, tree))
@inline def getHeadOpt(tree: Tree): Option[FormatToken] =
getHeadOpt(tree.tokens, tree)

def getLast(tokens: Tokens): FormatToken =
private def getLast(tokens: Tokens): FormatToken =
apply(TokenOps.findLastVisibleToken(tokens))
def getLast(tree: Tree): FormatToken =
getLast(tree.tokens)
def getLast(tokens: Tokens, tree: Tree): FormatToken =
getOnOrAfterOwned(getLast(tokens), tree)
@inline def getLast(tree: Tree): FormatToken =
getLast(tree.tokens, tree)

def getLastOpt(tokens: Tokens): Option[FormatToken] =
private def getLastOpt(tokens: Tokens): Option[FormatToken] =
TokenOps.findLastVisibleTokenOpt(tokens).map(apply)
def getLastOpt(tree: Tree): Option[FormatToken] =
getLastOpt(tree.tokens)
def getLastOpt(tokens: Tokens, tree: Tree): Option[FormatToken] =
getLastOpt(tokens).map(getOnOrAfterOwned(_, tree))
@inline def getLastOpt(tree: Tree): Option[FormatToken] =
getLastOpt(tree.tokens, tree)

def getLastNonTrivial(tokens: Tokens): FormatToken =
private def getLastNonTrivial(tokens: Tokens): FormatToken =
apply(TokenOps.findLastNonTrivialToken(tokens))
def getLastNonTrivial(tokens: Tokens, tree: Tree): FormatToken =
getOnOrAfterOwned(getLastNonTrivial(tokens), tree)
def getLastNonTrivial(tree: Tree): FormatToken =
getLastNonTrivial(tree.tokens)
getLastNonTrivial(tree.tokens, tree)

def getLastNonTrivialOpt(tokens: Tokens): Option[FormatToken] =
private def getLastNonTrivialOpt(tokens: Tokens): Option[FormatToken] =
TokenOps.findLastNonTrivialTokenOpt(tokens).map(apply)
def getLastNonTrivialOpt(tokens: Tokens, tree: Tree): Option[FormatToken] =
getLastNonTrivialOpt(tokens).map(getOnOrAfterOwned(_, tree))
def getLastNonTrivialOpt(tree: Tree): Option[FormatToken] =
getLastNonTrivialOpt(tree.tokens)
getLastNonTrivialOpt(tree.tokens, tree)

/* the following methods return the first format token such that
* its `right` is after the parameter and is not a comment */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -946,8 +946,9 @@ object TreeOps {
ownersMap += hash(tok) -> tree

val allTokens = topSourceTree.tokens(baseStyle.dialect)
var prevParens: List[Token] = Nil

def treeAt(elemIdx: Int, elem: Tree): Int = {
def treeAt(elemIdx: Int, elem: Tree, outerPrevLPs: Int): Int = {
if (TreeOps.isInfixApp(elem)) infixCount += 1

val endPos = elem.pos.end
Expand Down Expand Up @@ -978,6 +979,8 @@ object TreeOps {
var nextChild = firstChild
var nextChildStart = firstChildStart
var children = rest
var prevChild: Tree = null
var prevLPs = outerPrevLPs

@tailrec
def tokenAt(idx: Int): Int = {
Expand All @@ -986,7 +989,9 @@ object TreeOps {
val tok = allTokens(idx)
if (nextChild == null && elemIdx != 0 && tok.start >= endPos) idx
else if (nextChild != null && tok.end > nextChildStart) {
val nextIdx = treeAt(idx, nextChild)
if (prevChild != null) prevLPs = 0
prevChild = nextChild
val nextIdx = treeAt(idx, nextChild, prevLPs)
children match {
case Nil =>
nextChild = null
Expand All @@ -997,7 +1002,41 @@ object TreeOps {
}
tokenAt(nextIdx)
} else {
setOwner(tok, elem)
def excludeRightParen: Boolean = elem match {
case t: Term.If => prevChild eq t.cond // `expr` after `mods`
case _: Term.While | _: Term.For | _: Term.ForYield =>
prevChild eq firstChild // `expr` is first
case _: Term.Tuple | _: Type.Tuple | _: Pat.Tuple |
_: Term.ApplyInfix | _: Pat.ExtractInfix | _: Term.Apply |
_: Pat.Extract | _: Term.Do | _: Term.AnonymousFunction =>
nextChild == null
case _: Decl.Def | _: Decl.Given | _: Type.FunctionType |
_: Defn.Def | _: Defn.Macro | _: Defn.Given |
_: Defn.GivenAlias | _: Defn.ExtensionGroup =>
nextChild != null // body is next
case _: Init | _: Ctor => true
case _ => false
}

if (prevParens.nonEmpty && tok.is[RightParen]) {
if (prevChild == null || prevLPs == 0 || excludeRightParen)
setOwner(tok, elem)
else {
prevLPs -= 1
setOwner(tok, prevChild)
setOwner(prevParens.head, prevChild)
}
prevParens = prevParens.tail
} else {
setOwner(tok, elem)
if (!tok.is[Trivia] && nextChild != null) {
prevChild = null
if (tok.is[LeftParen]) {
prevLPs += 1
prevParens = tok :: prevParens
} else prevLPs = 0
}
}
tokenAt(idx + 1)
}
}
Expand All @@ -1006,7 +1045,7 @@ object TreeOps {
}
}

treeAt(0, topSourceTree)
treeAt(0, topSourceTree, 0)

val checkedNewlines = baseStyle.newlines.checkInfixConfig(infixCount)
val initStyle =
Expand Down

0 comments on commit cdee46b

Please sign in to comment.