aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2017-03-29 16:58:41 +0200
committerMartin Odersky <odersky@gmail.com>2017-04-11 09:33:11 +0200
commita5d94d23341b2f30f677f1420f1ce088a0f1ed5b (patch)
tree8d1ce019cf60853b3f9b8ed918f122d7c3f6ac82
parentd5c1e6dc677ef9ef49f02075747b2301ba45fd74 (diff)
downloaddotty-a5d94d23341b2f30f677f1420f1ce088a0f1ed5b.tar.gz
dotty-a5d94d23341b2f30f677f1420f1ce088a0f1ed5b.tar.bz2
dotty-a5d94d23341b2f30f677f1420f1ce088a0f1ed5b.zip
Decentralize unmangling, add new nameKinds
Start scheme where unmangling is done by NameKinds instead of in NameOps. Also add namekinds for protected accessors.
-rw-r--r--compiler/src/dotty/tools/dotc/ast/Desugar.scala4
-rw-r--r--compiler/src/dotty/tools/dotc/core/NameKinds.scala (renamed from compiler/src/dotty/tools/dotc/core/NameExtractors.scala)26
-rw-r--r--compiler/src/dotty/tools/dotc/core/NameOps.scala58
-rw-r--r--compiler/src/dotty/tools/dotc/core/StdNames.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala4
-rw-r--r--compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala6
-rw-r--r--compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala3
-rw-r--r--compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala4
-rw-r--r--compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala10
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Applications.scala3
10 files changed, 62 insertions, 58 deletions
diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala
index e9df66186..9cf530f8f 100644
--- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala
+++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala
@@ -6,7 +6,7 @@ import core._
import util.Positions._, Types._, Contexts._, Constants._, Names._, NameOps._, Flags._
import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._
import Decorators._
-import NameKinds.{UniqueName, EvidenceParamName}
+import NameKinds.{UniqueName, EvidenceParamName, DefaultGetterName}
import language.higherKinds
import typer.FrontEnd
import collection.mutable.ListBuffer
@@ -187,7 +187,7 @@ object desugar {
case (vparam :: vparams) :: vparamss1 =>
def defaultGetter: DefDef =
DefDef(
- name = meth.name.defaultGetterName(n),
+ name = DefaultGetterName(meth.name, n),
tparams = meth.tparams.map(tparam => dropContextBound(toDefParam(tparam))),
vparamss = takeUpTo(normalizedVparamss.nestedMap(toDefParam), n),
tpt = TypeTree(),
diff --git a/compiler/src/dotty/tools/dotc/core/NameExtractors.scala b/compiler/src/dotty/tools/dotc/core/NameKinds.scala
index 7350087a5..2c5e3ee3e 100644
--- a/compiler/src/dotty/tools/dotc/core/NameExtractors.scala
+++ b/compiler/src/dotty/tools/dotc/core/NameKinds.scala
@@ -31,6 +31,7 @@ object NameKinds {
override def toString = infoString
}
def definesNewName = false
+ def unmangle(name: SimpleTermName): TermName = name
def mkString(underlying: TermName, info: ThisInfo): String
def infoString: String
}
@@ -58,11 +59,17 @@ object NameKinds {
extends ClassifiedNameKind(tag, if (optInfoString.isEmpty) s"Prefix $prefix" else optInfoString) {
def mkString(underlying: TermName, info: ThisInfo) =
underlying.mapLast(n => termName(prefix + n.toString)).toString
+ override def unmangle(name: SimpleTermName): TermName =
+ if (name.startsWith(prefix)) apply(name.drop(prefix.length).asSimpleName)
+ else name
}
class SuffixNameKind(tag: Int, suffix: String, optInfoString: String = "")
extends ClassifiedNameKind(tag, if (optInfoString.isEmpty) s"Suffix $suffix" else optInfoString) {
def mkString(underlying: TermName, info: ThisInfo) = underlying.toString ++ suffix
+ override def unmangle(name: SimpleTermName): TermName =
+ if (name.endsWith(suffix)) apply(name.take(name.length - suffix.length).asSimpleName)
+ else name
}
trait QualifiedInfo extends NameInfo {
@@ -181,6 +188,20 @@ object NameKinds {
val prefix = if (underlying.isConstructorName) nme.DEFAULT_GETTER_INIT else underlying
prefix.toString + nme.DEFAULT_GETTER + (info.num + 1)
}
+
+ private val dgLen = nme.DEFAULT_GETTER.length
+
+ 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 index = name.drop(i).toString.toInt - 1
+ var original = name.take(i - dgLen).asTermName
+ if (original == nme.DEFAULT_GETTER_INIT) original = Names.CONSTRUCTOR
+ apply(original, index)
+ }
+ else name
+ }
}
object VariantName extends NumberedNameKind(VARIANT, "Variant") {
@@ -194,6 +215,8 @@ object NameKinds {
val SuperAccessorName = new PrefixNameKind(SUPERACCESSOR, "super$")
val InitializerName = new PrefixNameKind(INITIALIZER, "initial$")
val ShadowedName = new PrefixNameKind(SHADOWED, "(shadowed)")
+ val ProtectedAccessorName = new PrefixNameKind(PROTECTEDACCESSOR, "protected$")
+ val ProtectedSetterName = new PrefixNameKind(PROTECTEDSETTER, "protected$set") // dubious encoding, kept for Scala2 compatibility
val AvoidClashName = new SuffixNameKind(AVOIDCLASH, "$_avoid_name_clash_$")
val ModuleClassName = new SuffixNameKind(OBJECTCLASS, "$", optInfoString = "ModuleClass")
@@ -216,6 +239,9 @@ object NameKinds {
def infoString: String = "Signed"
}
+ val Scala2MethodNameKinds: List[NameKind] =
+ List(DefaultGetterName, ProtectedAccessorName, ProtectedSetterName)
+
def simpleNameKindOfTag : collection.Map[Int, ClassifiedNameKind] = simpleNameKinds
def qualifiedNameKindOfSeparator: collection.Map[String, QualifiedNameKind] = qualifiedNameKinds
def uniqueNameKindOfSeparator : collection.Map[String, UniqueNameKind] = uniqueNameKinds
diff --git a/compiler/src/dotty/tools/dotc/core/NameOps.scala b/compiler/src/dotty/tools/dotc/core/NameOps.scala
index 356b41efb..f936e5a34 100644
--- a/compiler/src/dotty/tools/dotc/core/NameOps.scala
+++ b/compiler/src/dotty/tools/dotc/core/NameOps.scala
@@ -60,13 +60,11 @@ object NameOps {
def isImplClassName = name endsWith IMPL_CLASS_SUFFIX
def isLocalDummyName = name startsWith LOCALDUMMY_PREFIX
def isLoopHeaderLabel = (name startsWith WHILE_PREFIX) || (name startsWith DO_WHILE_PREFIX)
- def isProtectedAccessorName = name startsWith PROTECTED_PREFIX
def isReplWrapperName = name.toSimpleName containsSlice INTERPRETER_IMPORT_WRAPPER
def isSetterName = name endsWith SETTER_SUFFIX
def isSingletonName = name endsWith SINGLETON_SUFFIX
def isImportName = name startsWith IMPORT
def isFieldName = name endsWith LOCAL_SUFFIX
- def isDefaultGetterName = name.isTermName && name.asTermName.defaultGetterIndex >= 0
def isScala2LocalSuffix = name.endsWith(" ")
def isModuleVarName(name: Name): Boolean =
name.stripAnonNumberSuffix endsWith MODULE_VAR_SUFFIX
@@ -400,54 +398,21 @@ object NameOps {
name.mapLast(n => n.take(n.length - LOCAL_SUFFIX.length).asSimpleName)
}
- /** Nominally, name$default$N, encoded for <init>
- * @param Post the parameters position.
- * @note Default getter name suffixes start at 1, so `pos` has to be adjusted by +1
- */
- def defaultGetterName(pos: Int): TermName =
- DefaultGetterName(name, pos)
-
/** Nominally, name from name$default$N, CONSTRUCTOR for <init> */
def defaultGetterToMethod: TermName =
name rewrite {
case DefaultGetterName(methName, _) => methName
}
- def defaultGetterToMethodOfMangled: TermName = {
- val p = name.indexOfSlice(DEFAULT_GETTER)
- if (p >= 0) {
- val q = name.take(p).asTermName
- // i.e., if (q.decoded == CONSTRUCTOR.toString) CONSTRUCTOR else q
- if (q == DEFAULT_GETTER_INIT) CONSTRUCTOR else q
- } else name
- }
-
/** If this is a default getter, its index (starting from 0), else -1 */
def defaultGetterIndex: Int =
name collect {
case DefaultGetterName(_, num) => num
} getOrElse -1
- 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))
- name.drop(i).toString.toInt - 1
- else
- -1
- }
-
def stripScala2LocalSuffix: TermName =
if (name.isScala2LocalSuffix) name.init.asTermName else name
- /** The name of an accessor for protected symbols. */
- def protectedAccessorName: TermName =
- PROTECTED_PREFIX ++ name.unexpandedName
-
- /** The name of a setter for protected symbols. Used for inherited Java fields. */
- def protectedSetterName: TermName =
- PROTECTED_SET_PREFIX ++ name.unexpandedName
-
def moduleVarName: TermName =
name ++ MODULE_VAR_SUFFIX
@@ -509,18 +474,25 @@ object NameOps {
case name => name
}
- def unmangleMethodName: TermName =
- if (name.isSimple) {
- val idx = name.defaultGetterIndexOfMangled
- if (idx >= 0) name.defaultGetterToMethodOfMangled.defaultGetterName(idx)
- else name
- }
- else name
-
def unmangleSuperName: TermName =
if (name.isSimple && name.startsWith(str.SUPER_PREFIX))
SuperAccessorName(name.drop(str.SUPER_PREFIX.length).asTermName)
else name
+
+ def unmangle(kind: NameKind): TermName = name rewrite {
+ case unmangled: SimpleTermName =>
+ kind.unmangle(unmangled)
+ case ExpandedName(prefix, last) =>
+ kind.unmangle(last) rewrite {
+ case kernel: SimpleTermName =>
+ ExpandedName(prefix, kernel)
+ }
+ }
+
+ def unmangle(kinds: List[NameKind]): TermName = {
+ val unmangled = (name /: kinds)(_.unmangle(_))
+ if (unmangled eq name) name else unmangled.unmangle(kinds)
+ }
}
private final val FalseSuper = "$$super".toTermName
diff --git a/compiler/src/dotty/tools/dotc/core/StdNames.scala b/compiler/src/dotty/tools/dotc/core/StdNames.scala
index 598d55650..7dd569d04 100644
--- a/compiler/src/dotty/tools/dotc/core/StdNames.scala
+++ b/compiler/src/dotty/tools/dotc/core/StdNames.scala
@@ -123,8 +123,6 @@ object StdNames {
val OVERLOADED: N = "<overloaded>"
val PACKAGE: N = "package"
val PACKAGE_CLS: N = "package$"
- val PROTECTED_PREFIX: N = "protected$"
- val PROTECTED_SET_PREFIX: N = PROTECTED_PREFIX + "set"
val ROOT: N = "<root>"
val SINGLETON_SUFFIX: N = ".type"
val SPECIALIZED_SUFFIX: N = "$sp"
diff --git a/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala b/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala
index 13315eb3e..b09da70e1 100644
--- a/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala
+++ b/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala
@@ -5,7 +5,7 @@ package classfile
import Contexts._, Symbols._, Types._, Names._, StdNames._, NameOps._, Scopes._, Decorators._
import SymDenotations._, unpickleScala2.Scala2Unpickler._, Constants._, Annotations._, util.Positions._
-import NameKinds.ModuleClassName
+import NameKinds.{ModuleClassName, DefaultGetterName}
import ast.tpd._
import java.io.{ File, IOException }
import java.lang.Integer.toHexString
@@ -598,7 +598,7 @@ class ClassfileParser(
def addDefaultGetter(attr: Symbol, n: Int) =
ctx.newSymbol(
owner = moduleRoot.symbol,
- name = nme.CONSTRUCTOR.defaultGetterName(n),
+ name = DefaultGetterName(nme.CONSTRUCTOR, n),
flags = attr.flags & Flags.AccessFlags,
info = defn.NothingType).entered
diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala b/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala
index 18d4a6344..f7e61c924 100644
--- a/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala
+++ b/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala
@@ -229,8 +229,10 @@ object TastyFormat {
final val DEFAULTGETTER = 11
final val VARIANT = 12
final val SUPERACCESSOR = 20
- final val INITIALIZER = 21
- final val SHADOWED = 22
+ final val PROTECTEDACCESSOR = 21
+ final val PROTECTEDSETTER = 22
+ final val INITIALIZER = 23
+ final val SHADOWED = 24
final val AVOIDCLASH = 27
final val OBJECTCLASS = 29
diff --git a/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala b/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala
index 976eb5df4..e4b6faa4b 100644
--- a/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala
+++ b/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala
@@ -9,6 +9,7 @@ import java.lang.Double.longBitsToDouble
import Contexts._, Symbols._, Types._, Scopes._, SymDenotations._, Names._, NameOps._
import StdNames._, Denotations._, NameOps._, Flags._, Constants._, Annotations._
+import NameKinds.Scala2MethodNameKinds
import dotty.tools.dotc.typer.ProtoTypes.{FunProtoTyped, FunProto}
import util.Positions._
import dotty.tools.dotc.ast.{tpd, Trees, untpd}, ast.tpd._
@@ -436,7 +437,7 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
if (flags is Method) {
name =
if (name == nme.TRAIT_CONSTRUCTOR) nme.CONSTRUCTOR
- else name.asTermName.unmangleMethodName
+ else name.asTermName.unmangle(Scala2MethodNameKinds)
}
if (flags is Scala2ExpandedName) {
name = name.unmangleExpandedName
diff --git a/compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala b/compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala
index 324aecdf0..db19bf6b6 100644
--- a/compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala
+++ b/compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala
@@ -5,6 +5,7 @@ import ast.{Trees, tpd}
import core._, core.Decorators._
import Annotations._, Contexts._, Flags._, Phases._, Trees._, Types._, Symbols._
import Names._, NameOps._, StdNames._
+import NameKinds.DefaultGetterName
import typer.Inliner
import typer.ErrorReporting.cyclicErrorMsg
import transform.SymUtils._
@@ -300,7 +301,8 @@ private class ExtractAPICollector(implicit val ctx: Context) extends ThunkHolder
sym.owner.companionModule // default getters for class constructors are found in the companion object
else
sym.owner
- (0 until pnames.length).map(i => qual.info.member(sym.name.defaultGetterName(start + i)).exists)
+ (0 until pnames.length).map(i =>
+ qual.info.member(DefaultGetterName(sym.name, start + i)).exists)
} else
(0 until pnames.length).map(Function.const(false))
val params = (pnames, ptypes, defaults).zipped.map((pname, ptype, isDefault) =>
diff --git a/compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala b/compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala
index bae1b897e..583834fb3 100644
--- a/compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala
+++ b/compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala
@@ -11,6 +11,7 @@ import Types._, Contexts._, Constants._, Names._, NameOps._, Flags._, DenotTrans
import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._, Scopes._, Denotations._
import util.Positions._
import Decorators._
+import NameKinds.{ProtectedAccessorName, ProtectedSetterName}
import Symbols._, TypeUtils._
/** This class performs the following functions:
@@ -168,7 +169,7 @@ class SuperAccessors(thisTransformer: DenotTransformer) {
assert(clazz.exists, sym)
ctx.debuglog("Decided for host class: " + clazz)
- val accName = sym.name.protectedAccessorName
+ val accName = ProtectedAccessorName(sym.name)
// if the result type depends on the this type of an enclosing class, the accessor
// has to take an object of exactly this type, otherwise it's more general
@@ -206,7 +207,8 @@ class SuperAccessors(thisTransformer: DenotTransformer) {
}
def isProtectedAccessor(tree: Tree)(implicit ctx: Context): Boolean = tree match {
- case Apply(TypeApply(Select(_, name), _), qual :: Nil) => name.isProtectedAccessorName
+ case Apply(TypeApply(Select(_, name), _), qual :: Nil) =>
+ name.is(ProtectedAccessorName) || name.is(ProtectedSetterName)
case _ => false
}
@@ -221,7 +223,7 @@ class SuperAccessors(thisTransformer: DenotTransformer) {
assert(clazz.exists, sym)
ctx.debuglog("Decided for host class: " + clazz)
- val accName = sym.name.protectedAccessorName
+ val accName = ProtectedAccessorName(sym.name)
// if the result type depends on the this type of an enclosing class, the accessor
// has to take an object of exactly this type, otherwise it's more general
@@ -265,7 +267,7 @@ class SuperAccessors(thisTransformer: DenotTransformer) {
assert(clazz.exists, field)
ctx.debuglog("Decided for host class: " + clazz)
- val accName = field.name.protectedSetterName
+ val accName = ProtectedSetterName(field.name)
val accType = MethodType(clazz.classInfo.selfType :: field.info :: Nil, defn.UnitType)
val protectedAccessor = clazz.info.decl(accName).symbol orElse {
val newAcc = ctx.newSymbol(
diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala
index 1fcebf4f0..db1e0bcfb 100644
--- a/compiler/src/dotty/tools/dotc/typer/Applications.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala
@@ -20,6 +20,7 @@ import Trees._
import config.Config
import Names._
import StdNames._
+import NameKinds.DefaultGetterName
import ProtoTypes._
import EtaExpansion._
import Inferencing._
@@ -345,7 +346,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
}
val getterPrefix =
if ((meth is Synthetic) && meth.name == nme.apply) nme.CONSTRUCTOR else meth.name
- def getterName = getterPrefix.defaultGetterName(n)
+ def getterName = DefaultGetterName(getterPrefix, n)
if (!meth.hasDefaultParams)
EmptyTree
else if (receiver.isEmpty) {