aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2017-04-03 17:35:21 +0200
committerMartin Odersky <odersky@gmail.com>2017-04-11 09:33:12 +0200
commit868a6a1025781eeac3eb884040639119542b3f49 (patch)
tree813b2acd02adf8709a38825858a7bbb0941bd63c
parentd0efabf2817468c248db8a2a6d5a6c0b58747867 (diff)
downloaddotty-868a6a1025781eeac3eb884040639119542b3f49.tar.gz
dotty-868a6a1025781eeac3eb884040639119542b3f49.tar.bz2
dotty-868a6a1025781eeac3eb884040639119542b3f49.zip
Make extension method names semantic
-rw-r--r--compiler/src/dotty/tools/dotc/core/NameKinds.scala33
-rw-r--r--compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala1
-rw-r--r--compiler/src/dotty/tools/dotc/transform/ExtensionMethods.scala5
3 files changed, 29 insertions, 10 deletions
diff --git a/compiler/src/dotty/tools/dotc/core/NameKinds.scala b/compiler/src/dotty/tools/dotc/core/NameKinds.scala
index 8ea19bed2..cda6e0c83 100644
--- a/compiler/src/dotty/tools/dotc/core/NameKinds.scala
+++ b/compiler/src/dotty/tools/dotc/core/NameKinds.scala
@@ -132,6 +132,13 @@ object NameKinds {
case DerivedTermName(underlying, info: this.NumberedInfo) => Some((underlying, info.num))
case _ => None
}
+ protected def skipSeparatorAndNum(name: SimpleTermName, separator: String): Int = {
+ var i = name.length
+ while (i > 0 && name(i - 1).isDigit) i -= 1
+ if (i > separator.length && i < name.length &&
+ name.slice(i - separator.length, i).toString == separator) i
+ else -1
+ }
}
case class UniqueNameKind(val separator: String)
@@ -205,6 +212,18 @@ object NameKinds {
val SkolemName = new UniqueNameKind("?")
val LiftedTreeName = new UniqueNameKind("liftedTree")
+ val UniqueExtMethName = new UniqueNameKind("$extension") {
+ override def unmangle(name: SimpleTermName): TermName = {
+ val i = skipSeparatorAndNum(name, separator)
+ if (i > 0) {
+ val index = name.drop(i).toString.toInt
+ var original = name.take(i - separator.length).asTermName
+ apply(original, index)
+ }
+ else name
+ }
+ }
+
val PatMatStdBinderName = new UniqueNameKind("x")
val PatMatPiName = new UniqueNameKind("pi") // FIXME: explain what this is
val PatMatPName = new UniqueNameKind("p") // FIXME: explain what this is
@@ -218,15 +237,12 @@ object NameKinds {
val prefix = if (underlying.isConstructorName) nme.DEFAULT_GETTER_INIT else underlying
prefix.toString + str.DEFAULT_GETTER + (info.num + 1)
}
-
- private val dgLen = str.DEFAULT_GETTER.length
-
+ // TODO: Reduce code duplication with UniqueExtMethName
override def unmangle(name: SimpleTermName): TermName = {
- var i = name.length
- while (i > 0 && name(i - 1).isDigit) i -= 1
- if (i > dgLen && i < name.length && name.slice(i - dgLen, i) == nme.DEFAULT_GETTER) {
+ val i = skipSeparatorAndNum(name, str.DEFAULT_GETTER)
+ if (i > 0) {
val index = name.drop(i).toString.toInt - 1
- var original = name.take(i - dgLen).asTermName
+ var original = name.take(i - str.DEFAULT_GETTER.length).asTermName
if (original == nme.DEFAULT_GETTER_INIT) original = Names.CONSTRUCTOR
apply(original, index)
}
@@ -260,6 +276,7 @@ object NameKinds {
val AvoidClashName = new SuffixNameKind(AVOIDCLASH, "$_avoid_name_clash_$")
val DirectName = new SuffixNameKind(DIRECT, "$direct")
val FieldName = new SuffixNameKind(FIELD, "$$local")
+ val ExtMethName = new SuffixNameKind(EXTMETH, "$extension")
val ModuleVarName = new SuffixNameKind(OBJECTVAR, "$module")
val ModuleClassName = new SuffixNameKind(OBJECTCLASS, "$", optInfoString = "ModuleClass")
@@ -283,7 +300,7 @@ object NameKinds {
}
val Scala2MethodNameKinds: List[NameKind] =
- List(DefaultGetterName, ProtectedAccessorName, ProtectedSetterName)
+ List(DefaultGetterName, ExtMethName, UniqueExtMethName, ProtectedAccessorName, ProtectedSetterName)
def simpleNameKindOfTag : collection.Map[Int, ClassifiedNameKind] = simpleNameKinds
def qualifiedNameKindOfTag : collection.Map[Int, QualifiedNameKind] = qualifiedNameKinds
diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala b/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala
index 68c5bf10e..f03e279c6 100644
--- a/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala
+++ b/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala
@@ -240,6 +240,7 @@ object TastyFormat {
final val DIRECT = 31
final val FIELD = 32
final val SETTER = 33
+ final val EXTMETH = 34
final val OBJECTVAR = 39
final val OBJECTCLASS = 40
diff --git a/compiler/src/dotty/tools/dotc/transform/ExtensionMethods.scala b/compiler/src/dotty/tools/dotc/transform/ExtensionMethods.scala
index 64474cecd..61f32edae 100644
--- a/compiler/src/dotty/tools/dotc/transform/ExtensionMethods.scala
+++ b/compiler/src/dotty/tools/dotc/transform/ExtensionMethods.scala
@@ -16,6 +16,7 @@ import Types._, Contexts._, Constants._, Names._, NameOps._, Flags._, DenotTrans
import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._, Scopes._, Denotations._
import TypeErasure.{ valueErasure, ErasedValueType }
import TypeUtils._
+import NameKinds.{ExtMethName, UniqueExtMethName}
import util.Positions._
import Decorators._
import SymUtils._
@@ -206,11 +207,11 @@ object ExtensionMethods {
val alts = decl.alternatives
val index = alts indexOf imeth.denot
assert(index >= 0, alts + " does not contain " + imeth)
- def altName(index: Int) = (imeth.name + "$extension" + index).toTermName
+ def altName(index: Int) = UniqueExtMethName(imeth.name.asTermName, index)
altName(index) #:: ((0 until alts.length).toStream filter (index != _) map altName)
case decl =>
assert(decl.exists, imeth.name + " not found in " + imeth.owner + "'s decls: " + imeth.owner.info.decls)
- Stream((imeth.name + "$extension").toTermName)
+ Stream(ExtMethName(imeth.name.asTermName))
}
}