Skip to content

Commit 1dc4c42

Browse files
committed
Add support for completions for extension definition
1 parent 97677cc commit 1dc4c42

File tree

4 files changed

+48
-5
lines changed

4 files changed

+48
-5
lines changed

compiler/src/dotty/tools/dotc/interactive/Completion.scala

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package dotty.tools.dotc.interactive
33
import scala.language.unsafeNulls
44

55
import dotty.tools.dotc.ast.untpd
6+
import dotty.tools.dotc.ast.NavigateAST
67
import dotty.tools.dotc.config.Printers.interactiv
78
import dotty.tools.dotc.core.Contexts._
89
import dotty.tools.dotc.core.Decorators._
@@ -129,16 +130,29 @@ object Completion {
129130
case _ => 0
130131
}
131132

133+
/**
134+
* Inspect `path` to deterimine whether enclosing tree is a result of tree extension.
135+
* If so, completion should use untyped path containing tree before extension to get proper results.
136+
*/
137+
def pathBeforeDesugaring(path: List[Tree], pos: SourcePosition)(using Context): List[Tree] =
138+
val hasUntypedTree = path.headOption.forall(NavigateAST.untypedPath(_, exactMatch = true).nonEmpty)
139+
if hasUntypedTree then
140+
path
141+
else
142+
NavigateAST.untypedPath(pos.span).collect:
143+
case tree: untpd.Tree => tree
144+
132145
private def computeCompletions(pos: SourcePosition, path: List[Tree])(using Context): (Int, List[Completion]) = {
133-
val mode = completionMode(path, pos)
134-
val rawPrefix = completionPrefix(path, pos)
146+
val path0 = pathBeforeDesugaring(path, pos)
147+
val mode = completionMode(path0, pos)
148+
val rawPrefix = completionPrefix(path0, pos)
135149

136150
val hasBackTick = rawPrefix.headOption.contains('`')
137151
val prefix = if hasBackTick then rawPrefix.drop(1) else rawPrefix
138152

139153
val completer = new Completer(mode, prefix, pos)
140154

141-
val completions = path match {
155+
val completions = path0 match {
142156
// Ignore synthetic select from `This` because in code it was `Ident`
143157
// See example in dotty.tools.languageserver.CompletionTest.syntheticThis
144158
case Select(qual @ This(_), _) :: _ if qual.span.isSynthetic => completer.scopeCompletions
@@ -153,7 +167,7 @@ object Completion {
153167
val backtickedCompletions =
154168
describedCompletions.map(completion => backtickCompletions(completion, hasBackTick))
155169

156-
val offset = completionOffset(path)
170+
val offset = completionOffset(path0)
157171

158172
interactiv.println(i"""completion with pos = $pos,
159173
| prefix = ${completer.prefix},

language-server/test/dotty/tools/languageserver/CompletionTest.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1528,4 +1528,13 @@ class CompletionTest {
15281528
)
15291529
)
15301530
}
1531+
1532+
@Test def desugaredErrorStatement: Unit =
1533+
code"""|trait Foo
1534+
|object T:
1535+
| extension (x: Fo$m1)
1536+
|"""
1537+
.completion(m1, Set(
1538+
("Foo",Class,"Foo")
1539+
))
15311540
}

presentation-compiler/src/main/dotty/tools/pc/completions/Completions.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ class Completions(
117117
end CursorPos
118118

119119
private lazy val cursorPos =
120-
calculateTypeInstanceAndNewPositions(path)
120+
calculateTypeInstanceAndNewPositions(Completion.pathBeforeDesugaring(path, pos))
121121

122122
private def calculateTypeInstanceAndNewPositions(
123123
path: List[Tree]

presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSuite.scala

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1252,3 +1252,23 @@ class CompletionSuite extends BaseCompletionSuite:
12521252
assertSingleItem = false,
12531253
)
12541254

1255+
@Test def `extension-definition-scope` =
1256+
check(
1257+
"""|object T:
1258+
| extension (x: ListBuffe@@)
1259+
|""".stripMargin,
1260+
"""|ListBuffer[T] - scala.collection.mutable
1261+
|ListBuffer - scala.collection.mutable
1262+
|""".stripMargin,
1263+
)
1264+
1265+
@Test def `extension-definition-symbol-search` =
1266+
check(
1267+
"""|trait Foo
1268+
|object T:
1269+
| extension (x: Fo@@)
1270+
|""".stripMargin,
1271+
"""|Foo test
1272+
|""".stripMargin
1273+
)
1274+

0 commit comments

Comments
 (0)