aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2017-03-28 22:25:09 +0200
committerMartin Odersky <odersky@gmail.com>2017-04-11 09:33:11 +0200
commitca5652cc5a74f00277ce942a001fa6e931ee3728 (patch)
tree9ef6e2b341bc10678bbe1f06d4c15fb28093da07
parent1e49ddad97c4e8207913857511ae62467f8cd3ce (diff)
downloaddotty-ca5652cc5a74f00277ce942a001fa6e931ee3728.tar.gz
dotty-ca5652cc5a74f00277ce942a001fa6e931ee3728.tar.bz2
dotty-ca5652cc5a74f00277ce942a001fa6e931ee3728.zip
Make freshName semantic
-rw-r--r--compiler/src/dotty/tools/dotc/ast/Desugar.scala10
-rw-r--r--compiler/src/dotty/tools/dotc/ast/tpd.scala3
-rw-r--r--compiler/src/dotty/tools/dotc/core/Contexts.scala3
-rw-r--r--compiler/src/dotty/tools/dotc/core/Denotations.scala4
-rw-r--r--compiler/src/dotty/tools/dotc/core/NameExtractors.scala138
-rw-r--r--compiler/src/dotty/tools/dotc/core/NameOps.scala27
-rw-r--r--compiler/src/dotty/tools/dotc/core/Names.scala23
-rw-r--r--compiler/src/dotty/tools/dotc/core/StdNames.scala15
-rw-r--r--compiler/src/dotty/tools/dotc/core/SymDenotations.scala6
-rw-r--r--compiler/src/dotty/tools/dotc/core/Symbols.scala3
-rw-r--r--compiler/src/dotty/tools/dotc/core/Types.scala8
-rw-r--r--compiler/src/dotty/tools/dotc/core/tasty/NameBuffer.scala34
-rw-r--r--compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala3
-rw-r--r--compiler/src/dotty/tools/dotc/core/tasty/TastyUnpickler.scala10
-rw-r--r--compiler/src/dotty/tools/dotc/parsing/Parsers.scala7
-rw-r--r--compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/transform/CapturedVars.scala3
-rw-r--r--compiler/src/dotty/tools/dotc/transform/LazyVals.scala14
-rw-r--r--compiler/src/dotty/tools/dotc/transform/LiftTry.scala3
-rw-r--r--compiler/src/dotty/tools/dotc/transform/MoveStatics.scala1
-rw-r--r--compiler/src/dotty/tools/dotc/transform/NonLocalReturns.scala3
-rw-r--r--compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala24
-rw-r--r--compiler/src/dotty/tools/dotc/transform/TailRec.scala37
-rw-r--r--compiler/src/dotty/tools/dotc/transform/TryCatchPatterns.scala3
-rw-r--r--compiler/src/dotty/tools/dotc/typer/EtaExpansion.scala9
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Inliner.scala4
-rw-r--r--compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala3
-rw-r--r--compiler/src/dotty/tools/dotc/util/FreshNameCreator.scala17
28 files changed, 244 insertions, 173 deletions
diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala
index e2679ef56..3671ccb73 100644
--- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala
+++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala
@@ -6,6 +6,7 @@ import core._
import util.Positions._, Types._, Contexts._, Constants._, Names._, NameOps._, Flags._
import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._
import Decorators._
+import NameExtractors.{UniqueName, EvidenceParamName}
import language.higherKinds
import typer.FrontEnd
import collection.mutable.ListBuffer
@@ -128,7 +129,7 @@ object desugar {
def makeImplicitParameters(tpts: List[Tree], forPrimaryConstructor: Boolean)(implicit ctx: Context) =
for (tpt <- tpts) yield {
val paramFlags: FlagSet = if (forPrimaryConstructor) PrivateLocalParamAccessor else Param
- val epname = ctx.freshName(nme.EVIDENCE_PARAM_PREFIX).toTermName
+ val epname = EvidenceParamName.fresh()
ValDef(epname, tpt, EmptyTree).withFlags(paramFlags | Implicit)
}
@@ -230,7 +231,7 @@ object desugar {
private def evidenceParams(meth: DefDef)(implicit ctx: Context): List[ValDef] =
meth.vparamss.reverse match {
case (vparams @ (vparam :: _)) :: _ if vparam.mods is Implicit =>
- vparams.dropWhile(!_.name.startsWith(nme.EVIDENCE_PARAM_PREFIX))
+ vparams.dropWhile(!_.name.is(EvidenceParamName))
case _ =>
Nil
}
@@ -635,7 +636,6 @@ object desugar {
case (named, tpt) :: Nil =>
derivedValDef(original, named, tpt, matchExpr, mods)
case _ =>
- val tmpName = ctx.freshName().toTermName
val patMods =
mods & Lazy | Synthetic | (if (ctx.owner.isClass) PrivateLocal else EmptyFlags)
val firstDef =
@@ -810,7 +810,7 @@ object desugar {
val selectPos = Position(left.pos.start, op.pos.end, op.pos.start)
Apply(Select(left, op.name).withPos(selectPos), args)
} else {
- val x = ctx.freshName().toTermName
+ val x = UniqueName.fresh()
val selectPos = Position(op.pos.start, right.pos.end, op.pos.start)
new InfixOpBlock(
ValDef(x, TypeTree(), left).withMods(synthetic),
@@ -888,7 +888,7 @@ object desugar {
case id: Ident if isVarPattern(id) && id.name != nme.WILDCARD => (id, id)
case Typed(id: Ident, _) if isVarPattern(id) && id.name != nme.WILDCARD => (pat, id)
case _ =>
- val name = ctx.freshName().toTermName
+ val name = UniqueName.fresh()
(Bind(name, pat), Ident(name))
}
diff --git a/compiler/src/dotty/tools/dotc/ast/tpd.scala b/compiler/src/dotty/tools/dotc/ast/tpd.scala
index ff66c8c8e..e4c6dd679 100644
--- a/compiler/src/dotty/tools/dotc/ast/tpd.scala
+++ b/compiler/src/dotty/tools/dotc/ast/tpd.scala
@@ -12,6 +12,7 @@ import Denotations._, Decorators._, DenotTransformers._
import collection.mutable
import util.{Property, SourceFile, NoSource}
import typer.ErrorReporting._
+import NameExtractors.TempResultName
import scala.annotation.tailrec
import scala.io.Codec
@@ -897,7 +898,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
def evalOnce(tree: Tree)(within: Tree => Tree)(implicit ctx: Context) = {
if (isIdempotentExpr(tree)) within(tree)
else {
- val vdef = SyntheticValDef(ctx.freshName("ev$").toTermName, tree)
+ val vdef = SyntheticValDef(TempResultName.fresh(), tree)
Block(vdef :: Nil, within(Ident(vdef.namedType)))
}
}
diff --git a/compiler/src/dotty/tools/dotc/core/Contexts.scala b/compiler/src/dotty/tools/dotc/core/Contexts.scala
index 8707b66f9..c80ad876a 100644
--- a/compiler/src/dotty/tools/dotc/core/Contexts.scala
+++ b/compiler/src/dotty/tools/dotc/core/Contexts.scala
@@ -174,9 +174,6 @@ object Contexts {
protected def freshNames_=(freshNames: FreshNameCreator) = _freshNames = freshNames
def freshNames: FreshNameCreator = _freshNames
- def freshName(prefix: String = ""): String = freshNames.newName(prefix)
- def freshName(prefix: Name): String = freshName(prefix.toString)
-
/** A map in which more contextual properties can be stored */
private var _moreProperties: Map[Key[Any], Any] = _
protected def moreProperties_=(moreProperties: Map[Key[Any], Any]) = _moreProperties = moreProperties
diff --git a/compiler/src/dotty/tools/dotc/core/Denotations.scala b/compiler/src/dotty/tools/dotc/core/Denotations.scala
index 60a506291..42837122a 100644
--- a/compiler/src/dotty/tools/dotc/core/Denotations.scala
+++ b/compiler/src/dotty/tools/dotc/core/Denotations.scala
@@ -1193,8 +1193,8 @@ object Denotations {
recur(underlying, n => wrap(ModuleClassName(n)))
case QualifiedName(prefix, selector) =>
select(recur(prefix), wrap(selector))
- case AnyQualifiedName(prefix, info) =>
- recur(prefix, n => wrap(info.mkString(n).toTermName))
+ case qn @ AnyQualifiedName(prefix, _) =>
+ recur(prefix, n => wrap(qn.info.mkString(n).toTermName))
case path: SimpleTermName =>
def recurSimple(len: Int, wrap: TermName => Name): Denotation = {
val point = path.lastIndexOf('.', len - 1)
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("<param>")
+ 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
diff --git a/compiler/src/dotty/tools/dotc/core/NameOps.scala b/compiler/src/dotty/tools/dotc/core/NameOps.scala
index 031cda1bd..6f2c75313 100644
--- a/compiler/src/dotty/tools/dotc/core/NameOps.scala
+++ b/compiler/src/dotty/tools/dotc/core/NameOps.scala
@@ -71,9 +71,7 @@ object NameOps {
def isModuleVarName(name: Name): Boolean =
name.stripAnonNumberSuffix endsWith MODULE_VAR_SUFFIX
def isSelectorName = name.startsWith(" ") && name.tail.forall(_.isDigit)
- def isLazyLocal = name.endsWith(nme.LAZY_LOCAL)
def isOuterSelect = name.endsWith(nme.OUTER_SELECT)
- def isInlineAccessor = name.startsWith(nme.INLINE_ACCESSOR_PREFIX)
/** Is name a variable name? */
def isVariableName: Boolean = name.length > 0 && {
@@ -112,16 +110,16 @@ object NameOps {
def moduleClassName: TypeName = name.derived(ModuleClassName).toTypeName
/** Convert this module class name to corresponding source module name */
- def sourceModuleName: TermName = stripModuleClassSuffix.toTermName
+ def sourceModuleName: TermName = name.toTermName.exclude(ModuleClassName)
/** If name ends in module class suffix, drop it */
def stripModuleClassSuffix: Name = name.exclude(ModuleClassName)
/** If flags is a ModuleClass but not a Package, add module class suffix */
- def adjustIfModuleClass(flags: Flags.FlagSet): N = {
+ def adjustIfModuleClass(flags: Flags.FlagSet): N = likeTyped {
if (flags is (ModuleClass, butNot = Package)) name.asTypeName.moduleClassName
- else likeTyped(name.toTermName.exclude(AvoidClashName))
- }.asInstanceOf[N]
+ else name.toTermName.exclude(AvoidClashName)
+ }
/** The superaccessor for method with given name */
def superName: TermName = SuperAccessorName(name.toTermName)
@@ -138,7 +136,7 @@ object NameOps {
def expandedName(prefix: Name, separator: Name = nme.EXPAND_SEPARATOR): N =
likeTyped {
def qualify(name: SimpleTermName) =
- separatorToQualified(separator.toString)(prefix.toTermName, name)
+ qualifiedExtractorOfSeparator(separator.toString)(prefix.toTermName, name)
name rewrite {
case name: SimpleTermName =>
qualify(name)
@@ -220,6 +218,13 @@ object NameOps {
}
*/
+ def freshened(implicit ctx: Context): N = likeTyped {
+ name.toTermName match {
+ case ModuleClassName(original) => ModuleClassName(original.freshened)
+ case name => UniqueName.fresh(name)
+ }
+ }
+
def unmangleClassName: N =
if (name.isSimple && name.isTypeName)
if (name.endsWith(MODULE_SUFFIX) && !tpnme.falseModuleClassNames.contains(name.asTypeName))
@@ -504,14 +509,6 @@ object NameOps {
case name => name
}
- def lazyLocalName = name ++ nme.LAZY_LOCAL
- def nonLazyName = {
- assert(name.isLazyLocal)
- name.dropRight(nme.LAZY_LOCAL.length)
- }
-
- def inlineAccessorName = nme.INLINE_ACCESSOR_PREFIX ++ name ++ "$"
-
def unmangleMethodName: TermName =
if (name.isSimple) {
val idx = name.defaultGetterIndexOfMangled
diff --git a/compiler/src/dotty/tools/dotc/core/Names.scala b/compiler/src/dotty/tools/dotc/core/Names.scala
index 81429a8d9..e4ebe61c2 100644
--- a/compiler/src/dotty/tools/dotc/core/Names.scala
+++ b/compiler/src/dotty/tools/dotc/core/Names.scala
@@ -130,7 +130,7 @@ object Names {
def likeKinded(name: Name): TermName = name.toTermName
- def info: NameInfo = simpleTermNameInfo
+ def info: NameInfo = SimpleTermNameExtractor.info
def underlying: TermName = unsupported("underlying")
@sharable private var derivedNames: AnyRef /* SimpleMap | j.u.HashMap */ =
@@ -174,9 +174,10 @@ object Names {
* name as underlying name.
*/
def derived(info: NameInfo): TermName = {
- val ownTag = this.info.tag
- if (ownTag < info.tag || info.definesNewName) add(info)
- else if (ownTag > info.tag) rewrap(underlying.derived(info))
+ val thisKind = this.info.extractor
+ val thatKind = info.extractor
+ if (thisKind.tag < thatKind.tag || thatKind.definesNewName) add(info)
+ else if (thisKind.tag > thatKind.tag) rewrap(underlying.derived(info))
else {
assert(info == this.info)
this
@@ -184,16 +185,16 @@ object Names {
}
def exclude(kind: NameExtractor): TermName = {
- val ownTag = this.info.tag
- if (ownTag < kind.tag || info.definesNewName) this
- else if (ownTag > kind.tag) rewrap(underlying.exclude(kind))
+ val thisKind = this.info.extractor
+ if (thisKind.tag < kind.tag || thisKind.definesNewName) this
+ else if (thisKind.tag > kind.tag) rewrap(underlying.exclude(kind))
else underlying
}
def is(kind: NameExtractor): Boolean = {
- val ownTag = this.info.tag
- ownTag == kind.tag ||
- !info.definesNewName && ownTag > kind.tag && underlying.is(kind)
+ val thisKind = this.info.extractor
+ thisKind == kind ||
+ !thisKind.definesNewName && thisKind.tag > kind.tag && underlying.is(kind)
}
override def hashCode = System.identityHashCode(this)
@@ -511,7 +512,7 @@ object Names {
implicit val NameOrdering: Ordering[Name] = new Ordering[Name] {
private def compareInfos(x: NameInfo, y: NameInfo): Int =
- if (x.tag != y.tag) x.tag - y.tag
+ if (x.extractor.tag != y.extractor.tag) x.extractor.tag - y.extractor.tag
else x match {
case x: QualifiedInfo =>
y match {
diff --git a/compiler/src/dotty/tools/dotc/core/StdNames.scala b/compiler/src/dotty/tools/dotc/core/StdNames.scala
index 09e808c7d..598d55650 100644
--- a/compiler/src/dotty/tools/dotc/core/StdNames.scala
+++ b/compiler/src/dotty/tools/dotc/core/StdNames.scala
@@ -22,7 +22,8 @@ object StdNames {
val INITIALIZER_PREFIX = "initial$"
val SHADOWED_PREFIX = "(shadowed)"
val AVOID_CLASH_SUFFIX = "$_avoid_name_clash_$"
- val LOCAL_DUMMY_PREFIX = "<local>_" // owner of local blocks
+
+ def sanitize(str: String) = str.replaceAll("""[<>]""", """\$""")
}
abstract class DefinedNames[N <: Name] {
@@ -96,7 +97,7 @@ object StdNames {
val ANON_CLASS: N = "$anon"
val ANON_FUN: N = "$anonfun"
- val BITMAP_PREFIX: N = "bitmap$"
+ val BITMAP_PREFIX: N = "bitmap$" // @darkdimius: $bitmap? Also, the next 4 names are unused.
val BITMAP_NORMAL: N = BITMAP_PREFIX // initialization bitmap for public/protected lazy vals
val BITMAP_TRANSIENT: N = BITMAP_PREFIX + "trans$" // initialization bitmap for transient lazy vals
val BITMAP_CHECKINIT: N = BITMAP_PREFIX + "init$" // initialization bitmap for checkinit values
@@ -106,13 +107,10 @@ object StdNames {
val DO_WHILE_PREFIX: N = "doWhile$"
val EMPTY: N = ""
val EMPTY_PACKAGE: N = Names.EMPTY_PACKAGE.toString
- val EVIDENCE_PARAM_PREFIX: N = "evidence$"
- val DEP_PARAM_PREFIX = "<param>"
val EXCEPTION_RESULT_PREFIX: N = "exceptionResult"
val EXPAND_SEPARATOR: N = str.EXPAND_SEPARATOR
val IMPL_CLASS_SUFFIX: N = "$class"
val IMPORT: N = "<import>"
- val INLINE_ACCESSOR_PREFIX = "$inlineAccessor$"
val INTERPRETER_IMPORT_WRAPPER: N = "$iw"
val INTERPRETER_LINE_PREFIX: N = "line"
val INTERPRETER_VAR_PREFIX: N = "res"
@@ -121,7 +119,6 @@ object StdNames {
val MODULE_SUFFIX: N = NameTransformer.MODULE_SUFFIX_STRING
val MODULE_VAR_SUFFIX: N = "$module"
val NAME_JOIN: N = NameTransformer.NAME_JOIN_STRING
- val USCORE_PARAM_PREFIX: N = "_$"
val OPS_PACKAGE: N = "<special-ops>"
val OVERLOADED: N = "<overloaded>"
val PACKAGE: N = "package"
@@ -139,9 +136,6 @@ object StdNames {
val COMPANION_CLASS_METHOD: N = "companion$class"
val TRAIT_SETTER_SEPARATOR: N = str.TRAIT_SETTER_SEPARATOR
val DIRECT_SUFFIX: N = "$direct"
- val LAZY_IMPLICIT_PREFIX: N = "$lazy_implicit$"
- val DOLLAR_VALUES: N = "$values"
- val DOLLAR_NEW: N = "$new"
// value types (and AnyRef) are all used as terms as well
// as (at least) arguments to the @specialize annotation.
@@ -249,8 +243,6 @@ object StdNames {
val EVT2U: N = "evt2u$"
val EQEQ_LOCAL_VAR: N = "eqEqTemp$"
val FAKE_LOCAL_THIS: N = "this$"
- val LAZY_LOCAL: N = "$lzy"
- val LAZY_LOCAL_INIT: N = "$lzyINIT"
val LAZY_FIELD_OFFSET: N = "OFFSET$"
val LAZY_SLOW_SUFFIX: N = "$lzycompute"
val LOCAL_SUFFIX: N = "$$local"
@@ -448,7 +440,6 @@ object StdNames {
val lang: N = "lang"
val length: N = "length"
val lengthCompare: N = "lengthCompare"
- val liftedTree: N = "liftedTree"
val `macro` : N = "macro"
val macroThis : N = "_this"
val macroContext : N = "c"
diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala
index eb16b2188..5e5a5df2d 100644
--- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -406,14 +406,14 @@ object SymDenotations {
}
var prefix = encl.fullNameSeparated(separator)
val fn =
- if (separatorToQualified.contains(sep)) {
+ if (qualifiedExtractorOfSeparator.contains(sep)) {
if (sep == "$")
// duplicate scalac's behavior: don't write a double '$$' for module class members.
prefix = prefix.exclude(ModuleClassName)
name rewrite {
case n: SimpleTermName =>
val n1 = if (filler.isEmpty) n else termName(filler ++ n)
- separatorToQualified(sep)(prefix.toTermName, n1)
+ qualifiedExtractorOfSeparator(sep)(prefix.toTermName, n1)
}
}
else {
@@ -1541,7 +1541,7 @@ object SymDenotations {
!(this is Frozen) ||
(scope ne this.unforcedDecls) ||
sym.hasAnnotation(defn.ScalaStaticAnnot) ||
- sym.name.isInlineAccessor ||
+ sym.name.is(InlineAccessorName) ||
isUsecase, i"trying to enter $sym in $this, frozen = ${this is Frozen}")
scope.enter(sym)
diff --git a/compiler/src/dotty/tools/dotc/core/Symbols.scala b/compiler/src/dotty/tools/dotc/core/Symbols.scala
index 95ff1cb75..69d6e8db3 100644
--- a/compiler/src/dotty/tools/dotc/core/Symbols.scala
+++ b/compiler/src/dotty/tools/dotc/core/Symbols.scala
@@ -19,6 +19,7 @@ import util.Positions._
import DenotTransformers._
import StdNames._
import NameOps._
+import NameExtractors.LazyImplicitName
import ast.tpd.Tree
import ast.TreeTypeMap
import Constants.Constant
@@ -260,7 +261,7 @@ trait Symbols { this: Context =>
/** Create a synthetic lazy implicit value */
def newLazyImplicit(info: Type) =
- newSymbol(owner, freshName(nme.LAZY_IMPLICIT_PREFIX).toTermName, Lazy, info)
+ newSymbol(owner, LazyImplicitName.fresh(), Lazy, info)
/** Create a symbol representing a selftype declaration for class `cls`. */
def newSelfSym(cls: ClassSymbol, name: TermName = nme.WILDCARD, selfInfo: Type = NoType): TermSymbol =
diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala
index b2502ee94..3f5a30922 100644
--- a/compiler/src/dotty/tools/dotc/core/Types.scala
+++ b/compiler/src/dotty/tools/dotc/core/Types.scala
@@ -7,7 +7,7 @@ import Symbols._
import Flags._
import Names._
import StdNames._, NameOps._
-import NameExtractors.ShadowedName
+import NameExtractors.{ShadowedName, SkolemName}
import Scopes._
import Constants._
import Contexts._
@@ -3001,9 +3001,9 @@ object Types {
override def hashCode: Int = identityHash
override def equals(that: Any) = this eq that.asInstanceOf[AnyRef]
- private var myRepr: String = null
- def repr(implicit ctx: Context) = {
- if (myRepr == null) myRepr = ctx.freshName("?")
+ private var myRepr: Name = null
+ def repr(implicit ctx: Context): Name = {
+ if (myRepr == null) myRepr = SkolemName.fresh()
myRepr
}
diff --git a/compiler/src/dotty/tools/dotc/core/tasty/NameBuffer.scala b/compiler/src/dotty/tools/dotc/core/tasty/NameBuffer.scala
index df43eabb2..2fd078bef 100644
--- a/compiler/src/dotty/tools/dotc/core/tasty/NameBuffer.scala
+++ b/compiler/src/dotty/tools/dotc/core/tasty/NameBuffer.scala
@@ -26,10 +26,13 @@ class NameBuffer extends TastyBuffer(10000) {
name1 match {
case SignedName(original, Signature(params, result)) =>
nameIndex(original); nameIndex(result); params.foreach(nameIndex)
- case AnyQualifiedName(prefix, info) =>
- nameIndex(prefix); nameIndex(info.name)
- case DerivedTermName(prefix, _) =>
- nameIndex(prefix)
+ case AnyQualifiedName(prefix, name) =>
+ nameIndex(prefix); nameIndex(name)
+ case AnyUniqueName(original, separator, num) =>
+ nameIndex(separator.toTermName)
+ if (original.nonEmpty) nameIndex(original)
+ case DerivedTermName(original, _) =>
+ nameIndex(original)
case _ =>
}
val ref = NameRef(nameRefs.size)
@@ -50,7 +53,8 @@ class NameBuffer extends TastyBuffer(10000) {
def writeNameRef(name: Name): Unit = writeNameRef(nameRefs(name.toTermName))
def pickleNameContents(name: Name): Unit = {
- writeByte(name.toTermName.info.tag)
+ val tag = name.toTermName.info.extractor.tag
+ writeByte(tag)
name.toTermName match {
case name: SimpleTermName =>
val bytes =
@@ -58,17 +62,23 @@ class NameBuffer extends TastyBuffer(10000) {
else Codec.toUTF8(chrs, name.start, name.length)
writeNat(bytes.length)
writeBytes(bytes, bytes.length)
- case AnyQualifiedName(prefix, info) =>
- withLength { writeNameRef(prefix); writeNameRef(info.name) }
- case SignedName(original, Signature(params, result)) =>
- withLength(
- { writeNameRef(original); writeNameRef(result); params.foreach(writeNameRef) },
- if ((params.length + 2) * maxIndexWidth <= maxNumInByte) 1 else 2)
+ case AnyQualifiedName(prefix, name) =>
+ withLength { writeNameRef(prefix); writeNameRef(name) }
+ case AnyUniqueName(original, separator, num) =>
+ withLength {
+ writeNameRef(separator.toTermName)
+ writeNat(num)
+ if (original.nonEmpty) writeNameRef(original)
+ }
case DefaultGetterName(method, paramNumber) =>
withLength { writeNameRef(method); writeNat(paramNumber) }
case VariantName(original, sign) =>
withLength { writeNameRef(original); writeNat(sign + 1) }
- case DerivedTermName(original, info) =>
+ case SignedName(original, Signature(params, result)) =>
+ withLength(
+ { writeNameRef(original); writeNameRef(result); params.foreach(writeNameRef) },
+ if ((params.length + 2) * maxIndexWidth <= maxNumInByte) 1 else 2)
+ case DerivedTermName(original, _) =>
withLength { writeNameRef(original) }
}
}
diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala b/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala
index d0fee04df..18d4a6344 100644
--- a/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala
+++ b/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala
@@ -33,11 +33,11 @@ Macro-format:
QUALIFIED Length qualified_NameRef selector_NameRef
SIGNED Length original_NameRef resultSig_NameRef paramSig_NameRef*
EXPANDED Length original_NameRef
+ UNIQUE Length separator_NameRef num_Nat original_NameRef?
OBJECTCLASS Length module_NameRef
SUPERACCESSOR Length accessed_NameRef
DEFAULTGETTER Length method_NameRef paramNumber_Nat
SHADOWED Length original_NameRef
- MANGLED Length mangle_NameRef name_NameRef
...
NameRef = Nat // ordinal number of name in name table, starting from 1.
@@ -231,7 +231,6 @@ object TastyFormat {
final val SUPERACCESSOR = 20
final val INITIALIZER = 21
final val SHADOWED = 22
- final val LOCALDUMMY = 23
final val AVOIDCLASH = 27
final val OBJECTCLASS = 29
diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TastyUnpickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TastyUnpickler.scala
index 7ebf3a2ea..756b7db5c 100644
--- a/compiler/src/dotty/tools/dotc/core/tasty/TastyUnpickler.scala
+++ b/compiler/src/dotty/tools/dotc/core/tasty/TastyUnpickler.scala
@@ -5,7 +5,7 @@ package tasty
import scala.collection.mutable
import TastyFormat._
import TastyBuffer.NameRef
-import Names.{Name, TermName, termName}
+import Names.{Name, TermName, termName, EmptyTermName}
import NameExtractors._
import java.util.UUID
@@ -55,6 +55,12 @@ class TastyUnpickler(reader: TastyReader) {
FlattenedName(readName(), readName().asSimpleName)
case EXPANDED =>
ExpandedName(readName(), readName().asSimpleName)
+ case UNIQUE =>
+ val separator = readName().toString
+ val num = readNat()
+ val originals = until(end)(readName())
+ val original = if (originals.isEmpty) EmptyTermName else originals.head
+ uniqueExtractorOfSeparator(separator)(original, num)
case DEFAULTGETTER =>
DefaultGetterName(readName(), readNat())
case VARIANT =>
@@ -67,7 +73,7 @@ class TastyUnpickler(reader: TastyReader) {
if (sig == Signature.NotAMethod) sig = Signature.NotAMethod
SignedName(original, sig)
case _ =>
- extractorOfTag(tag)(readName())
+ simpleExtractorOfTag(tag)(readName())
}
assert(currentAddr == end, s"bad name $result $start $currentAddr $end")
result
diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
index 3e3673e5e..d0451dd60 100644
--- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
+++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
@@ -12,6 +12,7 @@ import core._
import Flags._
import Contexts._
import Names._
+import NameExtractors.WildcardParamName
import ast.{Positioned, Trees, untpd}
import ast.Trees._
import Decorators._
@@ -1168,7 +1169,7 @@ object Parsers {
def bindingName(): TermName =
if (in.token == USCORE) {
in.nextToken()
- ctx.freshName(nme.USCORE_PARAM_PREFIX).toTermName
+ WildcardParamName.fresh()
}
else ident()
@@ -1224,7 +1225,7 @@ object Parsers {
path(thisOK = true)
case USCORE =>
val start = in.skipToken()
- val pname = ctx.freshName(nme.USCORE_PARAM_PREFIX).toTermName
+ val pname = WildcardParamName.fresh()
val param = ValDef(pname, TypeTree(), EmptyTree).withFlags(SyntheticTermParam)
.withPos(Position(start))
placeholderParams = param :: placeholderParams
@@ -1705,7 +1706,7 @@ object Parsers {
if (isConcreteOwner || in.token != USCORE) ident().toTypeName
else {
in.nextToken()
- ctx.freshName(nme.USCORE_PARAM_PREFIX).toTypeName
+ WildcardParamName.fresh().toTypeName
}
val hkparams = typeParamClauseOpt(ParamOwner.TypeParam)
val bounds =
diff --git a/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala b/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala
index 20e657ce7..ec9257acf 100644
--- a/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala
+++ b/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala
@@ -264,7 +264,7 @@ class PlainPrinter(_ctx: Context) extends Printer {
if (idx >= 0) selfRecName(idx + 1)
else "{...}.this" // TODO move underlying type to an addendum, e.g. ... z3 ... where z3: ...
case tp: SkolemType =>
- if (homogenizedView) toText(tp.info) else tp.repr
+ if (homogenizedView) toText(tp.info) else toText(tp.repr)
}
}
diff --git a/compiler/src/dotty/tools/dotc/transform/CapturedVars.scala b/compiler/src/dotty/tools/dotc/transform/CapturedVars.scala
index cd05589c3..368250cdf 100644
--- a/compiler/src/dotty/tools/dotc/transform/CapturedVars.scala
+++ b/compiler/src/dotty/tools/dotc/transform/CapturedVars.scala
@@ -12,6 +12,7 @@ import core.SymDenotations._
import core.StdNames.nme
import core.Names._
import core.NameOps._
+import core.NameExtractors.TempResultName
import ast.Trees._
import SymUtils._
import collection.{ mutable, immutable }
@@ -138,7 +139,7 @@ class CapturedVars extends MiniPhase with IdentityDenotTransformer { thisTransfo
val Select(_, nme.elem) = qual
recur(qual)
case Select(_, nme.elem) if refInfo.boxedRefClasses.contains(lhs.symbol.maybeOwner) =>
- val tempDef = transformFollowing(SyntheticValDef(ctx.freshName("ev$").toTermName, tree.rhs))
+ val tempDef = transformFollowing(SyntheticValDef(TempResultName.fresh(), tree.rhs))
transformFollowing(Block(tempDef :: Nil, cpy.Assign(tree)(lhs, ref(tempDef.symbol))))
case _ =>
tree
diff --git a/compiler/src/dotty/tools/dotc/transform/LazyVals.scala b/compiler/src/dotty/tools/dotc/transform/LazyVals.scala
index 2035fb04b..357baa3df 100644
--- a/compiler/src/dotty/tools/dotc/transform/LazyVals.scala
+++ b/compiler/src/dotty/tools/dotc/transform/LazyVals.scala
@@ -10,6 +10,7 @@ import Contexts._
import Symbols._
import Decorators._
import NameOps._
+import NameExtractors._
import StdNames.nme
import rewrite.Rewrites.patch
import util.Positions.Position
@@ -106,7 +107,7 @@ class LazyVals extends MiniPhaseTransform with IdentityDenotTransformer {
*/
def transformSyntheticModule(tree: ValOrDefDef)(implicit ctx: Context) = {
val sym = tree.symbol
- val holderSymbol = ctx.newSymbol(sym.owner, sym.asTerm.name.lazyLocalName,
+ val holderSymbol = ctx.newSymbol(sym.owner, LazyLocalName.fresh(sym.asTerm.name),
Flags.Synthetic, sym.info.widen.resultType).enteredAfter(this)
val field = ValDef(holderSymbol, tree.rhs.changeOwnerAfter(sym, holderSymbol, this))
val getter = DefDef(sym.asTerm, ref(holderSymbol))
@@ -119,8 +120,9 @@ class LazyVals extends MiniPhaseTransform with IdentityDenotTransformer {
*/
def transformLocalDef(x: ValOrDefDef)(implicit ctx: Context) = {
val valueInitter = x.rhs
- val holderName = ctx.freshName(x.name.asTermName.lazyLocalName).toTermName
- val initName = ctx.freshName(x.name ++ StdNames.nme.LAZY_LOCAL_INIT).toTermName
+ val xname = x.name.asTermName
+ val holderName = LazyLocalName.fresh(xname)
+ val initName = LazyLocalInitName.fresh(xname)
val tpe = x.tpe.widen.resultType.widen
val holderType =
@@ -211,7 +213,7 @@ class LazyVals extends MiniPhaseTransform with IdentityDenotTransformer {
val claz = x.symbol.owner.asClass
val tpe = x.tpe.widen.resultType.widen
assert(!(x.symbol is Flags.Mutable))
- val containerName = ctx.freshName(x.name.asTermName.lazyLocalName).toTermName
+ val containerName = LazyLocalName.fresh(x.name.asTermName)
val containerSymbol = ctx.newSymbol(claz, containerName,
x.symbol.flags &~ containerFlagsMask | containerFlags | Flags.Private,
tpe, coord = x.symbol.coord
@@ -223,7 +225,7 @@ class LazyVals extends MiniPhaseTransform with IdentityDenotTransformer {
Thicket(containerTree, slowPath)
}
else {
- val flagName = ctx.freshName(x.name ++ StdNames.nme.BITMAP_PREFIX).toTermName
+ val flagName = LazyBitMapName.fresh(x.name.asTermName)
val flagSymbol = ctx.newSymbol(x.symbol.owner, flagName, containerFlags | Flags.Private, defn.BooleanType).enteredAfter(this)
val flag = ValDef(flagSymbol, Literal(Constants.Constant(false)))
val slowPath = DefDef(x.symbol.asTerm, mkNonThreadSafeDef(ref(containerSymbol), ref(flagSymbol), x.rhs))
@@ -376,7 +378,7 @@ class LazyVals extends MiniPhaseTransform with IdentityDenotTransformer {
appendOffsetDefs += (claz -> new OffsetInfo(List(offsetTree), ord))
}
- val containerName = ctx.freshName(x.name.asTermName.lazyLocalName).toTermName
+ val containerName = LazyLocalName.fresh(x.name.asTermName)
val containerSymbol = ctx.newSymbol(claz, containerName, x.symbol.flags &~ containerFlagsMask | containerFlags, tpe, coord = x.symbol.coord).enteredAfter(this)
val containerTree = ValDef(containerSymbol, defaultValue(tpe))
diff --git a/compiler/src/dotty/tools/dotc/transform/LiftTry.scala b/compiler/src/dotty/tools/dotc/transform/LiftTry.scala
index d01195614..61554f5ce 100644
--- a/compiler/src/dotty/tools/dotc/transform/LiftTry.scala
+++ b/compiler/src/dotty/tools/dotc/transform/LiftTry.scala
@@ -8,6 +8,7 @@ import core.Contexts._
import core.Types._
import core.Flags._
import core.Decorators._
+import core.NameExtractors.LiftedTreeName
import NonLocalReturns._
/** Lifts try's that might be executed on non-empty expression stacks
@@ -56,7 +57,7 @@ class LiftTry extends MiniPhase with IdentityDenotTransformer { thisTransform =>
if (needLift) {
ctx.debuglog(i"lifting tree at ${tree.pos}, current owner = ${ctx.owner}")
val fn = ctx.newSymbol(
- ctx.owner, ctx.freshName("liftedTree").toTermName, Synthetic | Method,
+ ctx.owner, LiftedTreeName.fresh(), Synthetic | Method,
MethodType(Nil, tree.tpe.widenIfUnstable), coord = tree.pos)
tree.changeOwnerAfter(ctx.owner, fn, thisTransform)
Block(DefDef(fn, tree) :: Nil, ref(fn).appliedToNone)
diff --git a/compiler/src/dotty/tools/dotc/transform/MoveStatics.scala b/compiler/src/dotty/tools/dotc/transform/MoveStatics.scala
index b0ee0930d..652320639 100644
--- a/compiler/src/dotty/tools/dotc/transform/MoveStatics.scala
+++ b/compiler/src/dotty/tools/dotc/transform/MoveStatics.scala
@@ -55,6 +55,7 @@ class MoveStatics extends MiniPhaseTransform with SymTransformer { thisTransform
}
def move(module: TypeDef, companion: TypeDef): List[Tree] = {
+ assert(companion ne module)
if (!module.symbol.is(Flags.Module)) move(companion, module)
else {
val allMembers =
diff --git a/compiler/src/dotty/tools/dotc/transform/NonLocalReturns.scala b/compiler/src/dotty/tools/dotc/transform/NonLocalReturns.scala
index 7680e283e..945504743 100644
--- a/compiler/src/dotty/tools/dotc/transform/NonLocalReturns.scala
+++ b/compiler/src/dotty/tools/dotc/transform/NonLocalReturns.scala
@@ -5,6 +5,7 @@ import core._
import Contexts._, Symbols._, Types._, Flags._, Decorators._, StdNames._, Constants._, Phases._
import TreeTransforms._
import ast.Trees._
+import NameExtractors.NonLocalReturnKeyName
import collection.mutable
object NonLocalReturns {
@@ -38,7 +39,7 @@ class NonLocalReturns extends MiniPhaseTransform { thisTransformer =>
private def nonLocalReturnKey(meth: Symbol)(implicit ctx: Context) =
nonLocalReturnKeys.getOrElseUpdate(meth,
ctx.newSymbol(
- meth, ctx.freshName("nonLocalReturnKey").toTermName, Synthetic, defn.ObjectType, coord = meth.pos))
+ meth, NonLocalReturnKeyName.fresh(), Synthetic, defn.ObjectType, coord = meth.pos))
/** Generate a non-local return throw with given return expression from given method.
* I.e. for the method's non-local return key, generate:
diff --git a/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala b/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala
index dbc7666f7..f93eac0a2 100644
--- a/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala
+++ b/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala
@@ -11,6 +11,7 @@ import core.Symbols._
import core.Types._
import core.Constants._
import core.StdNames._
+import core.NameExtractors._
import dotty.tools.dotc.ast.{untpd, TreeTypeMap, tpd}
import dotty.tools.dotc.core
import dotty.tools.dotc.core.DenotTransformers.DenotTransformer
@@ -70,16 +71,14 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
class OptimizingMatchTranslator extends MatchOptimizer/*(val typer: analyzer.Typer)*/ with MatchTranslator
trait CodegenCore {
- private var ctr = 0 // left for debugging
// assert(owner ne null); assert(owner ne NoSymbol)
- def freshSym(pos: Position, tp: Type = NoType, prefix: String = "x", owner: Symbol = ctx.owner) = {
- ctr += 1
- ctx.newSymbol(owner, ctx.freshName(prefix + ctr).toTermName, Flags.Synthetic | Flags.Case, tp, coord = pos)
+ def freshSym(pos: Position, tp: Type = NoType, unique: UniqueNameExtractor = PatMatStdBinderName, owner: Symbol = ctx.owner) = {
+ ctx.newSymbol(owner, unique.fresh(), Flags.Synthetic | Flags.Case, tp, coord = pos)
}
- def newSynthCaseLabel(name: String, tpe: Type, owner: Symbol = ctx.owner) =
- ctx.newSymbol(owner, ctx.freshName(name).toTermName, Flags.Label | Flags.Synthetic | Flags.Method, tpe).asTerm
+ def newSynthCaseLabel(unique: UniqueNameExtractor, tpe: Type, owner: Symbol = ctx.owner) =
+ ctx.newSymbol(owner, unique.fresh(), Flags.Label | Flags.Synthetic | Flags.Method, tpe).asTerm
//NoSymbol.newLabel(freshName(name), NoPosition) setFlag treeInfo.SYNTH_CASE_FLAGS
// codegen relevant to the structure of the translation (how extractors are combined)
@@ -189,7 +188,8 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
//NoSymbol.newValueParameter(newTermName("x"), NoPosition, newFlags = SYNTHETIC) setInfo restpe.withoutAnnotations
- val caseSyms: List[TermSymbol] = cases.scanLeft(ctx.owner.asTerm)((curOwner, nextTree) => newSynthCaseLabel(ctx.freshName("case"), MethodType(Nil, restpe), curOwner)).tail
+ val caseSyms: List[TermSymbol] = cases.scanLeft(ctx.owner.asTerm)((curOwner, nextTree) =>
+ newSynthCaseLabel(PatMatCaseName, MethodType(Nil, restpe), curOwner)).tail
// must compute catchAll after caseLabels (side-effects nextCase)
// catchAll.isEmpty iff no synthetic default case needed (the (last) user-defined case is a default)
@@ -197,7 +197,7 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
val catchAllDef = matchFailGen.map { _(scrutSym) }
.getOrElse(Throw(New(defn.MatchErrorType, List(ref(scrutSym)))))
- val matchFail = newSynthCaseLabel(ctx.freshName("matchFail"), MethodType(Nil, restpe))
+ val matchFail = newSynthCaseLabel(PatMatMatchFailName, MethodType(Nil, restpe))
val catchAllDefBody = DefDef(matchFail, catchAllDef)
val nextCases = (caseSyms.tail ::: List(matchFail)).map(ref(_).ensureApplied)
@@ -249,7 +249,7 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
val isEmptyDenot = extractorMember(prev.tpe, nme.isEmpty)
assert(getDenot.exists && isEmptyDenot.exists, i"${prev.tpe}")
- val tmpSym = freshSym(prev.pos, prev.tpe, "o")
+ val tmpSym = freshSym(prev.pos, prev.tpe, PatMatOName)
val prevValue = ref(tmpSym).select(getDenot.symbol).ensureApplied
Block(
@@ -1056,9 +1056,9 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
}
def newBoundTree(tree: Tree, pt: Type): BoundTree = tree match {
- case SymbolBound(sym, Typed(subpat, tpe)) => BoundTree(freshSym(tree.pos, pt, prefix = "pi"), tree)
+ case SymbolBound(sym, Typed(subpat, tpe)) => BoundTree(freshSym(tree.pos, pt, PatMatPiName), tree)
case SymbolBound(sym, expr) => BoundTree(sym, expr)
- case _ => BoundTree(freshSym(tree.pos, pt, prefix = "p"), tree)
+ case _ => BoundTree(freshSym(tree.pos, pt, PatMatPName), tree)
}
final case class BoundTree(binder: Symbol, tree: Tree) {
@@ -1204,7 +1204,7 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
val selectorTp = sel.tpe.widen.deAnonymize/*withoutAnnotations*/
- val selectorSym = freshSym(sel.pos, selectorTp, "selector")
+ val selectorSym = freshSym(sel.pos, selectorTp, PatMatSelectorName)
val (nonSyntheticCases, defaultOverride) = cases match {
case init :+ last if isSyntheticDefaultCase(last) => (init, Some(((scrut: Symbol) => last.body)))
diff --git a/compiler/src/dotty/tools/dotc/transform/TailRec.scala b/compiler/src/dotty/tools/dotc/transform/TailRec.scala
index 8a695bf22..87e9c1013 100644
--- a/compiler/src/dotty/tools/dotc/transform/TailRec.scala
+++ b/compiler/src/dotty/tools/dotc/transform/TailRec.scala
@@ -1,16 +1,17 @@
-package dotty.tools.dotc.transform
-
-import dotty.tools.dotc.ast.Trees._
-import dotty.tools.dotc.ast.{TreeTypeMap, tpd}
-import dotty.tools.dotc.core.Contexts.Context
-import dotty.tools.dotc.core.Decorators._
-import dotty.tools.dotc.core.DenotTransformers.DenotTransformer
-import dotty.tools.dotc.core.Denotations.SingleDenotation
-import dotty.tools.dotc.core.Symbols._
-import dotty.tools.dotc.core.Types._
-import dotty.tools.dotc.core._
-import dotty.tools.dotc.transform.TailRec._
-import dotty.tools.dotc.transform.TreeTransforms.{MiniPhaseTransform, TransformerInfo}
+package dotty.tools.dotc
+package transform
+
+import ast.Trees._
+import ast.{TreeTypeMap, tpd}
+import core._
+import Contexts.Context
+import Decorators._
+import DenotTransformers.DenotTransformer
+import Denotations.SingleDenotation
+import Symbols._
+import Types._
+import NameExtractors.TailLabelName
+import TreeTransforms.{MiniPhaseTransform, TransformerInfo}
/**
* A Tail Rec Transformer
@@ -62,6 +63,7 @@ import dotty.tools.dotc.transform.TreeTransforms.{MiniPhaseTransform, Transforme
* </p>
*/
class TailRec extends MiniPhaseTransform with DenotTransformer with FullParameterization { thisTransform =>
+ import TailRec._
import dotty.tools.dotc.ast.tpd._
@@ -70,7 +72,6 @@ class TailRec extends MiniPhaseTransform with DenotTransformer with FullParamete
override def phaseName: String = "tailrec"
override def treeTransformPhase = thisTransform // TODO Make sure tailrec runs at next phase.
- final val labelPrefix = "tailLabel"
final val labelFlags = Flags.Synthetic | Flags.Label
/** Symbols of methods that have @tailrec annotatios inside */
@@ -87,12 +88,12 @@ class TailRec extends MiniPhaseTransform with DenotTransformer with FullParamete
tree
}
- private def mkLabel(method: Symbol, abstractOverClass: Boolean)(implicit c: Context): TermSymbol = {
- val name = c.freshName(labelPrefix)
+ private def mkLabel(method: Symbol, abstractOverClass: Boolean)(implicit ctx: Context): TermSymbol = {
+ val name = TailLabelName.fresh()
if (method.owner.isClass)
- c.newSymbol(method, name.toTermName, labelFlags, fullyParameterizedType(method.info, method.enclosingClass.asClass, abstractOverClass, liftThisType = false))
- else c.newSymbol(method, name.toTermName, labelFlags, method.info)
+ ctx.newSymbol(method, name.toTermName, labelFlags, fullyParameterizedType(method.info, method.enclosingClass.asClass, abstractOverClass, liftThisType = false))
+ else ctx.newSymbol(method, name.toTermName, labelFlags, method.info)
}
override def transformDefDef(tree: tpd.DefDef)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
diff --git a/compiler/src/dotty/tools/dotc/transform/TryCatchPatterns.scala b/compiler/src/dotty/tools/dotc/transform/TryCatchPatterns.scala
index 9a6ecef51..a651c0c74 100644
--- a/compiler/src/dotty/tools/dotc/transform/TryCatchPatterns.scala
+++ b/compiler/src/dotty/tools/dotc/transform/TryCatchPatterns.scala
@@ -5,6 +5,7 @@ import core.Symbols._
import core.StdNames._
import ast.Trees._
import core.Types._
+import core.NameExtractors.ExceptionBinderName
import dotty.tools.dotc.core.Decorators._
import dotty.tools.dotc.core.Flags
import dotty.tools.dotc.core.Contexts.Context
@@ -83,7 +84,7 @@ class TryCatchPatterns extends MiniPhaseTransform {
implicit ctx: Context, info: TransformerInfo): Option[CaseDef] = {
if (patternMatchCases.isEmpty) None
else {
- val exName = ctx.freshName("ex").toTermName
+ val exName = ExceptionBinderName.fresh()
val fallbackSelector =
ctx.newSymbol(ctx.owner, exName, Flags.Synthetic | Flags.Case, defn.ThrowableType, coord = pos)
val sel = Ident(fallbackSelector.termRef).withPos(pos)
diff --git a/compiler/src/dotty/tools/dotc/typer/EtaExpansion.scala b/compiler/src/dotty/tools/dotc/typer/EtaExpansion.scala
index 5aee0fd54..3f3a0cce3 100644
--- a/compiler/src/dotty/tools/dotc/typer/EtaExpansion.scala
+++ b/compiler/src/dotty/tools/dotc/typer/EtaExpansion.scala
@@ -12,6 +12,7 @@ import Symbols._
import Decorators._
import Names._
import StdNames._
+import NameExtractors.UniqueName
import Trees._
import Inferencing._
import util.Positions._
@@ -21,10 +22,10 @@ object EtaExpansion {
import tpd._
- private def lift(defs: mutable.ListBuffer[Tree], expr: Tree, prefix: String = "")(implicit ctx: Context): Tree =
+ private def lift(defs: mutable.ListBuffer[Tree], expr: Tree, prefix: TermName = EmptyTermName)(implicit ctx: Context): Tree =
if (isPureExpr(expr)) expr
else {
- val name = ctx.freshName(prefix).toTermName
+ val name = UniqueName.fresh(prefix)
val liftedType = fullyDefinedType(expr.tpe.widen, "lifted expression", expr.pos)
val sym = ctx.newSymbol(ctx.owner, name, EmptyFlags, liftedType, coord = positionCoord(expr.pos))
defs += ValDef(sym, expr)
@@ -48,7 +49,7 @@ object EtaExpansion {
}
/** Lift a function argument, stripping any NamedArg wrapper */
- def liftArg(defs: mutable.ListBuffer[Tree], arg: Tree, prefix: String = "")(implicit ctx: Context): Tree =
+ def liftArg(defs: mutable.ListBuffer[Tree], arg: Tree, prefix: TermName = EmptyTermName)(implicit ctx: Context): Tree =
arg match {
case arg @ NamedArg(name, arg1) => cpy.NamedArg(arg)(name, lift(defs, arg1, prefix))
case arg => lift(defs, arg, prefix)
@@ -62,7 +63,7 @@ object EtaExpansion {
case mt: MethodType =>
(args, mt.paramNames, mt.paramInfos).zipped map { (arg, name, tp) =>
if (tp.isInstanceOf[ExprType]) arg
- else liftArg(defs, arg, if (name contains '$') "" else name.toString + "$")
+ else liftArg(defs, arg, if (name contains '$') EmptyTermName else name)
}
case _ =>
args map (liftArg(defs, _))
diff --git a/compiler/src/dotty/tools/dotc/typer/Inliner.scala b/compiler/src/dotty/tools/dotc/typer/Inliner.scala
index f6d65fbb9..ad65af98c 100644
--- a/compiler/src/dotty/tools/dotc/typer/Inliner.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Inliner.scala
@@ -15,6 +15,7 @@ import StdNames.nme
import Contexts.Context
import Names.{Name, TermName}
import NameOps._
+import NameExtractors.InlineAccessorName
import SymDenotations.SymDenotation
import Annotations._
import transform.ExplicitOuter
@@ -49,8 +50,7 @@ object Inliner {
sym.is(AccessFlags) || sym.privateWithin.exists
/** The name of the next accessor to be generated */
- def accessorName(implicit ctx: Context) =
- ctx.freshNames.newName(inlineMethod.name.asTermName.inlineAccessorName.toString)
+ def accessorName(implicit ctx: Context) = InlineAccessorName.fresh(inlineMethod.name.asTermName)
/** A fresh accessor symbol.
*
diff --git a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala
index ab342dc17..03357fee3 100644
--- a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala
+++ b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala
@@ -5,6 +5,7 @@ package typer
import core._
import ast._
import Contexts._, Types._, Flags._, Denotations._, Names._, StdNames._, NameOps._, Symbols._
+import NameExtractors.DepParamName
import Trees._
import Constants._
import Scopes._
@@ -401,7 +402,7 @@ object ProtoTypes {
/** Create a new TypeParamRef that represents a dependent method parameter singleton */
def newDepTypeParamRef(tp: Type)(implicit ctx: Context): TypeParamRef = {
- val poly = PolyType(ctx.freshName(nme.DEP_PARAM_PREFIX).toTypeName :: Nil)(
+ val poly = PolyType(DepParamName.fresh().toTypeName :: Nil)(
pt => TypeBounds.upper(AndType(tp, defn.SingletonType)) :: Nil,
pt => defn.AnyType)
ctx.typeComparer.addToConstraint(poly, Nil)
diff --git a/compiler/src/dotty/tools/dotc/util/FreshNameCreator.scala b/compiler/src/dotty/tools/dotc/util/FreshNameCreator.scala
index 8892a570e..529e30f05 100644
--- a/compiler/src/dotty/tools/dotc/util/FreshNameCreator.scala
+++ b/compiler/src/dotty/tools/dotc/util/FreshNameCreator.scala
@@ -3,9 +3,12 @@ package dotc
package util
import scala.collection.mutable
+import core.Names.TermName
+import core.NameExtractors.UniqueNameExtractor
+import core.StdNames.str
-trait FreshNameCreator {
- def newName(prefix: String = ""): String
+abstract class FreshNameCreator {
+ def newName(prefix: TermName, unique: UniqueNameExtractor): TermName
}
object FreshNameCreator {
@@ -18,11 +21,11 @@ object FreshNameCreator {
* that the returned name has never been returned by a previous
* call to this function (provided the prefix does not end in a digit).
*/
- def newName(prefix: String): String = {
- val safePrefix = prefix.replaceAll("""[<>]""", """\$""")
- counters(safePrefix) += 1
- val counter = counters(safePrefix)
- if (prefix.isEmpty) "$" + counter + "$" else safePrefix + counter
+ def newName(prefix: TermName, unique: UniqueNameExtractor): TermName = {
+ val key = str.sanitize(prefix.toString + unique.separator)
+ counters(key) += 1
+ val counter = counters(key)
+ prefix.derived(unique.NumberedInfo(counter))
}
}
}