Skip to content

Commit 59b076b

Browse files
committed
Make isOperatorName more precise
1 parent a5e029a commit 59b076b

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

compiler/src/dotty/tools/dotc/core/NameOps.scala

+17-4
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import java.nio.CharBuffer
77
import scala.io.Codec
88
import Int.MaxValue
99
import Names.*, StdNames.*, Contexts.*, Symbols.*, Flags.*, NameKinds.*, Types.*
10-
import util.Chars.{isOperatorPart, digit2int}
10+
import util.Chars.{isOperatorPart, isIdentifierPart, digit2int}
1111
import Decorators.*
1212
import Definitions.*
1313
import nme.*
@@ -78,9 +78,22 @@ object NameOps {
7878
def isUnapplyName: Boolean = name == nme.unapply || name == nme.unapplySeq
7979
def isRightAssocOperatorName: Boolean = name.lastPart.last == ':'
8080

81-
def isOperatorName: Boolean = name match
82-
case name: SimpleName => name.exists(isOperatorPart)
83-
case _ => false
81+
/** Does this name match `{(letter | digit) '_' } op`?
82+
*
83+
* See examples in [[NameOpsTest]].
84+
*/
85+
def isOperatorName: Boolean =
86+
name match
87+
case name: SimpleName =>
88+
var i = name.length - 1
89+
// Ends with operator characters
90+
while i >= 0 && isOperatorPart(name(i)) do i -= 1
91+
if i == -1 then return true
92+
// Optionnally prefixed with alpha-numeric characters followed by `_`
93+
if name(i) != '_' then return false
94+
while i >= 0 && isIdentifierPart(name(i)) do i -= 1
95+
i == -1
96+
case _ => false
8497

8598
/** Is name of a variable pattern? */
8699
def isVarPattern: Boolean =
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package dotty.tools.dotc.core
2+
3+
import dotty.tools.dotc.core.NameOps.isOperatorName
4+
import dotty.tools.dotc.core.Names.{termName, SimpleName}
5+
6+
import org.junit.Test
7+
8+
class NameOpsTest:
9+
@Test def isOperatorNamePos: Unit =
10+
for name <- List("+", "::", "frozen_=:=", "$_+", "a2_+", "a_b_+") do
11+
assert(isOperatorName(termName(name)))
12+
13+
@Test def isOperatorNameNeg: Unit =
14+
for name <- List("foo", "*_*", "<init>", "$reserved", "a*", "2*") do
15+
assert(!isOperatorName(termName(name)))

0 commit comments

Comments
 (0)