@@ -16,6 +16,7 @@ import dotty.tools.dotc.core.Contexts.Context
16
16
import dotty .tools .dotc .core .Phases
17
17
import dotty .tools .dotc .core .StdNames .nme
18
18
import dotty .tools .dotc .core .Flags
19
+ import dotty .tools .dotc .core .Names .DerivedName
19
20
import dotty .tools .dotc .interactive .Interactive
20
21
import dotty .tools .dotc .interactive .Completion
21
22
import dotty .tools .dotc .interactive .InteractiveDriver
@@ -39,7 +40,8 @@ import scala.meta.pc.CompletionItemPriority
39
40
40
41
class CompletionProvider (
41
42
search : SymbolSearch ,
42
- driver : InteractiveDriver ,
43
+ cachingDriver : InteractiveDriver ,
44
+ freshDriver : () => InteractiveDriver ,
43
45
params : OffsetParams ,
44
46
config : PresentationCompilerConfig ,
45
47
buildTargetIdentifier : String ,
@@ -52,6 +54,16 @@ class CompletionProvider(
52
54
53
55
val (wasCursorApplied, code) = applyCompletionCursor(params)
54
56
val sourceFile = SourceFile .virtual(uri, code)
57
+
58
+ /** Creating a new fresh driver is way slower than reusing existing one,
59
+ * but runnig a compilation has side effects that modifies the state of the driver.
60
+ * We don't want to affect cachingDriver state with compilation including "CURSOR" suffix.
61
+ *
62
+ * We could in theory save this fresh driver for reuse, but it is a choice between extra memory usage and speed.
63
+ * The scenario in which "CURSOR" is applied (empty query or query equal to any keyword) has a slim chance of happening.
64
+ */
65
+
66
+ val driver = if wasCursorApplied then freshDriver() else cachingDriver
55
67
driver.run(uri, sourceFile)
56
68
57
69
given ctx : Context = driver.currentCtx
@@ -63,11 +75,12 @@ class CompletionProvider(
63
75
val adjustedPath = Interactive .resolveTypedOrUntypedPath(tpdPath0, pos)(using newctx)
64
76
65
77
val tpdPath = tpdPath0 match
66
- // $1$ // FIXME add check for a $1$ name to make sure we only do the below in lifting case
67
- case Select (qual, name) :: tail if qual.symbol.is(Flags .Synthetic ) =>
68
- qual.symbol.defTree match
69
- case valdef : ValDef => Select (valdef.rhs, name) :: tail
70
- case _ => tpdPath0
78
+ case Select (qual, name) :: tail
79
+ // If for any reason we end up in param after lifting, we want to inline the synthetic val
80
+ if qual.symbol.is(Flags .Synthetic ) && qual.symbol.name.isInstanceOf [DerivedName ] =>
81
+ qual.symbol.defTree match
82
+ case valdef : ValDef => Select (valdef.rhs, name) :: tail
83
+ case _ => tpdPath0
71
84
case _ => tpdPath0
72
85
73
86
0 commit comments