@@ -25,6 +25,7 @@ import reporting._, reporting.diagnostic.MessageContainer
25
25
import util ._
26
26
import interactive ._ , interactive .InteractiveDriver ._
27
27
import Interactive .Include
28
+ import config .Printers .interactiv
28
29
29
30
import languageserver .config .ProjectConfig
30
31
@@ -78,12 +79,29 @@ class DottyLanguageServer extends LanguageServer
78
79
.update(" -classpath" , (config.classDirectory +: config.dependencyClasspath).mkString(File .pathSeparator))
79
80
.update(" -sourcepath" , config.sourceDirectories.mkString(File .pathSeparator)) :+
80
81
" -scansource"
81
- myDrivers.put (config, new InteractiveDriver (settings) )
82
+ myDrivers(config) = new InteractiveDriver (settings)
82
83
}
83
84
}
84
85
myDrivers
85
86
}
86
87
88
+ /** Restart all presentation compiler drivers, copying open files over */
89
+ private def restart () = thisServer.synchronized {
90
+ interactiv.println(" restarting presentation compiler" )
91
+ val driverConfigs = for ((config, driver) <- myDrivers.toList) yield
92
+ (config, new InteractiveDriver (driver.settings), driver.openedFiles)
93
+ for ((config, driver, _) <- driverConfigs)
94
+ myDrivers(config) = driver
95
+ System .gc()
96
+ for ((_, driver, opened) <- driverConfigs; (uri, source) <- opened)
97
+ driver.run(uri, source)
98
+ if (Memory .isCritical())
99
+ println(s " WARNING: Insufficient memory to run Scala language server on these projects. " )
100
+ }
101
+
102
+ private def checkMemory () =
103
+ if (Memory .isCritical()) CompletableFutures .computeAsync { _ => restart() }
104
+
87
105
/** The driver instance responsible for compiling `uri` */
88
106
def driverFor (uri : URI ): InteractiveDriver = {
89
107
val matchingConfig =
@@ -112,10 +130,11 @@ class DottyLanguageServer extends LanguageServer
112
130
}
113
131
114
132
private [this ] def computeAsync [R ](fun : CancelChecker => R ): CompletableFuture [R ] =
115
- CompletableFutures .computeAsync({( cancelToken : CancelChecker ) =>
133
+ CompletableFutures .computeAsync { cancelToken =>
116
134
// We do not support any concurrent use of the compiler currently.
117
135
thisServer.synchronized {
118
136
cancelToken.checkCanceled()
137
+ checkMemory()
119
138
try {
120
139
fun(cancelToken)
121
140
} catch {
@@ -124,7 +143,7 @@ class DottyLanguageServer extends LanguageServer
124
143
throw ex
125
144
}
126
145
}
127
- })
146
+ }
128
147
129
148
override def initialize (params : InitializeParams ) = computeAsync { cancelToken =>
130
149
rootUri = params.getRootUri
@@ -160,6 +179,7 @@ class DottyLanguageServer extends LanguageServer
160
179
}
161
180
162
181
override def didOpen (params : DidOpenTextDocumentParams ): Unit = thisServer.synchronized {
182
+ checkMemory()
163
183
val document = params.getTextDocument
164
184
val uri = new URI (document.getUri)
165
185
val driver = driverFor(uri)
@@ -173,6 +193,7 @@ class DottyLanguageServer extends LanguageServer
173
193
}
174
194
175
195
override def didChange (params : DidChangeTextDocumentParams ): Unit = thisServer.synchronized {
196
+ checkMemory()
176
197
val document = params.getTextDocument
177
198
val uri = new URI (document.getUri)
178
199
val driver = driverFor(uri)
0 commit comments