aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2017-03-25 16:14:50 +0100
committerMartin Odersky <odersky@gmail.com>2017-04-11 09:33:10 +0200
commit624b4eb59862644646dec685833c67c64756a8bd (patch)
treefd9b747a48be37b8ad6d32d5b909a1e68d1ca849
parentf9a9ddb879e9de4730a463f28c8b6602e0e60bbc (diff)
downloaddotty-624b4eb59862644646dec685833c67c64756a8bd.tar.gz
dotty-624b4eb59862644646dec685833c67c64756a8bd.tar.bz2
dotty-624b4eb59862644646dec685833c67c64756a8bd.zip
Semantic SuperAccessor and Initializer names
-rw-r--r--compiler/src/dotty/tools/dotc/core/NameInfos.scala16
-rw-r--r--compiler/src/dotty/tools/dotc/core/NameOps.scala109
-rw-r--r--compiler/src/dotty/tools/dotc/core/SymDenotations.scala6
-rw-r--r--compiler/src/dotty/tools/dotc/core/tasty/NameBuffer.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala29
-rw-r--r--compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala18
6 files changed, 122 insertions, 58 deletions
diff --git a/compiler/src/dotty/tools/dotc/core/NameInfos.scala b/compiler/src/dotty/tools/dotc/core/NameInfos.scala
index f6d9e84c0..23a161756 100644
--- a/compiler/src/dotty/tools/dotc/core/NameInfos.scala
+++ b/compiler/src/dotty/tools/dotc/core/NameInfos.scala
@@ -22,6 +22,8 @@ object NameInfo {
val QualifiedKind = 1
val DefaultGetterKind = 3
val VariantKind = 4
+ val SuperAccessorKind = 5
+ val InitializerKind = 6
val ModuleClassKind = 10
val qualifier: Map[String, SimpleTermName => Qualified] =
@@ -87,6 +89,20 @@ object NameInfo {
def mkString(underlying: TermName) = varianceToPrefix(num).toString + underlying
}
+ val SuperAccessor = new NameInfo {
+ def kind = SuperAccessorKind
+ def mkString(underlying: TermName) =
+ underlying.mapLast(n => (nme.SUPER_PREFIX ++ n).asSimpleName).toString
+ override def toString = "SuperAccessor"
+ }
+
+ val Initializer = new NameInfo {
+ def kind = InitializerKind
+ def mkString(underlying: TermName) =
+ underlying.mapLast(n => (nme.INITIALIZER_PREFIX ++ n).asSimpleName).toString
+ override def toString = "Initializer"
+ }
+
val ModuleClass = new NameInfo {
def kind = ModuleClassKind
def mkString(underlying: TermName) = underlying + "$"
diff --git a/compiler/src/dotty/tools/dotc/core/NameOps.scala b/compiler/src/dotty/tools/dotc/core/NameOps.scala
index eb284168a..9d5d3bd6a 100644
--- a/compiler/src/dotty/tools/dotc/core/NameOps.scala
+++ b/compiler/src/dotty/tools/dotc/core/NameOps.scala
@@ -49,14 +49,25 @@ object NameOps {
}
}
- class PrefixNameExtractor(pre: TermName) {
- def apply(name: TermName): TermName = pre ++ name
+ class PrefixNameExtractor(pre: TermName, info: NameInfo) {
+ def apply(name: TermName): TermName =
+ if (Config.semanticNames) name.derived(info) else pre ++ name
+
def unapply(name: TermName): Option[TermName] =
- if (name startsWith pre) Some(name.drop(pre.length).asTermName) else None
+ if (Config.semanticNames)
+ name match {
+ case DerivedTermName(original, `info`) => Some(original)
+ case _ => None
+ }
+ else tryUnmangle(name)
+
+ def tryUnmangle(name: TermName): Option[TermName] =
+ if (name startsWith pre) Some(name.drop(pre.length).asTermName)
+ else None
}
- object SuperAccessorName extends PrefixNameExtractor(nme.SUPER_PREFIX)
- object InitializerName extends PrefixNameExtractor(nme.INITIALIZER_PREFIX)
+ object SuperAccessorName extends PrefixNameExtractor(nme.SUPER_PREFIX, NameInfo.SuperAccessor)
+ object InitializerName extends PrefixNameExtractor(nme.INITIALIZER_PREFIX, NameInfo.Initializer)
implicit class NameDecorator[N <: Name](val name: N) extends AnyVal {
import nme._
@@ -152,7 +163,9 @@ object NameOps {
}.asInstanceOf[N]
/** The superaccessor for method with given name */
- def superName: TermName = (nme.SUPER_PREFIX ++ name).toTermName
+ def superName: TermName =
+ if (Config.semanticNames) name.derived(NameInfo.SuperAccessor).toTermName
+ else (nme.SUPER_PREFIX ++ name).toTermName
/** The expanded name of `name` relative to given class `base`.
*/
@@ -165,9 +178,17 @@ object NameOps {
*/
def expandedName(prefix: Name, separator: Name = nme.EXPAND_SEPARATOR): N =
likeTyped(
- if (Config.semanticNames)
- prefix.derived(NameInfo.qualifier(separator.toString)(name.toSimpleName))
- // note: expanded name may itself be expanded. For example, look at javap of scala.App.initCode
+ if (Config.semanticNames) {
+ def qualify(name: SimpleTermName) =
+ prefix.derived(NameInfo.qualifier(separator.toString)(name))
+ name rewrite {
+ case name: SimpleTermName =>
+ qualify(name)
+ case DerivedTermName(_, _: NameInfo.Qualified) =>
+ // Note: an expanded name may itself be expanded. For example, look at javap of scala.App.initCode
+ qualify(name.toSimpleName)
+ }
+ }
else prefix ++ separator ++ name)
def expandedName(prefix: Name): N = expandedName(prefix, nme.EXPAND_SEPARATOR)
@@ -178,35 +199,45 @@ object NameOps {
* signs. This can happen for instance if a super accessor is paired with
* an encoded name, e.g. super$$plus$eq. See #765.
*/
- def unexpandedName: N = likeTyped {
+ def unexpandedName: N =
if (Config.semanticNames)
- name.rewrite {
- case DerivedTermName(_, NameInfo.Expand(unexp)) => unexp
+ likeTyped {
+ name.rewrite { case DerivedTermName(_, NameInfo.Expand(unexp)) => unexp }
}
- else {
- var idx = name.lastIndexOfSlice(nme.EXPAND_SEPARATOR)
+ else unexpandedNameOfMangled
- // Hack to make super accessors from traits work. They would otherwise fail because of #765
- // TODO: drop this once we have more robust name handling
- if (idx > FalseSuperLength && name.slice(idx - FalseSuperLength, idx) == FalseSuper)
- idx -= FalseSuper.length
+ def unexpandedNameOfMangled: N = likeTyped {
+ var idx = name.lastIndexOfSlice(nme.EXPAND_SEPARATOR)
- if (idx < 0) name else (name drop (idx + nme.EXPAND_SEPARATOR.length))
- }
+ // Hack to make super accessors from traits work. They would otherwise fail because of #765
+ // TODO: drop this once we have more robust name handling
+ if (idx > FalseSuperLength && name.slice(idx - FalseSuperLength, idx) == FalseSuper)
+ idx -= FalseSuper.length
+
+ if (idx < 0) name else (name drop (idx + nme.EXPAND_SEPARATOR.length))
}
- def expandedPrefix: N = likeTyped {
+ def expandedPrefix: N =
if (Config.semanticNames)
- name.rewrite {
- case DerivedTermName(prefix, NameInfo.Expand(_)) => prefix
+ likeTyped {
+ name.rewrite { case DerivedTermName(prefix, NameInfo.Expand(_)) => prefix }
}
- else {
- val idx = name.lastIndexOfSlice(nme.EXPAND_SEPARATOR)
- assert(idx >= 0)
- name.take(idx)
- }
+ else expandedPrefixOfMangled
+
+ def expandedPrefixOfMangled: N = {
+ val idx = name.lastIndexOfSlice(nme.EXPAND_SEPARATOR)
+ assert(idx >= 0)
+ likeTyped(name.take(idx))
}
+ def unmangleExpandedName: N =
+ if (Config.semanticNames && name.isSimple) {
+ val unmangled = unexpandedNameOfMangled
+ if (name eq unmangled) name
+ else likeTyped(expandedPrefixOfMangled.derived(NameInfo.Expand(unmangled.asSimpleName)))
+ }
+ else name
+
def shadowedName: N = likeTyped(nme.SHADOWED ++ name)
def revertShadowed: N = likeTyped(name.drop(nme.SHADOWED.length))
@@ -441,9 +472,9 @@ object NameOps {
name rewrite {
case DerivedTermName(methName, NameInfo.DefaultGetter(_)) => methName
}
- else mangledDefaultGetterToMethod
+ else defaultGetterToMethodOfMangled
- def mangledDefaultGetterToMethod: TermName = {
+ def defaultGetterToMethodOfMangled: TermName = {
val p = name.indexOfSlice(DEFAULT_GETTER)
if (p >= 0) {
val q = name.take(p).asTermName
@@ -458,9 +489,9 @@ object NameOps {
name collect {
case DerivedTermName(methName, NameInfo.DefaultGetter(num)) => num
} getOrElse -1
- else mangledDefaultGetterIndex
+ else defaultGetterIndexOfMangled
- def mangledDefaultGetterIndex: Int = {
+ def defaultGetterIndexOfMangled: Int = {
var i = name.length
while (i > 0 && name(i - 1).isDigit) i -= 1
if (i > 0 && i < name.length && name.take(i).endsWith(DEFAULT_GETTER))
@@ -551,11 +582,21 @@ object NameOps {
def unmangleMethodName: TermName =
if (Config.semanticNames && name.isSimple) {
- val idx = name.mangledDefaultGetterIndex
- if (idx >= 0) name.mangledDefaultGetterToMethod.defaultGetterName(idx)
+ val idx = name.defaultGetterIndexOfMangled
+ if (idx >= 0) name.defaultGetterToMethodOfMangled.defaultGetterName(idx)
else name
}
else name
+
+ def unmangleSuperName: TermName =
+ if (Config.semanticNames && name.isSimple)
+ SuperAccessorName.tryUnmangle(name.lastPart) match {
+ case scala.Some(original) =>
+ name.mapLast(_ => original.asSimpleName).derived(NameInfo.SuperAccessor)
+ case None =>
+ name
+ }
+ else name
}
private final val FalseSuper = "$$super".toTermName
diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala
index e50d6a133..845da95f2 100644
--- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -377,10 +377,8 @@ object SymDenotations {
// might have been moved from different origins into the same class
/** The name with which the denoting symbol was created */
- final def originalName(implicit ctx: Context) = {
- val d = initial
- if (d is ExpandedName) d.name.unexpandedName else d.name // !!!DEBUG, was: effectiveName
- }
+ final def originalName(implicit ctx: Context) =
+ initial.effectiveName
/** The encoded full path name of this denotation, where outer names and inner names
* are separated by `separator` strings.
diff --git a/compiler/src/dotty/tools/dotc/core/tasty/NameBuffer.scala b/compiler/src/dotty/tools/dotc/core/tasty/NameBuffer.scala
index 19eb731c7..61a2c7fc5 100644
--- a/compiler/src/dotty/tools/dotc/core/tasty/NameBuffer.scala
+++ b/compiler/src/dotty/tools/dotc/core/tasty/NameBuffer.scala
@@ -29,6 +29,8 @@ class NameBuffer extends TastyBuffer(10000) {
val tname = name.toTermName match {
case DerivedTermName(name1, NameInfo.ModuleClass) =>
ModuleClass(nameIndex(name1, toTasty))
+ case DerivedTermName(name1, NameInfo.SuperAccessor) =>
+ SuperAccessor(nameIndex(name1, toTasty))
case DerivedTermName(prefix, qual: NameInfo.Qualified) =>
val tcon: (NameRef, NameRef) => TastyName = qual match {
case _: NameInfo.Select => Qualified
diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala
index d81bd3ea8..34ce40cb0 100644
--- a/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala
+++ b/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala
@@ -60,19 +60,24 @@ class TreePickler(pickler: TastyPickler) {
}
private def pickleName(sym: Symbol)(implicit ctx: Context): Unit = {
- def encodeSuper(name: Name): TastyName.NameRef =
- if (sym is Flags.SuperAccessor) {
- val SuperAccessorName(n) = name
- nameIndex(TastyName.SuperAccessor(nameIndex(n)))
- }
- else nameIndex(name)
val nameRef =
- if (sym is Flags.ExpandedName)
- nameIndex(
- TastyName.Expanded(
- nameIndex(sym.name.expandedPrefix),
- encodeSuper(sym.name.unexpandedName)))
- else encodeSuper(sym.name)
+ if (Config.semanticNames) {
+ if (sym is Flags.ExpandedName) assert(sym.name.is(NameInfo.QualifiedKind))
+ nameIndex(sym.name)
+ }
+ else {
+ def encodeSuper(name: Name): TastyName.NameRef =
+ if (sym is Flags.SuperAccessor) {
+ val SuperAccessorName(n) = name
+ nameIndex(TastyName.SuperAccessor(nameIndex(n)))
+ } else nameIndex(name)
+ if (sym is Flags.ExpandedName)
+ nameIndex(
+ TastyName.Expanded(
+ nameIndex(sym.name.expandedPrefix),
+ encodeSuper(sym.name.unexpandedName)))
+ else encodeSuper(sym.name)
+ }
writeNat(nameRef.index)
}
diff --git a/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala b/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala
index 084b8d098..c37d60b41 100644
--- a/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala
+++ b/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala
@@ -420,10 +420,10 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
// symbols that were pickled with Pickler.writeSymInfo
val nameref = readNat()
- val name0 = at(nameref, readName)
+ var name = at(nameref, readName)
val owner = readSymbolRef()
- var flags = unpickleScalaFlags(readLongNat(), name0.isTypeName)
+ var flags = unpickleScalaFlags(readLongNat(), name.isTypeName)
if (flags is DefaultParameter) {
// DefaultParameterized flag now on method, not parameter
//assert(flags is Param, s"$name0 in $owner")
@@ -431,12 +431,14 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
owner.setFlag(DefaultParameterized)
}
- val name1 = name0.adjustIfModuleClass(flags)
- val name2 = if (name1 == nme.TRAIT_CONSTRUCTOR) nme.CONSTRUCTOR else name1
- val name =
- if (flags is ModuleClass) name2.unmangleClassName
- else if (flags is Method) name2.asTermName.unmangleMethodName
- else name2
+ name = name.adjustIfModuleClass(flags)
+ if (flags is Method) {
+ name =
+ if (name == nme.TRAIT_CONSTRUCTOR) nme.CONSTRUCTOR
+ else name.asTermName.unmangleMethodName
+ }
+ if (flags is ExpandedName) name = name.unmangleExpandedName
+ if (flags is SuperAccessor) name = name.asTermName.unmangleSuperName
def isClassRoot = (name == classRoot.name) && (owner == classRoot.owner) && !(flags is ModuleClass)
def isModuleClassRoot = (name == moduleClassRoot.name) && (owner == moduleClassRoot.owner) && (flags is Module)