diff options
-rw-r--r-- | src/dotty/tools/dotc/core/NameOps.scala | 34 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Names.scala | 31 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Printers.scala | 6 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/testnames.sc | 12 |
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 |