From e64c71dd58fc9965e5f25142ce9c4e7a4489e889 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Fri, 29 Oct 2021 14:31:01 +0200 Subject: [PATCH] [BSP] Support base source files --- .../internal/server/BuildServerProtocol.scala | 29 ++++++++--- .../server-test/buildserver/BaseSource.scala | 1 + .../test/scala/testpkg/BuildServerTest.scala | 49 +++++++++++++------ 3 files changed, 57 insertions(+), 22 deletions(-) create mode 100644 server-test/src/server-test/buildserver/BaseSource.scala diff --git a/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala b/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala index 401bf6d31..657653345 100644 --- a/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala +++ b/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala @@ -277,14 +277,18 @@ object BuildServerProtocol { bspBuildTargetSourcesItem := { val id = bspTargetIdentifier.value val dirs = unmanagedSourceDirectories.value - val managed = managedSources.value - val items = (dirs.toVector map { dir => - SourceItem(dir.toURI, SourceItemKind.Directory, generated = false) - }) ++ - (managed.toVector map { x => - SourceItem(x.toURI, SourceItemKind.File, generated = true) - }) - SourcesItem(id, items) + val sourceFiles = getStandaloneSourceFiles(unmanagedSources.value, dirs) + val managedDirs = managedSourceDirectories.value + val managedSourceFiles = getStandaloneSourceFiles(managedSources.value, managedDirs) + + def toSourceItem(itemKind: Int, generated: Boolean)(file: File): SourceItem = + SourceItem(file.toURI, itemKind, generated) + + val items = dirs.map(toSourceItem(SourceItemKind.Directory, generated = false)) ++ + sourceFiles.map(toSourceItem(SourceItemKind.File, generated = false)) ++ + managedDirs.map(toSourceItem(SourceItemKind.Directory, generated = true)) ++ + managedSourceFiles.map(toSourceItem(SourceItemKind.File, generated = true)) + SourcesItem(id, items.toVector) }, bspBuildTargetResourcesItem := { val id = bspTargetIdentifier.value @@ -456,6 +460,15 @@ object BuildServerProtocol { } } + private def getStandaloneSourceFiles( + sourceFiles: Seq[File], + sourceDirs: Seq[File] + ): Seq[File] = { + sourceFiles.filterNot { f => + sourceDirs.exists(dir => f.toPath.startsWith(dir.toPath)) + } + } + private def checkMetalsCompatibility( semanticdbEnabled: Boolean, semanticdbVersion: String, diff --git a/server-test/src/server-test/buildserver/BaseSource.scala b/server-test/src/server-test/buildserver/BaseSource.scala new file mode 100644 index 000000000..3359bd24f --- /dev/null +++ b/server-test/src/server-test/buildserver/BaseSource.scala @@ -0,0 +1 @@ +object BaseSource diff --git a/server-test/src/test/scala/testpkg/BuildServerTest.scala b/server-test/src/test/scala/testpkg/BuildServerTest.scala index 47aad7b31..f5340e131 100644 --- a/server-test/src/test/scala/testpkg/BuildServerTest.scala +++ b/server-test/src/test/scala/testpkg/BuildServerTest.scala @@ -10,8 +10,13 @@ package testpkg import sbt.internal.bsp._ import sbt.internal.langserver.ErrorCodes import sbt.IO +import sbt.internal.protocol.JsonRpcRequestMessage +import sbt.internal.protocol.codec.JsonRPCProtocol._ +import sjsonnew.JsonWriter +import sjsonnew.support.scalajson.unsafe.{ CompactPrinter, Converter } import java.io.File +import java.net.URI import java.nio.file.Paths import scala.concurrent.duration._ @@ -47,23 +52,28 @@ object BuildServerTest extends AbstractServerTest { test("buildTarget/sources") { _ => val buildTarget = buildTargetUri("util", "Compile") val badBuildTarget = buildTargetUri("badBuildTarget", "Compile") - svr.sendJsonRpc( - s"""{ "jsonrpc": "2.0", "id": "24", "method": "buildTarget/sources", "params": { - | "targets": [{ "uri": "$buildTarget" }, { "uri": "$badBuildTarget" }] - |} }""".stripMargin - ) + svr.sendJsonRpc(buildTargetSources(24, Seq(buildTarget, badBuildTarget))) assert(processing("buildTarget/sources")) val s = svr.waitFor[SourcesResult](10.seconds) val sources = s.items.head.sources.map(_.uri) assert(sources.contains(new File(svr.baseDirectory, "util/src/main/scala").toURI)) } - test("buildTarget/sources SBT") { _ => - val x = s"${svr.baseDirectory.getAbsoluteFile.toURI}#buildserver-build" - svr.sendJsonRpc( - s"""{ "jsonrpc": "2.0", "id": "25", "method": "buildTarget/sources", "params": { - | "targets": [{ "uri": "$x" }] - |} }""".stripMargin + test("buildTarget/sources: base sources") { _ => + val buildTarget = buildTargetUri("buildserver", "Compile") + svr.sendJsonRpc(buildTargetSources(25, Seq(buildTarget))) + assert(processing("buildTarget/sources")) + val s = svr.waitFor[SourcesResult](10.seconds) + val sources = s.items.head.sources + val expectedSource = SourceItem( + new File(svr.baseDirectory, "BaseSource.scala").toURI, + SourceItemKind.File, + generated = false ) + assert(sources.contains(expectedSource)) + } + test("buildTarget/sources: sbt") { _ => + val x = new URI(s"${svr.baseDirectory.getAbsoluteFile.toURI}#buildserver-build") + svr.sendJsonRpc(buildTargetSources(26, Seq(x))) assert(processing("buildTarget/sources")) val s = svr.waitFor[SourcesResult](10.seconds) val sources = s.items.head.sources.map(_.uri).sorted @@ -81,7 +91,6 @@ object BuildServerTest extends AbstractServerTest { ).map(rel => new File(svr.baseDirectory.getAbsoluteFile, rel).toURI).sorted assert(sources == expectedSources) } - test("buildTarget/compile") { _ => val buildTarget = buildTargetUri("util", "Compile") svr.sendJsonRpc( @@ -421,8 +430,20 @@ object BuildServerTest extends AbstractServerTest { } } - private def buildTargetUri(project: String, config: String): String = - s"${svr.baseDirectory.getAbsoluteFile.toURI}#$project/$config" + private def buildTargetSources(id: Int, buildTargets: Seq[URI]): String = { + val targets = buildTargets.map(BuildTargetIdentifier.apply).toVector + request(id, "buildTarget/sources", SourcesParams(targets)) + } + + private def request[T: JsonWriter](id: Int, method: String, params: T): String = { + val request = JsonRpcRequestMessage("2.0", id.toString, method, Converter.toJson(params).get) + val json = Converter.toJson(request).get + CompactPrinter(json) + } + + private def buildTargetUri(project: String, config: String): URI = { + new URI(s"${svr.baseDirectory.getAbsoluteFile.toURI}#$project/$config") + } private def metaBuildTarget: String = s"${svr.baseDirectory.getAbsoluteFile.toURI}project/#buildserver-build/Compile"