@@ -20,22 +20,34 @@ object Decorators {
2020 * with a normal wildcard. In the future, once #9255 is in trunk, replace with
2121 * a simple collective extension.
2222 */
23- implicit object PreNamedString :
24- extension (pn : PreName ) def toTypeName : TypeName = pn match
25- case s : String => typeName(s)
26- case n : Name => n.toTypeName
27- extension (pn : PreName ) def toTermName : TermName = pn match
23+ extension (pn : PreName )
24+ def toTermName : TermName = pn match
2825 case s : String => termName(s)
2926 case n : Name => n.toTermName
27+ def toTypeName : TypeName = pn match
28+ case s : String => typeName(s)
29+ case n : Name => n.toTypeName
3030
3131 extension (s : String ):
32- def splitWhere (f : Char => Boolean , doDropIndex : Boolean ): Option [(String , String )] = {
32+ def splitWhere (f : Char => Boolean , doDropIndex : Boolean ): Option [(String , String )] =
3333 def splitAt (idx : Int , doDropIndex : Boolean ): Option [(String , String )] =
3434 if (idx == - 1 ) None
3535 else Some ((s.take(idx), s.drop(if (doDropIndex) idx + 1 else idx)))
36-
3736 splitAt(s.indexWhere(f), doDropIndex)
38- }
37+
38+ /** Create a term name from a string slice, using a common buffer.
39+ * This avoids some allocation relative to `termName(s)`
40+ */
41+ def sliceToTermName (start : Int , end : Int )(using Context ): SimpleName =
42+ val base = ctx.base
43+ val len = end - start
44+ while len > base.nameCharBuffer.length do
45+ base.nameCharBuffer = new Array [Char ](base.nameCharBuffer.length * 2 )
46+ s.getChars(start, end, base.nameCharBuffer, 0 )
47+ termName(base.nameCharBuffer, 0 , len)
48+
49+ def sliceToTypeName (start : Int , end : Int )(using Context ): TypeName =
50+ sliceToTermName(start, end).toTypeName
3951
4052 /** Implements a findSymbol method on iterators of Symbols that
4153 * works like find but avoids Option, replacing None with NoSymbol.
0 commit comments