Skip to content

Commit 009fc63

Browse files
committed
Address review comments
1 parent 7205f20 commit 009fc63

File tree

6 files changed

+86
-64
lines changed

6 files changed

+86
-64
lines changed

Diff for: compiler/src/dotty/tools/dotc/ast/NavigateAST.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ object NavigateAST {
9898
def isBetterFit(currentBest: List[Positioned], candidate: List[Positioned]): Boolean =
9999
if currentBest.isEmpty && candidate.nonEmpty then true
100100
else if currentBest.nonEmpty && candidate.nonEmpty then
101-
val bestSpan= currentBest.head.span
101+
val bestSpan = currentBest.head.span
102102
val candidateSpan = candidate.head.span
103103

104104
bestSpan != candidateSpan &&

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ final class AutoImportsProvider(
6666
val results = symbols.result.filter(isExactMatch(_, name))
6767

6868
if results.nonEmpty then
69-
val correctedPos = CompletionPos.infer(pos, params, path, false).toSourcePosition
69+
val correctedPos =
70+
CompletionPos.infer(pos, params, path, wasCursorApplied = false).toSourcePosition
7071
val mkEdit =
7172
path match
7273
// if we are in import section just specify full name

Diff for: presentation-compiler/src/main/dotty/tools/pc/completions/CompletionProvider.scala

+21-7
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ import org.eclipse.lsp4j.Range as LspRange
3838
import org.eclipse.lsp4j.TextEdit
3939
import scala.meta.pc.CompletionItemPriority
4040

41+
object CompletionProvider:
42+
val allKeywords =
43+
val softKeywords = Tokens.softModifierNames + nme.as + nme.derives + nme.extension + nme.throws + nme.using
44+
Tokens.keywords.toList.map(Tokens.tokenString) ++ softKeywords.map(_.toString)
45+
4146
class CompletionProvider(
4247
search: SymbolSearch,
4348
cachingDriver: InteractiveDriver,
@@ -76,7 +81,20 @@ class CompletionProvider(
7681

7782
val tpdPath = tpdPath0 match
7883
case Select(qual, name) :: tail
79-
// If for any reason we end up in param after lifting, we want to inline the synthetic val
84+
/** If for any reason we end up in param after lifting, we want to inline the synthetic val:
85+
* List(1).iterator.sliding@@ will be transformed into:
86+
*
87+
* 1| val $1$: Iterator[Int] = List.apply[Int]([1 : Int]*).iterator
88+
* 2| {
89+
* 3| def $anonfun(size: Int, step: Int): $1$.GroupedIterator[Int] =
90+
* 4| $1$.sliding[Int](size, step)
91+
* 5| closure($anonfun)
92+
* 6| }:((Int, Int) => Iterator[Int]#GroupedIterator[Int])
93+
*
94+
* With completion being run at line 4 at @@:
95+
* 4| $1$.sliding@@[Int](size, step)
96+
*
97+
*/
8098
if qual.symbol.is(Flags.Synthetic) && qual.symbol.name.isInstanceOf[DerivedName] =>
8199
qual.symbol.defTree match
82100
case valdef: ValDef => Select(valdef.rhs, name) :: tail
@@ -138,10 +156,6 @@ class CompletionProvider(
138156
)
139157
end completions
140158

141-
val allKeywords =
142-
val softKeywords = Tokens.softModifierNames + nme.as + nme.derives + nme.extension + nme.throws + nme.using
143-
Tokens.keywords.toList.map(Tokens.tokenString) ++ softKeywords.map(_.toString)
144-
145159
/**
146160
* In case if completion comes from empty line like:
147161
* {{{
@@ -159,8 +173,8 @@ class CompletionProvider(
159173
val offset = params.offset().nn
160174
val query = Completion.naiveCompletionPrefix(text, offset)
161175

162-
if offset > 0 && text.charAt(offset - 1).isUnicodeIdentifierPart && !allKeywords.contains(query) then
163-
false -> text
176+
if offset > 0 && text.charAt(offset - 1).isUnicodeIdentifierPart
177+
&& !CompletionProvider.allKeywords.contains(query) then false -> text
164178
else
165179
val isStartMultilineComment =
166180

Diff for: presentation-compiler/src/main/dotty/tools/pc/completions/NamedArgCompletions.scala

+4-3
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ object NamedArgCompletions:
170170
.zipWithIndex
171171
.forall { case (pair, index) =>
172172
FuzzyArgMatcher(m.tparams)
173-
.doMatch(allArgsProvided = index != 0)
173+
.doMatch(allArgsProvided = index != 0, ident)
174174
.tupled(pair)
175175
} =>
176176
m
@@ -385,12 +385,13 @@ class FuzzyArgMatcher(tparams: List[Symbols.Symbol])(using Context):
385385
* We check the args types not the result type.
386386
*/
387387
def doMatch(
388-
allArgsProvided: Boolean
388+
allArgsProvided: Boolean,
389+
ident: Option[Ident]
389390
)(expectedArgs: List[Symbols.Symbol], actualArgs: List[Tree]) =
390391
(expectedArgs.length == actualArgs.length ||
391392
(!allArgsProvided && expectedArgs.length >= actualArgs.length)) &&
392393
actualArgs.zipWithIndex.forall {
393-
case (Ident(name), _) => true
394+
case (arg: Ident, _) if ident.contains(arg) => true
394395
case (NamedArg(name, arg), _) =>
395396
expectedArgs.exists { expected =>
396397
expected.name == name && (!arg.hasType || arg.typeOpt.unfold

Diff for: presentation-compiler/src/main/dotty/tools/pc/completions/OverrideCompletions.scala

+21-12
Original file line numberDiff line numberDiff line change
@@ -530,8 +530,11 @@ object OverrideCompletions:
530530
object OverrideExtractor:
531531
def unapply(path: List[Tree])(using Context) =
532532
path match
533-
// class FooImpl extends Foo:
534-
// def x|
533+
// abstract class Val:
534+
// def hello: Int = 2
535+
//
536+
// class Main extends Val:
537+
// def h|
535538
case (dd: (DefDef | ValDef)) :: (t: Template) :: (td: TypeDef) :: _
536539
if t.parents.nonEmpty =>
537540
val completing =
@@ -547,12 +550,13 @@ object OverrideCompletions:
547550
)
548551
)
549552

550-
// class FooImpl extends Foo:
553+
// abstract class Val:
554+
// def hello: Int = 2
555+
//
556+
// class Main extends Val:
551557
// ov|
552558
case (ident: Ident) :: (t: Template) :: (td: TypeDef) :: _
553-
if t.parents.nonEmpty && "override".startsWith(
554-
ident.name.show.replace(Cursor.value, "")
555-
) =>
559+
if t.parents.nonEmpty && "override".startsWith(ident.name.show.replace(Cursor.value, "")) =>
556560
Some(
557561
(
558562
td,
@@ -563,15 +567,13 @@ object OverrideCompletions:
563567
)
564568
)
565569

570+
// abstract class Val:
571+
// def hello: Int = 2
572+
//
566573
// class Main extends Val:
567574
// def@@
568575
case (id: Ident) :: (t: Template) :: (td: TypeDef) :: _
569-
if t.parents.nonEmpty && "def".startsWith(
570-
id.name.decoded.replace(
571-
Cursor.value,
572-
"",
573-
)
574-
) =>
576+
if t.parents.nonEmpty && "def".startsWith(id.name.decoded.replace(Cursor.value, "")) =>
575577
Some(
576578
(
577579
td,
@@ -581,6 +583,10 @@ object OverrideCompletions:
581583
None,
582584
)
583585
)
586+
587+
// abstract class Val:
588+
// def hello: Int = 2
589+
//
584590
// class Main extends Val:
585591
// he@@
586592
case (id: Ident) :: (t: Template) :: (td: TypeDef) :: _
@@ -595,6 +601,9 @@ object OverrideCompletions:
595601
)
596602
)
597603

604+
// abstract class Val:
605+
// def hello: Int = 2
606+
//
598607
// class Main extends Val:
599608
// hello@ // this transforms into this.hello, thus is a Select
600609
case (sel @ Select(th: This, name)) :: (t: Template) :: (td: TypeDef) :: _

Diff for: presentation-compiler/test/dotty/tools/pc/tests/CompilerCachingSuite.scala

+37-40
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,19 @@ class CompilerCachingSuite extends BasePCSuite:
2323

2424
val timeout = 5.seconds
2525

26-
private def checkCompilationCount(params: VirtualFileParams, expected: Int): Unit =
26+
private def checkCompilationCount(expected: Int): Unit =
2727
presentationCompiler match
2828
case pc: ScalaPresentationCompiler =>
29-
val compilations= pc.compilerAccess.withNonInterruptableCompiler(Some(params))(-1, EmptyCancelToken) { driver =>
29+
val compilations = pc.compilerAccess.withNonInterruptableCompiler(None)(-1, EmptyCancelToken) { driver =>
3030
driver.compiler().currentCtx.runId
3131
}.get(timeout.length, timeout.unit)
3232
assertEquals(expected, compilations, s"Expected $expected compilations but got $compilations")
3333
case _ => throw IllegalStateException("Presentation compiler should always be of type of ScalaPresentationCompiler")
3434

35-
private def getContext(params: VirtualFileParams): Context =
35+
private def getContext(): Context =
3636
presentationCompiler match
3737
case pc: ScalaPresentationCompiler =>
38-
pc.compilerAccess.withNonInterruptableCompiler(Some(params))(null, EmptyCancelToken) { driver =>
38+
pc.compilerAccess.withNonInterruptableCompiler(None)(null, EmptyCancelToken) { driver =>
3939
driver.compiler().currentCtx
4040
}.get(timeout.length, timeout.unit)
4141
case _ => throw IllegalStateException("Presentation compiler should always be of type of ScalaPresentationCompiler")
@@ -44,76 +44,73 @@ class CompilerCachingSuite extends BasePCSuite:
4444
def beforeEach: Unit =
4545
presentationCompiler.restart()
4646

47-
// We want to run art least one compilation, so runId points at 3.
47+
// We want to run at least one compilation, so runId points at 3.
4848
// This will ensure that we use the same driver, not recreate fresh one on each call
4949
val dryRunParams = CompilerOffsetParams(Paths.get("Test.scala").toUri(), "dryRun", 1, EmptyCancelToken)
50-
checkCompilationCount(dryRunParams, 2)
51-
val freshContext = getContext(dryRunParams)
50+
checkCompilationCount(2)
51+
val freshContext = getContext()
5252
presentationCompiler.complete(dryRunParams).get(timeout.length, timeout.unit)
53-
checkCompilationCount(dryRunParams, 3)
54-
val dryRunContext = getContext(dryRunParams)
53+
checkCompilationCount(3)
54+
val dryRunContext = getContext()
5555
assert(freshContext != dryRunContext)
5656

5757

5858
@Test
5959
def `cursor-compilation-does-not-corrupt-cache`: Unit =
60+
val contextPreCompilation = getContext()
6061

61-
val fakeParamsCursor = CompilerOffsetParams(Paths.get("Test.scala").toUri(), "def hello = new", 15, EmptyCancelToken)
6262
val fakeParams = CompilerOffsetParams(Paths.get("Test.scala").toUri(), "def hello = ne", 14, EmptyCancelToken)
63-
64-
val contextPreCompilation = getContext(fakeParams)
65-
6663
presentationCompiler.complete(fakeParams).get(timeout.length, timeout.unit)
67-
val contextPostFirst = getContext(fakeParams)
64+
val contextPostFirst = getContext()
6865
assert(contextPreCompilation != contextPostFirst)
69-
checkCompilationCount(fakeParams, 4)
66+
checkCompilationCount(4)
7067

68+
val fakeParamsCursor = CompilerOffsetParams(Paths.get("Test.scala").toUri(), "def hello = new", 15, EmptyCancelToken)
7169
presentationCompiler.complete(fakeParamsCursor).get(timeout.length, timeout.unit)
72-
val contextPostCursor = getContext(fakeParamsCursor)
70+
val contextPostCursor = getContext()
7371
assert(contextPreCompilation != contextPostCursor)
7472
assert(contextPostFirst == contextPostCursor)
75-
checkCompilationCount(fakeParamsCursor, 4)
73+
checkCompilationCount(4)
7674

7775
presentationCompiler.complete(fakeParams).get(timeout.length, timeout.unit)
78-
val contextPostSecond = getContext(fakeParams)
76+
val contextPostSecond = getContext()
7977
assert(contextPreCompilation != contextPostSecond)
8078
assert(contextPostFirst == contextPostCursor)
8179
assert(contextPostCursor == contextPostSecond)
82-
checkCompilationCount(fakeParamsCursor, 4)
80+
checkCompilationCount(4)
8381

8482
@Test
8583
def `compilation-for-same-snippet-is-cached`: Unit =
86-
val fakeParams = CompilerOffsetParams(Paths.get("Test.scala").toUri(), "def hello = ne", 14, EmptyCancelToken)
87-
88-
val contextPreCompilation = getContext(fakeParams)
84+
val contextPreCompilation = getContext()
8985

86+
val fakeParams = CompilerOffsetParams(Paths.get("Test.scala").toUri(), "def hello = ne", 14, EmptyCancelToken)
9087
presentationCompiler.complete(fakeParams).get(timeout.length, timeout.unit)
91-
val contextPostFirst = getContext(fakeParams)
88+
val contextPostFirst = getContext()
9289
assert(contextPreCompilation != contextPostFirst)
93-
checkCompilationCount(fakeParams, 4)
90+
checkCompilationCount(4)
9491

9592
presentationCompiler.complete(fakeParams).get(timeout.length, timeout.unit)
96-
val contextPostSecond = getContext(fakeParams)
93+
val contextPostSecond = getContext()
9794
assert(contextPreCompilation != contextPostFirst)
9895
assert(contextPostSecond == contextPostFirst)
99-
checkCompilationCount(fakeParams, 4)
96+
checkCompilationCount(4)
10097

10198
@Test
10299
def `compilation-for-different-snippet-is-not-cached`: Unit =
103100

104-
val fakeParams = CompilerOffsetParams(Paths.get("Test.scala").toUri(), "def hello = prin", 16, EmptyCancelToken)
105-
val fakeParams2 = CompilerOffsetParams(Paths.get("Test2.scala").toUri(), "def hello = prin", 16, EmptyCancelToken)
106-
val fakeParams3 = CompilerOffsetParams(Paths.get("Test2.scala").toUri(), "def hello = print", 17, EmptyCancelToken)
107101

108-
checkCompilationCount(fakeParams, 3)
102+
checkCompilationCount(3)
103+
val fakeParams = CompilerOffsetParams(Paths.get("Test.scala").toUri(), "def hello = prin", 16, EmptyCancelToken)
109104
presentationCompiler.complete(fakeParams).get(timeout.length, timeout.unit)
110-
checkCompilationCount(fakeParams, 4)
105+
checkCompilationCount(4)
111106

107+
val fakeParams2 = CompilerOffsetParams(Paths.get("Test2.scala").toUri(), "def hello = prin", 16, EmptyCancelToken)
112108
presentationCompiler.complete(fakeParams2).get(timeout.length, timeout.unit)
113-
checkCompilationCount(fakeParams2, 5)
109+
checkCompilationCount(5)
114110

111+
val fakeParams3 = CompilerOffsetParams(Paths.get("Test2.scala").toUri(), "def hello = print", 17, EmptyCancelToken)
115112
presentationCompiler.complete(fakeParams3).get(timeout.length, timeout.unit)
116-
checkCompilationCount(fakeParams3, 6)
113+
checkCompilationCount(6)
117114

118115

119116
private val testFunctions: List[OffsetParams => CompletableFuture[_]] = List(
@@ -137,14 +134,14 @@ class CompilerCachingSuite extends BasePCSuite:
137134
@Test
138135
def `different-api-calls-reuse-cache`: Unit =
139136
val fakeParams = CompilerOffsetParams(Paths.get("Test.scala").toUri(), "def hello = ne", 13, EmptyCancelToken)
140-
141137
presentationCompiler.complete(fakeParams).get(timeout.length, timeout.unit)
142-
val contextBefore = getContext(fakeParams)
138+
139+
val contextBefore = getContext()
143140

144141
val differentContexts = testFunctions.map: f =>
145142
f(fakeParams).get(timeout.length, timeout.unit)
146-
checkCompilationCount(fakeParams, 4)
147-
getContext(fakeParams)
143+
checkCompilationCount(4)
144+
getContext()
148145
.toSet
149146

150147
assert(differentContexts == Set(contextBefore))
@@ -155,12 +152,12 @@ class CompilerCachingSuite extends BasePCSuite:
155152
import scala.concurrent.ExecutionContext.Implicits.global
156153

157154
val fakeParams = CompilerOffsetParams(Paths.get("Test.scala").toUri(), "def hello = ne", 13, EmptyCancelToken)
158-
159155
presentationCompiler.complete(fakeParams).get(timeout.length, timeout.unit)
160-
val contextBefore = getContext(fakeParams)
156+
157+
val contextBefore = getContext()
161158

162159
val futures = testFunctions.map: f =>
163-
f(fakeParams).asScala.map(_ => getContext(fakeParams))
160+
f(fakeParams).asScala.map(_ => getContext())
164161

165162
val res = Await.result(Future.sequence(futures), timeout).toSet
166163
assert(res == Set(contextBefore))

0 commit comments

Comments
 (0)