Skip to content

Commit

Permalink
ScannerTokens: symbolic infix check to common (#3608)
Browse files Browse the repository at this point in the history
This way, this check will be available publically.
  • Loading branch information
kitbellew committed Mar 6, 2024
1 parent 37460d9 commit 4dc1d89
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 21 deletions.
Expand Up @@ -4,7 +4,6 @@ import scala.annotation.tailrec
import scala.meta.Dialect
import scala.meta.classifiers._
import scala.meta.inputs.Input
import scala.meta.internal.tokens.Chars
import scala.meta.internal.trees._
import scala.meta.prettyprinters._
import scala.meta.tokenizers._
Expand Down Expand Up @@ -68,24 +67,6 @@ final class ScannerTokens(val tokens: Tokens)(implicit dialect: Dialect) {
def asString: String =
s"[${token.getClass.getSimpleName}@${token.end}]${token.syntax.replace("\n", "")}"

def isBackquoted: Boolean = {
val text = token.text
text.startsWith("`") && text.endsWith("`")
}

def isIdentSymbolicInfixOperator: Boolean = isBackquoted || {
val text = token.text

@tailrec
def iter(idx: Int, nonEmpty: Boolean): Boolean = {
val ch = text(idx)
if (ch == '_') nonEmpty || idx > 0 && iter(idx - 1, false)
else Chars.isOperatorPart(ch) && (idx == 0 || iter(idx - 1, true))
}

val len = text.length
len == 0 || iter(len - 1, false)
}
}

// https://github.com/lampepfl/dotty/blob/4e7ab609/compiler/src/dotty/tools/dotc/parsing/Scanners.scala#L435
Expand Down Expand Up @@ -736,7 +717,7 @@ final class ScannerTokens(val tokens: Tokens)(implicit dialect: Dialect) {
lazy val isLeadingInfix = sepRegionsOrig match {
case Nil | (_: CanProduceLF) :: _
if !newlines && lastNewlinePos >= 0 && dialect.allowInfixOperatorAfterNL &&
next.is[Ident] && next.isIdentSymbolicInfixOperator =>
next.isSymbolicInfixOperator =>
isLeadingInfixArg(nextPos + 1, nextIndent)
case _ => LeadingInfix.No
}
Expand Down
@@ -1,3 +1,32 @@
package scala.meta

package object tokens extends tokens.Api
import scala.annotation.tailrec
import scala.meta.internal.tokens.Chars

package object tokens extends tokens.Api {

implicit class TokenExtensions(private val value: Token) extends AnyVal {
@inline def isBackquoted: Boolean = value.text.isBackquoted
@inline def isSymbolicInfixOperator: Boolean =
value.isInstanceOf[Token.Ident] && isIdentSymbolicInfixOperator
@inline def isIdentSymbolicInfixOperator: Boolean = value.text.isIdentSymbolicInfixOperator
}

implicit class StringExtensions(private val value: String) extends AnyVal {

def isBackquoted: Boolean = value.startsWith("`") && value.endsWith("`")

def isIdentSymbolicInfixOperator: Boolean = isBackquoted || {
@tailrec
def iter(idx: Int, nonEmpty: Boolean): Boolean = {
val ch = value(idx)
if (ch == '_') nonEmpty || idx > 0 && iter(idx - 1, false)
else Chars.isOperatorPart(ch) && (idx == 0 || iter(idx - 1, true))
}

val len = value.length
len == 0 || iter(len - 1, false)
}
}

}
Expand Up @@ -166,9 +166,11 @@ class SurfaceSuite extends FunSuite {
|scala.meta.tokenizers.Tokenized.Error *
|scala.meta.tokenizers.Tokenized.Success *
|scala.meta.tokens
|scala.meta.tokens.StringExtensions *
|scala.meta.tokens.Token
|scala.meta.tokens.Token.Interpolation *
|scala.meta.tokens.Token.Xml *
|scala.meta.tokens.TokenExtensions *
|scala.meta.tokens.Tokens
|scala.meta.transversers
|scala.meta.transversers.SimpleTraverser *
Expand Down Expand Up @@ -229,6 +231,10 @@ class SurfaceSuite extends FunSuite {
|* A.equals(Any): Boolean
|* A.hashCode(): Int
|* A.maybeParse(implicit scala.meta.Dialect, scala.meta.parsers.Parse[A]): scala.meta.package.Parsed[A]
|* String.equals(Any): Boolean
|* String.hashCode(): Int
|* String.isBackquoted: Boolean
|* String.isIdentSymbolicInfixOperator: Boolean
|* T(implicit scala.meta.classifiers.Classifiable[T]).is(implicit XtensionClassifiable.this.C[U]): Boolean
|* T(implicit scala.meta.classifiers.Classifiable[T]).isAny(implicit XtensionClassifiable.this.C[U1], XtensionClassifiable.this.C[U2]): Boolean
|* T(implicit scala.meta.classifiers.Classifiable[T]).isAny(implicit XtensionClassifiable.this.C[U1], XtensionClassifiable.this.C[U2], XtensionClassifiable.this.C[U3]): Boolean
Expand All @@ -253,6 +259,11 @@ class SurfaceSuite extends FunSuite {
|* scala.meta.Tree.reparseAs(implicit scala.meta.Dialect, scala.meta.parsers.Parse[A]): scala.meta.package.Parsed[A]
|* scala.meta.Tree.transform(PartialFunction[scala.meta.Tree,scala.meta.Tree]): scala.meta.Tree
|* scala.meta.Tree.traverse(PartialFunction[scala.meta.Tree,Unit]): Unit
|* scala.meta.tokens.Token.equals(Any): Boolean
|* scala.meta.tokens.Token.hashCode(): Int
|* scala.meta.tokens.Token.isBackquoted: Boolean
|* scala.meta.tokens.Token.isIdentSymbolicInfixOperator: Boolean
|* scala.meta.tokens.Token.isSymbolicInfixOperator: Boolean
""".trim.stripMargin.split('\n').mkString(EOL)
)
}
Expand Down
Expand Up @@ -446,6 +446,21 @@ class PublicSuite extends TreeSuiteBase {
test("scala.meta.XtensionTree") {}
test("scala.meta.XtensionTreeT") {}

test("scala.meta.tokens.TokenExtensions") {}
test("scala.meta.tokens.StringExtensions") {
import scala.meta.tokens.StringExtensions
assert(!"foo".isBackquoted)
assert(!"`foo".isBackquoted)
assert(!"foo`".isBackquoted)
assert("`".isBackquoted)
assert("`foo`".isBackquoted)

assert(!"foo".isIdentSymbolicInfixOperator)
assert("`foo`".isIdentSymbolicInfixOperator)
assert("foo_+".isIdentSymbolicInfixOperator)
assert("+".isIdentSymbolicInfixOperator)
}

test("scala.meta.trees.Origin") {}
test("scala.meta.trees.Origin.DialectOnly") {}
test("scala.meta.trees.Origin.None") {}
Expand Down

0 comments on commit 4dc1d89

Please sign in to comment.