@@ -48,6 +48,16 @@ case class Completion(label: String, description: String, symbols: List[Symbol])
4848
4949object Completion :
5050
51+ def scopeContext (pos : SourcePosition )(using Context ): CompletionResult =
52+ val tpdPath = Interactive .pathTo(ctx.compilationUnit.tpdTree, pos.span)
53+ val completionContext = Interactive .contextOfPath(tpdPath).withPhase(Phases .typerPhase)
54+ inContext(completionContext):
55+ val untpdPath = Interactive .resolveTypedOrUntypedPath(tpdPath, pos)
56+ val mode = completionMode(untpdPath, pos)
57+ val rawPrefix = completionPrefix(untpdPath, pos)
58+ val completer = new Completer (mode, pos, untpdPath, _ => true )
59+ completer.scopeCompletions
60+
5161 /** Get possible completions from tree at `pos`
5262 *
5363 * @return offset and list of symbols for possible completions
@@ -220,11 +230,11 @@ object Completion:
220230 val result = adjustedPath match
221231 // Ignore synthetic select from `This` because in code it was `Ident`
222232 // See example in dotty.tools.languageserver.CompletionTest.syntheticThis
223- case tpd.Select (qual @ tpd.This (_), _) :: _ if qual.span.isSynthetic => completer.scopeCompletions
233+ case tpd.Select (qual @ tpd.This (_), _) :: _ if qual.span.isSynthetic => completer.scopeCompletions.names
224234 case tpd.Select (qual, _) :: _ if qual.typeOpt.hasSimpleKind => completer.selectionCompletions(qual)
225235 case tpd.Select (qual, _) :: _ => Map .empty
226236 case (tree : tpd.ImportOrExport ) :: _ => completer.directMemberCompletions(tree.expr)
227- case _ => completer.scopeCompletions
237+ case _ => completer.scopeCompletions.names
228238
229239 interactiv.println(i """ completion info with pos = $pos,
230240 | term = ${completer.mode.is(Mode .Term )},
@@ -358,7 +368,7 @@ object Completion:
358368 * (even if the import follows it syntactically)
359369 * - a more deeply nested import shadowing a member or a local definition causes an ambiguity
360370 */
361- def scopeCompletions (using context : Context ): CompletionMap =
371+ def scopeCompletions (using context : Context ): CompletionResult =
362372
363373 /** Temporary data structure representing denotations with the same name introduced in a given scope
364374 * as a member of a type, by a local definition or by an import clause
@@ -369,14 +379,19 @@ object Completion:
369379 ScopedDenotations (denots.filter(includeFn), ctx)
370380
371381 val mappings = collection.mutable.Map .empty[Name , List [ScopedDenotations ]].withDefaultValue(List .empty)
382+ val renames = collection.mutable.Map .empty[Name , Name ]
372383 def addMapping (name : Name , denots : ScopedDenotations ) =
373384 mappings(name) = mappings(name) :+ denots
374385
375386 ctx.outersIterator.foreach { case ctx @ given Context =>
376387 if ctx.isImportContext then
377- importedCompletions.foreach { (name, denots) =>
388+ val imported = importedCompletions
389+ imported.names.foreach { (name, denots) =>
378390 addMapping(name, ScopedDenotations (denots, ctx, include(_, name)))
379391 }
392+ imported.renames.foreach { (name, newName) =>
393+ renames(name) = newName
394+ }
380395 else if ctx.owner.isClass then
381396 accessibleMembers(ctx.owner.thisType)
382397 .groupByName.foreach { (name, denots) =>
@@ -430,7 +445,7 @@ object Completion:
430445 }
431446 }
432447
433- resultMappings
448+ CompletionResult ( resultMappings, renames.toMap)
434449 end scopeCompletions
435450
436451 /** Widen only those types which are applied or are exactly nothing
@@ -472,13 +487,16 @@ object Completion:
472487 /** Completions introduced by imports directly in this context.
473488 * Completions from outer contexts are not included.
474489 */
475- private def importedCompletions (using Context ): CompletionMap =
490+ private def importedCompletions (using Context ): CompletionResult =
476491 val imp = ctx.importInfo
492+ val renames = collection.mutable.Map .empty[Name , Name ]
477493
478494 if imp == null then
479- Map .empty
495+ CompletionResult ( Map .empty, Map .empty)
480496 else
481497 def fromImport (name : Name , nameInScope : Name ): Seq [(Name , SingleDenotation )] =
498+ if name != nameInScope then
499+ renames(name) = nameInScope
482500 imp.site.member(name).alternatives
483501 .collect { case denot if include(denot, nameInScope) => nameInScope -> denot }
484502
@@ -506,7 +524,8 @@ object Completion:
506524 fromImport(original.toTypeName, nameInScope.toTypeName)
507525 }.toSeq.groupByName
508526
509- givenImports ++ wildcardMembers ++ explicitMembers
527+ val results = givenImports ++ wildcardMembers ++ explicitMembers
528+ CompletionResult (results, renames.toMap)
510529 end importedCompletions
511530
512531 /** Completions from implicit conversions including old style extensions using implicit classes */
@@ -584,7 +603,7 @@ object Completion:
584603
585604 // 1. The extension method is visible under a simple name, by being defined or inherited or imported in a scope enclosing the reference.
586605 val termCompleter = new Completer (Mode .Term , pos, untpdPath, matches)
587- val extMethodsInScope = termCompleter.scopeCompletions.toList.flatMap:
606+ val extMethodsInScope = termCompleter.scopeCompletions.names. toList.flatMap:
588607 case (name, denots) => denots.collect:
589608 case d : SymDenotation if d.isTerm && d.termRef.symbol.is(Extension ) => (d.termRef, name.asTermName)
590609
@@ -686,6 +705,7 @@ object Completion:
686705
687706 private type CompletionMap = Map [Name , Seq [SingleDenotation ]]
688707
708+ case class CompletionResult (names : Map [Name , Seq [SingleDenotation ]], renames : Map [Name , Name ])
689709 /**
690710 * The completion mode: defines what kinds of symbols should be included in the completion
691711 * results.
0 commit comments