aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2017-03-22 11:17:33 +0100
committerMartin Odersky <odersky@gmail.com>2017-04-11 09:33:10 +0200
commit01d9659e21a149801fd8ced6652cc0e94f4827e2 (patch)
tree2c64f5ede5ee7977d80cd31df916cc30b0665471
parent8144ac29420f18fc4a60690ac33d6247cb87a40c (diff)
downloaddotty-01d9659e21a149801fd8ced6652cc0e94f4827e2.tar.gz
dotty-01d9659e21a149801fd8ced6652cc0e94f4827e2.tar.bz2
dotty-01d9659e21a149801fd8ced6652cc0e94f4827e2.zip
Fix handling of qualified names
These always construct a new name, other derivations should not commute with Qualified.
-rw-r--r--compiler/src/dotty/tools/dotc/core/NameInfos.scala20
-rw-r--r--compiler/src/dotty/tools/dotc/core/Names.scala41
2 files changed, 42 insertions, 19 deletions
diff --git a/compiler/src/dotty/tools/dotc/core/NameInfos.scala b/compiler/src/dotty/tools/dotc/core/NameInfos.scala
index 4bbc5bbcf..51c04b9e4 100644
--- a/compiler/src/dotty/tools/dotc/core/NameInfos.scala
+++ b/compiler/src/dotty/tools/dotc/core/NameInfos.scala
@@ -8,7 +8,6 @@ import Names._
*/
abstract class NameInfo {
def kind: NameInfo.Kind
- def oneOfAKind = true
def mkString(underlying: TermName): String
}
@@ -18,22 +17,25 @@ object NameInfo {
val TermNameKind = 0
val QualifiedKind = 1
+ val ModuleClassKind = 2
+
+ def definesNewName(kind: Kind) = kind <= QualifiedKind
/** TermNames have the lowest possible kind */
val TermName = new NameInfo {
- def kind = 0
- def mkString(underlying: TermName) = underlying.toString // will cause an unsupptored exception
+ def kind = TermNameKind
+ def mkString(underlying: TermName) = underlying.toString // will cause an unsupported exception
}
- case class Qualified(name: TermName) extends NameInfo {
- def kind = 1
- override def oneOfAKind = false
- def mkString(underlying: TermName) = s"$underlying.$name"
+ case class Qualified(name: TermName, separator: String) extends NameInfo {
+ def kind = QualifiedKind
+ def mkString(underlying: TermName) = s"$underlying$separator$name"
+ override def toString = s"Qualified($name, $separator)"
}
val ModuleClass = new NameInfo {
- def kind = 10
+ def kind = ModuleClassKind
def mkString(underlying: TermName) = underlying + "$"
+ override def toString = "ModuleClass"
}
-
} \ No newline at end of file
diff --git a/compiler/src/dotty/tools/dotc/core/Names.scala b/compiler/src/dotty/tools/dotc/core/Names.scala
index 3c867c754..dbaa338a2 100644
--- a/compiler/src/dotty/tools/dotc/core/Names.scala
+++ b/compiler/src/dotty/tools/dotc/core/Names.scala
@@ -74,8 +74,10 @@ object Names {
/** A name of the same kind as this name and with same characters as given `name` */
def fromName(name: Name): ThisName
- override def toString =
- if (length == 0) "" else new String(chrs, start, length)
+ def derived(info: NameInfo): ThisName
+ def without(kind: NameInfo.Kind): ThisName
+ def is(kind: NameInfo.Kind): Boolean
+ def debugString: String
def toText(printer: Printer): Text = printer.toText(this)
@@ -202,20 +204,27 @@ object Names {
}
val ownKind = this.info.kind
- if (ownKind > info.kind)
+ if (NameInfo.definesNewName(info.kind)) addIt()
+ else if (ownKind > info.kind)
underlying.derived(info).derived(this.info)
- else if (ownKind == info.kind)
- if (info.oneOfAKind) {
- assert(info == this.info)
- this
- }
- else addIt()
+ else if (ownKind == info.kind) {
+ assert(info == this.info)
+ this
+ }
else addIt()
}
+ def without(kind: NameInfo.Kind): TermName = {
+ val ownKind = info.kind
+ if (ownKind < kind || NameInfo.definesNewName(ownKind)) this
+ else if (ownKind == kind) underlying.without(kind)
+ else underlying.without(kind).derived(this.info)
+ }
+
def is(kind: NameInfo.Kind): Boolean = {
val ownKind = info.kind
- ownKind == kind || ownKind > kind && underlying.is(kind)
+ ownKind == kind ||
+ !NameInfo.definesNewName(ownKind) && ownKind > kind && underlying.is(kind)
}
override def hashCode: Int = start
@@ -225,6 +234,10 @@ object Names {
class SimpleTermName(val start: Int, val length: Int, @sharable private[Names] var next: SimpleTermName) extends TermName {
// `next` is @sharable because it is only modified in the synchronized block of termName.
+ override def toString =
+ if (length == 0) "" else new String(chrs, start, length)
+
+ def debugString: String = toString
}
class TypeName(val toTermName: TermName) extends Name {
@@ -240,10 +253,17 @@ object Names {
def fromName(name: Name): TypeName = name.toTypeName
+ def derived(info: NameInfo): TypeName = toTermName.derived(info).toTypeName
+ def without(kind: NameInfo.Kind): TypeName = toTermName.without(kind).toTypeName
+ def is(kind: NameInfo.Kind) = toTermName.is(kind)
+
override def hashCode: Int = -start
override protected[this] def newBuilder: Builder[Char, Name] =
termNameBuilder.mapResult(_.toTypeName)
+
+ override def toString = toTermName.toString
+ override def debugString = toTermName.debugString + "/T"
}
/** A term name that's derived from an `underlying` name and that
@@ -254,6 +274,7 @@ object Names {
def start = underlying.start
override def length = underlying.length
override def toString = info.mkString(underlying)
+ override def debugString = s"${underlying.debugString}[$info]"
}
// Nametable