From a5d94d23341b2f30f677f1420f1ce088a0f1ed5b Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 29 Mar 2017 16:58:41 +0200 Subject: Decentralize unmangling, add new nameKinds Start scheme where unmangling is done by NameKinds instead of in NameOps. Also add namekinds for protected accessors. --- compiler/src/dotty/tools/dotc/ast/Desugar.scala | 4 +- .../src/dotty/tools/dotc/core/NameExtractors.scala | 222 ------------------ compiler/src/dotty/tools/dotc/core/NameKinds.scala | 248 +++++++++++++++++++++ compiler/src/dotty/tools/dotc/core/NameOps.scala | 58 ++--- compiler/src/dotty/tools/dotc/core/StdNames.scala | 2 - .../dotc/core/classfile/ClassfileParser.scala | 4 +- .../dotty/tools/dotc/core/tasty/TastyFormat.scala | 6 +- .../dotc/core/unpickleScala2/Scala2Unpickler.scala | 3 +- compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala | 4 +- .../tools/dotc/transform/SuperAccessors.scala | 10 +- .../src/dotty/tools/dotc/typer/Applications.scala | 3 +- 11 files changed, 284 insertions(+), 280 deletions(-) delete mode 100644 compiler/src/dotty/tools/dotc/core/NameExtractors.scala create mode 100644 compiler/src/dotty/tools/dotc/core/NameKinds.scala 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/NameExtractors.scala deleted file mode 100644 index 7350087a5..000000000 --- a/compiler/src/dotty/tools/dotc/core/NameExtractors.scala +++ /dev/null @@ -1,222 +0,0 @@ -package dotty.tools -package dotc -package core - -import Names._ -import NameOps._ -import StdNames._ -import util.DotClass -import tasty.TastyFormat._ -import Decorators._ -import Contexts.Context -import collection.mutable - -object NameKinds { - - @sharable private val simpleNameKinds = new mutable.HashMap[Int, ClassifiedNameKind] - @sharable private val uniqueNameKinds = new mutable.HashMap[String, UniqueNameKind] - @sharable private val qualifiedNameKinds = new mutable.HashMap[String, QualifiedNameKind] - - abstract class NameInfo extends DotClass { - def kind: NameKind - def mkString(underlying: TermName): String - def map(f: SimpleTermName => SimpleTermName): NameInfo = this - } - - abstract class NameKind(val tag: Int) extends DotClass { self => - type ThisInfo <: Info - class Info extends NameInfo { this: ThisInfo => - def kind = self - def mkString(underlying: TermName) = self.mkString(underlying, this) - override def toString = infoString - } - def definesNewName = false - def mkString(underlying: TermName, info: ThisInfo): String - def infoString: String - } - - object SimpleTermNameKind extends NameKind(UTF8) { self => - type ThisInfo = Info - val info = new Info - def mkString(underlying: TermName, info: ThisInfo) = unsupported("mkString") - def infoString = unsupported("infoString") - } - - abstract class ClassifiedNameKind(tag: Int, val infoString: String) extends NameKind(tag) { - type ThisInfo = Info - val info = new Info - def apply(qual: TermName) = - qual.derived(info) - def unapply(name: DerivedTermName): Option[TermName] = name match { - case DerivedTermName(underlying, `info`) => Some(underlying) - case _ => None - } - simpleNameKinds(tag) = this - } - - class PrefixNameKind(tag: Int, prefix: String, optInfoString: String = "") - 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 - } - - 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 - } - - trait QualifiedInfo extends NameInfo { - val name: SimpleTermName - } - - class QualifiedNameKind(tag: Int, val separator: String) - extends NameKind(tag) { - type ThisInfo = QualInfo - case class QualInfo(val name: SimpleTermName) extends Info with QualifiedInfo { - override def map(f: SimpleTermName => SimpleTermName): NameInfo = new QualInfo(f(name)) - override def toString = s"$infoString $name" - } - def apply(qual: TermName, name: SimpleTermName) = - qual.derived(new QualInfo(name)) - def unapply(name: DerivedTermName): Option[(TermName, SimpleTermName)] = name match { - case DerivedTermName(qual, info: this.QualInfo) => Some((qual, info.name)) - case _ => None - } - - override def definesNewName = true - - def mkString(underlying: TermName, info: ThisInfo) = - s"$underlying$separator${info.name}" - def infoString = s"Qualified $separator" - - qualifiedNameKinds(separator) = this - } - - object AnyQualifiedName { - def unapply(name: DerivedTermName): Option[(TermName, SimpleTermName)] = name match { - case DerivedTermName(qual, info: QualifiedInfo) => - Some((name.underlying, info.name)) - case _ => None - } - } - - trait NumberedInfo extends NameInfo { - def num: Int - } - - abstract class NumberedNameKind(tag: Int, val infoString: String) extends NameKind(tag) { self => - type ThisInfo = NumberedInfo - case class NumberedInfo(val num: Int) extends Info with NameKinds.NumberedInfo { - override def toString = s"$infoString $num" - } - def apply(qual: TermName, num: Int) = - qual.derived(new NumberedInfo(num)) - def unapply(name: DerivedTermName): Option[(TermName, Int)] = name match { - case DerivedTermName(underlying, info: this.NumberedInfo) => Some((underlying, info.num)) - case _ => None - } - } - - case class UniqueNameKind(val separator: String) - extends NumberedNameKind(UNIQUE, s"Unique $separator") { - override def definesNewName = true - def mkString(underlying: TermName, info: ThisInfo) = { - val safePrefix = str.sanitize(underlying.toString + separator) - safePrefix + info.num - } - - def fresh(prefix: TermName = EmptyTermName)(implicit ctx: Context): TermName = - ctx.freshNames.newName(prefix, this) - - uniqueNameKinds(separator) = this - } - - object AnyUniqueName { - def unapply(name: DerivedTermName): Option[(TermName, String, Int)] = name match { - case DerivedTermName(qual, info: NumberedInfo) => - info.kind match { - case unique: UniqueNameKind => Some((qual, unique.separator, info.num)) - case _ => None - } - case _ => None - } - } - - val QualifiedName = new QualifiedNameKind(QUALIFIED, ".") - val FlattenedName = new QualifiedNameKind(FLATTENED, "$") - val ExpandedName = new QualifiedNameKind(EXPANDED, str.EXPAND_SEPARATOR) - val TraitSetterName = new QualifiedNameKind(TRAITSETTER, str.TRAIT_SETTER_SEPARATOR) - - val UniqueName = new UniqueNameKind("$") { - override def mkString(underlying: TermName, info: ThisInfo) = - if (underlying.isEmpty) "$" + info.num + "$" else super.mkString(underlying, info) - } - - val InlineAccessorName = new UniqueNameKind("$_inlineAccessor_$") - val TempResultName = new UniqueNameKind("ev$") - val EvidenceParamName = new UniqueNameKind("evidence$") - val DepParamName = new UniqueNameKind("") - val LazyImplicitName = new UniqueNameKind("$_lazy_implicit_$") - val LazyLocalName = new UniqueNameKind("$lzy") - val LazyLocalInitName = new UniqueNameKind("$lzyINIT") - val LazyFieldOffsetName = new UniqueNameKind("$OFFSET") - val LazyBitMapName = new UniqueNameKind(nme.BITMAP_PREFIX.toString) - val NonLocalReturnKeyName = new UniqueNameKind("nonLocalReturnKey") - val WildcardParamName = new UniqueNameKind("_$") - val TailLabelName = new UniqueNameKind("tailLabel") - val ExceptionBinderName = new UniqueNameKind("ex") - val SkolemName = new UniqueNameKind("?") - val LiftedTreeName = new UniqueNameKind("liftedTree") - - 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 - val PatMatOName = new UniqueNameKind("o") // FIXME: explain what this is - val PatMatCaseName = new UniqueNameKind("case") - val PatMatMatchFailName = new UniqueNameKind("matchFail") - val PatMatSelectorName = new UniqueNameKind("selector") - - object DefaultGetterName extends NumberedNameKind(DEFAULTGETTER, "DefaultGetter") { - def mkString(underlying: TermName, info: ThisInfo) = { - val prefix = if (underlying.isConstructorName) nme.DEFAULT_GETTER_INIT else underlying - prefix.toString + nme.DEFAULT_GETTER + (info.num + 1) - } - } - - object VariantName extends NumberedNameKind(VARIANT, "Variant") { - val varianceToPrefix = Map(-1 -> '-', 0 -> '=', 1 -> '+') - val prefixToVariance = Map('-' -> -1, '=' -> 0, '+' -> 1) - def mkString(underlying: TermName, info: ThisInfo) = { - varianceToPrefix(info.num).toString + underlying - } - } - - val SuperAccessorName = new PrefixNameKind(SUPERACCESSOR, "super$") - val InitializerName = new PrefixNameKind(INITIALIZER, "initial$") - val ShadowedName = new PrefixNameKind(SHADOWED, "(shadowed)") - val AvoidClashName = new SuffixNameKind(AVOIDCLASH, "$_avoid_name_clash_$") - val ModuleClassName = new SuffixNameKind(OBJECTCLASS, "$", optInfoString = "ModuleClass") - - object SignedName extends NameKind(63) { - - /** @param parts resultSig followed by paramsSig */ - case class SignedInfo(sig: Signature) extends Info { - override def toString = s"$infoString $sig" - } - type ThisInfo = SignedInfo - - def apply(qual: TermName, sig: Signature) = - qual.derived(new SignedInfo(sig)) - def unapply(name: DerivedTermName): Option[(TermName, Signature)] = name match { - case DerivedTermName(underlying, info: SignedInfo) => Some((underlying, info.sig)) - case _ => None - } - - def mkString(underlying: TermName, info: ThisInfo): String = unsupported("mkString") - def infoString: String = "Signed" - } - - def simpleNameKindOfTag : collection.Map[Int, ClassifiedNameKind] = simpleNameKinds - def qualifiedNameKindOfSeparator: collection.Map[String, QualifiedNameKind] = qualifiedNameKinds - def uniqueNameKindOfSeparator : collection.Map[String, UniqueNameKind] = uniqueNameKinds -} \ No newline at end of file diff --git a/compiler/src/dotty/tools/dotc/core/NameKinds.scala b/compiler/src/dotty/tools/dotc/core/NameKinds.scala new file mode 100644 index 000000000..2c5e3ee3e --- /dev/null +++ b/compiler/src/dotty/tools/dotc/core/NameKinds.scala @@ -0,0 +1,248 @@ +package dotty.tools +package dotc +package core + +import Names._ +import NameOps._ +import StdNames._ +import util.DotClass +import tasty.TastyFormat._ +import Decorators._ +import Contexts.Context +import collection.mutable + +object NameKinds { + + @sharable private val simpleNameKinds = new mutable.HashMap[Int, ClassifiedNameKind] + @sharable private val uniqueNameKinds = new mutable.HashMap[String, UniqueNameKind] + @sharable private val qualifiedNameKinds = new mutable.HashMap[String, QualifiedNameKind] + + abstract class NameInfo extends DotClass { + def kind: NameKind + def mkString(underlying: TermName): String + def map(f: SimpleTermName => SimpleTermName): NameInfo = this + } + + abstract class NameKind(val tag: Int) extends DotClass { self => + type ThisInfo <: Info + class Info extends NameInfo { this: ThisInfo => + def kind = self + def mkString(underlying: TermName) = self.mkString(underlying, this) + override def toString = infoString + } + def definesNewName = false + def unmangle(name: SimpleTermName): TermName = name + def mkString(underlying: TermName, info: ThisInfo): String + def infoString: String + } + + object SimpleTermNameKind extends NameKind(UTF8) { self => + type ThisInfo = Info + val info = new Info + def mkString(underlying: TermName, info: ThisInfo) = unsupported("mkString") + def infoString = unsupported("infoString") + } + + abstract class ClassifiedNameKind(tag: Int, val infoString: String) extends NameKind(tag) { + type ThisInfo = Info + val info = new Info + def apply(qual: TermName) = + qual.derived(info) + def unapply(name: DerivedTermName): Option[TermName] = name match { + case DerivedTermName(underlying, `info`) => Some(underlying) + case _ => None + } + simpleNameKinds(tag) = this + } + + class PrefixNameKind(tag: Int, prefix: String, optInfoString: String = "") + 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 { + val name: SimpleTermName + } + + class QualifiedNameKind(tag: Int, val separator: String) + extends NameKind(tag) { + type ThisInfo = QualInfo + case class QualInfo(val name: SimpleTermName) extends Info with QualifiedInfo { + override def map(f: SimpleTermName => SimpleTermName): NameInfo = new QualInfo(f(name)) + override def toString = s"$infoString $name" + } + def apply(qual: TermName, name: SimpleTermName) = + qual.derived(new QualInfo(name)) + def unapply(name: DerivedTermName): Option[(TermName, SimpleTermName)] = name match { + case DerivedTermName(qual, info: this.QualInfo) => Some((qual, info.name)) + case _ => None + } + + override def definesNewName = true + + def mkString(underlying: TermName, info: ThisInfo) = + s"$underlying$separator${info.name}" + def infoString = s"Qualified $separator" + + qualifiedNameKinds(separator) = this + } + + object AnyQualifiedName { + def unapply(name: DerivedTermName): Option[(TermName, SimpleTermName)] = name match { + case DerivedTermName(qual, info: QualifiedInfo) => + Some((name.underlying, info.name)) + case _ => None + } + } + + trait NumberedInfo extends NameInfo { + def num: Int + } + + abstract class NumberedNameKind(tag: Int, val infoString: String) extends NameKind(tag) { self => + type ThisInfo = NumberedInfo + case class NumberedInfo(val num: Int) extends Info with NameKinds.NumberedInfo { + override def toString = s"$infoString $num" + } + def apply(qual: TermName, num: Int) = + qual.derived(new NumberedInfo(num)) + def unapply(name: DerivedTermName): Option[(TermName, Int)] = name match { + case DerivedTermName(underlying, info: this.NumberedInfo) => Some((underlying, info.num)) + case _ => None + } + } + + case class UniqueNameKind(val separator: String) + extends NumberedNameKind(UNIQUE, s"Unique $separator") { + override def definesNewName = true + def mkString(underlying: TermName, info: ThisInfo) = { + val safePrefix = str.sanitize(underlying.toString + separator) + safePrefix + info.num + } + + def fresh(prefix: TermName = EmptyTermName)(implicit ctx: Context): TermName = + ctx.freshNames.newName(prefix, this) + + uniqueNameKinds(separator) = this + } + + object AnyUniqueName { + def unapply(name: DerivedTermName): Option[(TermName, String, Int)] = name match { + case DerivedTermName(qual, info: NumberedInfo) => + info.kind match { + case unique: UniqueNameKind => Some((qual, unique.separator, info.num)) + case _ => None + } + case _ => None + } + } + + val QualifiedName = new QualifiedNameKind(QUALIFIED, ".") + val FlattenedName = new QualifiedNameKind(FLATTENED, "$") + val ExpandedName = new QualifiedNameKind(EXPANDED, str.EXPAND_SEPARATOR) + val TraitSetterName = new QualifiedNameKind(TRAITSETTER, str.TRAIT_SETTER_SEPARATOR) + + val UniqueName = new UniqueNameKind("$") { + override def mkString(underlying: TermName, info: ThisInfo) = + if (underlying.isEmpty) "$" + info.num + "$" else super.mkString(underlying, info) + } + + val InlineAccessorName = new UniqueNameKind("$_inlineAccessor_$") + val TempResultName = new UniqueNameKind("ev$") + val EvidenceParamName = new UniqueNameKind("evidence$") + val DepParamName = new UniqueNameKind("") + val LazyImplicitName = new UniqueNameKind("$_lazy_implicit_$") + val LazyLocalName = new UniqueNameKind("$lzy") + val LazyLocalInitName = new UniqueNameKind("$lzyINIT") + val LazyFieldOffsetName = new UniqueNameKind("$OFFSET") + val LazyBitMapName = new UniqueNameKind(nme.BITMAP_PREFIX.toString) + val NonLocalReturnKeyName = new UniqueNameKind("nonLocalReturnKey") + val WildcardParamName = new UniqueNameKind("_$") + val TailLabelName = new UniqueNameKind("tailLabel") + val ExceptionBinderName = new UniqueNameKind("ex") + val SkolemName = new UniqueNameKind("?") + val LiftedTreeName = new UniqueNameKind("liftedTree") + + 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 + val PatMatOName = new UniqueNameKind("o") // FIXME: explain what this is + val PatMatCaseName = new UniqueNameKind("case") + val PatMatMatchFailName = new UniqueNameKind("matchFail") + val PatMatSelectorName = new UniqueNameKind("selector") + + object DefaultGetterName extends NumberedNameKind(DEFAULTGETTER, "DefaultGetter") { + def mkString(underlying: TermName, info: ThisInfo) = { + 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") { + val varianceToPrefix = Map(-1 -> '-', 0 -> '=', 1 -> '+') + val prefixToVariance = Map('-' -> -1, '=' -> 0, '+' -> 1) + def mkString(underlying: TermName, info: ThisInfo) = { + varianceToPrefix(info.num).toString + underlying + } + } + + 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") + + object SignedName extends NameKind(63) { + + /** @param parts resultSig followed by paramsSig */ + case class SignedInfo(sig: Signature) extends Info { + override def toString = s"$infoString $sig" + } + type ThisInfo = SignedInfo + + def apply(qual: TermName, sig: Signature) = + qual.derived(new SignedInfo(sig)) + def unapply(name: DerivedTermName): Option[(TermName, Signature)] = name match { + case DerivedTermName(underlying, info: SignedInfo) => Some((underlying, info.sig)) + case _ => None + } + + def mkString(underlying: TermName, info: ThisInfo): String = unsupported("mkString") + 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 +} \ No newline at end of file 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 - * @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 */ 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 = "" 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 = "" 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) { -- cgit v1.2.3