aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2017-03-22 19:18:20 +0100
committerMartin Odersky <odersky@gmail.com>2017-04-11 09:33:10 +0200
commitbbc84eabcd244179299ad435b6e9d7473e5ff892 (patch)
treebda0f49b9cff4847fa174a3d52f9eb7b5806cdcc
parent19bc1ff09fa73e13be7e3464b8440c04b657aa82 (diff)
downloaddotty-bbc84eabcd244179299ad435b6e9d7473e5ff892.tar.gz
dotty-bbc84eabcd244179299ad435b6e9d7473e5ff892.tar.bz2
dotty-bbc84eabcd244179299ad435b6e9d7473e5ff892.zip
Implement startsWith/encode/decode for derived names.
-rw-r--r--compiler/src/dotty/tools/dotc/core/NameInfos.scala4
-rw-r--r--compiler/src/dotty/tools/dotc/core/Names.scala39
-rw-r--r--compiler/src/dotty/tools/dotc/core/StdNames.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/core/SymDenotations.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/util/NameTransformer.scala5
5 files changed, 34 insertions, 18 deletions
diff --git a/compiler/src/dotty/tools/dotc/core/NameInfos.scala b/compiler/src/dotty/tools/dotc/core/NameInfos.scala
index 650a0c0a4..031ca8f6e 100644
--- a/compiler/src/dotty/tools/dotc/core/NameInfos.scala
+++ b/compiler/src/dotty/tools/dotc/core/NameInfos.scala
@@ -9,6 +9,7 @@ import Names._
abstract class NameInfo extends util.DotClass {
def kind: NameInfo.Kind
def mkString(underlying: TermName): String
+ def map(f: SimpleTermName => SimpleTermName): NameInfo = this
def contains(ch: Char): Boolean = false
def ++(other: String): NameInfo = unsupported("++")
}
@@ -29,9 +30,10 @@ object NameInfo {
def mkString(underlying: TermName) = underlying.toString // will cause an unsupported exception
}
- case class Qualified(name: TermName, separator: String) extends NameInfo {
+ case class Qualified(name: SimpleTermName, separator: String) extends NameInfo {
def kind = QualifiedKind
def mkString(underlying: TermName) = s"$underlying$separator$name"
+ override def map(f: SimpleTermName => SimpleTermName): NameInfo = Qualified(f(name), separator)
override def contains(ch: Char): Boolean = name.contains(ch)
override def ++(other: String): NameInfo = Qualified(name ++ other, separator)
override def toString = s"Qualified($name, $separator)"
diff --git a/compiler/src/dotty/tools/dotc/core/Names.scala b/compiler/src/dotty/tools/dotc/core/Names.scala
index 9ec9e73f2..e9dbd7f7c 100644
--- a/compiler/src/dotty/tools/dotc/core/Names.scala
+++ b/compiler/src/dotty/tools/dotc/core/Names.scala
@@ -75,13 +75,10 @@ object Names {
def toText(printer: Printer): Text = printer.toText(this)
/** Replace \$op_name's by corresponding operator symbols. */
- def decode: Name =
- if (contains('$')) fromName(termName(NameTransformer.decode(toString)))
- else this
+ def decode: Name
/** Replace operator symbols by corresponding \$op_name's. */
- def encode: Name =
- if (dontEncode(toTermName)) this else NameTransformer.encode(this)
+ def encode: Name
/** A more efficient version of concatenation */
def ++ (other: Name): ThisName = ++ (other.toString)
@@ -89,7 +86,8 @@ object Names {
def replace(from: Char, to: Char): ThisName = fromName(toSimpleName.replace(from, to))
- def contains(ch: Char): Boolean
+ def startsWith(str: String): Boolean
+ def startsWith(name: Name): Boolean = startsWith(name.toString)
override def equals(that: Any) = this eq that.asInstanceOf[AnyRef]
}
@@ -187,14 +185,20 @@ object Names {
def apply(n: Int) = chrs(start + n)
- def ++ (other: String): ThisName = termName(toString + other)
+ def ++ (other: String): SimpleTermName = termName(toString + other)
- def contains(ch: Char): Boolean = {
+ private def contains(ch: Char): Boolean = {
var i = 0
while (i < length && chrs(start + i) != ch) i += 1
i < length
}
+ def startsWith(str: String): Boolean = {
+ var i = 0
+ while (i < str.length && i < length && apply(i) == str(i)) i += 1
+ i == str.length
+ }
+
override def replace(from: Char, to: Char): ThisName = {
val cs = new Array[Char](length)
Array.copy(chrs, start, cs, 0, length)
@@ -204,6 +208,13 @@ object Names {
fromName(termName(cs, 0, length))
}
+ def encode: SimpleTermName =
+ if (dontEncode(toTermName)) this else NameTransformer.encode(this)
+
+ /** Replace \$op_name's by corresponding operator symbols. */
+ def decode: SimpleTermName =
+ if (contains('$')) termName(NameTransformer.decode(toString)) else this
+
override def hashCode: Int = start
override def toString =
@@ -218,7 +229,10 @@ object Names {
def ++ (other: String): ThisName = toTermName.++(other).toTypeName
- def contains(ch: Char): Boolean = toTermName.contains(ch)
+ def startsWith(str: String): Boolean = toTermName.startsWith(str)
+
+ def encode: Name = toTermName.encode
+ def decode: Name = toTermName.decode
type ThisName = TypeName
def isTypeName = true
@@ -243,7 +257,9 @@ object Names {
class DerivedTermName(override val underlying: TermName, override val info: NameInfo)
extends TermName {
def ++ (other: String): ThisName = derived(info ++ other)
- def contains(ch: Char): Boolean = underlying.contains(ch) || info.contains(ch)
+ def startsWith(str: String): Boolean = underlying.startsWith(str)
+ def encode: Name = underlying.encode.derived(info.map(_.encode))
+ def decode: Name = underlying.decode.derived(info.map(_.decode))
override def toString = info.mkString(underlying)
override def debugString = s"${underlying.debugString}[$info]"
}
@@ -388,7 +404,7 @@ object Names {
val STATIC_CONSTRUCTOR: TermName = termName("<clinit>")
val EMPTY_PACKAGE: TermName = termName("<empty>")
- val dontEncode = Set[TermName](CONSTRUCTOR, EMPTY_PACKAGE)
+ val dontEncode = Set(CONSTRUCTOR, EMPTY_PACKAGE)
def termNameBuilder: Builder[Char, TermName] =
StringBuilder.newBuilder.mapResult(termName)
@@ -404,7 +420,6 @@ object Names {
def seq: WrappedString = new WrappedString(name.toString)
override protected[this] def thisCollection: WrappedString = seq
- def startsWith(name: Name): Boolean = startsWith(name.toString)
def endsWith(name: Name): Boolean = endsWith(name.toString)
def indexOfSlice(name: Name): Int = indexOfSlice(name.toString)
def lastIndexOfSlice(name: Name): Int = lastIndexOfSlice(name.toString)
diff --git a/compiler/src/dotty/tools/dotc/core/StdNames.scala b/compiler/src/dotty/tools/dotc/core/StdNames.scala
index e7928fd09..56f8ca189 100644
--- a/compiler/src/dotty/tools/dotc/core/StdNames.scala
+++ b/compiler/src/dotty/tools/dotc/core/StdNames.scala
@@ -92,7 +92,7 @@ object StdNames {
val BITMAP_CHECKINIT: N = BITMAP_PREFIX + "init$" // initialization bitmap for checkinit values
val BITMAP_CHECKINIT_TRANSIENT: N = BITMAP_PREFIX + "inittrans$" // initialization bitmap for transient checkinit values
val DEFAULT_GETTER: N = "$default$"
- val DEFAULT_GETTER_INIT: N = NameTransformer.encode("<init>")
+ val DEFAULT_GETTER_INIT: N = "$lessinit$greater"
val DO_WHILE_PREFIX: N = "doWhile$"
val EMPTY: N = ""
val EMPTY_PACKAGE: N = Names.EMPTY_PACKAGE.toString
diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala
index 0483e0ca1..070fdf345 100644
--- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -415,7 +415,7 @@ object SymDenotations {
if (sep == "$")
// duplicate scalac's behavior: don't write a double '$$' for module class members.
prefix = prefix.without(NameInfo.ModuleClassKind)
- prefix.derived(NameInfo.Qualified(name.toTermName, sep))
+ prefix.derived(NameInfo.Qualified(name.toSimpleName, sep))
}
else {
if (owner.is(ModuleClass, butNot = Package) && sep == "$")
diff --git a/compiler/src/dotty/tools/dotc/util/NameTransformer.scala b/compiler/src/dotty/tools/dotc/util/NameTransformer.scala
index 330d513fe..52f8e6ec0 100644
--- a/compiler/src/dotty/tools/dotc/util/NameTransformer.scala
+++ b/compiler/src/dotty/tools/dotc/util/NameTransformer.scala
@@ -60,7 +60,7 @@ object NameTransformer {
* @param name the string to encode
* @return the string with all recognized opchars replaced with their encoding
*/
- def encode[N <: Name](name: N): N = {
+ def encode(name: SimpleTermName): SimpleTermName = {
var buf: StringBuilder = null
val len = name.length
var i = 0
@@ -87,8 +87,7 @@ object NameTransformer {
i += 1
}
if (buf eq null) name
- else if (name.isTermName) buf.toString.toTermName.asInstanceOf[N]
- else buf.toString.toTypeName.asInstanceOf[N]
+ else termName(buf.toString)
}
/** Replace `\$opname` by corresponding operator symbol.