Skip to content

Commit d6d62f8

Browse files
committed
Revise qualified names
1. Fix problem in fullNameSeparated 2. Revise expandedName operations
1 parent 1138cac commit d6d62f8

File tree

9 files changed

+64
-88
lines changed

9 files changed

+64
-88
lines changed

compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -557,8 +557,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
557557
def fullName: String = sym.showFullName
558558
def simpleName: Name = sym.name
559559
def javaSimpleName: Name = toDenot(sym).name // addModuleSuffix(simpleName.dropLocal)
560-
def javaBinaryName: Name = toDenot(sym).fullNameSeparated("/").unmangleClassName // addModuleSuffix(fullNameInternal('/'))
561-
// We use `unmangleClassName` so that `stripModuleClassSuffix` works as expected.
560+
def javaBinaryName: Name = javaClassName.replace('.', '/').toTermName // TODO: can we make this a string? addModuleSuffix(fullNameInternal('/'))
562561
def javaClassName: String = toDenot(sym).fullName.toString// addModuleSuffix(fullNameInternal('.')).toString
563562
def name: Name = sym.name
564563
def rawname: Name = {

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

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ import collection.mutable
1414
object NameKinds {
1515

1616
@sharable private val simpleNameKinds = new mutable.HashMap[Int, ClassifiedNameKind]
17+
@sharable private val qualifiedNameKinds = new mutable.HashMap[Int, QualifiedNameKind]
1718
@sharable private val uniqueNameKinds = new mutable.HashMap[String, UniqueNameKind]
18-
@sharable private val qualifiedNameKinds = new mutable.HashMap[String, QualifiedNameKind]
1919

2020
abstract class NameInfo extends DotClass {
2121
def kind: NameKind
@@ -83,8 +83,18 @@ object NameKinds {
8383
override def map(f: SimpleTermName => SimpleTermName): NameInfo = new QualInfo(f(name))
8484
override def toString = s"$infoString $name"
8585
}
86-
def apply(qual: TermName, name: SimpleTermName) =
86+
def apply(qual: TermName, name: SimpleTermName): TermName =
8787
qual.derived(new QualInfo(name))
88+
89+
/** Overloaded version used only for ExpandedName and TraitSetterName.
90+
* Needed because the suffix of an expanded name may itself be expanded.
91+
* For example, look at javap of scala.App.initCode
92+
*/
93+
def apply(qual: TermName, name: TermName): TermName = name rewrite {
94+
case name: SimpleTermName => apply(qual, name)
95+
case AnyQualifiedName(_, _) => apply(qual, name.toSimpleName)
96+
}
97+
8898
def unapply(name: DerivedTermName): Option[(TermName, SimpleTermName)] = name match {
8999
case DerivedTermName(qual, info: this.QualInfo) => Some((qual, info.name))
90100
case _ => None
@@ -96,7 +106,7 @@ object NameKinds {
96106
s"$underlying$separator${info.name}"
97107
def infoString = s"Qualified $separator"
98108

99-
qualifiedNameKinds(separator) = this
109+
qualifiedNameKinds(tag) = this
100110
}
101111

102112
object AnyQualifiedName {
@@ -150,8 +160,8 @@ object NameKinds {
150160
}
151161

152162
val QualifiedName = new QualifiedNameKind(QUALIFIED, ".")
153-
val FlattenedName = new QualifiedNameKind(FLATTENED, "$")
154-
val TraitSetterName = new QualifiedNameKind(TRAITSETTER, str.TRAIT_SETTER_SEPARATOR)
163+
val FlatName = new QualifiedNameKind(FLATTENED, "$")
164+
val ExpandPrefixName = new QualifiedNameKind(EXPANDPREFIX, "$")
155165

156166
val ExpandedName = new QualifiedNameKind(EXPANDED, str.EXPAND_SEPARATOR) {
157167
private val FalseSuper = "$$super".toTermName
@@ -172,6 +182,8 @@ object NameKinds {
172182
}
173183
}
174184

185+
val TraitSetterName = new QualifiedNameKind(TRAITSETTER, str.TRAIT_SETTER_SEPARATOR)
186+
175187
val UniqueName = new UniqueNameKind("$") {
176188
override def mkString(underlying: TermName, info: ThisInfo) =
177189
if (underlying.isEmpty) "$" + info.num + "$" else super.mkString(underlying, info)
@@ -260,7 +272,7 @@ object NameKinds {
260272
val Scala2MethodNameKinds: List[NameKind] =
261273
List(DefaultGetterName, ProtectedAccessorName, ProtectedSetterName)
262274

263-
def simpleNameKindOfTag : collection.Map[Int, ClassifiedNameKind] = simpleNameKinds
264-
def qualifiedNameKindOfSeparator: collection.Map[String, QualifiedNameKind] = qualifiedNameKinds
265-
def uniqueNameKindOfSeparator : collection.Map[String, UniqueNameKind] = uniqueNameKinds
275+
def simpleNameKindOfTag : collection.Map[Int, ClassifiedNameKind] = simpleNameKinds
276+
def qualifiedNameKindOfTag : collection.Map[Int, QualifiedNameKind] = qualifiedNameKinds
277+
def uniqueNameKindOfSeparator: collection.Map[String, UniqueNameKind] = uniqueNameKinds
266278
}

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

Lines changed: 15 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,8 @@ object NameOps {
5959
def isStaticConstructorName = name == STATIC_CONSTRUCTOR
6060
def isImplClassName = name endsWith IMPL_CLASS_SUFFIX
6161
def isLocalDummyName = name startsWith LOCALDUMMY_PREFIX
62-
def isLoopHeaderLabel = (name startsWith WHILE_PREFIX) || (name startsWith DO_WHILE_PREFIX)
6362
def isReplWrapperName = name.toSimpleName containsSlice INTERPRETER_IMPORT_WRAPPER
6463
def isSetterName = name endsWith SETTER_SUFFIX
65-
def isSingletonName = name endsWith SINGLETON_SUFFIX
6664
def isImportName = name startsWith IMPORT
6765
def isFieldName = name endsWith LOCAL_SUFFIX
6866
def isScala2LocalSuffix = name.endsWith(" ")
@@ -110,8 +108,16 @@ object NameOps {
110108
/** Convert this module class name to corresponding source module name */
111109
def sourceModuleName: TermName = name.toTermName.exclude(ModuleClassName)
112110

113-
/** If name ends in module class suffix, drop it */
114-
def stripModuleClassSuffix: Name = name.exclude(ModuleClassName)
111+
/** If name ends in module class suffix, drop it. This
112+
* method needs to work on mangled as well as unmangled names because
113+
* it is also called from the backend.
114+
*/
115+
def stripModuleClassSuffix: Name = name match {
116+
case name: SimpleTermName if name.endsWith("$") =>
117+
name.unmangleClassName.exclude(ModuleClassName)
118+
case _ =>
119+
name.exclude(ModuleClassName)
120+
}
115121

116122
/** If flags is a ModuleClass but not a Package, add module class suffix */
117123
def adjustIfModuleClass(flags: Flags.FlagSet): N = likeTyped {
@@ -122,43 +128,17 @@ object NameOps {
122128
/** The superaccessor for method with given name */
123129
def superName: TermName = SuperAccessorName(name.toTermName)
124130

125-
/** The expanded name of `name` relative to given class `base`.
126-
*/
127-
def expandedName(base: Symbol, separator: Name)(implicit ctx: Context): N =
128-
expandedName(if (base.name.is(ExpandedName)) base.name else base.fullNameSeparated("$"), separator)
129-
130-
def expandedName(base: Symbol)(implicit ctx: Context): N = expandedName(base, nme.EXPAND_SEPARATOR)
131-
132-
/** The expanded name of `name` relative to `basename` with given `separator`
133-
*/
134-
def expandedName(prefix: Name, separator: Name = nme.EXPAND_SEPARATOR): N =
135-
likeTyped {
136-
def qualify(name: SimpleTermName) =
137-
qualifiedNameKindOfSeparator(separator.toString)(prefix.toTermName, name)
138-
name rewrite {
139-
case name: SimpleTermName =>
140-
qualify(name)
141-
case AnyQualifiedName(_, _) =>
142-
// Note: an expanded name may itself be expanded. For example, look at javap of scala.App.initCode
143-
qualify(name.toSimpleName)
144-
}
145-
}
146-
147-
def expandedName(prefix: Name): N = expandedName(prefix, nme.EXPAND_SEPARATOR)
131+
def expandedName(base: Symbol, kind: QualifiedNameKind = ExpandedName)(implicit ctx: Context): N = {
132+
val prefix =
133+
if (base.name.is(ExpandedName)) base.name else base.fullNameSeparated(ExpandPrefixName)
134+
likeTyped { kind(prefix.toTermName, name.toTermName) }
135+
}
148136

149137
/** Revert the expanded name. */
150138
def unexpandedName: N = likeTyped {
151139
name.rewrite { case ExpandedName(_, unexp) => unexp }
152140
}
153141

154-
def expandedPrefix: N = likeTyped { name.exclude(ExpandedName) }
155-
156-
def expandedPrefixOfMangled: N = {
157-
val idx = name.lastIndexOfSlice(nme.EXPAND_SEPARATOR)
158-
assert(idx >= 0)
159-
likeTyped(name.take(idx))
160-
}
161-
162142
def implClassName: N = likeTyped(name ++ tpnme.IMPL_CLASS_SUFFIX)
163143

164144
def errorName: N = likeTyped(name ++ nme.ERROR)

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,6 @@ object StdNames {
124124
val PACKAGE: N = "package"
125125
val PACKAGE_CLS: N = "package$"
126126
val ROOT: N = "<root>"
127-
val SINGLETON_SUFFIX: N = ".type"
128127
val SPECIALIZED_SUFFIX: N = "$sp"
129128
val SUPER_PREFIX: N = "super$"
130129
val WHILE_PREFIX: N = "while$"

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

Lines changed: 21 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -378,55 +378,44 @@ object SymDenotations {
378378
/** The encoded full path name of this denotation, where outer names and inner names
379379
* are separated by `separator` strings.
380380
* Never translates expansions of operators back to operator symbol.
381-
* Drops package objects. Represents terms in the owner chain by a simple `~`.
381+
* Drops package objects. Represents each term in the owner chain by a simple `~`.
382382
* (Note: scalac uses nothing to represent terms, which can cause name clashes
383383
* between same-named definitions in different enclosing methods. Before this commit
384384
* we used `$' but this can cause ambiguities with the class separator '$').
385385
* A separator "" means "flat name"; the real separator in this case is "$" and
386386
* enclosing packages do not form part of the name.
387387
*/
388-
def fullNameSeparated(separator: String)(implicit ctx: Context): Name = {
389-
val stopAtPackage = separator.isEmpty
390-
val sep = if (stopAtPackage) "$" else separator
388+
def fullNameSeparated(kind: QualifiedNameKind)(implicit ctx: Context): Name =
391389
if (symbol == NoSymbol ||
392390
owner == NoSymbol ||
393391
owner.isEffectiveRoot ||
394-
stopAtPackage && owner.is(PackageClass)) name
392+
kind == FlatName && owner.is(PackageClass)) name
395393
else {
396394
var filler = ""
397395
var encl = owner
398396
while (!encl.isClass && !encl.isPackageObject) {
399397
encl = encl.owner
400398
filler += "~"
401399
}
402-
var prefix = encl.fullNameSeparated(separator)
403-
val fn =
404-
if (qualifiedNameKindOfSeparator.contains(sep)) {
405-
if (sep == "$")
406-
// duplicate scalac's behavior: don't write a double '$$' for module class members.
407-
prefix = prefix.exclude(ModuleClassName)
408-
name rewrite {
409-
case n: SimpleTermName =>
410-
val n1 = if (filler.isEmpty) n else termName(filler ++ n)
411-
qualifiedNameKindOfSeparator(sep)(prefix.toTermName, n1)
412-
}
413-
}
414-
else {
415-
val sep1 =
416-
if (owner.is(ModuleClass, butNot = Package) && sep == "$") ""
417-
else sep
418-
// duplicate scalac's behavior: don't write a double '$$' for module class members.
419-
prefix ++ sep1 ++ name
420-
}
400+
var prefix = encl.fullNameSeparated(kind)
401+
if (kind.separator == "$")
402+
// duplicate scalac's behavior: don't write a double '$$' for module class members.
403+
prefix = prefix.exclude(ModuleClassName)
404+
def qualify(n: SimpleTermName) =
405+
kind(prefix.toTermName, if (filler.isEmpty) n else termName(filler ++ n))
406+
val fn = name rewrite {
407+
case name: SimpleTermName => qualify(name)
408+
case name @ AnyQualifiedName(_, _) => qualify(name.toSimpleName)
409+
}
421410
if (isType) fn.toTypeName else fn.toTermName
422411
}
423-
}
412+
424413

425414
/** The encoded flat name of this denotation, where joined names are separated by `separator` characters. */
426-
def flatName(implicit ctx: Context): Name = fullNameSeparated("")
415+
def flatName(implicit ctx: Context): Name = fullNameSeparated(FlatName)
427416

428417
/** `fullName` where `.' is the separator character */
429-
def fullName(implicit ctx: Context): Name = fullNameSeparated(".")
418+
def fullName(implicit ctx: Context): Name = fullNameSeparated(QualifiedName)
430419

431420
// ----- Tests -------------------------------------------------
432421

@@ -1762,13 +1751,13 @@ object SymDenotations {
17621751
}
17631752
}
17641753

1765-
private[this] var fullNameCache: SimpleMap[String, Name] = SimpleMap.Empty
1766-
override final def fullNameSeparated(separator: String)(implicit ctx: Context): Name = {
1767-
val cached = fullNameCache(separator)
1754+
private[this] var fullNameCache: SimpleMap[QualifiedNameKind, Name] = SimpleMap.Empty
1755+
override final def fullNameSeparated(kind: QualifiedNameKind)(implicit ctx: Context): Name = {
1756+
val cached = fullNameCache(kind)
17681757
if (cached != null) cached
17691758
else {
1770-
val fn = super.fullNameSeparated(separator)
1771-
fullNameCache = fullNameCache.updated(separator, fn)
1759+
val fn = super.fullNameSeparated(kind)
1760+
fullNameCache = fullNameCache.updated(kind, fn)
17721761
fn
17731762
}
17741763
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,8 +222,9 @@ object TastyFormat {
222222
final val UTF8 = 1
223223
final val QUALIFIED = 2
224224
final val FLATTENED = 3
225+
final val EXPANDPREFIX = 5
225226
final val EXPANDED = 4
226-
final val TRAITSETTER = 5
227+
final val TRAITSETTER = 6
227228
final val UNIQUE = 10
228229
final val DEFAULTGETTER = 11
229230
final val VARIANT = 12

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

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,8 @@ class TastyUnpickler(reader: TastyReader) {
4949
case UTF8 =>
5050
goto(end)
5151
termName(bytes, start.index, length)
52-
case QUALIFIED =>
53-
QualifiedName(readName(), readName().asSimpleName)
54-
case FLATTENED =>
55-
FlattenedName(readName(), readName().asSimpleName)
56-
case EXPANDED =>
57-
ExpandedName(readName(), readName().asSimpleName)
52+
case QUALIFIED | FLATTENED | EXPANDED | EXPANDPREFIX =>
53+
qualifiedNameKindOfTag(tag)(readName(), readName().asSimpleName)
5854
case UNIQUE =>
5955
val separator = readName().toString
6056
val num = readNat()

compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ class PlainPrinter(_ctx: Context) extends Printer {
130130
case tp: TypeType =>
131131
toTextRHS(tp)
132132
case tp: TermRef
133-
if !tp.denotationIsCurrent && !homogenizedView || // always print underyling when testing picklers
133+
if !tp.denotationIsCurrent && !homogenizedView || // always print underlying when testing picklers
134134
tp.symbol.is(Module) ||
135135
tp.symbol.name.isImportName =>
136136
toTextRef(tp) ~ ".type"

compiler/src/dotty/tools/dotc/transform/AugmentScala2Traits.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import DenotTransformers._
1414
import Annotations._
1515
import StdNames._
1616
import NameOps._
17-
import NameKinds._
17+
import NameKinds.{ExpandedName, TraitSetterName}
1818
import ast.Trees._
1919

2020
/** This phase augments Scala2 traits with implementation classes and with additional members
@@ -74,7 +74,7 @@ class AugmentScala2Traits extends MiniPhaseTransform with IdentityDenotTransform
7474
def traitSetter(getter: TermSymbol) =
7575
getter.copy(
7676
name = getter.ensureNotPrivate.name
77-
.expandedName(getter.owner, nme.TRAIT_SETTER_SEPARATOR)
77+
.expandedName(getter.owner, TraitSetterName)
7878
.asTermName.setterName,
7979
flags = Method | Accessor,
8080
info = MethodType(getter.info.resultType :: Nil, defn.UnitType))

0 commit comments

Comments
 (0)