diff --git a/compiler/src/dotty/tools/dotc/interactive/Completion.scala b/compiler/src/dotty/tools/dotc/interactive/Completion.scala index 966c95cad0fc..e5f8dc92d76b 100644 --- a/compiler/src/dotty/tools/dotc/interactive/Completion.scala +++ b/compiler/src/dotty/tools/dotc/interactive/Completion.scala @@ -152,8 +152,7 @@ object Completion { nameToSymbols.map { case (name, symbols) => val typesFirst = symbols.sortWith((s1, s2) => s1.isType && !s2.isType) val desc = description(typesFirst) - val label = NameTransformer.decodeIllegalChars(name.toString) - Completion(label, desc, typesFirst) + Completion(name.show, desc, typesFirst) } } diff --git a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala index 8fb3f98531e2..a05b4e6cc82c 100644 --- a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala +++ b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala @@ -24,7 +24,7 @@ import scala.tasty.util.Chars.isOperatorPart import transform.TypeUtils._ import language.implicitConversions -import dotty.tools.dotc.util.SourcePosition +import dotty.tools.dotc.util.{NameTransformer, SourcePosition} import dotty.tools.dotc.ast.untpd.{MemberDef, Modifiers, PackageDef, RefTree, Template, TypeDef, ValOrDefDef} class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { @@ -75,7 +75,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { }.toCommonFlags override def nameString(name: Name): String = - if (ctx.settings.YdebugNames.value) name.debugString else name.toString + if (ctx.settings.YdebugNames.value) name.debugString else NameTransformer.decodeIllegalChars(name.toString) override protected def simpleNameString(sym: Symbol): String = nameString(if (ctx.property(XprintMode).isEmpty) sym.originalName else sym.name) diff --git a/compiler/src/dotty/tools/dotc/util/NameTransformer.scala b/compiler/src/dotty/tools/dotc/util/NameTransformer.scala index 7fc724ad1cc1..8e88509f58b3 100644 --- a/compiler/src/dotty/tools/dotc/util/NameTransformer.scala +++ b/compiler/src/dotty/tools/dotc/util/NameTransformer.scala @@ -62,7 +62,12 @@ object NameTransformer { var i = 0 while (i < name.length) { if (i < name.length - 5 && name(i) == '$' && name(i + 1) == 'u') { - sb.append(Integer.valueOf(name.substring(i + 2, i + 6), 16).toChar) + val numbers = name.substring(i + 2, i + 6) + try sb.append(Integer.valueOf(name.substring(i + 2, i + 6), 16).toChar) + catch { + case _: java.lang.NumberFormatException => + sb.append("$u").append(numbers) + } i += 6 } else { sb.append(name(i)) diff --git a/compiler/test-resources/repl/unicodeChars b/compiler/test-resources/repl/unicodeChars new file mode 100644 index 000000000000..666ef45d415e --- /dev/null +++ b/compiler/test-resources/repl/unicodeChars @@ -0,0 +1,9 @@ +scala> type → + +scala> def bar: → = ??? +def bar: → + +scala> type `🤪` + +scala> def baz: `🤪` = ??? +def baz: 🤪 diff --git a/language-server/test/dotty/tools/languageserver/HoverTest.scala b/language-server/test/dotty/tools/languageserver/HoverTest.scala index f7de9d1e7da9..3ee0d1f53089 100644 --- a/language-server/test/dotty/tools/languageserver/HoverTest.scala +++ b/language-server/test/dotty/tools/languageserver/HoverTest.scala @@ -188,4 +188,16 @@ class HoverTest { .hover(m1 to m2, hoverContent("Int(1)")) .hover(m3 to m4, hoverContent("Int(1) @annot1 @annot2 @annot3 @annot4 @annot5")) } + + @Test def unicodeChar: Unit = { + code"""object Test { + | type → + | type `🤪` + | def ${m1}bar${m2}: → = ??? + | def ${m3}baz${m4}: `🤪` = ??? + |}""".withSource + .hover(m1 to m2, hoverContent("Test.→")) + .hover(m3 to m4, hoverContent("Test.🤪")) + + } }