aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-03-01 10:41:32 +0100
committerMartin Odersky <odersky@gmail.com>2013-03-01 10:41:32 +0100
commit49e6eb07bf55cf9eabb260e7b7a8fef45923e8df (patch)
treedbb68d57b2820588b2f9e2b1189dc90d798549dd
parent75507c832cf281b18e3dff0cefdee315d777bec9 (diff)
downloaddotty-49e6eb07bf55cf9eabb260e7b7a8fef45923e8df.tar.gz
dotty-49e6eb07bf55cf9eabb260e7b7a8fef45923e8df.tar.bz2
dotty-49e6eb07bf55cf9eabb260e7b7a8fef45923e8df.zip
Bug fixes and cleanups for names.
-rw-r--r--src/dotty/tools/dotc/core/NameOps.scala34
-rw-r--r--src/dotty/tools/dotc/core/Names.scala31
-rw-r--r--src/dotty/tools/dotc/core/Printers.scala6
-rw-r--r--src/dotty/tools/dotc/core/testnames.sc12
4 files changed, 52 insertions, 31 deletions
diff --git a/src/dotty/tools/dotc/core/NameOps.scala b/src/dotty/tools/dotc/core/NameOps.scala
index c67bded72..1099afb46 100644
--- a/src/dotty/tools/dotc/core/NameOps.scala
+++ b/src/dotty/tools/dotc/core/NameOps.scala
@@ -46,7 +46,7 @@ object NameOps {
}
}
- implicit class NameDecorator(val name: Name) extends AnyVal {
+ implicit class NameDecorator[N <: Name](val name: N) extends AnyVal {
import nme._
def isConstructorName = name == CONSTRUCTOR || name == TRAIT_CONSTRUCTOR
@@ -101,6 +101,16 @@ object NameOps {
def stripModuleSuffix: Name =
if (isModuleName) name dropRight MODULE_SUFFIX.length else name
+ /** The expanded name of `name` relative to this class `base` with given `separator`
+ */
+ def expandedName(base: Symbol, separator: Name = nme.EXPAND_SEPARATOR)(implicit ctx: Context): N =
+ name.fromName((base.fullName('$') ++ separator ++ name)).asInstanceOf[N]
+
+ def unexpandedName(separator: Name = nme.EXPAND_SEPARATOR): N = {
+ val idx = name.lastIndexOfSlice(separator)
+ if (idx < 0) name else (name drop (idx + separator.length)).asInstanceOf[N]
+ }
+
/** Translate a name into a list of simple TypeNames and TermNames.
* In all segments before the last, type/term is determined by whether
* the following separator char is '.' or '#'. The last segment
@@ -152,34 +162,14 @@ object NameOps {
tpnme.Float -> jtpnme.BoxedFloat,
tpnme.Double -> jtpnme.BoxedDouble)
- // needed???
- implicit class TypeNameDecorator(val name: TypeName) extends AnyVal {
- def isUnboxedName = Boxed contains name
- def boxedName: TypeName = Boxed(name)
-
- /** The expanded name of `name` relative to this class `base` with given `separator`
- */
- def expandedName(base: Symbol, separator: Name = nme.EXPAND_SEPARATOR)(implicit ctx: Context): TypeName =
- (base.fullName('$') ++ separator ++ name).toTypeName
-
- def unexpandedName(separator: Name = nme.EXPAND_SEPARATOR) = {
- val idx = name.lastIndexOfSlice(separator)
- if (idx < 0) name else name drop (idx + separator.length)
- }
- }
implicit class TermNameDecorator(val name: TermName) extends AnyVal {
import nme._
- /** The expanded name of `name` relative to this class `base` with given `separator`
- */
- def expandedName(base: Symbol, separator: Name = EXPAND_SEPARATOR)(implicit ctx: Context): TermName =
- (base.fullName('$') ++ separator ++ name).toTermName
-
/** The expanded setter name of `name` relative to this class `base`
*/
def expandedSetterName(base: Symbol)(implicit ctx: Context): TermName =
- expandedName(base, separator = TRAIT_SETTER_SEPARATOR)
+ name.expandedName(base, separator = TRAIT_SETTER_SEPARATOR)
def getterName: TermName = name match {
case name: LocalName => name.toGlobalName
diff --git a/src/dotty/tools/dotc/core/Names.scala b/src/dotty/tools/dotc/core/Names.scala
index c046fd74b..3b9a78dc5 100644
--- a/src/dotty/tools/dotc/core/Names.scala
+++ b/src/dotty/tools/dotc/core/Names.scala
@@ -50,6 +50,9 @@ object Names {
/** Is this name a term name? */
def isTermName: Boolean
+ /** Is this name a local name? */
+ def isLocalName: Boolean = this.isInstanceOf[LocalName]
+
/** This name converted to a type name */
def toTypeName: TypeName
@@ -70,8 +73,22 @@ object Names {
*/
def fromChars(cs: Array[Char], offset: Int, len: Int): ThisName
+ /** Create new name of same kind as this name and with same
+ * characters as given `name`.
+ */
+ def fromName(name: Name): ThisName = fromChars(chrs, name.start, name.length)
+
override def toString = new String(chrs, start, length)
+ /** Show name with namespace suffix: /L for local names,
+ * /V for other term names, /T for type names
+ */
+ def showDetailed: String = toString + {
+ (if (isLocalName) "/L"
+ else if (isTypeName) "/T"
+ else "/V")
+ }
+
/** Write to UTF8 representation of this name to given character array.
* Start copying to index `to`. Return index of next free byte in array.
* Array must have enough remaining space for all bytes
@@ -178,7 +195,8 @@ object Names {
override def hashCode: Int = -start
- override protected[this] def newBuilder: Builder[Char, Name] = typeNameBuilder
+ override protected[this] def newBuilder: Builder[Char, Name] =
+ termNameBuilder.mapResult(_.toTypeName)
def fromChars(cs: Array[Char], offset: Int, len: Int): TypeName = typeName(cs, offset, len)
}
@@ -212,6 +230,10 @@ object Names {
class LocalName(start: Int, length: Int, _next: TermName) extends TermName(start, length, _next) {
override def hashCode: Int = start + 1
def toGlobalName: TermName = next
+ override protected[this] def newBuilder: Builder[Char, Name] =
+ termNameBuilder.mapResult(_.toLocalName)
+ override def fromChars(cs: Array[Char], offset: Int, len: Int): TermName =
+ termName(cs, offset, len).toLocalName
}
// Nametable
@@ -330,7 +352,7 @@ object Names {
def typeName(bs: Array[Byte], offset: Int, len: Int): TypeName =
termName(bs, offset, len).toTypeName
- /** Create a term name from a string, wihtout encoding operators */
+ /** Create a term name from a string, without encoding operators */
def termName(s: String): TermName = termName(s.toCharArray, 0, s.length)
/** Create a term name from a string, encode if necessary*/
@@ -350,12 +372,9 @@ object Names {
/** The type name represented by the empoty string */
val EmptyTypeName = EmptyTermName.toTypeName
- val termNameBuilder: Builder[Char, TermName] =
+ def termNameBuilder: Builder[Char, TermName] =
StringBuilder.newBuilder.mapResult(termName)
- val typeNameBuilder: Builder[Char, TypeName] =
- StringBuilder.newBuilder.mapResult(typeName)
-
implicit val nameCanBuildFrom: CanBuildFrom[Name, Char, Name] = new CanBuildFrom[Name, Char, Name] {
def apply(from: Name): Builder[Char, Name] =
StringBuilder.newBuilder.mapResult(s => from.fromChars(s.toCharArray, 0, s.length))
diff --git a/src/dotty/tools/dotc/core/Printers.scala b/src/dotty/tools/dotc/core/Printers.scala
index 7bc835f36..4c97a5bfa 100644
--- a/src/dotty/tools/dotc/core/Printers.scala
+++ b/src/dotty/tools/dotc/core/Printers.scala
@@ -30,7 +30,7 @@ object Printers {
abstract class Printer {
- /** Show name, same as name.toString */
+ /** Show name, same as name.toString + kind suffix if plain printer */
def show(name: Name): String
/** Show name with "type" or "term" prefix */
@@ -119,7 +119,7 @@ object Printers {
|| (sym.name == nme.PACKAGE) // package
)
- def show(name: Name): String = name.toString
+ def show(name: Name): String = name.showDetailed
def showDetailed(name: Name): String =
(if (name.isTypeName) "type " else "term ") + name
@@ -377,6 +377,8 @@ object Printers {
class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
override protected def recursionLimitExceeeded() = {}
+ override def show(name: Name): String = name.toString
+
override protected def showSimpleName(sym: Symbol) = sym.originalName.decode
override def showPrefix(tp: Type): String = controlled {
diff --git a/src/dotty/tools/dotc/core/testnames.sc b/src/dotty/tools/dotc/core/testnames.sc
index 19c24b226..21c4a0ee6 100644
--- a/src/dotty/tools/dotc/core/testnames.sc
+++ b/src/dotty/tools/dotc/core/testnames.sc
@@ -4,7 +4,6 @@ object testnames {
println("Welcome to the Scala worksheet") //> Welcome to the Scala worksheet
import Names._
-
val n = termName("hello") //> n : dotty.tools.dotc.core.Names.TermName = hello
val tn = n.toTypeName //> tn : dotty.tools.dotc.core.Names.TypeName = hello
val ln = n.toLocalName //> ln : dotty.tools.dotc.core.Names.LocalName = hello
@@ -37,4 +36,15 @@ object testnames {
termName("abc") //> res18: dotty.tools.dotc.core.Names.TermName = abc
nfoo.filter(_ >= 'l') //> res19: dotty.tools.dotc.core.Names.Name = lloplusplus
nfoo map (_.toUpper) //> res20: dotty.tools.dotc.core.Names.Name = HELLO$PLUS$PLUS
+
+ import Decorators._
+
+ val local = "local".toTermName.toLocalName //> local : dotty.tools.dotc.core.Names.LocalName = local
+ val local1 = local ++ "!" //> local1 : dotty.tools.dotc.core.testnames.local.ThisName = local!
+ local1.showDetailed //> res21: String = local!/L
+ val local2 = "Foo.".toTermName ++: local1 //> local2 : dotty.tools.dotc.core.Names.Name = Foo.local!
+ local2.showDetailed //> res22: String = Foo.local!/V
+ local1.dropRight(2).showDetailed //> res23: String = loca/L
+ local1.fromName("Foo.".toTermName ++ local1).showDetailed
+ //> res24: String = Foo.local!/L
} \ No newline at end of file