From 0021ffb0f1a0a857b7cdc8cdf769ae727dcb4b2c Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 27 Mar 2017 21:55:26 +0200 Subject: Add ShadowedName and AvoidClashName --- compiler/src/dotty/tools/dotc/core/NameExtractors.scala | 7 +++++-- compiler/src/dotty/tools/dotc/core/NameOps.scala | 15 +-------------- compiler/src/dotty/tools/dotc/core/Names.scala | 10 +++++----- compiler/src/dotty/tools/dotc/core/StdNames.scala | 4 ++-- compiler/src/dotty/tools/dotc/core/SymDenotations.scala | 2 +- compiler/src/dotty/tools/dotc/core/Types.scala | 7 ++++--- .../src/dotty/tools/dotc/core/tasty/TastyFormat.scala | 2 ++ .../src/dotty/tools/dotc/core/tasty/TreePickler.scala | 2 +- .../src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala | 2 +- compiler/src/dotty/tools/dotc/transform/Erasure.scala | 3 ++- .../src/dotty/tools/dotc/transform/FirstTransform.scala | 4 ++-- 11 files changed, 26 insertions(+), 32 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/NameExtractors.scala b/compiler/src/dotty/tools/dotc/core/NameExtractors.scala index f84ee565d..6045f0c10 100644 --- a/compiler/src/dotty/tools/dotc/core/NameExtractors.scala +++ b/compiler/src/dotty/tools/dotc/core/NameExtractors.scala @@ -1,4 +1,5 @@ -package dotty.tools.dotc +package dotty.tools +package dotc package core import Names._ @@ -11,7 +12,7 @@ import collection.mutable object NameExtractors { - private val extractors = new mutable.HashMap[Int, ClassifiedNameExtractor] + @sharable private val extractors = new mutable.HashMap[Int, ClassifiedNameExtractor] abstract class NameInfo extends DotClass { def tag: Int @@ -124,6 +125,8 @@ 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") object SignedName extends NameExtractor(63) { diff --git a/compiler/src/dotty/tools/dotc/core/NameOps.scala b/compiler/src/dotty/tools/dotc/core/NameOps.scala index f467fbcd5..031cda1bd 100644 --- a/compiler/src/dotty/tools/dotc/core/NameOps.scala +++ b/compiler/src/dotty/tools/dotc/core/NameOps.scala @@ -64,10 +64,8 @@ object NameOps { def isReplWrapperName = name.toSimpleName containsSlice INTERPRETER_IMPORT_WRAPPER def isSetterName = name endsWith SETTER_SUFFIX def isSingletonName = name endsWith SINGLETON_SUFFIX - def isAvoidClashName = name endsWith AVOID_CLASH_SUFFIX def isImportName = name startsWith IMPORT def isFieldName = name endsWith LOCAL_SUFFIX - def isShadowedName = name.startsWith(nme.SHADOWED) def isDefaultGetterName = name.isTermName && name.asTermName.defaultGetterIndex >= 0 def isScala2LocalSuffix = name.endsWith(" ") def isModuleVarName(name: Name): Boolean = @@ -119,17 +117,10 @@ object NameOps { /** If name ends in module class suffix, drop it */ def stripModuleClassSuffix: Name = name.exclude(ModuleClassName) - /** Append a suffix so that this name does not clash with another name in the same scope */ - def avoidClashName: TermName = (name ++ AVOID_CLASH_SUFFIX).toTermName - - /** If name ends in "avoid clash" suffix, drop it */ - def stripAvoidClashSuffix: Name = - if (isAvoidClashName) name dropRight AVOID_CLASH_SUFFIX.length else name - /** If flags is a ModuleClass but not a Package, add module class suffix */ def adjustIfModuleClass(flags: Flags.FlagSet): N = { if (flags is (ModuleClass, butNot = Package)) name.asTypeName.moduleClassName - else stripAvoidClashSuffix + else likeTyped(name.toTermName.exclude(AvoidClashName)) }.asInstanceOf[N] /** The superaccessor for method with given name */ @@ -192,10 +183,6 @@ object NameOps { } else name - def shadowedName: N = likeTyped(nme.SHADOWED ++ name) - - def revertShadowed: N = likeTyped(name.drop(nme.SHADOWED.length)) - def implClassName: N = likeTyped(name ++ tpnme.IMPL_CLASS_SUFFIX) def errorName: N = likeTyped(name ++ nme.ERROR) diff --git a/compiler/src/dotty/tools/dotc/core/Names.scala b/compiler/src/dotty/tools/dotc/core/Names.scala index 4524f2061..d1788b6f9 100644 --- a/compiler/src/dotty/tools/dotc/core/Names.scala +++ b/compiler/src/dotty/tools/dotc/core/Names.scala @@ -167,13 +167,16 @@ object Names { } } + private def rewrap(underlying: TermName) = + if (underlying eq this.underlying) this else underlying.add(info) + /** Return derived name with given `info` and the current * name as underlying name. */ def derived(info: NameInfo): TermName = { val ownTag = this.info.tag if (ownTag < info.tag || definesNewName(info.tag)) add(info) - else if (ownTag > info.tag) underlying.derived(info).add(this.info) + else if (ownTag > info.tag) rewrap(underlying.derived(info)) else { assert(info == this.info) this @@ -183,7 +186,7 @@ object Names { def exclude(kind: NameExtractor): TermName = { val ownTag = this.info.tag if (ownTag < kind.tag || definesNewName(ownTag)) this - else if (ownTag > kind.tag) underlying.exclude(kind).add(this.info) + else if (ownTag > kind.tag) rewrap(underlying.exclude(kind)) else underlying } @@ -202,9 +205,6 @@ object Names { def apply(n: Int) = chrs(start + n) - //override def derived(info: NameInfo): TermName = add(info) - //override def is(kind: NameExtractor) = false - private def contains(ch: Char): Boolean = { var i = 0 while (i < length && chrs(start + i) != ch) i += 1 diff --git a/compiler/src/dotty/tools/dotc/core/StdNames.scala b/compiler/src/dotty/tools/dotc/core/StdNames.scala index bf404d630..09e808c7d 100644 --- a/compiler/src/dotty/tools/dotc/core/StdNames.scala +++ b/compiler/src/dotty/tools/dotc/core/StdNames.scala @@ -21,6 +21,8 @@ object StdNames { val SUPER_PREFIX = "super$" val INITIALIZER_PREFIX = "initial$" val SHADOWED_PREFIX = "(shadowed)" + val AVOID_CLASH_SUFFIX = "$_avoid_name_clash_$" + val LOCAL_DUMMY_PREFIX = "_" // owner of local blocks } abstract class DefinedNames[N <: Name] { @@ -117,7 +119,6 @@ object StdNames { val INTERPRETER_WRAPPER_SUFFIX: N = "$object" val LOCALDUMMY_PREFIX: N = " @@ -1804,7 +1805,7 @@ object Types { fixDenot(TermRef.withSig(prefix, name, sig), prefix) override def shadowed(implicit ctx: Context): NamedType = - fixDenot(TermRef.withSig(prefix, name.shadowedName, sig), prefix) + fixDenot(TermRef.withSig(prefix, name.derived(ShadowedName), sig), prefix) override def equals(that: Any) = that match { case that: TermRefWithSignature => diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala b/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala index de70c04f3..792c11cee 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala @@ -230,6 +230,8 @@ 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 final val SIGNED = 63 diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala index e697ff028..355eef1ca 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala @@ -352,7 +352,7 @@ class TreePickler(pickler: TastyPickler) { case Select(qual, name) => writeByte(if (name.isTypeName) SELECTtpt else SELECT) val realName = tree.tpe match { - case tp: NamedType if tp.name.isShadowedName => tp.name + case tp: NamedType if tp.name.is(ShadowedName) => tp.name case _ => name } val sig = tree.tpe.signature diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala index 8a9b68093..b8e6bbdf0 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala @@ -857,7 +857,7 @@ class TreeUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName, posUnpi val localCtx = if (name == nme.CONSTRUCTOR) ctx.addMode(Mode.InSuperCall) else ctx val qual = readTerm()(localCtx) - val unshadowed = if (name.isShadowedName) name.revertShadowed else name + val unshadowed = name.exclude(ShadowedName) untpd.Select(qual, unshadowed).withType(tpf(qual.tpe.widenIfUnstable)) } diff --git a/compiler/src/dotty/tools/dotc/transform/Erasure.scala b/compiler/src/dotty/tools/dotc/transform/Erasure.scala index d64120085..e9fe42e78 100644 --- a/compiler/src/dotty/tools/dotc/transform/Erasure.scala +++ b/compiler/src/dotty/tools/dotc/transform/Erasure.scala @@ -11,6 +11,7 @@ import core.Types._ import core.Names._ import core.StdNames._ import core.NameOps._ +import core.NameExtractors.ShadowedName import core.Decorators._ import core.Constants._ import core.Definitions._ @@ -363,7 +364,7 @@ object Erasure extends TypeTestsCasts{ def select(qual: Tree, sym: Symbol): Tree = { val name = tree.typeOpt match { - case tp: NamedType if tp.name.isShadowedName => sym.name.shadowedName + case tp: NamedType if tp.name.is(ShadowedName) => sym.name.derived(ShadowedName) case _ => sym.name } untpd.cpy.Select(tree)(qual, sym.name) diff --git a/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala b/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala index 8328e43de..803504944 100644 --- a/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala +++ b/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala @@ -19,8 +19,8 @@ import dotty.tools.dotc.core.Denotations.SingleDenotation import scala.collection.mutable import DenotTransformers._ import typer.Checking -import Names.Name import NameOps._ +import NameExtractors.AvoidClashName import StdNames._ @@ -129,7 +129,7 @@ class FirstTransform extends MiniPhaseTransform with InfoTransformer with Annota case _ => false } - val uniqueName = if (nameClash) objName.avoidClashName else objName + val uniqueName = if (nameClash) AvoidClashName(objName) else objName Thicket(stat :: ModuleDef(registerCompanion(uniqueName, stat.symbol), Nil).trees) case stat => stat } -- cgit v1.2.3