Skip to content

Commit

Permalink
fix: add special case for autoimport inside Import tree (scalameta#4555)
Browse files Browse the repository at this point in the history
fix: add special case for autoimport inside `Import` tree

Previously, the behaviour for auto-import action wasn't specified for
`import <<$SYMBOL>>` case.
Now in imports the required symbol using specifying full name in case if it's missing in scope as we do that in completions
  • Loading branch information
dos65 authored Oct 24, 2022
1 parent 06fd2ff commit adadc11
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import scala.meta.internal.jdk.CollectionConverters._
import scala.meta.pc.AutoImportsResult
import scala.meta.pc.OffsetParams

import org.eclipse.lsp4j.TextEdit
import org.eclipse.{lsp4j => l}

final class AutoImportsProvider(
val compiler: MetalsGlobal,
Expand Down Expand Up @@ -44,13 +44,28 @@ final class AutoImportsProvider(

search.search(name, buildTargetIdentifier, visitor)

def isInImportTree: Boolean = lastVisitedParentTrees match {
case (_: Import) :: _ => true
case _ => false
}

def namePos: l.Range =
pos
.withStart(pos.start - name.length())
.withEnd(pos.end)
.toLsp

def isExactMatch(sym: Symbol, name: String): Boolean =
sym.name.dropLocal.decoded == name

symbols.result().collect {
case sym if isExactMatch(sym, name) =>
val pkg = sym.owner.fullName
val edits = importPosition match {
// if we are in import section just specify full name
case None if isInImportTree =>
val nameEdit = new l.TextEdit(namePos, sym.fullNameSyntax)
List(nameEdit)
case None =>
// No import position means we can't insert an import without clashing with
// existing symbols in scope, so we just do nothing
Expand All @@ -62,12 +77,7 @@ final class AutoImportsProvider(
context,
value
)
val namePos =
pos
.withStart(pos.start - name.length())
.withEnd(pos.end)
.toLsp
val nameEdit = new TextEdit(namePos, short)
val nameEdit = new l.TextEdit(namePos, short)
nameEdit :: edits
}
AutoImportsResultImpl(pkg, edits.asJava)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,18 +74,30 @@ final class AutoImportsProvider(

if results.nonEmpty then
val correctedPos = CompletionPos.infer(pos, params, path).sourcePos
val generator =
AutoImports.generator(
correctedPos,
params.text,
tree,
indexedContext.importContext,
config,
)
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 <- generator.forSymbol(sym)
edits <- mkEdit(sym)
yield AutoImportsResultImpl(
sym.owner.showFullName,
edits.asJava,
Expand Down
16 changes: 16 additions & 0 deletions tests/cross/src/test/scala/tests/pc/AutoImportsSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,22 @@ class AutoImportsSuite extends BaseAutoImportsSuite {
|""".stripMargin,
)

checkEdit(
"import-in-import",
"""|package inimport
|
|object A {
| import <<ExecutionContext>>.global
|}
|""".stripMargin,
"""|package inimport
|
|object A {
| import scala.concurrent.ExecutionContext.global
|}
|""".stripMargin,
)

checkAmmoniteEdit(
"first-auto-import-amm-script",
ammoniteWrapper(
Expand Down

0 comments on commit adadc11

Please sign in to comment.