Skip to content

Commit 94e70aa

Browse files
committed
Make extension method names semantic
1 parent 1e8843d commit 94e70aa

File tree

3 files changed

+29
-10
lines changed

3 files changed

+29
-10
lines changed

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

+25-8
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,13 @@ object NameKinds {
132132
case DerivedTermName(underlying, info: this.NumberedInfo) => Some((underlying, info.num))
133133
case _ => None
134134
}
135+
protected def skipSeparatorAndNum(name: SimpleTermName, separator: String): Int = {
136+
var i = name.length
137+
while (i > 0 && name(i - 1).isDigit) i -= 1
138+
if (i > separator.length && i < name.length &&
139+
name.sliceToString(i - separator.length, i) == separator) i
140+
else -1
141+
}
135142
}
136143

137144
case class UniqueNameKind(val separator: String)
@@ -205,6 +212,18 @@ object NameKinds {
205212
val SkolemName = new UniqueNameKind("?")
206213
val LiftedTreeName = new UniqueNameKind("liftedTree")
207214

215+
val UniqueExtMethName = new UniqueNameKind("$extension") {
216+
override def unmangle(name: SimpleTermName): TermName = {
217+
val i = skipSeparatorAndNum(name, separator)
218+
if (i > 0) {
219+
val index = name.drop(i).toString.toInt
220+
var original = name.take(i - separator.length).asTermName
221+
apply(original, index)
222+
}
223+
else name
224+
}
225+
}
226+
208227
val PatMatStdBinderName = new UniqueNameKind("x")
209228
val PatMatPiName = new UniqueNameKind("pi") // FIXME: explain what this is
210229
val PatMatPName = new UniqueNameKind("p") // FIXME: explain what this is
@@ -218,15 +237,12 @@ object NameKinds {
218237
val prefix = if (underlying.isConstructorName) nme.DEFAULT_GETTER_INIT else underlying
219238
prefix.toString + str.DEFAULT_GETTER + (info.num + 1)
220239
}
221-
222-
private val dgLen = str.DEFAULT_GETTER.length
223-
240+
// TODO: Reduce code duplication with UniqueExtMethName
224241
override def unmangle(name: SimpleTermName): TermName = {
225-
var i = name.length
226-
while (i > 0 && name(i - 1).isDigit) i -= 1
227-
if (i > dgLen && i < name.length && name.slice(i - dgLen, i) == nme.DEFAULT_GETTER) {
242+
val i = skipSeparatorAndNum(name, str.DEFAULT_GETTER)
243+
if (i > 0) {
228244
val index = name.drop(i).toString.toInt - 1
229-
var original = name.take(i - dgLen).asTermName
245+
var original = name.take(i - str.DEFAULT_GETTER.length).asTermName
230246
if (original == nme.DEFAULT_GETTER_INIT) original = Names.CONSTRUCTOR
231247
apply(original, index)
232248
}
@@ -260,6 +276,7 @@ object NameKinds {
260276
val AvoidClashName = new SuffixNameKind(AVOIDCLASH, "$_avoid_name_clash_$")
261277
val DirectName = new SuffixNameKind(DIRECT, "$direct")
262278
val FieldName = new SuffixNameKind(FIELD, "$$local")
279+
val ExtMethName = new SuffixNameKind(EXTMETH, "$extension")
263280
val ModuleVarName = new SuffixNameKind(OBJECTVAR, "$module")
264281
val ModuleClassName = new SuffixNameKind(OBJECTCLASS, "$", optInfoString = "ModuleClass")
265282

@@ -283,7 +300,7 @@ object NameKinds {
283300
}
284301

285302
val Scala2MethodNameKinds: List[NameKind] =
286-
List(DefaultGetterName, ProtectedAccessorName, ProtectedSetterName)
303+
List(DefaultGetterName, ExtMethName, UniqueExtMethName, ProtectedAccessorName, ProtectedSetterName)
287304

288305
def simpleNameKindOfTag : collection.Map[Int, ClassifiedNameKind] = simpleNameKinds
289306
def qualifiedNameKindOfTag : collection.Map[Int, QualifiedNameKind] = qualifiedNameKinds

compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala

+1
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ object TastyFormat {
239239
final val DIRECT = 31
240240
final val FIELD = 32
241241
final val SETTER = 33
242+
final val EXTMETH = 34
242243
final val OBJECTVAR = 39
243244
final val OBJECTCLASS = 40
244245

compiler/src/dotty/tools/dotc/transform/ExtensionMethods.scala

+3-2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import Types._, Contexts._, Constants._, Names._, NameOps._, Flags._, DenotTrans
1616
import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._, Scopes._, Denotations._
1717
import TypeErasure.{ valueErasure, ErasedValueType }
1818
import TypeUtils._
19+
import NameKinds.{ExtMethName, UniqueExtMethName}
1920
import util.Positions._
2021
import Decorators._
2122
import SymUtils._
@@ -206,11 +207,11 @@ object ExtensionMethods {
206207
val alts = decl.alternatives
207208
val index = alts indexOf imeth.denot
208209
assert(index >= 0, alts + " does not contain " + imeth)
209-
def altName(index: Int) = (imeth.name + "$extension" + index).toTermName
210+
def altName(index: Int) = UniqueExtMethName(imeth.name.asTermName, index)
210211
altName(index) #:: ((0 until alts.length).toStream filter (index != _) map altName)
211212
case decl =>
212213
assert(decl.exists, imeth.name + " not found in " + imeth.owner + "'s decls: " + imeth.owner.info.decls)
213-
Stream((imeth.name + "$extension").toTermName)
214+
Stream(ExtMethName(imeth.name.asTermName))
214215
}
215216
}
216217

0 commit comments

Comments
 (0)