Skip to content

Commit 4ee83bc

Browse files
authored
Merge pull request #2692 from Gedochao/maintenance/semanticdb-improvements
Add a Scala/Java version agnostic option for setting the SemanticDB target root and source root directories
2 parents 3dcfb33 + 9336862 commit 4ee83bc

File tree

15 files changed

+455
-138
lines changed

15 files changed

+455
-138
lines changed

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

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -825,7 +825,11 @@ object Build {
825825
val classesDir0 = classesDir(inputs.workspace, inputs.projectName, scope)
826826
val scaladocDir = classesDir(inputs.workspace, inputs.projectName, scope, suffix = "-doc")
827827

828-
val generateSemanticDbs = options.scalaOptions.generateSemanticDbs.getOrElse(false)
828+
val generateSemanticDbs =
829+
options.scalaOptions.semanticDbOptions.generateSemanticDbs.getOrElse(false)
830+
val semanticDbTargetRoot = options.scalaOptions.semanticDbOptions.semanticDbTargetRoot
831+
val semanticDbSourceRoot =
832+
options.scalaOptions.semanticDbOptions.semanticDbSourceRoot.getOrElse(inputs.workspace)
829833

830834
val releaseFlagVersion = releaseFlag(options, compilerJvmVersionOpt, logger).map(_.toString)
831835

@@ -842,21 +846,25 @@ object Build {
842846
ScalacOpt(s"-Xplugin:$path")
843847
}
844848

845-
val semanticDbScalacOptions =
846-
if (generateSemanticDbs)
847-
if (params.scalaVersion.startsWith("2."))
848-
Seq(
849-
"-Yrangepos",
850-
"-P:semanticdb:failures:warning",
851-
"-P:semanticdb:synthetics:on",
852-
s"-P:semanticdb:sourceroot:${inputs.workspace}"
853-
).map(ScalacOpt(_))
854-
else
855-
Seq(
856-
"-Xsemanticdb",
857-
"-sourceroot",
858-
inputs.workspace.toString
859-
).map(ScalacOpt(_))
849+
val semanticDbTargetRootOptions: Seq[ScalacOpt] =
850+
(semanticDbTargetRoot match
851+
case Some(targetRoot) if params.scalaVersion.startsWith("2.") =>
852+
Seq(s"-P:semanticdb:targetroot:$targetRoot")
853+
case Some(targetRoot) => Seq("-semanticdb-target", targetRoot.toString)
854+
case None => Nil
855+
).map(ScalacOpt(_))
856+
val semanticDbScalacOptions: Seq[ScalacOpt] =
857+
if generateSemanticDbs then
858+
semanticDbTargetRootOptions ++ (
859+
if params.scalaVersion.startsWith("2.") then
860+
Seq(
861+
"-Yrangepos",
862+
"-P:semanticdb:failures:warning",
863+
"-P:semanticdb:synthetics:on",
864+
s"-P:semanticdb:sourceroot:$semanticDbSourceRoot"
865+
)
866+
else Seq("-Xsemanticdb", "-sourceroot", semanticDbSourceRoot.toString)
867+
).map(ScalacOpt(_))
860868
else Nil
861869

862870
val sourceRootScalacOptions =
@@ -922,9 +930,10 @@ object Build {
922930
Seq("-J--add-exports", s"-Jjdk.compiler/$pkg=ALL-UNNAMED")
923931
}
924932

933+
val javacTargetRoot = semanticDbTargetRoot.getOrElse("javac-classes-directory")
925934
Seq(
926935
// does the path need to be escaped somehow?
927-
s"-Xplugin:semanticdb -sourceroot:${inputs.workspace} -targetroot:javac-classes-directory"
936+
s"-Xplugin:semanticdb -sourceroot:$semanticDbSourceRoot -targetroot:$javacTargetRoot"
928937
) ++ exports
929938
}
930939
else

