Skip to content

Fix standard library symbols completion (solves #9760) #9805

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions compiler/src/dotty/tools/dotc/interactive/Completion.scala
Original file line number Diff line number Diff line change
Expand Up @@ -263,8 +263,12 @@ object Completion {
*/
private def accessibleMembers(site: Type)(using Context): Seq[Symbol] = site match {
case site: NamedType if site.symbol.is(Package) =>
// Don't look inside package members -- it's too expensive.
site.decls.toList.filter(sym => sym.isAccessibleFrom(site, superAccess = false))
extension (tpe: Type)
def accessibleSymbols = tpe.decls.toList.filter(sym => sym.isAccessibleFrom(site, superAccess = false))

val packageDecls = site.accessibleSymbols
val packageObjectsDecls = packageDecls.filter(_.isPackageObject).flatMap(_.thisType.accessibleSymbols)
packageDecls ++ packageObjectsDecls
case _ =>
def appendMemberSyms(name: Name, buf: mutable.Buffer[SingleDenotation]): Unit =
try buf ++= site.member(name).alternatives
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ object Interactive {

def contextOfPath(path: List[Tree])(using Context): Context = path match {
case Nil | _ :: Nil =>
ctx.run.runContext.fresh.setCompilationUnit(ctx.compilationUnit)
ctx.fresh
case nested :: encl :: rest =>
val outer = contextOfPath(encl :: rest)
try encl match {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,13 +143,15 @@ class InteractiveDriver(val settings: List[String]) extends Driver {
def run(uri: URI, sourceCode: String): List[Diagnostic] = run(uri, toSource(uri, sourceCode))

def run(uri: URI, source: SourceFile): List[Diagnostic] = {
import typer.ImportInfo._

val previousCtx = myCtx
try {
val reporter =
new StoreReporter(null) with UniqueMessagePositions with HideNonSensicalMessages

val run = compiler.newRun(using myInitCtx.fresh.setReporter(reporter))
myCtx = run.runContext
myCtx = run.runContext.withRootImports

given Context = myCtx

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,44 @@ import dotty.tools.languageserver.util.actions.CodeCompletion
class CompletionTest {

@Test def completion0: Unit = {
code"class Foo { val xyz: Int = 0; def y: Int = xy$m1 }".withSource
code"class Foo { val xyz: Int = 0; def y: Int = xy${m1} }".withSource
.completion(m1, Set(("xyz", Field, "Int")))
}

@Test def completionFromScalaPredef: Unit = {
code"class Foo { def foo: Unit = prin${m1} }".withSource
.completion(m1, Set(
("print", Method, "(x: Any): Unit"),
("printf", Method, "(text: String, xs: Any*): Unit"),
("println", Method, "(x: Any): Unit")
))
}

@Test def completionFromDottyPredef: Unit = {
code"class Foo { val foo = summ${m1} }".withSource
.completion(m1, Set(("summon", Method, "[T](using x: T): x.type")))
}

@Test def completionFromScalaPackage: Unit = {
code"class Foo { val foo: Conv${m1} }".withSource
.completion(m1, Set(("Conversion", Class, "scala.Conversion")))
}

@Test def completionFromScalaPackageObject: Unit = {
code"class Foo { val foo: BigD${m1} }".withSource
.completion(m1, Set(("BigDecimal", Field, "type and getter BigDecimal")))
}

@Test def completionFromSyntheticPackageObject: Unit = {
code"class Foo { val foo: IArr${m1} }".withSource
.completion(m1, Set(("IArray", Field, "type and object IArray")))
}

@Test def completionFromJavaDefaults: Unit = {
code"class Foo { val foo: Runn${m1} }".withSource
.completion(m1, Set(("Runnable", Class, "trait and object Runnable")))
}

@Test def completionWithImplicitConversion: Unit = {
withSources(
code"object Foo { implicit class WithBaz(bar: Bar) { def baz = 0 } }",
Expand All @@ -29,7 +63,7 @@ class CompletionTest {
).completion(m1, Set(("MyClass", Class, "Foo.MyClass")))
}

@Test def ImportCompleteClassNoPrefix: Unit = {
@Test def importCompleteClassNoPrefix: Unit = {
withSources(
code"""object Foo { class MyClass }""",
code"""import Foo.${m1}"""
Expand Down