Skip to content

Commit

Permalink
TokenClasses: don't use classifiers
Browse files Browse the repository at this point in the history
Scalameta is gradually phasing out macros, so let's stop using custom
classifiers.

Also, let's switch to using standard scalameta token branches instead
of custom ones defined within scalafmt:
- Trivia -> Token.Trivia
- Whitespace -> Token.Whitespace
- Delim -> Token.Symbolic
- Literal -> Token.Literal
- rename Keyword as Reserved and represent it as Token.Keyword and
  false/true/null
- remove Modifier since it's covered by Reserved and used only once,
  where Reserved applies already
  • Loading branch information
kitbellew committed Oct 23, 2023
1 parent 12db65f commit b103a89
Show file tree
Hide file tree
Showing 9 changed files with 43 additions and 123 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -931,11 +931,11 @@ class FormatOps(

def functionExpire(function: Term.FunctionTerm): (T, ExpiresOn) = {
def dropWS(rtoks: Seq[T]): Seq[T] =
rtoks.dropWhile(_.is[Whitespace])
rtoks.dropWhile(_.is[T.Whitespace])
def orElse(rtoks: Seq[T]) = {
val last = rtoks.head
if (last.is[T.RightParen] && matchingOpt(last).contains(rtoks.last))
rtoks.tail.find(!_.is[Whitespace]).get -> ExpiresOn.After
rtoks.tail.find(!_.is[T.Whitespace]).get -> ExpiresOn.After
else
last -> ExpiresOn.After
}
Expand Down Expand Up @@ -1012,7 +1012,7 @@ class FormatOps(
def opensConfigStyleImplicitParamList(
formatToken: FormatToken
)(implicit style: ScalafmtConfig): Boolean =
formatToken.right.is[soft.ImplicitOrUsing] &&
soft.ImplicitOrUsing.unapply(formatToken.right) &&
style.newlines.notBeforeImplicitParamListModifier &&
hasImplicitParamList(formatToken.meta.rightOwner)

Expand Down Expand Up @@ -1332,7 +1332,7 @@ class FormatOps(
val nlSplit = Split(Newline, 1, policy = policy).withIndent(firstIndent)
Seq(slbSplit, noSplit.andPolicy(noSlbPolicy), nlSplit)
} else {
val rightIsImplicit = r.is[soft.ImplicitOrUsing]
val rightIsImplicit = soft.ImplicitOrUsing.unapply(r)
val implicitNL = rightIsImplicit &&
style.newlines.forceBeforeImplicitParamListModifier
val implicitParams = if (rightIsImplicit) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ object FormatTokens {
val tokCnt = arr.length
while (tokIdx < tokCnt)
arr(tokIdx) match {
case Whitespace() => tokIdx += 1
case _: Token.Whitespace => tokIdx += 1
case right =>
process(right)
tokIdx += 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,7 @@ class Router(formatOps: FormatOps) {
_: T.RightParen,
_,
ParamClauseParentLeft(extGroup: Defn.ExtensionGroup)
) if nextNonComment(formatToken).right.isNot[LeftParenOrBrace] =>
) if !LeftParenOrBrace.unapply(nextNonComment(formatToken).right) =>
val expireToken = getLastToken(extGroup)
def nlSplit(cost: Int = 0)(implicit fileLine: FileLine) =
Split(Newline, cost).withIndent(style.indent.main, expireToken, After)
Expand Down Expand Up @@ -616,11 +616,11 @@ class Router(formatOps: FormatOps) {
!style.optIn.annotationNewlines && annoRight
case Newlines.fold =>
right.is[T.Comment] || annoRight ||
!style.optIn.annotationNewlines && right.is[Keyword]
!style.optIn.annotationNewlines && Reserved.unapply(right)
case Newlines.keep =>
newlines == 0 && (annoRight || right.is[Keyword])
newlines == 0 && (annoRight || Reserved.unapply(right))
case _ =>
newlines == 0 && right.is[Keyword]
newlines == 0 && Reserved.unapply(right)
})
Seq(
// This split needs to have an optimalAt field.
Expand Down Expand Up @@ -677,7 +677,8 @@ class Router(formatOps: FormatOps) {
case _ => false
})
case _: Defn.ExtensionGroup =>
style.spaces.afterKeywordBeforeParen && left.is[soft.KwExtension]
style.spaces.afterKeywordBeforeParen &&
soft.KwExtension.unapply(left)
case _ => false
})
def baseNoSplit(implicit fileLine: FileLine) = Split(modification, 0)
Expand Down Expand Up @@ -1930,7 +1931,7 @@ class Router(formatOps: FormatOps) {
else baseSplits ++ splits.map(_.onlyFor(SplitTag.SelectChainFirstNL))

// ApplyUnary
case FormatToken(T.Ident(_), Literal(), _) if leftOwner == rightOwner =>
case FormatToken(T.Ident(_), T.Literal(), _) if leftOwner == rightOwner =>
Seq(
Split(NoSplit, 0)
)
Expand All @@ -1951,7 +1952,7 @@ class Router(formatOps: FormatOps) {
Seq(
Split(Space, 0)
)
case FormatToken(T.At(), Delim(), _) =>
case FormatToken(T.At(), _: T.Symbolic, _) =>
Seq(Split(NoSplit, 0))
case FormatToken(T.At(), right @ T.Ident(_), _) =>
// Add space if right starts with a symbol
Expand Down Expand Up @@ -2494,8 +2495,8 @@ class Router(formatOps: FormatOps) {
Split(NoSplit, 0)
)
case FormatToken(
T.Ident(_) | Literal() | T.Interpolation.End() | T.Xml.End(),
T.Ident(_) | Literal() | T.Xml.Start(),
T.Ident(_) | T.Literal() | T.Interpolation.End() | T.Xml.End(),
T.Ident(_) | T.Literal() | T.Xml.Start(),
_
) =>
Seq(
Expand Down Expand Up @@ -2640,20 +2641,20 @@ class Router(formatOps: FormatOps) {
Split(NewlineT(formatToken.hasBlankLine), 0)
)

case FormatToken(_, Keyword(), _) =>
case FormatToken(_, Reserved(), _) =>
Seq(
Split(Space, 0)
)

case FormatToken(Keyword() | Modifier(), _, _) =>
case FormatToken(Reserved(), _, _) =>
Seq(
Split(Space, 0)
)
case FormatToken(T.LeftBracket(), _, _) =>
Seq(
Split(NoSplit, 0)
)
case FormatToken(_, Delim(), _) =>
case FormatToken(_, _: T.Symbolic, _) =>
Seq(
Split(Space, 0)
)
Expand All @@ -2666,7 +2667,7 @@ class Router(formatOps: FormatOps) {
Seq(
Split(mod, 0)
)
case FormatToken(Delim(), _, _) =>
case FormatToken(_: T.Symbolic, _, _) =>
Seq(
Split(Space, 0)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import org.scalafmt.internal.FormatToken
import org.scalafmt.internal.FormatTokens
import org.scalafmt.util.StyleMap
import org.scalafmt.util.TokenOps
import org.scalafmt.util.Whitespace

class FormatTokensRewrite(
ftoks: FormatTokens,
Expand Down Expand Up @@ -169,7 +168,7 @@ class FormatTokensRewrite(

case _ if ft.meta.formatOff =>

case Whitespace() =>
case _: T.Whitespace =>

case _ => applyRules
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ object Imports extends RewriteFactory {
if (hadLf) Some(true) else { hadLf = true; None }
case t: Token.Comment if TokenOps.isSingleLineIfComment(t) =>
slc.prepend(t); hadLf = false; None
case Whitespace() => None
case _: Token.Whitespace => None
case _ => if (!hadLf && slc.nonEmpty) slc.remove(0); Some(false)
}
slc.result()
Expand All @@ -407,7 +407,7 @@ object Imports extends RewriteFactory {
case _: Token.LF => Some(false)
case t: Token.Comment if TokenOps.isSingleLineIfComment(t) =>
Some(true)
case Whitespace() | _: Token.Comma => None
case _: Token.Whitespace | _: Token.Comma => None
case _ => Some(false)
}
}
Expand Down Expand Up @@ -451,7 +451,7 @@ object Imports extends RewriteFactory {
val nextOff = off - 1
ctx.tokens(nextOff) match {
case t: Token.LF => t.input.text.substring(t.end, nonWs.start)
case Whitespace() => iter(nextOff, nonWs)
case _: Token.Whitespace => iter(nextOff, nonWs)
case t => iter(nextOff, t)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import scala.collection.mutable

import metaconfig.ConfCodecEx
import scala.meta._
import scala.meta.tokens.Token.LF
import scala.meta.tokens.{Token => T}
import scala.meta.transversers.SimpleTraverser

import org.scalafmt.config.ReaderUtil
import org.scalafmt.config.RewriteSettings
import org.scalafmt.config.ScalafmtConfig
import org.scalafmt.util.{TokenOps, TokenTraverser, TreeOps, Trivia, Whitespace}
import org.scalafmt.util.{TokenOps, TokenTraverser, TreeOps}

case class RewriteCtx(
style: ScalafmtConfig,
Expand Down Expand Up @@ -55,21 +55,21 @@ case class RewriteCtx(
def onlyWhitespaceBefore(index: Int): Boolean =
tokenTraverser
.findAtOrBefore(index - 1) {
case _: LF | _: Token.BOF => Some(true)
case Whitespace() => None
case _: T.LF | _: T.BOF => Some(true)
case _: T.Whitespace => None
case _ => Some(false)
}
.isDefined

def findNonWhitespaceWith(
f: (Token => Option[Boolean]) => Option[Token]
): Option[(Token, Option[LF])] = {
var lf: Option[LF] = None
): Option[(Token, Option[T.LF])] = {
var lf: Option[T.LF] = None
val nonWs = f {
case t: LF =>
case t: T.LF =>
if (lf.nonEmpty) Some(false)
else { lf = Some(t); None }
case Whitespace() => None
case _: T.Whitespace => None
case _ => Some(true)
}
nonWs.map((_, lf))
Expand All @@ -83,8 +83,8 @@ case class RewriteCtx(
if (onlyWhitespaceBefore(beg))
tokenTraverser
.findAtOrAfter(end + 1) {
case _: LF => Some(true)
case Whitespace() => None
case _: T.LF => Some(true)
case _: T.Whitespace => None
case _ => Some(false)
}
.map(TokenPatch.Remove)
Expand All @@ -94,8 +94,8 @@ case class RewriteCtx(
def isPrefixExpr(expr: Tree): Boolean =
RewriteCtx.isSimpleExprOr(expr) { case t: Term.Select =>
val maybeDot = tokenTraverser.findBefore(t.name.tokens.head) {
case Trivia() => None
case x => Some(x.is[Token.Dot])
case _: T.Trivia => None
case x => Some(x.is[T.Dot])
}
maybeDot.isDefined
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ object LoggerOps {

def cleanup(token: Token): String =
token match {
case Literal() | Interpolation.Part(_) =>
case Token.Literal() | Interpolation.Part(_) =>
escape(token.syntax).stripPrefix("\"").stripSuffix("\"")
case _ => token.syntax.replace("\n", "")
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,121 +1,41 @@
package org.scalafmt.util

import scala.meta.Dialect
import scala.meta.internal.classifiers.classifier
import scala.meta.internal.parsers.SoftKeywords
import scala.meta.tokens.Token
import scala.meta.tokens.Token._

@classifier
trait Keyword
object Keyword {
def unapply(token: Token): Boolean = {
token.is[KwAbstract] || token.is[KwCase] || token.is[KwCatch] ||
token.is[KwClass] || token.is[KwDef] || token.is[KwDo] ||
token.is[KwElse] || token.is[KwEnum] || token.is[KwExport] ||
token.is[KwExtends] || token.is[KwFalse] || token.is[KwFinal] ||
token.is[KwFinally] || token.is[KwFor] || token.is[KwForsome] ||
token.is[KwGiven] || token.is[KwIf] || token.is[KwImplicit] ||
token.is[KwImport] || token.is[KwLazy] || token.is[KwMatch] ||
token.is[KwMacro] || token.is[KwNew] || token.is[KwNull] ||
token.is[KwObject] || token.is[KwOverride] || token.is[KwPackage] ||
token.is[KwPrivate] || token.is[KwProtected] || token.is[KwReturn] ||
token.is[KwSealed] || token.is[KwSuper] || token.is[KwThis] ||
token.is[KwThen] ||
token.is[KwThrow] || token.is[KwTrait] || token.is[KwTrue] ||
token.is[KwTry] || token.is[KwType] || token.is[KwVal] ||
token.is[KwVar] || token.is[KwWhile] || token.is[KwWith] ||
token.is[KwYield]
object Reserved {
def unapply(token: Token): Boolean = token match {
case _: Keyword | _: KwFalse | _: KwNull | _: KwTrue => true
case _ => false
}
}

@classifier
trait Delim
object Delim {
def unapply(token: Token): Boolean = {
token.is[Hash] || token.is[Colon] || token.is[Viewbound] ||
token.is[LeftArrow] || token.is[Subtype] || token.is[Equals] ||
token.is[RightArrow] || token.is[Supertype] || token.is[At] ||
token.is[Underscore] || token.is[LeftParen] || token.is[RightParen] ||
token.is[Comma] || token.is[Dot] || token.is[Semicolon] ||
token.is[LeftBracket] || token.is[RightBracket] || token.is[LeftBrace] ||
token.is[RightBrace] || token.is[ContextArrow] || token.is[TypeLambdaArrow]
}
}

@classifier
trait Modifier
object Modifier {
def unapply(token: Token): Boolean = {
token.is[KwAbstract] || token.is[KwFinal] || token.is[KwSealed] ||
token.is[KwImplicit] || token.is[KwLazy] || token.is[KwPrivate] ||
token.is[KwProtected] || token.is[KwOverride]
}
}

@classifier
trait Literal
object Literal {
def unapply(token: Token): Boolean = {
token.is[Constant.Int] || token.is[Constant.Long] ||
token.is[Constant.Float] || token.is[Constant.Double] ||
token.is[Constant.Char] || token.is[Constant.Symbol] ||
token.is[Constant.String] || token.is[KwNull] || token.is[KwTrue] ||
token.is[KwFalse]
}
}

@classifier
trait Whitespace
object Whitespace {
def unapply(token: Token): Boolean = {
token.is[Space] || token.is[Tab] || token.is[CR] || token.is[LF] ||
token.is[FF]
}
}

@classifier
trait Trivia
object Trivia {
def unapply(token: Token): Boolean = {
token.is[Whitespace] || token.is[Comment]
}
}

@classifier
trait LeftParenOrBracket
object LeftParenOrBracket {
def unapply(tok: Token): Boolean =
tok.is[LeftParen] || tok.is[LeftBracket]
}

@classifier
trait RightParenOrBracket
object RightParenOrBracket {
def unapply(tok: Token): Boolean =
tok.is[RightParen] || tok.is[RightBracket]
}

@classifier
trait LeftParenOrBrace
object LeftParenOrBrace {
def unapply(tok: Token): Boolean = tok.is[LeftParen] || tok.is[LeftBrace]
}

class SoftKeywordClasses(dialect: Dialect) extends SoftKeywords(dialect) {
@classifier
trait ImplicitOrUsing
object ImplicitOrUsing {
def unapply(tok: Token): Boolean = {
tok.is[KwImplicit] || tok.is[KwUsing]
tok.is[KwImplicit] || KwUsing.unapply(tok)
}
}

@classifier
trait ExtendsOrDerives
object ExtendsOrDerives {
def unapply(tok: Token): Boolean = {
tok.is[KwExtends] || tok.is[KwDerives]
tok.is[KwExtends] || KwDerives.unapply(tok)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,6 @@ class TokenTraverser(tokens: Tokens, input: Input) {
object TokenTraverser {

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

}

0 comments on commit b103a89

Please sign in to comment.