Skip to content

Commit 8332ee9

Browse files
authored
Merge pull request scalacenter#1704 from Duhemm/implement-inverse-sources
Implement buildTarget/inverseSources BSP endpoint
2 parents a9b3ea5 + feba66f commit 8332ee9

File tree

4 files changed

+60
-1
lines changed

4 files changed

+60
-1
lines changed

frontend/src/main/scala/bloop/bsp/BloopBspServices.scala

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ final class BloopBspServices(
101101
.notificationAsync(endpoints.Build.exit)(p => exit(p))
102102
.requestAsync(endpoints.Workspace.buildTargets)(p => schedule(buildTargets(p)))
103103
.requestAsync(endpoints.BuildTarget.sources)(p => schedule(sources(p)))
104+
.requestAsync(endpoints.BuildTarget.inverseSources)(p => schedule(inverseSources(p)))
104105
.requestAsync(endpoints.BuildTarget.resources)(p => schedule(resources(p)))
105106
.requestAsync(endpoints.BuildTarget.scalacOptions)(p => schedule(scalacOptions(p)))
106107
.requestAsync(endpoints.BuildTarget.javacOptions)(p => schedule(javacOptions(p)))
@@ -1070,6 +1071,23 @@ final class BloopBspServices(
10701071
}
10711072
}
10721073

1074+
def inverseSources(request: bsp.InverseSourcesParams): BspEndpointResponse[bsp.InverseSourcesResult] = {
1075+
def matchesSources(document: Path, project: Project): Boolean =
1076+
project.sources.exists(src => document.startsWith(src.underlying))
1077+
def matchesGlobs(document: Path, project: Project): Boolean =
1078+
project.sourcesGlobs.exists(glob => glob.matches(document))
1079+
val document = AbsolutePath(request.textDocument.uri.toPath).underlying
1080+
ifInitialized(None) { (state: State, logger: BspServerLogger) =>
1081+
val matchingProjects = state.build.loadedProjects.filter { loadedProject =>
1082+
val project = loadedProject.project
1083+
matchesSources(document, project) || matchesGlobs(document, project)
1084+
}.map { loadedProject =>
1085+
bsp.BuildTargetIdentifier(loadedProject.project.bspUri)
1086+
}
1087+
Task.now((state, Right(bsp.InverseSourcesResult(matchingProjects))))
1088+
}
1089+
}
1090+
10731091
def resources(
10741092
request: bsp.ResourcesParams
10751093
): BspEndpointResponse[bsp.ResourcesResult] = {

frontend/src/test/scala/bloop/bsp/BspBaseSuite.scala

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,19 @@ abstract class BspBaseSuite extends BaseSuite with BspClientTest {
290290
TestUtil.await(FiniteDuration(5, "s"))(dependencySourcesTask)
291291
}
292292

293+
def requestInverseSources(document: AbsolutePath): bsp.InverseSourcesResult = {
294+
val inverseSourcesTask = {
295+
endpoints.BuildTarget.inverseSources
296+
.request(bsp.InverseSourcesParams(bsp.TextDocumentIdentifier(bsp.Uri(document.toBspUri))))
297+
.map {
298+
case Left(error) => fail(s"Received error ${error}")
299+
case Right(targets) => targets
300+
}
301+
}
302+
303+
TestUtil.await(FiniteDuration(5, "s"))(inverseSourcesTask)
304+
}
305+
293306
import bloop.cli.ExitStatus
294307
def toBspStatus(status: ExitStatus): bsp.StatusCode = {
295308
status match {

frontend/src/test/scala/bloop/bsp/BspProtocolSpec.scala

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,4 +540,32 @@ class BspProtocolSpec(
540540
}
541541
}
542542

543+
test("inverse sources request works") {
544+
TestUtil.withinWorkspace { workspace =>
545+
val logger = new RecordingLogger(ansiCodesSupported = false)
546+
loadBspBuildFromResources("cross-test-build-scalajs-0.6", workspace, logger) { build =>
547+
val mainProject = build.projectFor("test-project")
548+
val testProject = build.projectFor("test-project-test")
549+
val mainJsProject = build.projectFor("test-projectJS")
550+
val testJsProject = build.projectFor("test-projectJS-test")
551+
val rootMain = build.projectFor("cross-test-build-scalajs-0-6")
552+
val rootTest = build.projectFor("cross-test-build-scalajs-0-6-test")
553+
554+
def checkInverseSources(project: TestProject): Unit = {
555+
project.sources.foreach { source =>
556+
val inverseSourcesResult = build.state.requestInverseSources(source)
557+
assert(inverseSourcesResult.targets.contains(project.bspId))
558+
}
559+
}
560+
561+
checkInverseSources(mainProject)
562+
checkInverseSources(testProject)
563+
checkInverseSources(mainJsProject)
564+
checkInverseSources(testJsProject)
565+
checkInverseSources(rootMain)
566+
checkInverseSources(rootTest)
567+
}
568+
}
569+
}
570+
543571
}

frontend/src/test/scala/bloop/util/TestProject.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ final case class TestProject(
2424
deps: Option[List[TestProject]]
2525
) {
2626
def baseDir: AbsolutePath = AbsolutePath(config.directory)
27+
def sources: List[AbsolutePath] = config.sources.map(AbsolutePath(_))
2728
def srcFor(relPath: String, exists: Boolean = true): AbsolutePath = {
28-
val sources = config.sources.map(AbsolutePath(_))
2929
if (exists) TestProject.srcFor(sources, relPath)
3030
else {
3131
val targetPath = RelativePath(relPath.stripPrefix(java.io.File.separator))

0 commit comments

Comments
 (0)