Skip to content

Commit 6060cd6

Browse files
committed
Ensure *.semanticdb files still land along with the compiled classes when a virtual directory is used by BSP
1 parent cfc9dac commit 6060cd6

4 files changed

Lines changed: 62 additions & 9 deletions

File tree

modules/build/src/main/scala/scala/build/Build.scala

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,10 @@ object Build {
303303
workspace = inputs.workspace,
304304
updateSemanticDbs = true,
305305
scalaVersion = sv,
306-
buildOptions = build.options
306+
buildOptions =
307+
inputs.originalWorkspaceOpt.fold(build.options)(
308+
build.options.withResolvedSemanticDbSourceRoot
309+
)
307310
).left.foreach(_.foreach(logger.message(_)))
308311
case _ =>
309312
}
@@ -942,7 +945,8 @@ object Build {
942945
options.scalaOptions.semanticDbOptions.generateSemanticDbs.getOrElse(false)
943946
val semanticDbTargetRoot = options.scalaOptions.semanticDbOptions.semanticDbTargetRoot
944947
val semanticDbSourceRoot =
945-
options.scalaOptions.semanticDbOptions.semanticDbSourceRoot.getOrElse(inputs.workspace)
948+
options.scalaOptions.semanticDbOptions.semanticDbSourceRoot
949+
.getOrElse(inputs.originalWorkspaceOpt.getOrElse(inputs.workspace))
946950

947951
val scalaCompilerParamsOpt = artifacts.scalaOpt match {
948952
case Some(scalaArtifacts) =>

modules/build/src/main/scala/scala/build/bsp/BspImpl.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,10 @@ final class BspImpl(
363363
currentBloopSession.inputs.workspace,
364364
updateSemanticDbs = true,
365365
scalaVersion = sv,
366-
buildOptions = data.buildOptions
366+
buildOptions =
367+
currentBloopSession.inputs.originalWorkspaceOpt.fold(data.buildOptions)(
368+
data.buildOptions.withResolvedSemanticDbSourceRoot
369+
)
367370
).left.foreach(_.foreach(showGlobalWarningOnce))
368371

369372
if (res.getStatusCode == b.StatusCode.OK)

modules/integration/src/test/scala/scala/cli/integration/BspTestDefinitions.scala

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2451,18 +2451,25 @@ abstract class BspTestDefinitions extends ScalaCliSuite
24512451
clientDescription = if isIntelliJ then "IntelliJ" else "any client"
24522452
bspClientName = if isIntelliJ then "IntelliJ" else "test"
24532453
} {
2454-
def baseDirectoryOfMainTarget(
2454+
def mainTargetOf(
24552455
remoteServer: b.BuildServer & b.ScalaBuildServer & b.JavaBuildServer & b.JvmBuildServer &
24562456
TestBspClient.WrappedSourcesBuildServer
2457-
): os.Path = {
2457+
): b.BuildTarget = {
24582458
val buildTargetsResp = remoteServer.workspaceBuildTargets().asScala.await
24592459
val targets = buildTargetsResp.getTargets.asScala.toSeq
2460-
val mainTarget = targets.find(t => !t.getId.getUri.contains("-test")).getOrElse {
2460+
targets.find(t => !t.getId.getUri.contains("-test")).getOrElse {
24612461
sys.error(s"No main build target found in ${targets.map(_.getId.getUri)}")
24622462
}
2463-
os.Path(Paths.get(new URI(mainTarget.getBaseDirectory)))
24642463
}
24652464

2465+
def baseDirectoryOf(target: b.BuildTarget): os.Path =
2466+
os.Path(Paths.get(new URI(target.getBaseDirectory)))
2467+
2468+
def collectSemDbFiles(root: os.Path): Seq[os.Path] =
2469+
os.walk(root)
2470+
.filter(_.last.endsWith(".semanticdb"))
2471+
.filter(p => !p.segments.exists(_ == "bloop-internal-classes"))
2472+
24662473
test(s"workspaceBuildTargets baseDirectory: default workspace ($clientDescription)") {
24672474
withBsp(
24682475
inputs = TestInputs(
@@ -2476,9 +2483,21 @@ abstract class BspTestDefinitions extends ScalaCliSuite
24762483
bspClientName = bspClientName
24772484
) { (root, _, remoteServer) =>
24782485
Future {
2479-
val baseDir = baseDirectoryOfMainTarget(remoteServer)
2486+
val mainTarget = mainTargetOf(remoteServer)
2487+
val baseDir = baseDirectoryOf(mainTarget)
24802488
if isIntelliJ then expect(baseDir == root)
24812489
else expect(baseDir == root / Constants.workspaceDirName)
2490+
2491+
val compileResp =
2492+
remoteServer
2493+
.buildTargetCompile(new b.CompileParams(List(mainTarget.getId).asJava))
2494+
.asScala
2495+
.await
2496+
expect(compileResp.getStatusCode == b.StatusCode.OK)
2497+
2498+
val semDbFiles = collectSemDbFiles(root)
2499+
expect(semDbFiles.nonEmpty)
2500+
expect(semDbFiles.forall(_.segments.contains(Constants.workspaceDirName)))
24822501
}
24832502
}
24842503
}
@@ -2503,9 +2522,20 @@ abstract class BspTestDefinitions extends ScalaCliSuite
25032522
) {
25042523
(_, _, remoteServer) =>
25052524
Future {
2506-
val baseDir = baseDirectoryOfMainTarget(remoteServer)
2525+
val mainTarget = mainTargetOf(remoteServer)
2526+
val baseDir = baseDirectoryOf(mainTarget)
25072527
val expectedBaseDir = root / "dir"
25082528
expect(baseDir == expectedBaseDir)
2529+
2530+
val compileResp =
2531+
remoteServer
2532+
.buildTargetCompile(new b.CompileParams(List(mainTarget.getId).asJava))
2533+
.asScala
2534+
.await
2535+
expect(compileResp.getStatusCode == b.StatusCode.OK)
2536+
2537+
val semDbFilesUnderRoot = collectSemDbFiles(root)
2538+
expect(semDbFilesUnderRoot.isEmpty)
25092539
}
25102540
}
25112541
finally os.perms.set(root / "dir", "rwxr-xr-x")

modules/options/src/main/scala/scala/build/options/BuildOptions.scala

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,22 @@ final case class BuildOptions(
5353

5454
import BuildOptions.JavaHomeInfo
5555

56+
/** When the build workspace was moved to a virtual directory (e.g. after
57+
* [[scala.build.input.Inputs.checkAttributes]] fallback) and the user did not set an explicit
58+
* semanticdb source root, use the given original workspace so semanticdb paths stay relative to
59+
* the user's project root.
60+
*/
61+
def withResolvedSemanticDbSourceRoot(originalWorkspace: os.Path): BuildOptions =
62+
if scalaOptions.semanticDbOptions.semanticDbSourceRoot.isEmpty then
63+
copy(scalaOptions =
64+
scalaOptions.copy(
65+
semanticDbOptions = scalaOptions.semanticDbOptions.copy(
66+
semanticDbSourceRoot = Some(originalWorkspace)
67+
)
68+
)
69+
)
70+
else this
71+
5672
lazy val platform: Positioned[Platform] =
5773
scalaOptions.platform.getOrElse(Positioned(List(Position.Custom("DEFAULT")), Platform.JVM))
5874

0 commit comments

Comments
 (0)