scalameta / metals

Scala language server with rich IDE features 🚀
https://scalameta.org/metals/
Apache License 2.0
2.1k stars 333 forks source link

Look in package objects for import suggestions #2583

Open Jasper-M opened 3 years ago

Jasper-M commented 3 years ago

Is your feature request related to a problem? Please describe. I will use the doobie library for this example. E.g. I have this file:

package example

object Foo {
  def xa[F[_]]: Transactor[F] = ???
}

This will not compile because type Transactor is not found. When I click on Transactor a suggestion will pop up to Import 'Transactor' from 'doobie.util.transactor'. However the import from package object doobie is not suggested at all, while I would prefer to import what I need from doobie without resorting to a wildcard import.

This is relatively common in Scala libraries, to expose the "public" API through aliases in a package object.

Describe the solution you'd like Also look in package objects (or top-level definitions for Scala 3) when suggesting imports.

Search terms: missing import package object

tgodzik commented 3 years ago

Thanks for reporting! I would say this is more of a bug that we should fix when scanning for toplevels. Let's move it to the main repo.

dos65 commented 3 years ago

The current toplevel parser in metals doesn't handle this case when a package object is defined using a set of mixins like in doobie - https://github.com/tpolecat/doobie/blob/master/modules/core/src/main/scala/doobie/package.scala#L14 . It only extracts symbols that are defined directly in package object.

That's why imprort doobie.Transactor doesn't appear in suggested imports.

We need to investigate how it might be solved. The obvious one might be extending the parser to handle extends and with and do some postprocessing by copying symbols from mixins into package. That should work for Scala2.

For Scala3 probably we can try to read Tasty because it is used in Scaladoc and as I heard it works correctly with this case.