Skip to content

Commit 48a7c64

Browse files
authored
feature: Skip auto importing symbols we know are wrong in current context (#22813)
Same as https://github.com/scalameta/metals/pull/7272/files
2 parents 28072c5 + 9f22805 commit 48a7c64

File tree

2 files changed

+90
-3
lines changed

2 files changed

+90
-3
lines changed

presentation-compiler/src/main/dotty/tools/pc/AutoImportsProvider.scala

+27-3
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@ import scala.meta.pc.*
1010

1111
import dotty.tools.dotc.ast.tpd.*
1212
import dotty.tools.dotc.core.Symbols.*
13+
import dotty.tools.dotc.core.StdNames.*
1314
import dotty.tools.dotc.interactive.Interactive
1415
import dotty.tools.dotc.interactive.InteractiveDriver
1516
import dotty.tools.dotc.util.SourceFile
1617
import dotty.tools.pc.completions.CompletionPos
1718
import dotty.tools.pc.utils.InteractiveEnrichments.*
1819

1920
import org.eclipse.lsp4j as l
21+
import dotty.tools.dotc.core.Flags.Method
2022

2123
final class AutoImportsProvider(
2224
search: SymbolSearch,
@@ -47,6 +49,17 @@ final class AutoImportsProvider(
4749
)
4850
import indexedContext.ctx
4951

52+
53+
def correctInTreeContext(sym: Symbol) = path match
54+
case (_: Ident) :: (sel: Select) :: _ =>
55+
sym.info.allMembers.exists(_.name == sel.name)
56+
case (_: Ident) :: (_: Apply) :: _ if !sym.is(Method) =>
57+
def applyInObject =
58+
sym.companionModule.info.allMembers.exists(_.name == nme.apply)
59+
def applyInClass = sym.info.allMembers.exists(_.name == nme.apply)
60+
applyInClass || applyInObject
61+
case _ => true
62+
5063
val isSeen = mutable.Set.empty[String]
5164
val symbols = List.newBuilder[Symbol]
5265
def visit(sym: Symbol): Boolean =
@@ -90,13 +103,24 @@ final class AutoImportsProvider(
90103
end match
91104
end mkEdit
92105

93-
for
106+
val all = for
94107
sym <- results
95108
edits <- mkEdit(sym)
96-
yield AutoImportsResultImpl(
109+
yield (AutoImportsResultImpl(
97110
sym.owner.showFullName,
98111
edits.asJava
99-
)
112+
), sym)
113+
114+
all match
115+
case (onlyResult, _) :: Nil => List(onlyResult)
116+
case Nil => Nil
117+
case moreResults =>
118+
val moreExact = moreResults.filter { case (_, sym) =>
119+
correctInTreeContext(sym)
120+
}
121+
if moreExact.nonEmpty then moreExact.map(_._1)
122+
else moreResults.map(_._1)
123+
100124
else List.empty
101125
end if
102126
end autoImports

presentation-compiler/test/dotty/tools/pc/tests/edit/AutoImportsSuite.scala

+63
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,69 @@ class AutoImportsSuite extends BaseAutoImportsSuite:
1212
| <<Future>>.successful(2)
1313
|}
1414
|""".stripMargin,
15+
"""|scala.concurrent
16+
|""".stripMargin
17+
)
18+
19+
@Test def `basic-apply` =
20+
check(
21+
"""|object A {
22+
| <<Future>>(2)
23+
|}
24+
|""".stripMargin,
25+
"""|scala.concurrent
26+
|""".stripMargin,
27+
)
28+
29+
@Test def `basic-function-apply` =
30+
check(
31+
"""|
32+
|object ForgeFor{
33+
| def importMe(): Int = ???
34+
|}
35+
|object ForgeFor2{
36+
| case class importMe()
37+
|}
38+
|
39+
|
40+
|object test2 {
41+
| <<importMe>>()
42+
|}
43+
|""".stripMargin,
44+
"""|ForgeFor2
45+
|ForgeFor
46+
|""".stripMargin
47+
)
48+
49+
@Test def `basic-apply-wrong` =
50+
check(
51+
"""|object A {
52+
| new <<Future>>(2)
53+
|}
54+
|""".stripMargin,
55+
"""|scala.concurrent
56+
|java.util.concurrent
57+
|""".stripMargin
58+
)
59+
60+
@Test def `basic-fuzzy` =
61+
check(
62+
"""|object A {
63+
| <<Future>>.thisMethodDoesntExist(2)
64+
|}
65+
|""".stripMargin,
66+
"""|scala.concurrent
67+
|java.util.concurrent
68+
|""".stripMargin
69+
)
70+
71+
@Test def `typed-simple` =
72+
check(
73+
"""|object A {
74+
| import scala.concurrent.Promise
75+
| val fut: <<Future>> = Promise[Unit]().future
76+
|}
77+
|""".stripMargin,
1578
"""|scala.concurrent
1679
|java.util.concurrent
1780
|""".stripMargin

0 commit comments

Comments
 (0)