modules/build/src/test/scala/scala/build/tests/BuildTests.scala

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,9 @@ abstract class BuildTests(server: Boolean) extends TestUtil.ScalaCliBuildSuite {
180180
val testInputs = TestInputs(os.rel / "simple.sc" -> scriptContents)
181181
val buildOptions = defaultOptions.copy(
182182
scalaOptions = defaultOptions.scalaOptions.copy(
183-
generateSemanticDbs = Some(true)
183+
semanticDbOptions = defaultOptions.scalaOptions.semanticDbOptions.copy(
184+
generateSemanticDbs = Some(true)
185+
)
184186
)
185187
)
186188
testInputs.withBuild(buildOptions, buildThreads, bloopConfigOpt) { (_, _, maybeBuild) =>
@@ -227,7 +229,9 @@ abstract class BuildTests(server: Boolean) extends TestUtil.ScalaCliBuildSuite {
227229
)
228230
val buildOptions = defaultScala3Options.copy(
229231
scalaOptions = defaultScala3Options.scalaOptions.copy(
230-
generateSemanticDbs = Some(true)
232+
semanticDbOptions = defaultScala3Options.scalaOptions.semanticDbOptions.copy(
233+
generateSemanticDbs = Some(true)
234+
)
231235
)
232236
)
233237
testInputs.withBuild(buildOptions, buildThreads, bloopConfigOpt) { (_, _, maybeBuild) =>

modules/cli/src/main/scala/scala/cli/commands/bsp/Bsp.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,10 @@ object Bsp extends ScalaCommand[BspOptions] {
138138
fetchSources = baseOptions.classPathOptions.fetchSources.orElse(Some(true))
139139
),
140140
scalaOptions = baseOptions.scalaOptions.copy(
141-
generateSemanticDbs = baseOptions.scalaOptions.generateSemanticDbs.orElse(Some(true))
141+
semanticDbOptions = baseOptions.scalaOptions.semanticDbOptions.copy(
142+
generateSemanticDbs =
143+
baseOptions.scalaOptions.semanticDbOptions.generateSemanticDbs.orElse(Some(true))
144+
)
142145
),
143146
notForBloopOptions = baseOptions.notForBloopOptions.copy(
144147
addRunnerDependencyOpt =
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package scala.cli.commands.shared
2+
3+
import caseapp.*
4+
import com.github.plokhotnyuk.jsoniter_scala.core.*
5+
import com.github.plokhotnyuk.jsoniter_scala.macros.*
6+
7+
import scala.cli.commands.tags
8+
9+
case class SemanticDbOptions(
10+
@Hidden
11+
@Tag(tags.should)
12+
@HelpMessage("Generate SemanticDBs")
13+
@Name("semanticdb")
14+
semanticDb: Option[Boolean] = None,
15+
@Hidden
16+
@Tag(tags.should)
17+
@HelpMessage("SemanticDB target root (default to the compiled classes destination directory)")
18+
@Name("semanticdbTargetRoot")
19+
@Name("semanticdbTargetroot")
20+
semanticDbTargetRoot: Option[String] = None,
21+
@Hidden
22+
@Tag(tags.should)
23+
@HelpMessage("SemanticDB source root (default to the project root directory)")
24+
@Name("semanticdbSourceRoot")
25+
@Name("semanticdbSourceroot")
26+
semanticDbSourceRoot: Option[String] = None
27+
)
28+
29+
object SemanticDbOptions {
30+
implicit lazy val parser: Parser[SemanticDbOptions] = Parser.derive
31+
implicit lazy val help: Help[SemanticDbOptions] = Help.derive
32+
implicit lazy val jsonCodec: JsonValueCodec[SemanticDbOptions] = JsonCodecMaker.make
33+
}

modules/cli/src/main/scala/scala/cli/commands/shared/SharedOptions.scala

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -187,10 +187,8 @@ final case class SharedOptions(
187187
@Hidden
188188
runner: Option[Boolean] = None,
189189

190-
@Hidden
191-
@Tag(tags.should)
192-
@HelpMessage("Generate SemanticDBs")
193-
semanticDb: Option[Boolean] = None,
190+
@Recurse
191+
semanticDbOptions: SemanticDbOptions = SemanticDbOptions(),
194192

195193
@Recurse
196194
input: SharedInputOptions = SharedInputOptions(),
@@ -360,7 +358,11 @@ final case class SharedOptions(
360358
scalaBinaryVersion = scalaBinaryVersion.map(_.trim).filter(_.nonEmpty),
361359
addScalaLibrary = scalaLibrary.orElse(java.map(!_)),
362360
addScalaCompiler = withCompiler,
363-
generateSemanticDbs = semanticDb,
361+
semanticDbOptions = bo.SemanticDbOptions(
362+
generateSemanticDbs = semanticDbOptions.semanticDb,
363+
semanticDbTargetRoot = semanticDbOptions.semanticDbTargetRoot.map(os.Path(_, os.pwd)),
364+
semanticDbSourceRoot = semanticDbOptions.semanticDbSourceRoot.map(os.Path(_, os.pwd))
365+
),
364366
scalacOptions = scalac
365367
.scalacOption
366368
.withScalacExtraOptions(scalacExtra)

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

Lines changed: 2 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import scala.cli.integration.util.BloopUtil
99
abstract class CompileTestDefinitions(val scalaVersionOpt: Option[String])
1010
extends ScalaCliSuite
1111
with TestScalaVersionArgs
12-
with CompilerPluginTestDefinitions {
12+
with CompilerPluginTestDefinitions
13+
with SemanticDbTestDefinitions {
1314

1415
protected lazy val extraOptions: Seq[String] = scalaVersionArgs ++ TestUtil.extraOptions
1516

@@ -467,80 +468,6 @@ abstract class CompileTestDefinitions(val scalaVersionOpt: Option[String])
467468
}
468469
}
469470

470-
test("Manual javac SemanticDB") {
471-
val inputs = TestInputs(
472-
os.rel / "foo" / "Test.java" ->
473-
"""package foo;
474-
|
475-
|public class Test {
476-
| public static void main(String[] args) {
477-
| System.err.println("Hello");
478-
| }
479-
|}
480-
|""".stripMargin
481-
)
482-
inputs.fromRoot { root =>
483-
val compilerPackages = Seq(
484-
"com.sun.tools.javac.api",
485-
"com.sun.tools.javac.code",
486-
"com.sun.tools.javac.model",
487-
"com.sun.tools.javac.tree",
488-
"com.sun.tools.javac.util"
489-
)
490-
val exports = compilerPackages
491-
.flatMap { pkg =>
492-
Seq("-J--add-exports", s"-Jjdk.compiler/$pkg=ALL-UNNAMED")
493-
}
494-
.flatMap(opt => List("--javac-opt", opt))
495-
val javaSemDbOptions = Seq(
496-
"--javac-plugin",
497-
"com.sourcegraph:semanticdb-javac:0.7.4",
498-
"--javac-opt",
499-
s"-Xplugin:semanticdb -sourceroot:$root -targetroot:javac-classes-directory"
500-
) ++ exports
501-
os.proc(TestUtil.cli, "compile", extraOptions, javaSemDbOptions, ".")
502-
.call(cwd = root)
503-
504-
val files = os.walk(root / Constants.workspaceDirName)
505-
val semDbFiles = files
506-
.filter(_.last.endsWith(".semanticdb"))
507-
.filter(!_.segments.exists(_ == "bloop-internal-classes"))
508-
expect(semDbFiles.length == 1)
509-
val semDbFile = semDbFiles.head
510-
expect(
511-
semDbFile.endsWith(os.rel / "META-INF" / "semanticdb" / "foo" / "Test.java.semanticdb")
512-
)
513-
}
514-
}
515-
516-
test("Javac SemanticDB") {
517-
val inputs = TestInputs(
518-
os.rel / "foo" / "Test.java" ->
519-
"""package foo;
520-
|
521-
|public class Test {
522-
| public static void main(String[] args) {
523-
| System.err.println("Hello");
524-
| }
525-
|}
526-
|""".stripMargin
527-
)
528-
inputs.fromRoot { root =>
529-
os.proc(TestUtil.cli, "compile", extraOptions, "--semantic-db", ".")
530-
.call(cwd = root)
531-
532-
val files = os.walk(root / Constants.workspaceDirName)
533-
val semDbFiles = files
534-
.filter(_.last.endsWith(".semanticdb"))
535-
.filter(!_.segments.exists(_ == "bloop-internal-classes"))
536-
expect(semDbFiles.length == 1)
537-
val semDbFile = semDbFiles.head
538-
expect(
539-
semDbFile.endsWith(os.rel / "META-INF" / "semanticdb" / "foo" / "Test.java.semanticdb")
540-
)
541-
}
542-
}
543-
544471
if (actualScalaVersion.startsWith("3"))
545472
test("generate scoverage.coverage file") {
546473
val fileName = "Hello.scala"

0 commit comments

Comments
 (0)