Skip to content

Commit

Permalink
Merge pull request VirtusLab#2692 from Gedochao/maintenance/semanticd…
Browse files Browse the repository at this point in the history
…b-improvements

Add a Scala/Java version agnostic option for setting the SemanticDB target root  and source root directories
  • Loading branch information
Gedochao authored Jan 25, 2024
2 parents 3dcfb33 + 9336862 commit 4ee83bc
Show file tree
Hide file tree
Showing 15 changed files with 455 additions and 138 deletions.
43 changes: 26 additions & 17 deletions modules/build/src/main/scala/scala/build/Build.scala
Original file line number Diff line number Diff line change
Expand Up @@ -825,7 +825,11 @@ object Build {
val classesDir0 = classesDir(inputs.workspace, inputs.projectName, scope)
val scaladocDir = classesDir(inputs.workspace, inputs.projectName, scope, suffix = "-doc")

val generateSemanticDbs = options.scalaOptions.generateSemanticDbs.getOrElse(false)
val generateSemanticDbs =
options.scalaOptions.semanticDbOptions.generateSemanticDbs.getOrElse(false)
val semanticDbTargetRoot = options.scalaOptions.semanticDbOptions.semanticDbTargetRoot
val semanticDbSourceRoot =
options.scalaOptions.semanticDbOptions.semanticDbSourceRoot.getOrElse(inputs.workspace)

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

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

val semanticDbScalacOptions =
if (generateSemanticDbs)
if (params.scalaVersion.startsWith("2."))
Seq(
"-Yrangepos",
"-P:semanticdb:failures:warning",
"-P:semanticdb:synthetics:on",
s"-P:semanticdb:sourceroot:${inputs.workspace}"
).map(ScalacOpt(_))
else
Seq(
"-Xsemanticdb",
"-sourceroot",
inputs.workspace.toString
).map(ScalacOpt(_))
val semanticDbTargetRootOptions: Seq[ScalacOpt] =
(semanticDbTargetRoot match
case Some(targetRoot) if params.scalaVersion.startsWith("2.") =>
Seq(s"-P:semanticdb:targetroot:$targetRoot")
case Some(targetRoot) => Seq("-semanticdb-target", targetRoot.toString)
case None => Nil
).map(ScalacOpt(_))
val semanticDbScalacOptions: Seq[ScalacOpt] =
if generateSemanticDbs then
semanticDbTargetRootOptions ++ (
if params.scalaVersion.startsWith("2.") then
Seq(
"-Yrangepos",
"-P:semanticdb:failures:warning",
"-P:semanticdb:synthetics:on",
s"-P:semanticdb:sourceroot:$semanticDbSourceRoot"
)
else Seq("-Xsemanticdb", "-sourceroot", semanticDbSourceRoot.toString)
).map(ScalacOpt(_))
else Nil

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

val javacTargetRoot = semanticDbTargetRoot.getOrElse("javac-classes-directory")
Seq(
// does the path need to be escaped somehow?
s"-Xplugin:semanticdb -sourceroot:${inputs.workspace} -targetroot:javac-classes-directory"
s"-Xplugin:semanticdb -sourceroot:$semanticDbSourceRoot -targetroot:$javacTargetRoot"
) ++ exports
}
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,9 @@ abstract class BuildTests(server: Boolean) extends TestUtil.ScalaCliBuildSuite {
val testInputs = TestInputs(os.rel / "simple.sc" -> scriptContents)
val buildOptions = defaultOptions.copy(
scalaOptions = defaultOptions.scalaOptions.copy(
generateSemanticDbs = Some(true)
semanticDbOptions = defaultOptions.scalaOptions.semanticDbOptions.copy(
generateSemanticDbs = Some(true)
)
)
)
testInputs.withBuild(buildOptions, buildThreads, bloopConfigOpt) { (_, _, maybeBuild) =>
Expand Down Expand Up @@ -227,7 +229,9 @@ abstract class BuildTests(server: Boolean) extends TestUtil.ScalaCliBuildSuite {
)
val buildOptions = defaultScala3Options.copy(
scalaOptions = defaultScala3Options.scalaOptions.copy(
generateSemanticDbs = Some(true)
semanticDbOptions = defaultScala3Options.scalaOptions.semanticDbOptions.copy(
generateSemanticDbs = Some(true)
)
)
)
testInputs.withBuild(buildOptions, buildThreads, bloopConfigOpt) { (_, _, maybeBuild) =>
Expand Down
5 changes: 4 additions & 1 deletion modules/cli/src/main/scala/scala/cli/commands/bsp/Bsp.scala
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,10 @@ object Bsp extends ScalaCommand[BspOptions] {
fetchSources = baseOptions.classPathOptions.fetchSources.orElse(Some(true))
),
scalaOptions = baseOptions.scalaOptions.copy(
generateSemanticDbs = baseOptions.scalaOptions.generateSemanticDbs.orElse(Some(true))
semanticDbOptions = baseOptions.scalaOptions.semanticDbOptions.copy(
generateSemanticDbs =
baseOptions.scalaOptions.semanticDbOptions.generateSemanticDbs.orElse(Some(true))
)
),
notForBloopOptions = baseOptions.notForBloopOptions.copy(
addRunnerDependencyOpt =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package scala.cli.commands.shared

import caseapp.*
import com.github.plokhotnyuk.jsoniter_scala.core.*
import com.github.plokhotnyuk.jsoniter_scala.macros.*

import scala.cli.commands.tags

case class SemanticDbOptions(
@Hidden
@Tag(tags.should)
@HelpMessage("Generate SemanticDBs")
@Name("semanticdb")
semanticDb: Option[Boolean] = None,
@Hidden
@Tag(tags.should)
@HelpMessage("SemanticDB target root (default to the compiled classes destination directory)")
@Name("semanticdbTargetRoot")
@Name("semanticdbTargetroot")
semanticDbTargetRoot: Option[String] = None,
@Hidden
@Tag(tags.should)
@HelpMessage("SemanticDB source root (default to the project root directory)")
@Name("semanticdbSourceRoot")
@Name("semanticdbSourceroot")
semanticDbSourceRoot: Option[String] = None
)

object SemanticDbOptions {
implicit lazy val parser: Parser[SemanticDbOptions] = Parser.derive
implicit lazy val help: Help[SemanticDbOptions] = Help.derive
implicit lazy val jsonCodec: JsonValueCodec[SemanticDbOptions] = JsonCodecMaker.make
}
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,8 @@ final case class SharedOptions(
@Hidden
runner: Option[Boolean] = None,

@Hidden
@Tag(tags.should)
@HelpMessage("Generate SemanticDBs")
semanticDb: Option[Boolean] = None,
@Recurse
semanticDbOptions: SemanticDbOptions = SemanticDbOptions(),

@Recurse
input: SharedInputOptions = SharedInputOptions(),
Expand Down Expand Up @@ -360,7 +358,11 @@ final case class SharedOptions(
scalaBinaryVersion = scalaBinaryVersion.map(_.trim).filter(_.nonEmpty),
addScalaLibrary = scalaLibrary.orElse(java.map(!_)),
addScalaCompiler = withCompiler,
generateSemanticDbs = semanticDb,
semanticDbOptions = bo.SemanticDbOptions(
generateSemanticDbs = semanticDbOptions.semanticDb,
semanticDbTargetRoot = semanticDbOptions.semanticDbTargetRoot.map(os.Path(_, os.pwd)),
semanticDbSourceRoot = semanticDbOptions.semanticDbSourceRoot.map(os.Path(_, os.pwd))
),
scalacOptions = scalac
.scalacOption
.withScalacExtraOptions(scalacExtra)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import scala.cli.integration.util.BloopUtil
abstract class CompileTestDefinitions(val scalaVersionOpt: Option[String])
extends ScalaCliSuite
with TestScalaVersionArgs
with CompilerPluginTestDefinitions {
with CompilerPluginTestDefinitions
with SemanticDbTestDefinitions {

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

Expand Down Expand Up @@ -467,80 +468,6 @@ abstract class CompileTestDefinitions(val scalaVersionOpt: Option[String])
}
}

test("Manual javac SemanticDB") {
val inputs = TestInputs(
os.rel / "foo" / "Test.java" ->
"""package foo;
|
|public class Test {
| public static void main(String[] args) {
| System.err.println("Hello");
| }
|}
|""".stripMargin
)
inputs.fromRoot { root =>
val compilerPackages = Seq(
"com.sun.tools.javac.api",
"com.sun.tools.javac.code",
"com.sun.tools.javac.model",
"com.sun.tools.javac.tree",
"com.sun.tools.javac.util"
)
val exports = compilerPackages
.flatMap { pkg =>
Seq("-J--add-exports", s"-Jjdk.compiler/$pkg=ALL-UNNAMED")
}
.flatMap(opt => List("--javac-opt", opt))
val javaSemDbOptions = Seq(
"--javac-plugin",
"com.sourcegraph:semanticdb-javac:0.7.4",
"--javac-opt",
s"-Xplugin:semanticdb -sourceroot:$root -targetroot:javac-classes-directory"
) ++ exports
os.proc(TestUtil.cli, "compile", extraOptions, javaSemDbOptions, ".")
.call(cwd = root)

val files = os.walk(root / Constants.workspaceDirName)
val semDbFiles = files
.filter(_.last.endsWith(".semanticdb"))
.filter(!_.segments.exists(_ == "bloop-internal-classes"))
expect(semDbFiles.length == 1)
val semDbFile = semDbFiles.head
expect(
semDbFile.endsWith(os.rel / "META-INF" / "semanticdb" / "foo" / "Test.java.semanticdb")
)
}
}

test("Javac SemanticDB") {
val inputs = TestInputs(
os.rel / "foo" / "Test.java" ->
"""package foo;
|
|public class Test {
| public static void main(String[] args) {
| System.err.println("Hello");
| }
|}
|""".stripMargin
)
inputs.fromRoot { root =>
os.proc(TestUtil.cli, "compile", extraOptions, "--semantic-db", ".")
.call(cwd = root)

val files = os.walk(root / Constants.workspaceDirName)
val semDbFiles = files
.filter(_.last.endsWith(".semanticdb"))
.filter(!_.segments.exists(_ == "bloop-internal-classes"))
expect(semDbFiles.length == 1)
val semDbFile = semDbFiles.head
expect(
semDbFile.endsWith(os.rel / "META-INF" / "semanticdb" / "foo" / "Test.java.semanticdb")
)
}
}

if (actualScalaVersion.startsWith("3"))
test("generate scoverage.coverage file") {
val fileName = "Hello.scala"
Expand Down
Loading

0 comments on commit 4ee83bc

Please sign in to comment.