aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2017-03-30 13:44:02 +0200
committerMartin Odersky <odersky@gmail.com>2017-04-11 09:33:11 +0200
commit21ded6ee9f727bd5a1c3975809c06868fe1b5536 (patch)
tree84675fd26ebfd422bb166088f8b048f7963c9720
parentae694957bfb9f5121eee3434243ecaabb6b24d1d (diff)
downloaddotty-21ded6ee9f727bd5a1c3975809c06868fe1b5536.tar.gz
dotty-21ded6ee9f727bd5a1c3975809c06868fe1b5536.tar.bz2
dotty-21ded6ee9f727bd5a1c3975809c06868fe1b5536.zip
Revise qualified names
1. Fix problem in fullNameSeparated 2. Revise expandedName operations
-rw-r--r--compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala3
-rw-r--r--compiler/src/dotty/tools/dotc/core/NameKinds.scala28
-rw-r--r--compiler/src/dotty/tools/dotc/core/NameOps.scala50
-rw-r--r--compiler/src/dotty/tools/dotc/core/StdNames.scala1
-rw-r--r--compiler/src/dotty/tools/dotc/core/SymDenotations.scala53
-rw-r--r--compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala3
-rw-r--r--compiler/src/dotty/tools/dotc/core/tasty/TastyUnpickler.scala8
-rw-r--r--compiler/src/dotty/tools/dotc/transform/AugmentScala2Traits.scala4
8 files changed, 63 insertions, 87 deletions
diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala
index 10288a4be..7ef6b7ef9 100644
--- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala
+++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala
@@ -557,8 +557,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
def fullName: String = sym.showFullName
def simpleName: Name = sym.name
def javaSimpleName: Name = toDenot(sym).name // addModuleSuffix(simpleName.dropLocal)
- def javaBinaryName: Name = toDenot(sym).fullNameSeparated("/").unmangleClassName // addModuleSuffix(fullNameInternal('/'))
- // We use `unmangleClassName` so that `stripModuleClassSuffix` works as expected.
+ def javaBinaryName: Name = javaClassName.replace('.', '/').toTermName // TODO: can we make this a string? addModuleSuffix(fullNameInternal('/'))
def javaClassName: String = toDenot(sym).fullName.toString// addModuleSuffix(fullNameInternal('.')).toString
def name: Name = sym.name
def rawname: Name = {
diff --git a/compiler/src/dotty/tools/dotc/core/NameKinds.scala b/compiler/src/dotty/tools/dotc/core/NameKinds.scala
index eea5aefe3..381bb3fc0 100644
--- a/compiler/src/dotty/tools/dotc/core/NameKinds.scala
+++ b/compiler/src/dotty/tools/dotc/core/NameKinds.scala
@@ -14,8 +14,8 @@ import collection.mutable
object NameKinds {
@sharable private val simpleNameKinds = new mutable.HashMap[Int, ClassifiedNameKind]
+ @sharable private val qualifiedNameKinds = new mutable.HashMap[Int, QualifiedNameKind]
@sharable private val uniqueNameKinds = new mutable.HashMap[String, UniqueNameKind]
- @sharable private val qualifiedNameKinds = new mutable.HashMap[String, QualifiedNameKind]
abstract class NameInfo extends DotClass {
def kind: NameKind
@@ -83,8 +83,18 @@ object NameKinds {
override def map(f: SimpleTermName => SimpleTermName): NameInfo = new QualInfo(f(name))
override def toString = s"$infoString $name"
}
- def apply(qual: TermName, name: SimpleTermName) =
+ def apply(qual: TermName, name: SimpleTermName): TermName =
qual.derived(new QualInfo(name))
+
+ /** Overloaded version used only for ExpandedName and TraitSetterName.
+ * Needed because the suffix of an expanded name may itself be expanded.
+ * For example, look at javap of scala.App.initCode
+ */
+ def apply(qual: TermName, name: TermName): TermName = name rewrite {
+ case name: SimpleTermName => apply(qual, name)
+ case AnyQualifiedName(_, _) => apply(qual, name.toSimpleName)
+ }
+
def unapply(name: DerivedTermName): Option[(TermName, SimpleTermName)] = name match {
case DerivedTermName(qual, info: this.QualInfo) => Some((qual, info.name))
case _ => None
@@ -96,7 +106,7 @@ object NameKinds {
s"$underlying$separator${info.name}"
def infoString = s"Qualified $separator"
- qualifiedNameKinds(separator) = this
+ qualifiedNameKinds(tag) = this
}
object AnyQualifiedName {
@@ -150,8 +160,8 @@ object NameKinds {
}
val QualifiedName = new QualifiedNameKind(QUALIFIED, ".")
- val FlattenedName = new QualifiedNameKind(FLATTENED, "$")
- val TraitSetterName = new QualifiedNameKind(TRAITSETTER, str.TRAIT_SETTER_SEPARATOR)
+ val FlatName = new QualifiedNameKind(FLATTENED, "$")
+ val ExpandPrefixName = new QualifiedNameKind(EXPANDPREFIX, "$")
val ExpandedName = new QualifiedNameKind(EXPANDED, str.EXPAND_SEPARATOR) {
private val FalseSuper = "$$super".toTermName
@@ -172,6 +182,8 @@ object NameKinds {
}
}
+ val TraitSetterName = new QualifiedNameKind(TRAITSETTER, str.TRAIT_SETTER_SEPARATOR)
+
val UniqueName = new UniqueNameKind("$") {
override def mkString(underlying: TermName, info: ThisInfo) =
if (underlying.isEmpty) "$" + info.num + "$" else super.mkString(underlying, info)
@@ -260,7 +272,7 @@ object NameKinds {
val Scala2MethodNameKinds: List[NameKind] =
List(DefaultGetterName, ProtectedAccessorName, ProtectedSetterName)
- def simpleNameKindOfTag : collection.Map[Int, ClassifiedNameKind] = simpleNameKinds
- def qualifiedNameKindOfSeparator: collection.Map[String, QualifiedNameKind] = qualifiedNameKinds
- def uniqueNameKindOfSeparator : collection.Map[String, UniqueNameKind] = uniqueNameKinds
+ def simpleNameKindOfTag : collection.Map[Int, ClassifiedNameKind] = simpleNameKinds
+ def qualifiedNameKindOfTag : collection.Map[Int, QualifiedNameKind] = qualifiedNameKinds
+ def uniqueNameKindOfSeparator: collection.Map[String, UniqueNameKind] = uniqueNameKinds
} \ 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 8d5344d8a..01ce4807c 100644
--- a/compiler/src/dotty/tools/dotc/core/NameOps.scala
+++ b/compiler/src/dotty/tools/dotc/core/NameOps.scala
@@ -59,10 +59,8 @@ object NameOps {
def isStaticConstructorName = name == STATIC_CONSTRUCTOR
def isImplClassName = name endsWith IMPL_CLASS_SUFFIX
def isLocalDummyName = name startsWith LOCALDUMMY_PREFIX
- def isLoopHeaderLabel = (name startsWith WHILE_PREFIX) || (name startsWith DO_WHILE_PREFIX)
def isReplWrapperName = name.toSimpleName containsSlice INTERPRETER_IMPORT_WRAPPER
def isSetterName = name endsWith SETTER_SUFFIX
- def isSingletonName = name endsWith SINGLETON_SUFFIX
def isImportName = name startsWith IMPORT
def isFieldName = name endsWith LOCAL_SUFFIX
def isScala2LocalSuffix = name.endsWith(" ")
@@ -110,8 +108,16 @@ object NameOps {
/** Convert this module class name to corresponding source module name */
def sourceModuleName: TermName = name.toTermName.exclude(ModuleClassName)
- /** If name ends in module class suffix, drop it */
- def stripModuleClassSuffix: Name = name.exclude(ModuleClassName)
+ /** If name ends in module class suffix, drop it. This
+ * method needs to work on mangled as well as unmangled names because
+ * it is also called from the backend.
+ */
+ def stripModuleClassSuffix: Name = name match {
+ case name: SimpleTermName if name.endsWith("$") =>
+ name.unmangleClassName.exclude(ModuleClassName)
+ case _ =>
+ name.exclude(ModuleClassName)
+ }
/** If flags is a ModuleClass but not a Package, add module class suffix */
def adjustIfModuleClass(flags: Flags.FlagSet): N = likeTyped {
@@ -122,43 +128,17 @@ object NameOps {
/** The superaccessor for method with given name */
def superName: TermName = SuperAccessorName(name.toTermName)
- /** The expanded name of `name` relative to given class `base`.
- */
- def expandedName(base: Symbol, separator: Name)(implicit ctx: Context): N =
- expandedName(if (base.name.is(ExpandedName)) base.name else base.fullNameSeparated("$"), separator)
-
- def expandedName(base: Symbol)(implicit ctx: Context): N = expandedName(base, nme.EXPAND_SEPARATOR)
-
- /** The expanded name of `name` relative to `basename` with given `separator`
- */
- def expandedName(prefix: Name, separator: Name = nme.EXPAND_SEPARATOR): N =
- likeTyped {
- def qualify(name: SimpleTermName) =
- qualifiedNameKindOfSeparator(separator.toString)(prefix.toTermName, name)
- name rewrite {
- case name: SimpleTermName =>
- qualify(name)
- case AnyQualifiedName(_, _) =>
- // Note: an expanded name may itself be expanded. For example, look at javap of scala.App.initCode
- qualify(name.toSimpleName)
- }
- }
-
- def expandedName(prefix: Name): N = expandedName(prefix, nme.EXPAND_SEPARATOR)
+ def expandedName(base: Symbol, kind: QualifiedNameKind = ExpandedName)(implicit ctx: Context): N = {
+ val prefix =
+ if (base.name.is(ExpandedName)) base.name else base.fullNameSeparated(ExpandPrefixName)
+ likeTyped { kind(prefix.toTermName, name.toTermName) }
+ }
/** Revert the expanded name. */
def unexpandedName: N = likeTyped {
name.rewrite { case ExpandedName(_, unexp) => unexp }
}
- def expandedPrefix: N = likeTyped { name.exclude(ExpandedName) }
-
- def expandedPrefixOfMangled: N = {
- val idx = name.lastIndexOfSlice(nme.EXPAND_SEPARATOR)
- assert(idx >= 0)
- likeTyped(name.take(idx))
- }
-
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/StdNames.scala b/compiler/src/dotty/tools/dotc/core/StdNames.scala
index 7dd569d04..51821c51b 100644
--- a/compiler/src/dotty/tools/dotc/core/StdNames.scala
+++ b/compiler/src/dotty/tools/dotc/core/StdNames.scala
@@ -124,7 +124,6 @@ object StdNames {
val PACKAGE: N = "package"
val PACKAGE_CLS: N = "package$"
val ROOT: N = "<root>"
- val SINGLETON_SUFFIX: N = ".type"
val SPECIALIZED_SUFFIX: N = "$sp"
val SUPER_PREFIX: N = "super$"
val WHILE_PREFIX: N = "while$"
diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala
index 3d0b306c0..f4682bf7d 100644
--- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -383,20 +383,18 @@ object SymDenotations {
/** The encoded full path name of this denotation, where outer names and inner names
* are separated by `separator` strings.
* Never translates expansions of operators back to operator symbol.
- * Drops package objects. Represents terms in the owner chain by a simple `~`.
+ * Drops package objects. Represents each term in the owner chain by a simple `~`.
* (Note: scalac uses nothing to represent terms, which can cause name clashes
* between same-named definitions in different enclosing methods. Before this commit
* we used `$' but this can cause ambiguities with the class separator '$').
* A separator "" means "flat name"; the real separator in this case is "$" and
* enclosing packages do not form part of the name.
*/
- def fullNameSeparated(separator: String)(implicit ctx: Context): Name = {
- val stopAtPackage = separator.isEmpty
- val sep = if (stopAtPackage) "$" else separator
+ def fullNameSeparated(kind: QualifiedNameKind)(implicit ctx: Context): Name =
if (symbol == NoSymbol ||
owner == NoSymbol ||
owner.isEffectiveRoot ||
- stopAtPackage && owner.is(PackageClass)) name
+ kind == FlatName && owner.is(PackageClass)) name
else {
var filler = ""
var encl = owner
@@ -404,34 +402,25 @@ object SymDenotations {
encl = encl.owner
filler += "~"
}
- var prefix = encl.fullNameSeparated(separator)
- val fn =
- if (qualifiedNameKindOfSeparator.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)
- qualifiedNameKindOfSeparator(sep)(prefix.toTermName, n1)
- }
- }
- else {
- val sep1 =
- if (owner.is(ModuleClass, butNot = Package) && sep == "$") ""
- else sep
- // duplicate scalac's behavior: don't write a double '$$' for module class members.
- prefix ++ sep1 ++ name
- }
+ var prefix = encl.fullNameSeparated(kind)
+ if (kind.separator == "$")
+ // duplicate scalac's behavior: don't write a double '$$' for module class members.
+ prefix = prefix.exclude(ModuleClassName)
+ def qualify(n: SimpleTermName) =
+ kind(prefix.toTermName, if (filler.isEmpty) n else termName(filler ++ n))
+ val fn = name rewrite {
+ case name: SimpleTermName => qualify(name)
+ case name @ AnyQualifiedName(_, _) => qualify(name.toSimpleName)
+ }
if (isType) fn.toTypeName else fn.toTermName
}
- }
+
/** The encoded flat name of this denotation, where joined names are separated by `separator` characters. */
- def flatName(implicit ctx: Context): Name = fullNameSeparated("")
+ def flatName(implicit ctx: Context): Name = fullNameSeparated(FlatName)
/** `fullName` where `.' is the separator character */
- def fullName(implicit ctx: Context): Name = fullNameSeparated(".")
+ def fullName(implicit ctx: Context): Name = fullNameSeparated(QualifiedName)
// ----- Tests -------------------------------------------------
@@ -1763,13 +1752,13 @@ object SymDenotations {
}
}
- private[this] var fullNameCache: SimpleMap[String, Name] = SimpleMap.Empty
- override final def fullNameSeparated(separator: String)(implicit ctx: Context): Name = {
- val cached = fullNameCache(separator)
+ private[this] var fullNameCache: SimpleMap[QualifiedNameKind, Name] = SimpleMap.Empty
+ override final def fullNameSeparated(kind: QualifiedNameKind)(implicit ctx: Context): Name = {
+ val cached = fullNameCache(kind)
if (cached != null) cached
else {
- val fn = super.fullNameSeparated(separator)
- fullNameCache = fullNameCache.updated(separator, fn)
+ val fn = super.fullNameSeparated(kind)
+ fullNameCache = fullNameCache.updated(kind, fn)
fn
}
}
diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala b/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala
index f7e61c924..ec59e711a 100644
--- a/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala
+++ b/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala
@@ -223,8 +223,9 @@ object TastyFormat {
final val UTF8 = 1
final val QUALIFIED = 2
final val FLATTENED = 3
+ final val EXPANDPREFIX = 5
final val EXPANDED = 4
- final val TRAITSETTER = 5
+ final val TRAITSETTER = 6
final val UNIQUE = 10
final val DEFAULTGETTER = 11
final val VARIANT = 12
diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TastyUnpickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TastyUnpickler.scala
index a14691ed5..835222727 100644
--- a/compiler/src/dotty/tools/dotc/core/tasty/TastyUnpickler.scala
+++ b/compiler/src/dotty/tools/dotc/core/tasty/TastyUnpickler.scala
@@ -49,12 +49,8 @@ class TastyUnpickler(reader: TastyReader) {
case UTF8 =>
goto(end)
termName(bytes, start.index, length)
- case QUALIFIED =>
- QualifiedName(readName(), readName().asSimpleName)
- case FLATTENED =>
- FlattenedName(readName(), readName().asSimpleName)
- case EXPANDED =>
- ExpandedName(readName(), readName().asSimpleName)
+ case QUALIFIED | FLATTENED | EXPANDED | EXPANDPREFIX =>
+ qualifiedNameKindOfTag(tag)(readName(), readName().asSimpleName)
case UNIQUE =>
val separator = readName().toString
val num = readNat()
diff --git a/compiler/src/dotty/tools/dotc/transform/AugmentScala2Traits.scala b/compiler/src/dotty/tools/dotc/transform/AugmentScala2Traits.scala
index a8d82045e..f2ffaff5d 100644
--- a/compiler/src/dotty/tools/dotc/transform/AugmentScala2Traits.scala
+++ b/compiler/src/dotty/tools/dotc/transform/AugmentScala2Traits.scala
@@ -14,7 +14,7 @@ import DenotTransformers._
import Annotations._
import StdNames._
import NameOps._
-import NameKinds._
+import NameKinds.{ExpandedName, TraitSetterName}
import ast.Trees._
/** This phase augments Scala2 traits with implementation classes and with additional members
@@ -74,7 +74,7 @@ class AugmentScala2Traits extends MiniPhaseTransform with IdentityDenotTransform
def traitSetter(getter: TermSymbol) =
getter.copy(
name = getter.ensureNotPrivate.name
- .expandedName(getter.owner, nme.TRAIT_SETTER_SEPARATOR)
+ .expandedName(getter.owner, TraitSetterName)
.asTermName.setterName,
flags = Method | Accessor,
info = MethodType(getter.info.resultType :: Nil, defn.UnitType))