Skip to content

Commit bb6787f

Browse files
committed
Better completion description for multiple symbols
When multiple symbols are concerned by one completion result, we show the different kinds of symbols.
1 parent 863e903 commit bb6787f

File tree

2 files changed

+53
-20
lines changed

2 files changed

+53
-20
lines changed

compiler/src/dotty/tools/dotc/interactive/Completion.scala

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -149,24 +149,39 @@ object Completion {
149149
val groupedSymbols = {
150150
val symbols = completions.toListWithNames
151151
val nameToSymbols = symbols.groupBy(_._2.stripModuleClassSuffix.toSimpleName)
152-
nameToSymbols.mapValues(_.map(_._1)).toList
152+
nameToSymbols.mapValues { symbols =>
153+
symbols
154+
.map(_._1)
155+
.distinct // Show symbols that have been renamed multiple times only once
156+
}.toList
153157
}
154158
groupedSymbols.map { case (name, symbols) =>
155-
val typesFirst = symbols.sortWith((s, _) => s.isType)
156-
// Use distinct to remove duplicates with class, module class, etc.
157-
val descriptions = typesFirst.map(description).distinct.mkString(", ")
158-
Completion(name.toString, descriptions, typesFirst)
159+
val typesFirst = symbols.sortWith((s1, s2) => s1.isType && !s2.isType)
160+
val desc = description(typesFirst)
161+
Completion(name.toString, desc, typesFirst)
159162
}
160163
}
161164

162165
/**
163-
* A description for `sym`.
166+
* A description for completion result that represents `symbols`.
164167
*
165-
* For types, show the symbol's full name, or its type for term symbols.
168+
* If `symbols` contains a single symbol, show its full name in case it's a type, or its type if
169+
* it's a term.
170+
*
171+
* When there are multiple symbols, show their kinds.
166172
*/
167-
private def description(sym: Symbol)(implicit ctx: Context): String = {
168-
if (sym.isType) sym.showFullName
169-
else sym.info.widenTermRefExpr.show
173+
private def description(symbols: List[Symbol])(implicit ctx: Context): String = {
174+
symbols match {
175+
case sym :: Nil =>
176+
if (sym.isType) sym.showFullName
177+
else sym.info.widenTermRefExpr.show
178+
179+
case sym :: _ =>
180+
symbols.map(ctx.printer.kindString).mkString("", " and ", s" ${sym.name.show}")
181+
182+
case Nil =>
183+
""
184+
}
170185
}
171186

172187
/**

language-server/test/dotty/tools/languageserver/CompletionTest.scala

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ class CompletionTest {
8989
object Foo""",
9090
code"""package pgk1
9191
import pkg0.F${m1}"""
92-
).completion(m1, Set(("Foo", Class, "pkg0.Foo")))
92+
).completion(m1, Set(("Foo", Class, "class and object Foo")))
9393
}
9494

9595
@Test def importCompleteIncludePackage: Unit = {
@@ -121,7 +121,7 @@ class CompletionTest {
121121

122122
@Test def importJavaClass: Unit = {
123123
code"""import java.io.FileDesc${m1}""".withSource
124-
.completion(m1, Set(("FileDescriptor", Class, "java.io.FileDescriptor")))
124+
.completion(m1, Set(("FileDescriptor", Class, "class and object FileDescriptor")))
125125
}
126126

127127
@Test def importJavaStaticMethod: Unit = {
@@ -143,7 +143,7 @@ class CompletionTest {
143143

144144
@Test def importRename: Unit = {
145145
code"""import java.io.{FileDesc${m1} => Foo}""".withSource
146-
.completion(m1, Set(("FileDescriptor", Class, "java.io.FileDescriptor")))
146+
.completion(m1, Set(("FileDescriptor", Class, "class and object FileDescriptor")))
147147
}
148148

149149
@Test def markDeprecatedSymbols: Unit = {
@@ -203,7 +203,7 @@ class CompletionTest {
203203
@Test def completionOnRenamedImport: Unit = {
204204
code"""import java.io.{FileDescriptor => AwesomeStuff}
205205
trait Foo { val x: Awesom$m1 }""".withSource
206-
.completion(m1, Set(("AwesomeStuff", Class, "java.io.FileDescriptor")))
206+
.completion(m1, Set(("AwesomeStuff", Class, "class and object FileDescriptor")))
207207
}
208208

209209
@Test def completionOnRenamedImport2: Unit = {
@@ -212,7 +212,7 @@ class CompletionTest {
212212
import java.io.{FileDescriptor => MyImportedSymbol}
213213
val x: MyImp$m1
214214
}""".withSource
215-
.completion(m1, Set(("MyImportedSymbol", Class, "java.io.FileDescriptor")))
215+
.completion(m1, Set(("MyImportedSymbol", Class, "class and object FileDescriptor")))
216216
}
217217

218218
@Test def completionRenamedAndOriginalNames: Unit = {
@@ -221,8 +221,8 @@ class CompletionTest {
221221
| import java.util.{HashMap => HashMap2}
222222
| val x: Hash$m1
223223
|}""".withSource
224-
.completion(m1, Set(("HashMap", Class, "java.util.HashMap"),
225-
("HashMap2", Class, "java.util.HashMap")))
224+
.completion(m1, Set(("HashMap", Class, "class and object HashMap"),
225+
("HashMap2", Class, "class and object HashMap")))
226226
}
227227

228228
@Test def completionRenamedThrice: Unit = {
@@ -232,8 +232,26 @@ class CompletionTest {
232232
| import java.util.{HashMap => MyHashMap3}
233233
| val x: MyHash$m1
234234
|}""".withSource
235-
.completion(m1, Set(("MyHashMap", Class, "java.util.HashMap"),
236-
("MyHashMap2", Class, "java.util.HashMap"),
237-
("MyHashMap3", Class, "java.util.HashMap")))
235+
.completion(m1, Set(("MyHashMap", Class, "class and object HashMap"),
236+
("MyHashMap2", Class, "class and object HashMap"),
237+
("MyHashMap3", Class, "class and object HashMap")))
238+
}
239+
240+
@Test def completionClassAndMethod: Unit = {
241+
code"""object Foo {
242+
| class bar
243+
| def bar = 0
244+
|}
245+
|import Foo.b$m1""".withSource
246+
.completion(m1, Set(("bar", Class, "class and method bar")))
247+
}
248+
249+
@Test def completionTypeAndLazyValue: Unit = {
250+
code"""object Foo {
251+
| type bar = Int
252+
| lazy val bar = 3
253+
|}
254+
|import Foo.b$m1""".withSource
255+
.completion(m1, Set(("bar", Field, "type and lazy value bar")))
238256
}
239257
}

0 commit comments

Comments
 (0)