diff options
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) |