From ca5652cc5a74f00277ce942a001fa6e931ee3728 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 28 Mar 2017 22:25:09 +0200 Subject: Make freshName semantic --- .../src/dotty/tools/dotc/core/NameExtractors.scala | 138 ++++++++++++++------- 1 file changed, 96 insertions(+), 42 deletions(-) (limited to 'compiler/src/dotty/tools/dotc/core/NameExtractors.scala') diff --git a/compiler/src/dotty/tools/dotc/core/NameExtractors.scala b/compiler/src/dotty/tools/dotc/core/NameExtractors.scala index 2c5f5c164..1439ce002 100644 --- a/compiler/src/dotty/tools/dotc/core/NameExtractors.scala +++ b/compiler/src/dotty/tools/dotc/core/NameExtractors.scala @@ -8,33 +8,38 @@ import StdNames._ import util.DotClass import tasty.TastyFormat._ import Decorators._ +import Contexts.Context import collection.mutable object NameExtractors { - @sharable private val extractors = new mutable.HashMap[Int, ClassifiedNameExtractor] + @sharable private val simpleExtractors = new mutable.HashMap[Int, ClassifiedNameExtractor] + @sharable private val uniqueExtractors = new mutable.HashMap[String, UniqueNameExtractor] + @sharable private val qualifiedExtractors = new mutable.HashMap[String, QualifiedNameExtractor] abstract class NameInfo extends DotClass { - def tag: Int - def definesNewName: Boolean = false + def extractor: NameExtractor def mkString(underlying: TermName): String def map(f: SimpleTermName => SimpleTermName): NameInfo = this } - val simpleTermNameInfo = new NameInfo { - def tag = UTF8 - def mkString(underlying: TermName): String = unsupported("mkString") - } - abstract class NameExtractor(val tag: Int) extends DotClass { self => - def mkString(underlying: TermName, info: ThisInfo): String - def infoString: String type ThisInfo <: Info class Info extends NameInfo { this: ThisInfo => - def tag = self.tag + def extractor = self def mkString(underlying: TermName) = self.mkString(underlying, this) override def toString = infoString } + def definesNewName = false + def mkString(underlying: TermName, info: ThisInfo): String + def infoString: String + } + + object SimpleTermNameExtractor extends NameExtractor(UTF8) { self => + type ThisInfo = Info + val info = new Info + def mkString(underlying: TermName, info: ThisInfo) = unsupported("mkString") + def infoString = unsupported("infoString") } abstract class ClassifiedNameExtractor(tag: Int, val infoString: String) extends NameExtractor(tag) { @@ -46,15 +51,17 @@ object NameExtractors { case DerivedTermName(underlying, `info`) => Some(underlying) case _ => None } - extractors(tag) = this + simpleExtractors(tag) = this } - class PrefixNameExtractor(tag: Int, prefix: String, infoString: String) extends ClassifiedNameExtractor(tag, infoString) { + class PrefixNameExtractor(tag: Int, prefix: String, optInfoString: String = "") + extends ClassifiedNameExtractor(tag, if (optInfoString.isEmpty) s"Prefix $prefix" else optInfoString) { def mkString(underlying: TermName, info: ThisInfo) = underlying.mapLast(n => termName(prefix + n.toString)).toString } - class SuffixNameExtractor(tag: Int, suffix: String, infoString: String) extends ClassifiedNameExtractor(tag, infoString) { + class SuffixNameExtractor(tag: Int, suffix: String, optInfoString: String = "") + extends ClassifiedNameExtractor(tag, if (optInfoString.isEmpty) s"Suffix $suffix" else optInfoString) { def mkString(underlying: TermName, info: ThisInfo) = underlying.toString ++ suffix } @@ -62,10 +69,10 @@ object NameExtractors { val name: SimpleTermName } - abstract class QualifiedNameExtractor(tag: Int, val separator: String, val infoString: String) extends NameExtractor(tag) { + class QualifiedNameExtractor(tag: Int, val separator: String) + extends NameExtractor(tag) { type ThisInfo = QualInfo case class QualInfo(val name: SimpleTermName) extends Info with QualifiedInfo { - override def definesNewName = true override def map(f: SimpleTermName => SimpleTermName): NameInfo = new QualInfo(f(name)) override def toString = s"$infoString $name" } @@ -75,26 +82,32 @@ object NameExtractors { case DerivedTermName(qual, info: this.QualInfo) => Some((qual, info.name)) case _ => None } + + override def definesNewName = true + def mkString(underlying: TermName, info: ThisInfo) = s"$underlying$separator${info.name}" + def infoString = s"Qualified $separator" + + qualifiedExtractors(separator) = this } object AnyQualifiedName { - def unapply(name: DerivedTermName): Option[(TermName, QualifiedInfo)] = name match { + def unapply(name: DerivedTermName): Option[(TermName, SimpleTermName)] = name match { case DerivedTermName(qual, info: QualifiedInfo) => - Some((name.underlying, info)) + Some((name.underlying, info.name)) case _ => None } } trait NumberedInfo { def num: Int + def extractor: NameExtractor } abstract class NumberedNameExtractor(tag: Int, val infoString: String) extends NameExtractor(tag) { self => type ThisInfo = NumberedInfo case class NumberedInfo(val num: Int) extends Info with NameExtractors.NumberedInfo { - override def definesNewName = self.definesNewName override def toString = s"$infoString $num" } def apply(qual: TermName, num: Int) = @@ -103,20 +116,66 @@ object NameExtractors { case DerivedTermName(underlying, info: this.NumberedInfo) => Some((underlying, info.num)) case _ => None } - def definesNewName = false } - class UniqueNameExtractor(sep: String) extends NumberedNameExtractor(UNIQUE, "Unique") { - val separator = if (sep.isEmpty) "$" else sep - override def definesNewName = !sep.isEmpty - def mkString(underlying: TermName, info: ThisInfo) = - underlying.toString + separator + info.num + case class UniqueNameExtractor(val separator: String) + extends NumberedNameExtractor(UNIQUE, s"Unique $separator") { + override def definesNewName = true + def mkString(underlying: TermName, info: ThisInfo) = { + val safePrefix = str.sanitize(underlying.toString + separator) + safePrefix + info.num + } + + def fresh(prefix: TermName = EmptyTermName)(implicit ctx: Context): TermName = + ctx.freshNames.newName(prefix, this) + + uniqueExtractors(separator) = this + } + + object AnyUniqueName { + def unapply(name: DerivedTermName): Option[(TermName, String, Int)] = name match { + case DerivedTermName(qual, info: NumberedInfo) => + info.extractor match { + case unique: UniqueNameExtractor => Some((qual, unique.separator, info.num)) + case _ => None + } + case _ => None + } } - object QualifiedName extends QualifiedNameExtractor(QUALIFIED, ".", "Qualified") - object FlattenedName extends QualifiedNameExtractor(FLATTENED, "$", "Flattened") - object ExpandedName extends QualifiedNameExtractor(EXPANDED, str.EXPAND_SEPARATOR, "Expanded") - object TraitSetterName extends QualifiedNameExtractor(TRAITSETTER, str.TRAIT_SETTER_SEPARATOR, "TraitSetter") + val QualifiedName = new QualifiedNameExtractor(QUALIFIED, ".") + val FlattenedName = new QualifiedNameExtractor(FLATTENED, "$") + val ExpandedName = new QualifiedNameExtractor(EXPANDED, str.EXPAND_SEPARATOR) + val TraitSetterName = new QualifiedNameExtractor(TRAITSETTER, str.TRAIT_SETTER_SEPARATOR) + + val UniqueName = new UniqueNameExtractor("$") { + override def mkString(underlying: TermName, info: ThisInfo) = + if (underlying.isEmpty) "$" + info.num + "$" else super.mkString(underlying, info) + } + + val InlineAccessorName = new UniqueNameExtractor("$_inlineAccessor_$") + val TempResultName = new UniqueNameExtractor("ev$") + val EvidenceParamName = new UniqueNameExtractor("evidence$") + val DepParamName = new UniqueNameExtractor("") + val LazyImplicitName = new UniqueNameExtractor("$_lazy_implicit_$") + val LazyLocalName = new UniqueNameExtractor("$lzy") + val LazyLocalInitName = new UniqueNameExtractor("$lzyINIT") + val LazyFieldOffsetName = new UniqueNameExtractor("$OFFSET") + val LazyBitMapName = new UniqueNameExtractor(nme.BITMAP_PREFIX.toString) + val NonLocalReturnKeyName = new UniqueNameExtractor("nonLocalReturnKey") + val WildcardParamName = new UniqueNameExtractor("_$") + val TailLabelName = new UniqueNameExtractor("tailLabel") + val ExceptionBinderName = new UniqueNameExtractor("ex") + val SkolemName = new UniqueNameExtractor("?") + val LiftedTreeName = new UniqueNameExtractor("liftedTree") + + val PatMatStdBinderName = new UniqueNameExtractor("x") + val PatMatPiName = new UniqueNameExtractor("pi") // FIXME: explain what this is + val PatMatPName = new UniqueNameExtractor("p") // FIXME: explain what this is + val PatMatOName = new UniqueNameExtractor("o") // FIXME: explain what this is + val PatMatCaseName = new UniqueNameExtractor("case") + val PatMatMatchFailName = new UniqueNameExtractor("matchFail") + val PatMatSelectorName = new UniqueNameExtractor("selector") object DefaultGetterName extends NumberedNameExtractor(DEFAULTGETTER, "DefaultGetter") { def mkString(underlying: TermName, info: ThisInfo) = { @@ -133,12 +192,11 @@ object NameExtractors { } } - val SuperAccessorName = new PrefixNameExtractor(SUPERACCESSOR, str.SUPER_PREFIX, "SuperAccessor") - val InitializerName = new PrefixNameExtractor(INITIALIZER, str.INITIALIZER_PREFIX, "Initializer") - val ShadowedName = new PrefixNameExtractor(SHADOWED, str.SHADOWED_PREFIX, "Shadowed") - val LocalDummyName = new PrefixNameExtractor(LOCALDUMMY, str.LOCAL_DUMMY_PREFIX, "LocalDummy") - val AvoidClashName = new SuffixNameExtractor(AVOIDCLASH, str.AVOID_CLASH_SUFFIX, "AvoidClash") - val ModuleClassName = new SuffixNameExtractor(OBJECTCLASS, "$", "ModuleClass") + val SuperAccessorName = new PrefixNameExtractor(SUPERACCESSOR, "super$") + val InitializerName = new PrefixNameExtractor(INITIALIZER, "initial$") + val ShadowedName = new PrefixNameExtractor(SHADOWED, "(shadowed)") + val AvoidClashName = new SuffixNameExtractor(AVOIDCLASH, "$_avoid_name_clash_$") + val ModuleClassName = new SuffixNameExtractor(OBJECTCLASS, "$", optInfoString = "ModuleClass") object SignedName extends NameExtractor(63) { @@ -159,11 +217,7 @@ object NameExtractors { def infoString: String = "Signed" } - def extractorOfTag(tag: Int) = extractors(tag) - - val separatorToQualified: Map[String, QualifiedNameExtractor] = - Map("." -> QualifiedName, - "$" -> FlattenedName, - str.EXPAND_SEPARATOR -> ExpandedName, - str.TRAIT_SETTER_SEPARATOR -> TraitSetterName) + def simpleExtractorOfTag : collection.Map[Int, ClassifiedNameExtractor] = simpleExtractors + def qualifiedExtractorOfSeparator: collection.Map[String, QualifiedNameExtractor] = qualifiedExtractors + def uniqueExtractorOfSeparator : collection.Map[String, UniqueNameExtractor] = uniqueExtractors } \ No newline at end of file -- cgit v1.2.3