Skip to content

Commit 01ebe06

Browse files
committed
Semantic SuperAccessor and Initializer names
1 parent 7635876 commit 01ebe06

File tree

6 files changed

+122
-58
lines changed

6 files changed

+122
-58
lines changed

compiler/src/dotty/tools/dotc/core/NameInfos.scala

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ object NameInfo {
2222
val QualifiedKind = 1
2323
val DefaultGetterKind = 3
2424
val VariantKind = 4
25+
val SuperAccessorKind = 5
26+
val InitializerKind = 6
2527
val ModuleClassKind = 10
2628

2729
val qualifier: Map[String, SimpleTermName => Qualified] =
@@ -87,6 +89,20 @@ object NameInfo {
8789
def mkString(underlying: TermName) = varianceToPrefix(num).toString + underlying
8890
}
8991

92+
val SuperAccessor = new NameInfo {
93+
def kind = SuperAccessorKind
94+
def mkString(underlying: TermName) =
95+
underlying.mapLast(n => (nme.SUPER_PREFIX ++ n).asSimpleName).toString
96+
override def toString = "SuperAccessor"
97+
}
98+
99+
val Initializer = new NameInfo {
100+
def kind = InitializerKind
101+
def mkString(underlying: TermName) =
102+
underlying.mapLast(n => (nme.INITIALIZER_PREFIX ++ n).asSimpleName).toString
103+
override def toString = "Initializer"
104+
}
105+
90106
val ModuleClass = new NameInfo {
91107
def kind = ModuleClassKind
92108
def mkString(underlying: TermName) = underlying + "$"

compiler/src/dotty/tools/dotc/core/NameOps.scala

Lines changed: 75 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,25 @@ object NameOps {
4949
}
5050
}
5151

52-
class PrefixNameExtractor(pre: TermName) {
53-
def apply(name: TermName): TermName = pre ++ name
52+
class PrefixNameExtractor(pre: TermName, info: NameInfo) {
53+
def apply(name: TermName): TermName =
54+
if (Config.semanticNames) name.derived(info) else pre ++ name
55+
5456
def unapply(name: TermName): Option[TermName] =
55-
if (name startsWith pre) Some(name.drop(pre.length).asTermName) else None
57+
if (Config.semanticNames)
58+
name match {
59+
case DerivedTermName(original, `info`) => Some(original)
60+
case _ => None
61+
}
62+
else tryUnmangle(name)
63+
64+
def tryUnmangle(name: TermName): Option[TermName] =
65+
if (name startsWith pre) Some(name.drop(pre.length).asTermName)
66+
else None
5667
}
5768

58-
object SuperAccessorName extends PrefixNameExtractor(nme.SUPER_PREFIX)
59-
object InitializerName extends PrefixNameExtractor(nme.INITIALIZER_PREFIX)
69+
object SuperAccessorName extends PrefixNameExtractor(nme.SUPER_PREFIX, NameInfo.SuperAccessor)
70+
object InitializerName extends PrefixNameExtractor(nme.INITIALIZER_PREFIX, NameInfo.Initializer)
6071

6172
implicit class NameDecorator[N <: Name](val name: N) extends AnyVal {
6273
import nme._
@@ -152,7 +163,9 @@ object NameOps {
152163
}.asInstanceOf[N]
153164

154165
/** The superaccessor for method with given name */
155-
def superName: TermName = (nme.SUPER_PREFIX ++ name).toTermName
166+
def superName: TermName =
167+
if (Config.semanticNames) name.derived(NameInfo.SuperAccessor).toTermName
168+
else (nme.SUPER_PREFIX ++ name).toTermName
156169

157170
/** The expanded name of `name` relative to given class `base`.
158171
*/
@@ -165,9 +178,17 @@ object NameOps {
165178
*/
166179
def expandedName(prefix: Name, separator: Name = nme.EXPAND_SEPARATOR): N =
167180
likeTyped(
168-
if (Config.semanticNames)
169-
prefix.derived(NameInfo.qualifier(separator.toString)(name.toSimpleName))
170-
// note: expanded name may itself be expanded. For example, look at javap of scala.App.initCode
181+
if (Config.semanticNames) {
182+
def qualify(name: SimpleTermName) =
183+
prefix.derived(NameInfo.qualifier(separator.toString)(name))
184+
name rewrite {
185+
case name: SimpleTermName =>
186+
qualify(name)
187+
case DerivedTermName(_, _: NameInfo.Qualified) =>
188+
// Note: an expanded name may itself be expanded. For example, look at javap of scala.App.initCode
189+
qualify(name.toSimpleName)
190+
}
191+
}
171192
else prefix ++ separator ++ name)
172193

173194
def expandedName(prefix: Name): N = expandedName(prefix, nme.EXPAND_SEPARATOR)
@@ -178,35 +199,45 @@ object NameOps {
178199
* signs. This can happen for instance if a super accessor is paired with
179200
* an encoded name, e.g. super$$plus$eq. See #765.
180201
*/
181-
def unexpandedName: N = likeTyped {
202+
def unexpandedName: N =
182203
if (Config.semanticNames)
183-
name.rewrite {
184-
case DerivedTermName(_, NameInfo.Expand(unexp)) => unexp
204+
likeTyped {
205+
name.rewrite { case DerivedTermName(_, NameInfo.Expand(unexp)) => unexp }
185206
}
186-
else {
187-
var idx = name.lastIndexOfSlice(nme.EXPAND_SEPARATOR)
207+
else unexpandedNameOfMangled
188208

189-
// Hack to make super accessors from traits work. They would otherwise fail because of #765
190-
// TODO: drop this once we have more robust name handling
191-
if (idx > FalseSuperLength && name.slice(idx - FalseSuperLength, idx) == FalseSuper)
192-
idx -= FalseSuper.length
209+
def unexpandedNameOfMangled: N = likeTyped {
210+
var idx = name.lastIndexOfSlice(nme.EXPAND_SEPARATOR)
193211

194-
if (idx < 0) name else (name drop (idx + nme.EXPAND_SEPARATOR.length))
195-
}
212+
// Hack to make super accessors from traits work. They would otherwise fail because of #765
213+
// TODO: drop this once we have more robust name handling
214+
if (idx > FalseSuperLength && name.slice(idx - FalseSuperLength, idx) == FalseSuper)
215+
idx -= FalseSuper.length
216+
217+
if (idx < 0) name else (name drop (idx + nme.EXPAND_SEPARATOR.length))
196218
}
197219

198-
def expandedPrefix: N = likeTyped {
220+
def expandedPrefix: N =
199221
if (Config.semanticNames)
200-
name.rewrite {
201-
case DerivedTermName(prefix, NameInfo.Expand(_)) => prefix
222+
likeTyped {
223+
name.rewrite { case DerivedTermName(prefix, NameInfo.Expand(_)) => prefix }
202224
}
203-
else {
204-
val idx = name.lastIndexOfSlice(nme.EXPAND_SEPARATOR)
205-
assert(idx >= 0)
206-
name.take(idx)
207-
}
225+
else expandedPrefixOfMangled
226+
227+
def expandedPrefixOfMangled: N = {
228+
val idx = name.lastIndexOfSlice(nme.EXPAND_SEPARATOR)
229+
assert(idx >= 0)
230+
likeTyped(name.take(idx))
208231
}
209232

233+
def unmangleExpandedName: N =
234+
if (Config.semanticNames && name.isSimple) {
235+
val unmangled = unexpandedNameOfMangled
236+
if (name eq unmangled) name
237+
else likeTyped(expandedPrefixOfMangled.derived(NameInfo.Expand(unmangled.asSimpleName)))
238+
}
239+
else name
240+
210241
def shadowedName: N = likeTyped(nme.SHADOWED ++ name)
211242

212243
def revertShadowed: N = likeTyped(name.drop(nme.SHADOWED.length))
@@ -415,9 +446,9 @@ object NameOps {
415446
name rewrite {
416447
case DerivedTermName(methName, NameInfo.DefaultGetter(_)) => methName
417448
}
418-
else mangledDefaultGetterToMethod
449+
else defaultGetterToMethodOfMangled
419450

420-
def mangledDefaultGetterToMethod: TermName = {
451+
def defaultGetterToMethodOfMangled: TermName = {
421452
val p = name.indexOfSlice(DEFAULT_GETTER)
422453
if (p >= 0) {
423454
val q = name.take(p).asTermName
@@ -432,9 +463,9 @@ object NameOps {
432463
name collect {
433464
case DerivedTermName(methName, NameInfo.DefaultGetter(num)) => num
434465
} getOrElse -1
435-
else mangledDefaultGetterIndex
466+
else defaultGetterIndexOfMangled
436467

437-
def mangledDefaultGetterIndex: Int = {
468+
def defaultGetterIndexOfMangled: Int = {
438469
var i = name.length
439470
while (i > 0 && name(i - 1).isDigit) i -= 1
440471
if (i > 0 && i < name.length && name.take(i).endsWith(DEFAULT_GETTER))
@@ -525,11 +556,21 @@ object NameOps {
525556

526557
def unmangleMethodName: TermName =
527558
if (Config.semanticNames && name.isSimple) {
528-
val idx = name.mangledDefaultGetterIndex
529-
if (idx >= 0) name.mangledDefaultGetterToMethod.defaultGetterName(idx)
559+
val idx = name.defaultGetterIndexOfMangled
560+
if (idx >= 0) name.defaultGetterToMethodOfMangled.defaultGetterName(idx)
530561
else name
531562
}
532563
else name
564+
565+
def unmangleSuperName: TermName =
566+
if (Config.semanticNames && name.isSimple)
567+
SuperAccessorName.tryUnmangle(name.lastPart) match {
568+
case scala.Some(original) =>
569+
name.mapLast(_ => original.asSimpleName).derived(NameInfo.SuperAccessor)
570+
case None =>
571+
name
572+
}
573+
else name
533574
}
534575

535576
private final val FalseSuper = "$$super".toTermName

compiler/src/dotty/tools/dotc/core/SymDenotations.scala

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -372,10 +372,8 @@ object SymDenotations {
372372
// might have been moved from different origins into the same class
373373

374374
/** The name with which the denoting symbol was created */
375-
final def originalName(implicit ctx: Context) = {
376-
val d = initial
377-
if (d is ExpandedName) d.name.unexpandedName else d.name // !!!DEBUG, was: effectiveName
378-
}
375+
final def originalName(implicit ctx: Context) =
376+
initial.effectiveName
379377

380378
/** The encoded full path name of this denotation, where outer names and inner names
381379
* are separated by `separator` strings.

compiler/src/dotty/tools/dotc/core/tasty/NameBuffer.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ class NameBuffer extends TastyBuffer(10000) {
2929
val tname = name.toTermName match {
3030
case DerivedTermName(name1, NameInfo.ModuleClass) =>
3131
ModuleClass(nameIndex(name1, toTasty))
32+
case DerivedTermName(name1, NameInfo.SuperAccessor) =>
33+
SuperAccessor(nameIndex(name1, toTasty))
3234
case DerivedTermName(prefix, qual: NameInfo.Qualified) =>
3335
val tcon: (NameRef, NameRef) => TastyName = qual match {
3436
case _: NameInfo.Select => Qualified

compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -60,19 +60,24 @@ class TreePickler(pickler: TastyPickler) {
6060
}
6161

6262
private def pickleName(sym: Symbol)(implicit ctx: Context): Unit = {
63-
def encodeSuper(name: Name): TastyName.NameRef =
64-
if (sym is Flags.SuperAccessor) {
65-
val SuperAccessorName(n) = name
66-
nameIndex(TastyName.SuperAccessor(nameIndex(n)))
67-
}
68-
else nameIndex(name)
6963
val nameRef =
70-
if (sym is Flags.ExpandedName)
71-
nameIndex(
72-
TastyName.Expanded(
73-
nameIndex(sym.name.expandedPrefix),
74-
encodeSuper(sym.name.unexpandedName)))
75-
else encodeSuper(sym.name)
64+
if (Config.semanticNames) {
65+
if (sym is Flags.ExpandedName) assert(sym.name.is(NameInfo.QualifiedKind))
66+
nameIndex(sym.name)
67+
}
68+
else {
69+
def encodeSuper(name: Name): TastyName.NameRef =
70+
if (sym is Flags.SuperAccessor) {
71+
val SuperAccessorName(n) = name
72+
nameIndex(TastyName.SuperAccessor(nameIndex(n)))
73+
} else nameIndex(name)
74+
if (sym is Flags.ExpandedName)
75+
nameIndex(
76+
TastyName.Expanded(
77+
nameIndex(sym.name.expandedPrefix),
78+
encodeSuper(sym.name.unexpandedName)))
79+
else encodeSuper(sym.name)
80+
}
7681
writeNat(nameRef.index)
7782
}
7883

compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -418,23 +418,25 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
418418

419419
// symbols that were pickled with Pickler.writeSymInfo
420420
val nameref = readNat()
421-
val name0 = at(nameref, readName)
421+
var name = at(nameref, readName)
422422
val owner = readSymbolRef()
423423

424-
var flags = unpickleScalaFlags(readLongNat(), name0.isTypeName)
424+
var flags = unpickleScalaFlags(readLongNat(), name.isTypeName)
425425
if (flags is DefaultParameter) {
426426
// DefaultParameterized flag now on method, not parameter
427427
//assert(flags is Param, s"$name0 in $owner")
428428
flags = flags &~ DefaultParameterized
429429
owner.setFlag(DefaultParameterized)
430430
}
431431

432-
val name1 = name0.adjustIfModuleClass(flags)
433-
val name2 = if (name1 == nme.TRAIT_CONSTRUCTOR) nme.CONSTRUCTOR else name1
434-
val name =
435-
if (flags is ModuleClass) name2.unmangleClassName
436-
else if (flags is Method) name2.asTermName.unmangleMethodName
437-
else name2
432+
name = name.adjustIfModuleClass(flags)
433+
if (flags is Method) {
434+
name =
435+
if (name == nme.TRAIT_CONSTRUCTOR) nme.CONSTRUCTOR
436+
else name.asTermName.unmangleMethodName
437+
}
438+
if (flags is ExpandedName) name = name.unmangleExpandedName
439+
if (flags is SuperAccessor) name = name.asTermName.unmangleSuperName
438440

439441
def isClassRoot = (name == classRoot.name) && (owner == classRoot.owner) && !(flags is ModuleClass)
440442
def isModuleClassRoot = (name == moduleClassRoot.name) && (owner == moduleClassRoot.owner) && (flags is Module)

0 commit comments

Comments
 (0)