@@ -8,7 +8,6 @@ import java.util.concurrent.atomic.AtomicInteger
8
8
import java .nio .file .{FileSystems , Files , Path }
9
9
import java .util .concurrent .ConcurrentHashMap
10
10
import java .util .stream .Collectors
11
-
12
11
import bloop .io .Environment .lineSeparator
13
12
import bloop .io .ServerHandle
14
13
import bloop .util .JavaRuntime
@@ -33,16 +32,15 @@ import ch.epfl.scala.bsp.{
33
32
JvmEnvironmentItem ,
34
33
MessageType ,
35
34
ShowMessageParams ,
35
+ Uri ,
36
36
endpoints
37
37
}
38
-
39
38
import scala .meta .jsonrpc .{JsonRpcClient , Response => JsonRpcResponse , Services => JsonRpcServices }
40
39
import monix .eval .Task
41
40
import monix .reactive .Observer
42
41
import monix .execution .Scheduler
43
42
import monix .execution .atomic .AtomicInt
44
43
import monix .execution .atomic .AtomicBoolean
45
-
46
44
import scala .collection .concurrent .TrieMap
47
45
import scala .collection .mutable
48
46
import scala .collection .JavaConverters ._
@@ -108,6 +106,7 @@ final class BloopBspServices(
108
106
.requestAsync(endpoints.BuildTarget .sources)(p => schedule(sources(p)))
109
107
.requestAsync(endpoints.BuildTarget .resources)(p => schedule(resources(p)))
110
108
.requestAsync(endpoints.BuildTarget .scalacOptions)(p => schedule(scalacOptions(p)))
109
+ .requestAsync(endpoints.BuildTarget .javacOptions)(p => schedule(javacOptions(p)))
111
110
.requestAsync(endpoints.BuildTarget .compile)(p => schedule(compile(p)))
112
111
.requestAsync(endpoints.BuildTarget .test)(p => schedule(test(p)))
113
112
.requestAsync(endpoints.BuildTarget .run)(p => schedule(run(p)))
@@ -1118,32 +1117,39 @@ final class BloopBspServices(
1118
1117
}
1119
1118
}
1120
1119
1120
+ private def getClasspath (state : State , project : Project ): List [Uri ] = {
1121
+ val uris = mutable.Map .empty[Path , bsp.Uri ]
1122
+ val dag = state.build.getDagFor(project)
1123
+ val fullClasspath = project.fullClasspath(dag, state.client)
1124
+ val classpath =
1125
+ fullClasspath.map(e => uris.getOrElseUpdate(e.underlying, bsp.Uri (e.toBspUri))).toList
1126
+ classpath
1127
+ }
1128
+
1129
+ private def getClassesDir (state : State , project : Project ): bsp.Uri = {
1130
+ bsp.Uri (state.client.getUniqueClassesDirFor(project, forceGeneration = true ).toBspUri)
1131
+ }
1132
+
1121
1133
def scalacOptions (
1122
1134
request : bsp.ScalacOptionsParams
1123
1135
): BspEndpointResponse [bsp.ScalacOptionsResult ] = {
1124
1136
def scalacOptions (
1125
1137
projects : Seq [ProjectMapping ],
1126
1138
state : State
1127
1139
): BspResult [bsp.ScalacOptionsResult ] = {
1128
- val uris = mutable.Map .empty[Path , bsp.Uri ]
1129
1140
val response = bsp.ScalacOptionsResult (
1130
1141
projects.iterator.map {
1131
1142
case (target, project) =>
1132
- val dag = state.build.getDagFor(project)
1133
- val fullClasspath = project.fullClasspath(dag, state.client)
1134
- val classpath =
1135
- fullClasspath.map(e => uris.getOrElseUpdate(e.underlying, bsp.Uri (e.toBspUri))).toList
1136
- val classesDir =
1137
- state.client.getUniqueClassesDirFor(project, forceGeneration = true ).toBspUri
1143
+ val classpath = getClasspath(state, project)
1144
+ val classesDir = getClassesDir(state, project)
1138
1145
bsp.ScalacOptionsItem (
1139
1146
target = target,
1140
1147
options = project.scalacOptions.toList,
1141
1148
classpath = classpath,
1142
- classDirectory = bsp. Uri ( classesDir)
1149
+ classDirectory = classesDir
1143
1150
)
1144
1151
}.toList
1145
1152
)
1146
-
1147
1153
Task .now((state, Right (response)))
1148
1154
}
1149
1155
@@ -1152,13 +1158,46 @@ final class BloopBspServices(
1152
1158
case Left (error) =>
1153
1159
// Log the mapping error to the user via a log event + an error status code
1154
1160
logger.error(error)
1155
- // TODO(jvican): Add status code to scalac options result
1156
1161
Task .now((state, Right (bsp.ScalacOptionsResult (Nil ))))
1157
1162
case Right (mappings) => scalacOptions(mappings, state)
1158
1163
}
1159
1164
}
1160
1165
}
1161
1166
1167
+ def javacOptions (
1168
+ request : bsp.JavacOptionsParams
1169
+ ): BspEndpointResponse [bsp.JavacOptionsResult ] = {
1170
+ def javacOptions (
1171
+ projects : Seq [ProjectMapping ],
1172
+ state : State
1173
+ ): BspResult [bsp.JavacOptionsResult ] = {
1174
+ val response = bsp.JavacOptionsResult (
1175
+ projects.iterator.map {
1176
+ case (target, project) =>
1177
+ val classpath = getClasspath(state, project)
1178
+ val classesDir = getClassesDir(state, project)
1179
+ bsp.JavacOptionsItem (
1180
+ target = target,
1181
+ options = project.javacOptions.toList,
1182
+ classpath = classpath,
1183
+ classDirectory = classesDir
1184
+ )
1185
+ }.toList
1186
+ )
1187
+ Task .now((state, Right (response)))
1188
+ }
1189
+
1190
+ ifInitialized(None ) { (state : State , logger : BspServerLogger ) =>
1191
+ mapToProjects(request.targets, state) match {
1192
+ case Left (error) =>
1193
+ // Log the mapping error to the user via a log event + an error status code
1194
+ logger.error(error)
1195
+ Task .now((state, Right (bsp.JavacOptionsResult (Nil ))))
1196
+ case Right (mappings) => javacOptions(mappings, state)
1197
+ }
1198
+ }
1199
+ }
1200
+
1162
1201
val isShutdown = scala.concurrent.Promise [BspResponse [Unit ]]()
1163
1202
val isShutdownTask = Task .fromFuture(isShutdown.future).memoize
1164
1203
def shutdown (shutdown : bsp.Shutdown ): Unit = {
0 commit comments