scalameta / metals

Scala language server with rich IDE features šŸš€
https://scalameta.org/metals/
Apache License 2.0
2.08k stars 330 forks source link

Completions get confused with multiple same-name classes on classpath #5256

Closed gnp closed 1 year ago

gnp commented 1 year ago

I had a project that had both sttp and http4s on the classpath. I had a file that imported sttp.model.Uri (but of course not the http4s class of the same name). Completion offered me a uri.withoutFragment option which was perfect for me, but when I used it -- it would not compile. I had trouble using F12 to go to the Uri class definition. Eventually I was able to get something to show and it was finding the http4s class. I removed http4s from classpath and things behaved better. But it seems metals + vscode can get confused when there are multiple classes on the classpath with the same short name. I burned some time working through this, and fortunately for me I was able to remove the (no longer needed) http4s from classpath. But it should not have been necessary, IMO.

import $ivy.`com.softwaremill.sttp.client3::core:3.8.15`
//import $ivy.`org.http4s::http4s-core:0.23.19-RC3` // Problem does not occur with this version
import $ivy.`org.http4s::http4s-core:0.23.9`

import sttp.model.Uri

val uri = Uri.parse("http://example.com/#foo").getOrElse(throw new IllegalStateException("Ugh"))

uri.withou// Metals / VSCode offers methods of hhtp4s' Uri class -- for example withoutFragment

Expected behaviour:

I expected completion proposals that are only from the sttp Uri class.

Operating system: Mac OS X

Java version: 17.0.6

Editor/extension: Visual Studio Code v1.78.2

Metals version: 0.11.12

Extra context or search terms:

Workspace information:

tgodzik commented 1 year ago

Thanks for reporting! @kasiaMarek do you think it might be related to the issue in worksheets that you were fixing?

gnp commented 1 year ago

Note: I showed the repro in worksheets

But, the issue originally happened to me in regular development.

Best,

ā€” Gregor

From: Tomasz Godzik @.> Date: Monday, May 22, 2023 at 10:11 AM To: scalameta/metals @.> Cc: Gregor Purdy @.>, Author @.> Subject: Re: [scalameta/metals] Completions get confused with multiple same-name classes on classpath (Issue #5256)

Thanks for reporting! @kasiaMarekhttps://github.com/kasiaMarek do you think it might be related to the issue in worksheets that you were fixing?

ā€” Reply to this email directly, view it on GitHubhttps://github.com/scalameta/metals/issues/5256#issuecomment-1557597212, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AAAPIFZY5OPQD5VEP5QIM6DXHOM4BANCNFSM6AAAAAAYKLUOGI. You are receiving this because you authored the thread.Message ID: @.***>

tgodzik commented 1 year ago

Note: I showed the repro in worksheets But, the issue originally happened to me in regular development.

Ach! Thanks for letting me know, I only briefly looked at the issue.

kasiaMarek commented 1 year ago

I played a bit with this trying to get into a bad state and I'm not really able to reproduce what you've experienced.

The fact that you could not go to a definition suggests that your project was not compiling correctly. In such cases "go to definition" uses a fallback and searches almost just by name, so results can be totally off. However, it'a a very odd behaviour for completions that you've reported.

In general if you run metals doctor you'll should see if everything is fine in your workspace. And if something breaks restarting metals server and/or switching the build server to sbt (bloop in known to break at times).

Maybe @tgodzik will have an idea of what could've gone wrong.

tgodzik commented 1 year ago

I can't reproduce it either, can you reproduce this in that worksheet @gnp ? @kasiaMarek is right, it's almost impossible to get a wrong completion, since they come from the compiler and are based on the symbol, not the name.

Is it possible that maybe you have an extension method somewhere and the bug was that it wasn't properly imported?

Or maybe it was a text only completion from VS Code?

tgodzik commented 1 year ago

Can you stll reproduce the issue? Maybe some screen recording would be possible to do?

gnp commented 1 year ago

Here is a screen recording of a new project with nothing in the folder except an empty build.sbt, a scalafmt config file and the worksheet:

https://github.com/scalameta/metals/assets/62487/4f15095e-d149-418b-bbcd-39b56b3317bf

kasiaMarek commented 1 year ago

This isn't a completion from metals but from VSCode. Whenever metals finds no completions, VSCode will try to suggest something. When doing this VSCode treats all you wrote as some text and looks in context for strings that match what you're trying to write, especially it will find withoutFragment since the word appears in the comment. You can always see the difference between metals vs VSCode completions:

  1. metals completions always have more information, like: args types, return type, package (if requires an import),
  2. each completion has a little icon that tells you what kind of completion it is, the ones provided by VSCode are text completions denoted by the abc icon.