diff --git a/compiler/src/dotty/tools/dotc/interactive/Interactive.scala b/compiler/src/dotty/tools/dotc/interactive/Interactive.scala index e051a144b1b3..1872dcf86f31 100644 --- a/compiler/src/dotty/tools/dotc/interactive/Interactive.scala +++ b/compiler/src/dotty/tools/dotc/interactive/Interactive.scala @@ -94,13 +94,22 @@ object Interactive { private def safely[T](op: => List[T]): List[T] = try op catch { case ex: TypeError => Nil } + private def addExtraImports(extraImports: List[untpd.Import], ctx: Context): Context = { + extraImports.foldLeft(ctx) { case (c, i) => c.importContext(i, i.symbol(c)) } + } + /** Get possible completions from tree at `pos` * + * @param pos The cursor position in the current compilation unit, where the + * completion should be introduced. + * @param extraImports Additional import statements that are not reflected in + * the compilation unit, but which should be considered. * @return offset and list of symbols for possible completions */ - def completions(pos: SourcePosition)(implicit ctx: Context): (Int, List[Symbol]) = { + def completions(pos: SourcePosition, extraImports: List[untpd.Import] = Nil)(implicit ctx: Context): (Int, List[Symbol]) = { val path = pathTo(ctx.compilationUnit.tpdTree, pos.pos) - computeCompletions(pos, path)(contextOfPath(path)) + val completionCtx = addExtraImports(extraImports, contextOfPath(path)) + computeCompletions(pos, path)(completionCtx) } private def computeCompletions(pos: SourcePosition, path: List[Tree])(implicit ctx: Context): (Int, List[Symbol]) = { diff --git a/compiler/src/dotty/tools/repl/ReplDriver.scala b/compiler/src/dotty/tools/repl/ReplDriver.scala index 536c5fccd2c1..879e65264d32 100644 --- a/compiler/src/dotty/tools/repl/ReplDriver.scala +++ b/compiler/src/dotty/tools/repl/ReplDriver.scala @@ -167,7 +167,7 @@ class ReplDriver(settings: Array[String], unit.tpdTree = tree implicit val ctx = state.context.fresh.setCompilationUnit(unit) val srcPos = SourcePosition(file, Position(cursor)) - val (_, completions) = Interactive.completions(srcPos) + val (_, completions) = Interactive.completions(srcPos, state.imports) completions.map(makeCandidate) } .getOrElse(Nil) diff --git a/compiler/test/dotty/tools/repl/TabcompleteTests.scala b/compiler/test/dotty/tools/repl/TabcompleteTests.scala index c5c84c7b88bc..2421e9e5a367 100644 --- a/compiler/test/dotty/tools/repl/TabcompleteTests.scala +++ b/compiler/test/dotty/tools/repl/TabcompleteTests.scala @@ -60,4 +60,14 @@ class TabcompleteTests extends ReplTest { val expected = List("comp1", "comp2", "comp3") assertEquals(expected, tabComplete("(new Foo).comp").sorted) } + + @Test def tabCompleteImport = + fromInitialState { implicit state => + val src = "import java.io.FileDescriptor" + run(src) + } + .andThen { implicit state => + val expected = List("FileDescriptor") + assertEquals(expected, tabComplete("val foo: FileDesc")) + } }