Skip to content

Commit 127b4b0

Browse files
committed
Decentralize unmangling, add new nameKinds
Start scheme where unmangling is done by NameKinds instead of in NameOps. Also add namekinds for protected accessors.
1 parent 3c4f481 commit 127b4b0

File tree

10 files changed

+62
-58
lines changed

10 files changed

+62
-58
lines changed

compiler/src/dotty/tools/dotc/ast/Desugar.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import core._
66
import util.Positions._, Types._, Contexts._, Constants._, Names._, NameOps._, Flags._
77
import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._
88
import Decorators._
9-
import NameKinds.{UniqueName, EvidenceParamName}
9+
import NameKinds.{UniqueName, EvidenceParamName, DefaultGetterName}
1010
import language.higherKinds
1111
import typer.FrontEnd
1212
import collection.mutable.ListBuffer
@@ -186,7 +186,7 @@ object desugar {
186186
case (vparam :: vparams) :: vparamss1 =>
187187
def defaultGetter: DefDef =
188188
DefDef(
189-
name = meth.name.defaultGetterName(n),
189+
name = DefaultGetterName(meth.name, n),
190190
tparams = meth.tparams.map(tparam => dropContextBound(toDefParam(tparam))),
191191
vparamss = takeUpTo(normalizedVparamss.nestedMap(toDefParam), n),
192192
tpt = TypeTree(),

compiler/src/dotty/tools/dotc/core/NameExtractors.scala renamed to compiler/src/dotty/tools/dotc/core/NameKinds.scala

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ object NameKinds {
3131
override def toString = infoString
3232
}
3333
def definesNewName = false
34+
def unmangle(name: SimpleTermName): TermName = name
3435
def mkString(underlying: TermName, info: ThisInfo): String
3536
def infoString: String
3637
}
@@ -58,11 +59,17 @@ object NameKinds {
5859
extends ClassifiedNameKind(tag, if (optInfoString.isEmpty) s"Prefix $prefix" else optInfoString) {
5960
def mkString(underlying: TermName, info: ThisInfo) =
6061
underlying.mapLast(n => termName(prefix + n.toString)).toString
62+
override def unmangle(name: SimpleTermName): TermName =
63+
if (name.startsWith(prefix)) apply(name.drop(prefix.length).asSimpleName)
64+
else name
6165
}
6266

6367
class SuffixNameKind(tag: Int, suffix: String, optInfoString: String = "")
6468
extends ClassifiedNameKind(tag, if (optInfoString.isEmpty) s"Suffix $suffix" else optInfoString) {
6569
def mkString(underlying: TermName, info: ThisInfo) = underlying.toString ++ suffix
70+
override def unmangle(name: SimpleTermName): TermName =
71+
if (name.endsWith(suffix)) apply(name.take(name.length - suffix.length).asSimpleName)
72+
else name
6673
}
6774

6875
trait QualifiedInfo extends NameInfo {
@@ -181,6 +188,20 @@ object NameKinds {
181188
val prefix = if (underlying.isConstructorName) nme.DEFAULT_GETTER_INIT else underlying
182189
prefix.toString + nme.DEFAULT_GETTER + (info.num + 1)
183190
}
191+
192+
private val dgLen = nme.DEFAULT_GETTER.length
193+
194+
override def unmangle(name: SimpleTermName): TermName = {
195+
var i = name.length
196+
while (i > 0 && name(i - 1).isDigit) i -= 1
197+
if (i > dgLen && i < name.length && name.slice(i - dgLen, i) == nme.DEFAULT_GETTER) {
198+
val index = name.drop(i).toString.toInt - 1
199+
var original = name.take(i - dgLen).asTermName
200+
if (original == nme.DEFAULT_GETTER_INIT) original = Names.CONSTRUCTOR
201+
apply(original, index)
202+
}
203+
else name
204+
}
184205
}
185206

186207
object VariantName extends NumberedNameKind(VARIANT, "Variant") {
@@ -194,6 +215,8 @@ object NameKinds {
194215
val SuperAccessorName = new PrefixNameKind(SUPERACCESSOR, "super$")
195216
val InitializerName = new PrefixNameKind(INITIALIZER, "initial$")
196217
val ShadowedName = new PrefixNameKind(SHADOWED, "(shadowed)")
218+
val ProtectedAccessorName = new PrefixNameKind(PROTECTEDACCESSOR, "protected$")
219+
val ProtectedSetterName = new PrefixNameKind(PROTECTEDSETTER, "protected$set") // dubious encoding, kept for Scala2 compatibility
197220
val AvoidClashName = new SuffixNameKind(AVOIDCLASH, "$_avoid_name_clash_$")
198221
val ModuleClassName = new SuffixNameKind(OBJECTCLASS, "$", optInfoString = "ModuleClass")
199222

@@ -216,6 +239,9 @@ object NameKinds {
216239
def infoString: String = "Signed"
217240
}
218241

242+
val Scala2MethodNameKinds: List[NameKind] =
243+
List(DefaultGetterName, ProtectedAccessorName, ProtectedSetterName)
244+
219245
def simpleNameKindOfTag : collection.Map[Int, ClassifiedNameKind] = simpleNameKinds
220246
def qualifiedNameKindOfSeparator: collection.Map[String, QualifiedNameKind] = qualifiedNameKinds
221247
def uniqueNameKindOfSeparator : collection.Map[String, UniqueNameKind] = uniqueNameKinds

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

Lines changed: 15 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,11 @@ object NameOps {
6060
def isImplClassName = name endsWith IMPL_CLASS_SUFFIX
6161
def isLocalDummyName = name startsWith LOCALDUMMY_PREFIX
6262
def isLoopHeaderLabel = (name startsWith WHILE_PREFIX) || (name startsWith DO_WHILE_PREFIX)
63-
def isProtectedAccessorName = name startsWith PROTECTED_PREFIX
6463
def isReplWrapperName = name.toSimpleName containsSlice INTERPRETER_IMPORT_WRAPPER
6564
def isSetterName = name endsWith SETTER_SUFFIX
6665
def isSingletonName = name endsWith SINGLETON_SUFFIX
6766
def isImportName = name startsWith IMPORT
6867
def isFieldName = name endsWith LOCAL_SUFFIX
69-
def isDefaultGetterName = name.isTermName && name.asTermName.defaultGetterIndex >= 0
7068
def isScala2LocalSuffix = name.endsWith(" ")
7169
def isModuleVarName(name: Name): Boolean =
7270
name.stripAnonNumberSuffix endsWith MODULE_VAR_SUFFIX
@@ -369,54 +367,21 @@ object NameOps {
369367
name.mapLast(n => n.take(n.length - LOCAL_SUFFIX.length).asSimpleName)
370368
}
371369

372-
/** Nominally, name$default$N, encoded for <init>
373-
* @param Post the parameters position.
374-
* @note Default getter name suffixes start at 1, so `pos` has to be adjusted by +1
375-
*/
376-
def defaultGetterName(pos: Int): TermName =
377-
DefaultGetterName(name, pos)
378-
379370
/** Nominally, name from name$default$N, CONSTRUCTOR for <init> */
380371
def defaultGetterToMethod: TermName =
381372
name rewrite {
382373
case DefaultGetterName(methName, _) => methName
383374
}
384375

385-
def defaultGetterToMethodOfMangled: TermName = {
386-
val p = name.indexOfSlice(DEFAULT_GETTER)
387-
if (p >= 0) {
388-
val q = name.take(p).asTermName
389-
// i.e., if (q.decoded == CONSTRUCTOR.toString) CONSTRUCTOR else q
390-
if (q == DEFAULT_GETTER_INIT) CONSTRUCTOR else q
391-
} else name
392-
}
393-
394376
/** If this is a default getter, its index (starting from 0), else -1 */
395377
def defaultGetterIndex: Int =
396378
name collect {
397379
case DefaultGetterName(_, num) => num
398380
} getOrElse -1
399381

400-
def defaultGetterIndexOfMangled: Int = {
401-
var i = name.length
402-
while (i > 0 && name(i - 1).isDigit) i -= 1
403-
if (i > 0 && i < name.length && name.take(i).endsWith(DEFAULT_GETTER))
404-
name.drop(i).toString.toInt - 1
405-
else
406-
-1
407-
}
408-
409382
def stripScala2LocalSuffix: TermName =
410383
if (name.isScala2LocalSuffix) name.init.asTermName else name
411384

412-
/** The name of an accessor for protected symbols. */
413-
def protectedAccessorName: TermName =
414-
PROTECTED_PREFIX ++ name.unexpandedName
415-
416-
/** The name of a setter for protected symbols. Used for inherited Java fields. */
417-
def protectedSetterName: TermName =
418-
PROTECTED_SET_PREFIX ++ name.unexpandedName
419-
420385
def moduleVarName: TermName =
421386
name ++ MODULE_VAR_SUFFIX
422387

@@ -478,18 +443,25 @@ object NameOps {
478443
case name => name
479444
}
480445

481-
def unmangleMethodName: TermName =
482-
if (name.isSimple) {
483-
val idx = name.defaultGetterIndexOfMangled
484-
if (idx >= 0) name.defaultGetterToMethodOfMangled.defaultGetterName(idx)
485-
else name
486-
}
487-
else name
488-
489446
def unmangleSuperName: TermName =
490447
if (name.isSimple && name.startsWith(str.SUPER_PREFIX))
491448
SuperAccessorName(name.drop(str.SUPER_PREFIX.length).asTermName)
492449
else name
450+
451+
def unmangle(kind: NameKind): TermName = name rewrite {
452+
case unmangled: SimpleTermName =>
453+
kind.unmangle(unmangled)
454+
case ExpandedName(prefix, last) =>
455+
kind.unmangle(last) rewrite {
456+
case kernel: SimpleTermName =>
457+
ExpandedName(prefix, kernel)
458+
}
459+
}
460+
461+
def unmangle(kinds: List[NameKind]): TermName = {
462+
val unmangled = (name /: kinds)(_.unmangle(_))
463+
if (unmangled eq name) name else unmangled.unmangle(kinds)
464+
}
493465
}
494466

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

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,6 @@ object StdNames {
123123
val OVERLOADED: N = "<overloaded>"
124124
val PACKAGE: N = "package"
125125
val PACKAGE_CLS: N = "package$"
126-
val PROTECTED_PREFIX: N = "protected$"
127-
val PROTECTED_SET_PREFIX: N = PROTECTED_PREFIX + "set"
128126
val ROOT: N = "<root>"
129127
val SINGLETON_SUFFIX: N = ".type"
130128
val SPECIALIZED_SUFFIX: N = "$sp"

compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ package classfile
55

66
import Contexts._, Symbols._, Types._, Names._, StdNames._, NameOps._, Scopes._, Decorators._
77
import SymDenotations._, unpickleScala2.Scala2Unpickler._, Constants._, Annotations._, util.Positions._
8-
import NameKinds.ModuleClassName
8+
import NameKinds.{ModuleClassName, DefaultGetterName}
99
import ast.tpd._
1010
import java.io.{ File, IOException }
1111
import java.lang.Integer.toHexString
@@ -598,7 +598,7 @@ class ClassfileParser(
598598
def addDefaultGetter(attr: Symbol, n: Int) =
599599
ctx.newSymbol(
600600
owner = moduleRoot.symbol,
601-
name = nme.CONSTRUCTOR.defaultGetterName(n),
601+
name = DefaultGetterName(nme.CONSTRUCTOR, n),
602602
flags = attr.flags & Flags.AccessFlags,
603603
info = defn.NothingType).entered
604604

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,8 +228,10 @@ object TastyFormat {
228228
final val DEFAULTGETTER = 11
229229
final val VARIANT = 12
230230
final val SUPERACCESSOR = 20
231-
final val INITIALIZER = 21
232-
final val SHADOWED = 22
231+
final val PROTECTEDACCESSOR = 21
232+
final val PROTECTEDSETTER = 22
233+
final val INITIALIZER = 23
234+
final val SHADOWED = 24
233235
final val AVOIDCLASH = 27
234236
final val OBJECTCLASS = 29
235237

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import java.lang.Double.longBitsToDouble
99

1010
import Contexts._, Symbols._, Types._, Scopes._, SymDenotations._, Names._, NameOps._
1111
import StdNames._, Denotations._, NameOps._, Flags._, Constants._, Annotations._
12+
import NameKinds.Scala2MethodNameKinds
1213
import dotty.tools.dotc.typer.ProtoTypes.{FunProtoTyped, FunProto}
1314
import util.Positions._
1415
import dotty.tools.dotc.ast.{tpd, Trees, untpd}, ast.tpd._
@@ -434,7 +435,7 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
434435
if (flags is Method) {
435436
name =
436437
if (name == nme.TRAIT_CONSTRUCTOR) nme.CONSTRUCTOR
437-
else name.asTermName.unmangleMethodName
438+
else name.asTermName.unmangle(Scala2MethodNameKinds)
438439
}
439440
if (flags is Scala2ExpandedName) {
440441
name = name.unmangleExpandedName

compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import ast.{Trees, tpd}
55
import core._, core.Decorators._
66
import Annotations._, Contexts._, Flags._, Phases._, Trees._, Types._, Symbols._
77
import Names._, NameOps._, StdNames._
8+
import NameKinds.DefaultGetterName
89
import typer.Inliner
910
import typer.ErrorReporting.cyclicErrorMsg
1011
import transform.SymUtils._
@@ -300,7 +301,8 @@ private class ExtractAPICollector(implicit val ctx: Context) extends ThunkHolder
300301
sym.owner.companionModule // default getters for class constructors are found in the companion object
301302
else
302303
sym.owner
303-
(0 until pnames.length).map(i => qual.info.member(sym.name.defaultGetterName(start + i)).exists)
304+
(0 until pnames.length).map(i =>
305+
qual.info.member(DefaultGetterName(sym.name, start + i)).exists)
304306
} else
305307
(0 until pnames.length).map(Function.const(false))
306308
val params = (pnames, ptypes, defaults).zipped.map((pname, ptype, isDefault) =>

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import Types._, Contexts._, Constants._, Names._, NameOps._, Flags._, DenotTrans
1111
import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._, Scopes._, Denotations._
1212
import util.Positions._
1313
import Decorators._
14+
import NameKinds.{ProtectedAccessorName, ProtectedSetterName}
1415
import Symbols._, TypeUtils._
1516

1617
/** This class performs the following functions:
@@ -168,7 +169,7 @@ class SuperAccessors(thisTransformer: DenotTransformer) {
168169
assert(clazz.exists, sym)
169170
ctx.debuglog("Decided for host class: " + clazz)
170171

171-
val accName = sym.name.protectedAccessorName
172+
val accName = ProtectedAccessorName(sym.name)
172173

173174
// if the result type depends on the this type of an enclosing class, the accessor
174175
// has to take an object of exactly this type, otherwise it's more general
@@ -206,7 +207,8 @@ class SuperAccessors(thisTransformer: DenotTransformer) {
206207
}
207208

208209
def isProtectedAccessor(tree: Tree)(implicit ctx: Context): Boolean = tree match {
209-
case Apply(TypeApply(Select(_, name), _), qual :: Nil) => name.isProtectedAccessorName
210+
case Apply(TypeApply(Select(_, name), _), qual :: Nil) =>
211+
name.is(ProtectedAccessorName) || name.is(ProtectedSetterName)
210212
case _ => false
211213
}
212214

@@ -221,7 +223,7 @@ class SuperAccessors(thisTransformer: DenotTransformer) {
221223
assert(clazz.exists, sym)
222224
ctx.debuglog("Decided for host class: " + clazz)
223225

224-
val accName = sym.name.protectedAccessorName
226+
val accName = ProtectedAccessorName(sym.name)
225227

226228
// if the result type depends on the this type of an enclosing class, the accessor
227229
// has to take an object of exactly this type, otherwise it's more general
@@ -265,7 +267,7 @@ class SuperAccessors(thisTransformer: DenotTransformer) {
265267
assert(clazz.exists, field)
266268
ctx.debuglog("Decided for host class: " + clazz)
267269

268-
val accName = field.name.protectedSetterName
270+
val accName = ProtectedSetterName(field.name)
269271
val accType = MethodType(clazz.classInfo.selfType :: field.info :: Nil, defn.UnitType)
270272
val protectedAccessor = clazz.info.decl(accName).symbol orElse {
271273
val newAcc = ctx.newSymbol(

compiler/src/dotty/tools/dotc/typer/Applications.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import Trees._
2020
import config.Config
2121
import Names._
2222
import StdNames._
23+
import NameKinds.DefaultGetterName
2324
import ProtoTypes._
2425
import EtaExpansion._
2526
import Inferencing._
@@ -338,7 +339,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
338339
}
339340
val getterPrefix =
340341
if ((meth is Synthetic) && meth.name == nme.apply) nme.CONSTRUCTOR else meth.name
341-
def getterName = getterPrefix.defaultGetterName(n)
342+
def getterName = DefaultGetterName(getterPrefix, n)
342343
if (!meth.hasDefaultParams)
343344
EmptyTree
344345
else if (receiver.isEmpty) {

0 commit comments

Comments
 (0)