diff --git a/rules/private/phases/phase_semanticdb.bzl b/rules/private/phases/phase_semanticdb.bzl index de0a0862..d2a7a9e5 100644 --- a/rules/private/phases/phase_semanticdb.bzl +++ b/rules/private/phases/phase_semanticdb.bzl @@ -6,7 +6,16 @@ load( ) def _semanticdb_directory_from_file(file): - return file.path[:file.path.find("META-INF") - 1] + """ + This is janky, but we're limited in what we can do in this function. From the + [documentation](https://bazel.build/rules/lib/builtins/Args#add_all) on `Args#add_all`: + + To avoid unintended retention of large analysis-phase data structures into the execution phase, + the `map_each` function must be declared by a top-level `def` statement; it may not be a + nested function closure by default. + """ + + return "{}/{}".format(file.root.path, file.short_path[:file.short_path.find("META-INF") - 1]) # # PHASE: semanticdb @@ -40,18 +49,20 @@ def phase_semanticdb(ctx, g): if scala_configuration.version.startswith("2"): arguments.add("--compiler_option=-P:semanticdb:failures:error") + arguments.add("--compiler_option_referencing_path=-P:semanticdb:sourceroot:${workDir}") arguments.add_all( [outputs[0]], - format_each = "--compiler_option_referencing_path=-P:semanticdb:targetroot:%s", + format_each = "--compiler_option_referencing_path=-P:semanticdb:targetroot:${path} %s", map_each = _semanticdb_directory_from_file, ) else: arguments.add_all( [outputs[0]], - format_each = "--compiler_option_referencing_path=-semanticdb-target:%s", + format_each = "--compiler_option_referencing_path=-semanticdb-target:${path} %s", map_each = _semanticdb_directory_from_file, ) + arguments.add("--compiler_option_referencing_path=-sourceroot:${workDir}") arguments.add("--compiler_option=-Ysemanticdb") g.out.providers.append( diff --git a/src/main/scala/higherkindness/rules_scala/workers/common/CommonArguments.scala b/src/main/scala/higherkindness/rules_scala/workers/common/CommonArguments.scala index 4fa5ffb2..7cc28ba0 100644 --- a/src/main/scala/higherkindness/rules_scala/workers/common/CommonArguments.scala +++ b/src/main/scala/higherkindness/rules_scala/workers/common/CommonArguments.scala @@ -7,6 +7,7 @@ import common.sandbox.SandboxUtil import net.sourceforge.argparse4j.impl.{Arguments => ArgumentsImpl} import net.sourceforge.argparse4j.inf.{Argument, ArgumentParser, ArgumentType, Namespace} import java.util.{Collections, List as JList} +import scala.annotation.nowarn import scala.collection.mutable.Buffer import scala.jdk.CollectionConverters.* import java.io.File @@ -61,22 +62,23 @@ object Analysis { } object CommonArguments { - private val scala2SemanticDbTargetRootRegex = """-P:semanticdb:targetroot:(.*)""".r - private val scala3SemanticDbTargetRootRegex = """-semanticdb-target:(.*)""".r - - private def adjustCompilerOptions(workDir: Path, options: List[String]) = { - def adjustStringPath(path: String) = - SandboxUtil.getSandboxPath(workDir, Paths.get(path)).toString - - options.flatMap { - case scala2SemanticDbTargetRootRegex(path) => - List(s"-P:semanticdb:sourceroot:${workDir.toString}", s"-P:semanticdb:targetroot:${adjustStringPath(path)}") - - case scala3SemanticDbTargetRootRegex(path) => - List(s"-semanticdb-target:${adjustStringPath(path)}", s"-sourceroot:${workDir.toString}") - - case option => List(option) + private val pathPlaceholderRegex = """\$\{path\}""".r + private def adjustCompilerOptions(workDir: Path, options: List[String]) = options.map { option => + val i = option.lastIndexOf(' ') + val withPathReplaced = if (i == -1) { + option + } else { + val template = option.slice(0, i) + val path = option.slice(i + 1, option.length) + + template.replace( + "${path}": @nowarn("cat=lint-missing-interpolator"), + SandboxUtil.getSandboxPath(workDir, Paths.get(path)).toString, + ) } + + withPathReplaced + .replace("${workDir}": @nowarn("cat=lint-missing-interpolator"), workDir.toString) } /**