@@ -66,6 +66,9 @@ object Names {
6666 def asSimpleName : SimpleTermName
6767 def toSimpleName : SimpleTermName
6868 def rewrite (f : PartialFunction [Name , Name ]): ThisName
69+ def collect [T ](f : PartialFunction [Name , T ]): Option [T ]
70+ def mapLast (f : SimpleTermName => SimpleTermName ): ThisName
71+ def mapParts (f : SimpleTermName => SimpleTermName ): ThisName
6972
7073 /** A name of the same kind as this name and with same characters as given `name` */
7174 def likeKinded (name : Name ): ThisName
@@ -88,9 +91,8 @@ object Names {
8891
8992 /** A more efficient version of concatenation */
9093 def ++ (other : Name ): ThisName = ++ (other.toString)
91- def ++ (other : String ): ThisName
92-
93- def replace (from : Char , to : Char ): ThisName = likeKinded(asSimpleName.replace(from, to))
94+ def ++ (other : String ): ThisName = mapLast(n => termName(n.toString + other))
95+ def replace (from : Char , to : Char ): ThisName = mapParts(_.replace(from, to))
9496
9597 def isEmpty : Boolean
9698
@@ -198,8 +200,6 @@ object Names {
198200
199201 def apply (n : Int ) = chrs(start + n)
200202
201- def ++ (other : String ): SimpleTermName = termName(toString + other)
202-
203203 private def contains (ch : Char ): Boolean = {
204204 var i = 0
205205 while (i < length && chrs(start + i) != ch) i += 1
@@ -220,19 +220,29 @@ object Names {
220220 i > str.length
221221 }
222222
223- override def replace (from : Char , to : Char ): ThisName = {
223+ override def replace (from : Char , to : Char ): SimpleTermName = {
224224 val cs = new Array [Char ](length)
225225 Array .copy(chrs, start, cs, 0 , length)
226226 for (i <- 0 until length) {
227227 if (cs(i) == from) cs(i) = to
228228 }
229- likeKinded( termName(cs, 0 , length) )
229+ termName(cs, 0 , length)
230230 }
231231
232232 def isSimple = true
233233 def asSimpleName = this
234234 def toSimpleName = this
235- def rewrite (f : PartialFunction [Name , Name ]): ThisName = likeKinded(f(this ))
235+ def rewrite (f : PartialFunction [Name , Name ]): ThisName =
236+ if (f.isDefinedAt(this )) likeKinded(f(this )) else this
237+ def collect [T ](f : PartialFunction [Name , T ]): Option [T ] = f.lift(this )
238+ def mapLast (f : SimpleTermName => SimpleTermName ) = f(this )
239+ def mapParts (f : SimpleTermName => SimpleTermName ) = f(this )
240+
241+ /* def exists(p: Char => Boolean): Boolean = {
242+ var i = 0
243+ while (i < length && !p(chrs(start + i))) i += 1
244+ i < length
245+ }*/
236246
237247 def encode : SimpleTermName =
238248 if (dontEncode(toTermName)) this else NameTransformer .encode(this )
@@ -254,8 +264,6 @@ object Names {
254264
255265 class TypeName (val toTermName : TermName ) extends Name {
256266
257- def ++ (other : String ): ThisName = toTermName.++ (other).toTypeName
258-
259267 def isEmpty = toTermName.isEmpty
260268
261269 def encode = toTermName.encode.toTypeName
@@ -274,6 +282,9 @@ object Names {
274282 def asSimpleName = toTermName.asSimpleName
275283 def toSimpleName = toTermName.toSimpleName
276284 def rewrite (f : PartialFunction [Name , Name ]): ThisName = toTermName.rewrite(f).toTypeName
285+ def collect [T ](f : PartialFunction [Name , T ]): Option [T ] = toTermName.collect(f)
286+ def mapLast (f : SimpleTermName => SimpleTermName ) = toTermName.mapLast(f).toTypeName
287+ def mapParts (f : SimpleTermName => SimpleTermName ) = toTermName.mapParts(f).toTypeName
277288
278289 def likeKinded (name : Name ): TypeName = name.toTypeName
279290
@@ -298,10 +309,6 @@ object Names {
298309 case qual : NameInfo .Qualified => qual.name
299310 case _ => underlying.lastPart
300311 }
301- def ++ (other : String ): ThisName = info match {
302- case qual : NameInfo .Qualified => underlying.derived(qual.map(_ ++ other))
303- case _ => (underlying ++ other).derived(info)
304- }
305312 override def toString = info.mkString(underlying)
306313 override def debugString = s " ${underlying.debugString}[ $info] "
307314
@@ -315,6 +322,25 @@ object Names {
315322 case qual : NameInfo .Qualified => this
316323 case _ => underlying.rewrite(f).derived(info)
317324 }
325+
326+ def collect [T ](f : PartialFunction [Name , T ]): Option [T ] =
327+ if (f.isDefinedAt(this )) Some (f(this ))
328+ else info match {
329+ case qual : NameInfo .Qualified => None
330+ case _ => underlying.collect(f)
331+ }
332+
333+ def mapLast (f : SimpleTermName => SimpleTermName ): ThisName =
334+ info match {
335+ case qual : NameInfo .Qualified => underlying.derived(qual.map(f))
336+ case _ => underlying.mapLast(f).derived(info)
337+ }
338+
339+ def mapParts (f : SimpleTermName => SimpleTermName ): ThisName =
340+ info match {
341+ case qual : NameInfo .Qualified => underlying.mapParts(f).derived(qual.map(f))
342+ case _ => underlying.mapParts(f).derived(info)
343+ }
318344 }
319345
320346 // Nametable
@@ -478,23 +504,54 @@ object Names {
478504 }
479505
480506 implicit val NameOrdering : Ordering [Name ] = new Ordering [Name ] {
507+ private def compareInfos (x : NameInfo , y : NameInfo ): Int =
508+ if (x.kind != y.kind) x.kind - y.kind
509+ else x match {
510+ case x : NameInfo .Qualified =>
511+ y match {
512+ case y : NameInfo .Qualified =>
513+ val s = x.separator.compareTo(y.separator)
514+ if (s == 0 ) compareSimpleNames(x.name, y.name) else s
515+ }
516+ case x : NameInfo .Numbered =>
517+ y match {
518+ case y : NameInfo .Numbered =>
519+ x.num - y.num
520+ }
521+ case _ =>
522+ assert(x == y)
523+ 0
524+ }
525+ private def compareSimpleNames (x : SimpleTermName , y : SimpleTermName ): Int = {
526+ val until = x.length min y.length
527+ var i = 0
528+ while (i < until && x(i) == y(i)) i = i + 1
529+ if (i < until) {
530+ if (x(i) < y(i)) - 1
531+ else /* (x(i) > y(i))*/ 1
532+ } else {
533+ x.length - y.length
534+ }
535+ }
536+ private def compareTermNames (x : TermName , y : TermName ): Int = x match {
537+ case x : SimpleTermName =>
538+ y match {
539+ case y : SimpleTermName => compareSimpleNames(x, y)
540+ case _ => - 1
541+ }
542+ case DerivedTermName (xPre, xInfo) =>
543+ y match {
544+ case DerivedTermName (yPre, yInfo) =>
545+ val s = compareInfos(xInfo, yInfo)
546+ if (s == 0 ) compareTermNames(xPre, yPre) else s
547+ case _ => 1
548+ }
549+ }
481550 def compare (x : Name , y : Name ): Int = {
482551 if (x.isTermName && y.isTypeName) 1
483552 else if (x.isTypeName && y.isTermName) - 1
484553 else if (x eq y) 0
485- else {
486- val until = x.length min y.length
487- var i = 0
488-
489- while (i < until && x(i) == y(i)) i = i + 1
490-
491- if (i < until) {
492- if (x(i) < y(i)) - 1
493- else /* (x(i) > y(i))*/ 1
494- } else {
495- x.length - y.length
496- }
497- }
554+ else compareTermNames(x.toTermName, y.toTermName)
498555 }
499556 }
500557}
0 commit comments