Skip to content

Commit

Permalink
AvoidInfix: fix isWrapped, look for external paren
Browse files Browse the repository at this point in the history
  • Loading branch information
kitbellew committed May 31, 2022
1 parent 850e98e commit dd63d5d
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class AvoidInfix(implicit ctx: RewriteCtx) extends RewriteSession {
builder += TokenPatch.AddLeft(opHead, ".", keepTok = true)

val opLast = op.tokens.last
val opNextOpt = ctx.tokenTraverser.nextNonTrivialToken(opLast)
val opNextOpt = nextNonTrivial(opLast)

def moveOpenDelim(prev: Token, open: Token): Unit = {
// move delimiter (before comment or newline)
Expand All @@ -65,7 +65,7 @@ class AvoidInfix(implicit ctx: RewriteCtx) extends RewriteSession {
rb <- ctx.getMatchingOpt(lb)
rbNext <- {
moveOpenDelim(opLast, lb)
ctx.tokenTraverser.nextNonTrivialToken(rb)
nextNonTrivial(rb)
}
} yield (rb, rbNext)
// move the left paren if enclosed, else enclose
Expand Down Expand Up @@ -129,9 +129,21 @@ class AvoidInfix(implicit ctx: RewriteCtx) extends RewriteSession {
})
}

private def isWrapped(t: Tree): Boolean = t.tokens.head match {
case h: Token.LeftParen => ctx.getMatchingOpt(h).contains(t.tokens.last)
case _ => false
private def isWrapped(t: Tree): Boolean = {
val head = t.tokens.head
val last = t.tokens.last
isMatching(head, last) ||
ctx.tokenTraverser.prevNonTrivialToken(head).exists {
isMatching(_, nextNonTrivial(last).orNull)
}
}

@inline
private def isMatching(head: Token, last: => Token): Boolean =
head.is[Token.LeftParen] && ctx.isMatching(head, last)

@inline
private def nextNonTrivial(token: Token): Option[Token] =
ctx.tokenTraverser.nextNonTrivialToken(token)

}
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ case class RewriteCtx(
@inline def getMatchingOpt(a: Token): Option[Token] =
matchingParens.get(TokenOps.hash(a))

@inline def isMatching(a: Token, b: Token) =
getMatchingOpt(a).contains(b)
@inline def isMatching(a: Token, b: => Token) =
getMatchingOpt(a).exists(_ eq b)

@inline def getIndex(token: Token) = tokenTraverser.getIndex(token)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,19 @@ class TokenTraverser(tokens: Tokens, input: Input) {
}
}

def nextNonTrivialToken(token: Token): Option[Token] =
findAfter(token)(x => if (x.is[Trivia]) None else Some(true))

def prevToken(token: Token): Token = {
tok2idx.get(token) match {
case Some(i) if i > 0 => tokens(i - 1)
case _ => token
}
}

def nextNonTrivialToken(token: Token): Option[Token] =
findAfter(token)(TokenTraverser.isTrivialPred)

def prevNonTrivialToken(token: Token): Option[Token] =
findBefore(token)(TokenTraverser.isTrivialPred)

/** Find a token after the given one. The search stops when the predicate
* returns Some value (or the end is reached).
* @return
Expand Down Expand Up @@ -119,3 +122,10 @@ class TokenTraverser(tokens: Tokens, input: Input) {
}

}

object TokenTraverser {

private def isTrivialPred(token: Token): Option[Boolean] =
if (token.is[Trivia]) None else Some(true)

}
6 changes: 3 additions & 3 deletions scalafmt-tests/src/test/resources/rewrite/AvoidInfix.stat
Original file line number Diff line number Diff line change
Expand Up @@ -399,14 +399,14 @@ rewrite.neverInfix.includeFilters = [ "[^*]+" ]
===
1 foo (2 +: 3) / 4
>>>
1.foo(((2 +: 3))./(4))
1.foo((2 +: 3)./(4))
<<< avoid double wrap 2
rewrite.neverInfix.includeFilters = [ "[^*]+" ]
===
1 foo ((2) +: 3) / 4
>>>
1.foo((((2) +: 3))./(4))
1.foo(((2) +: 3)./(4))
<<< rewrite wrapped placeholder
foo baz (_)
>>>
foo baz (_)
foo.baz(_)

0 comments on commit dd63d5d

Please sign in to comment.