@@ -289,39 +289,43 @@ object SymDenotations {
289
289
}
290
290
291
291
/** The encoded full path name of this denotation, where outer names and inner names
292
- * are separated by `separator` characters .
292
+ * are separated by `separator` strings .
293
293
* Never translates expansions of operators back to operator symbol.
294
- * Drops package objects. Represents terms in the owner chain by a simple `separator`.
294
+ * Drops package objects. Represents terms in the owner chain by a simple `~`.
295
+ * (Note: scalac uses nothing to represent terms, which can cause name clashes
296
+ * between same-named definitions in different enclosing methods. Before this commit
297
+ * we used `$' but this can cause ambiguities with the class separator '$').
298
+ * A separator "" means "flat name"; the real separator in this case is "$" and
299
+ * enclosing packages do not form part of the name.
295
300
*/
296
- def fullNameSeparated (separator : Char )(implicit ctx : Context ): Name =
297
- if (symbol == NoSymbol || owner == NoSymbol || owner.isEffectiveRoot) name
301
+ def fullNameSeparated (separator : String )(implicit ctx : Context ): Name = {
302
+ var sep = separator
303
+ var stopAtPackage = false
304
+ if (sep.isEmpty) {
305
+ sep = " $"
306
+ stopAtPackage = true
307
+ }
308
+ if (symbol == NoSymbol ||
309
+ owner == NoSymbol ||
310
+ owner.isEffectiveRoot ||
311
+ stopAtPackage && owner.is(PackageClass )) name
298
312
else {
299
- var owner = this
300
- var sep = " "
301
- do {
302
- owner = owner.owner
303
- sep += separator
304
- } while ( ! owner.isClass && ! owner.isPackageObject)
305
- val fn = owner .fullNameSeparated(separator) ++ sep ++ name
313
+ var encl = owner
314
+ while ( ! encl.isClass && ! encl.isPackageObject) {
315
+ encl = encl.owner
316
+ sep += " ~ "
317
+ }
318
+ if ( owner.is( ModuleClass ) && sep == " $ " ) sep = " " // duplicate scalac's behavior: don't write a double '$$' for module class members.
319
+ val fn = encl .fullNameSeparated(separator) ++ sep ++ name
306
320
if (isType) fn.toTypeName else fn.toTermName
307
321
}
322
+ }
308
323
309
324
/** The encoded flat name of this denotation, where joined names are separated by `separator` characters. */
310
- def flatName (separator : Char = '$' )(implicit ctx : Context ): Name =
311
- if (symbol == NoSymbol || owner == NoSymbol || owner.isEffectiveRoot || (owner is PackageClass )) name
312
- else {
313
- var owner = this
314
- var sep = " "
315
- do {
316
- owner = owner.owner
317
- sep += separator
318
- } while (! owner.isClass && ! owner.isPackageObject)
319
- val fn = owner.flatName(separator) ++ sep ++ name
320
- if (isType) fn.toTypeName else fn.toTermName
321
- }
325
+ def flatName (implicit ctx : Context ): Name = fullNameSeparated(" " )
322
326
323
327
/** `fullName` where `.' is the separator character */
324
- def fullName (implicit ctx : Context ): Name = fullNameSeparated('.' )
328
+ def fullName (implicit ctx : Context ): Name = fullNameSeparated(" . " )
325
329
326
330
// ----- Tests -------------------------------------------------
327
331
@@ -1572,8 +1576,8 @@ object SymDenotations {
1572
1576
}
1573
1577
}
1574
1578
1575
- private [this ] var fullNameCache : SimpleMap [Character , Name ] = SimpleMap .Empty
1576
- override final def fullNameSeparated (separator : Char )(implicit ctx : Context ): Name = {
1579
+ private [this ] var fullNameCache : SimpleMap [String , Name ] = SimpleMap .Empty
1580
+ override final def fullNameSeparated (separator : String )(implicit ctx : Context ): Name = {
1577
1581
val cached = fullNameCache(separator)
1578
1582
if (cached != null ) cached
1579
1583
else {
0 commit comments