Skip to content

Commit ae59176

Browse files
committed
Address review comments
1 parent 82e84d2 commit ae59176

File tree

2 files changed

+51
-21
lines changed

2 files changed

+51
-21
lines changed

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

Lines changed: 44 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -166,38 +166,59 @@ object Interactive {
166166
private def computeCompletions(pos: SourcePosition, path: List[Tree])(implicit ctx: Context): (Int, List[Symbol]) = {
167167
val completions = Scopes.newScope.openForMutations
168168

169+
type Mode = Int
170+
object Mode {
171+
/** No symbol should be included */
172+
val None: Mode = 0
173+
174+
/** Term symbols are allowed */
175+
val Term: Mode = 1
176+
177+
/** Type symbols are allowed */
178+
val Type: Mode = 2
179+
180+
/** Both term and type symbols are allowed */
181+
val Import: Mode = Term | Type
182+
183+
/** Does `m0` include `m1`? */
184+
def is(m0: Mode, m1: Mode): Boolean = (m0 & m1) == m1
185+
}
186+
169187
/**
170188
* The information about the current completion.
171189
*
172-
* @param position The position where the completion result should be inserted.
173-
* @param prefix A prefix that potential completion results must match.
174-
* @param termOnly If set, only terms should be considered as completion results.
175-
* @param typeOnly If set, only types should be considered as completion results.
176-
* @param inImport If set, indicates that this is the completion of an import node.
190+
* @param offset The offset where the completion result should be inserted.
191+
* @param prefix A prefix that potential completion results must match.
192+
* @param mode The completion mode.
177193
*/
178-
case class CompletionInfo(position: Int, prefix: String, termOnly: Boolean, typeOnly: Boolean, inImport: Boolean)
194+
case class CompletionInfo(offset: Int, prefix: String, mode: Mode)
179195

180196
/**
181197
* Extract basic info about completion location and the kind of symbols to include.
182198
*
183199
* @param path The path to the position where completion happens
184200
* @param inImport If set, indicates that this is the completion of an import node. When
185201
* completing imports, both types and terms are always included.
186-
* @return The completion info
202+
* @return The information about completion (offset, kinds of symbol, etc.)
187203
*/
188204
def completionInfo(path: List[Tree], inImport: Boolean): CompletionInfo = path match {
189205
case (ref: RefTree) :: _ =>
190206
if (ref.name == nme.ERROR)
191-
CompletionInfo(ref.pos.point, "", false, false, inImport)
192-
else
207+
CompletionInfo(ref.pos.point, "", Mode.None)
208+
else {
209+
val mode =
210+
if (inImport) Mode.Import
211+
else if (ref.name.isTermName) Mode.Term
212+
else Mode.Type
213+
193214
CompletionInfo(
194215
ref.pos.point,
195216
ref.name.toString.take(pos.pos.point - ref.pos.point),
196-
!inImport && ref.name.isTermName, // Types and terms are always accepted in imports
197-
!inImport && ref.name.isTypeName,
198-
inImport)
217+
mode)
218+
}
219+
199220
case _ =>
200-
CompletionInfo(0, "", false, false, false)
221+
CompletionInfo(0, "", Mode.None)
201222
}
202223

203224
val info = path match {
@@ -208,7 +229,7 @@ object Interactive {
208229

209230
case (imp: Import) :: _ =>
210231
imp.selectors.find(_.pos.contains(pos.pos)) match {
211-
case None => CompletionInfo(imp.expr.pos.point, "", false, false, true)
232+
case None => CompletionInfo(imp.expr.pos.point, "", Mode.Import)
212233
case Some(sel) => completionInfo(sel.asInstanceOf[tpd.Tree] :: Nil, /* inImport = */ true)
213234
}
214235

@@ -228,18 +249,20 @@ object Interactive {
228249
* as completion results. However, if a user explicitly writes all '$' characters in an
229250
* identifier, we should complete the rest.
230251
*/
231-
def include(sym: Symbol) =
252+
def include(sym: Symbol) = {
232253
sym.name.startsWith(info.prefix) &&
233254
!sym.name.toString.drop(info.prefix.length).contains('$') &&
234255
!sym.isPrimaryConstructor &&
235256
(!sym.is(Package) || !sym.moduleClass.exists) &&
236257
!sym.is(allOf(Mutable, Accessor)) &&
237-
(!info.termOnly || sym.isTerm) &&
238-
(!info.typeOnly || sym.isType)
258+
(
259+
(Mode.is(info.mode, Mode.Term) && sym.isTerm)
260+
|| (Mode.is(info.mode, Mode.Type) && sym.isType)
261+
)
262+
}
239263

240264
def enter(sym: Symbol) =
241265
if (include(sym)) completions.enter(sym)
242-
243266
def add(sym: Symbol) =
244267
if (sym.exists && !completions.lookup(sym.name).exists) enter(sym)
245268

@@ -313,7 +336,7 @@ object Interactive {
313336

314337
def getMemberCompletions(qual: Tree): Unit = {
315338
addAccessibleMembers(qual.tpe)
316-
if (!info.inImport) {
339+
if (!Mode.is(info.mode, Mode.Import)) {
317340
// Implicit conversions do not kick in when importing
318341
implicitConversionTargets(qual)(ctx.fresh.setExploreTyperState())
319342
.foreach(addAccessibleMembers(_))
@@ -328,7 +351,7 @@ object Interactive {
328351
}
329352

330353
val completionList =
331-
if (!info.inImport) completions.toList
354+
if (!Mode.is(info.mode, Mode.Import)) completions.toList
332355
else {
333356
// In imports, show only the type symbols when there are multiple options with the same name
334357
completions.toList.groupBy(_.name.stripModuleClassSuffix.toSimpleName).mapValues {
@@ -338,7 +361,7 @@ object Interactive {
338361
}
339362

340363
interactiv.println(i"completion with pos = $pos, prefix = $info.prefix, termOnly = $info.termOnly, typeOnly = $info.typeOnly = $completionList%, %")
341-
(info.position, completionList)
364+
(info.offset, completionList)
342365
}
343366

344367
/** Possible completions of members of `prefix` which are accessible when called inside `boundary` */

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,4 +159,11 @@ class CompletionTest {
159159
assertTrue("bar was not deprecated", result.getDeprecated)
160160
})
161161
}
162+
163+
@Test def i4397: Unit = {
164+
code"""class Foo {
165+
| .${m1}
166+
|}""".withSource
167+
.completion(m1, Set())
168+
}
162169
}

0 commit comments

Comments
 (0)