@@ -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` */
0 commit comments