/
AutoImportsProvider.scala
103 lines (89 loc) 路 3.02 KB
/
AutoImportsProvider.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package scala.meta.internal.pc
import java.nio.file.Paths
import scala.collection.mutable
import scala.jdk.CollectionConverters.*
import scala.meta.internal.metals.ReportContext
import scala.meta.internal.mtags.MtagsEnrichments.*
import scala.meta.internal.pc.AutoImports.*
import scala.meta.internal.pc.completions.CompletionPos
import scala.meta.pc.*
import dotty.tools.dotc.ast.tpd.*
import dotty.tools.dotc.core.Symbols.*
import dotty.tools.dotc.interactive.Interactive
import dotty.tools.dotc.interactive.InteractiveDriver
import dotty.tools.dotc.util.SourceFile
import org.eclipse.lsp4j as l
final class AutoImportsProvider(
search: SymbolSearch,
driver: InteractiveDriver,
name: String,
params: OffsetParams,
config: PresentationCompilerConfig,
buildTargetIdentifier: String,
)(using ReportContext):
def autoImports(isExtension: Boolean): List[AutoImportsResult] =
val uri = params.uri
val filePath = Paths.get(uri)
driver.run(
uri,
SourceFile.virtual(filePath.toString, params.text),
)
val unit = driver.currentCtx.run.units.head
val tree = unit.tpdTree
val pos = driver.sourcePosition(params)
val newctx = driver.currentCtx.fresh.setCompilationUnit(unit)
val path =
Interactive.pathTo(newctx.compilationUnit.tpdTree, pos.span)(using newctx)
val indexedContext = IndexedContext(
Interactive.contextOfPath(path)(using newctx)
)
import indexedContext.ctx
val isSeen = mutable.Set.empty[String]
val symbols = List.newBuilder[Symbol]
def visit(sym: Symbol): Boolean =
val name = sym.denot.fullName.show
if !isSeen(name) then
isSeen += name
symbols += sym
true
else false
def isExactMatch(sym: Symbol, query: String): Boolean =
sym.name.show == query
val visitor = new CompilerSearchVisitor(visit)
if isExtension then
search.searchMethods(name, buildTargetIdentifier, visitor)
else search.search(name, buildTargetIdentifier, visitor)
val results = symbols.result.filter(isExactMatch(_, name))
if results.nonEmpty then
val correctedPos = CompletionPos.infer(pos, params, path).sourcePos
val mkEdit =
path match
// if we are in import section just specify full name
case (_: Ident) :: (_: Import) :: _ =>
(sym: Symbol) =>
val nameEdit =
new l.TextEdit(correctedPos.toLsp, sym.fullNameBackticked)
Some(List(nameEdit))
case _ =>
val generator =
AutoImports.generator(
correctedPos,
params.text,
tree,
indexedContext.importContext,
config,
)
(sym: Symbol) => generator.forSymbol(sym)
end match
end mkEdit
for
sym <- results
edits <- mkEdit(sym)
yield AutoImportsResultImpl(
sym.owner.showFullName,
edits.asJava,
)
else List.empty
end if
end autoImports
end AutoImportsProvider