Skip to content

Commit 6c7b46c

Browse files
authored
Merge pull request #79 from lucidsoftware/dont-generate-semanticdb-for-generated-or-external-sources
Don't generate SemanticDB for generated or external sources
2 parents 782f590 + 1a8dcb0 commit 6c7b46c

File tree

3 files changed

+74
-31
lines changed

3 files changed

+74
-31
lines changed

rules/private/phases/phase_semanticdb.bzl

+18-15
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,15 @@ load(
55
_SemanticDbInfo = "SemanticDbInfo",
66
)
77

8-
def _semanticdb_directory_from_file(file):
8+
def _semanticdb_directory_from_output_jar(file):
99
"""
10-
This is janky, but we're limited in what we can do in this function. From the
11-
[documentation](https://bazel.build/rules/lib/builtins/Args#add_all) on `Args#add_all`:
12-
13-
To avoid unintended retention of large analysis-phase data structures into the execution phase,
14-
the `map_each` function must be declared by a top-level `def` statement; it may not be a
15-
nested function closure by default.
10+
Using the path of the output JAR to determine the SemanticDB target root is janky, but the
11+
output directory won't be known at build-time, so we have to use the output JAR path as a proxy.
12+
It should be built under the same configuration as the SemanticDB files, since both are produced
13+
by the same compilation action.
1614
"""
1715

18-
return file.path[:file.path.find("META-INF") - 1]
16+
return "{}/semanticdb".format(file.dirname)
1917

2018
#
2119
# PHASE: semanticdb
@@ -33,7 +31,13 @@ def phase_semanticdb(ctx, g):
3331
outputs = []
3432

3533
for source in ctx.files.srcs:
36-
if source.extension == "scala":
34+
# Generated or external files will have the output directory (beginning with `bazel-out`) in
35+
# their paths, which we don't want because it isn't guaranteed to be consistent
36+
if (
37+
source.extension == "scala" and
38+
source.is_source and
39+
source.owner.repo_name == ctx.label.repo_name
40+
):
3741
path = paths.join(
3842
directory_name,
3943
"META-INF",
@@ -44,22 +48,21 @@ def phase_semanticdb(ctx, g):
4448
outputs.append(ctx.actions.declare_file(path))
4549

4650
def add_scalacopts(arguments):
47-
if len(outputs) == 0:
48-
return
51+
output_jar = g.classpaths.jar
4952

5053
if toolchain.scala_configuration.version.startswith("2"):
5154
arguments.add("--compiler_option=-P:semanticdb:failures:error")
5255
arguments.add("--compiler_option_referencing_path=-P:semanticdb:sourceroot:${workDir}")
5356
arguments.add_all(
54-
[outputs[0]],
57+
[output_jar],
5558
format_each = "--compiler_option_referencing_path=-P:semanticdb:targetroot:${path} %s",
56-
map_each = _semanticdb_directory_from_file,
59+
map_each = _semanticdb_directory_from_output_jar,
5760
)
5861
else:
5962
arguments.add_all(
60-
[outputs[0]],
63+
[output_jar],
6164
format_each = "--compiler_option_referencing_path=-semanticdb-target:${path} %s",
62-
map_each = _semanticdb_directory_from_file,
65+
map_each = _semanticdb_directory_from_output_jar,
6366
)
6467

6568
arguments.add("--compiler_option_referencing_path=-sourceroot:${workDir}")

tests/plugins/semanticdb/BUILD

+24-4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
load("@bazel_skylib//rules:copy_file.bzl", "copy_file")
2+
load("@rules_java//java:java_library.bzl", "java_library")
13
load("@rules_scala_annex//rules:register_toolchain.bzl", "register_zinc_toolchain")
24
load("@rules_scala_annex//rules:scala.bzl", "scala_library")
35
load("@rules_scala_annex//rules/scala:versions.bzl", "scala_2_13_version", "scala_3_version")
@@ -38,7 +40,6 @@ scala_library(
3840
name = "semanticdb-2_13",
3941
srcs = glob(["*.scala"]),
4042
scala_toolchain_name = "scala_2_13_with_semanticdb",
41-
tags = ["manual"],
4243
)
4344

4445
read_semanticdb_info(
@@ -50,7 +51,6 @@ scala_library(
5051
name = "semanticdb-3",
5152
srcs = glob(["*.scala"]),
5253
scala_toolchain_name = "scala_3_with_semanticdb",
53-
tags = ["manual"],
5454
)
5555

5656
read_semanticdb_info(
@@ -60,7 +60,27 @@ read_semanticdb_info(
6060

6161
scala_library(
6262
name = "semanticdb-empty",
63-
srcs = [],
6463
scala_toolchain_name = "scala_2_13_with_semanticdb",
65-
tags = ["manual"],
64+
)
65+
66+
java_library(
67+
name = "sourcejar-library",
68+
resources = glob(["*.scala"]),
69+
)
70+
71+
copy_file(
72+
name = "sourcejar",
73+
src = ":sourcejar-library",
74+
out = "sourcejar.srcjar",
75+
)
76+
77+
scala_library(
78+
name = "semanticdb-sourcejar",
79+
srcs = [":sourcejar"],
80+
scala_toolchain_name = "scala_2_13_with_semanticdb",
81+
)
82+
83+
read_semanticdb_info(
84+
name = "semanticdb-sourcejar-semanticdb-info",
85+
scala_target = ":semanticdb-sourcejar",
6686
)

tests/plugins/semanticdb/test

+32-12
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ bazel_bin="$(bazel info bazel-bin)"
55

66
check_for_semanticdb_files() {
77
for filename in "A.scala.semanticdb" "B.scala.semanticdb"; do
8-
path="../../bazel-bin/plugins/semanticdb/semanticdb-$1/semanticdb/META-INF/semanticdb/plugins/semanticdb/$filename"
8+
path="../../bazel-bin/plugins/semanticdb/$1/semanticdb/META-INF/semanticdb/plugins/semanticdb/$filename"
99

1010
if [ ! -f "$path" ]; then
1111
echo "Error: $path doesn't exist"
@@ -15,22 +15,42 @@ check_for_semanticdb_files() {
1515
}
1616

1717
check_semanticdb_info() {
18-
bazel build ":semanticdb-$1-semanticdb-info"
18+
bazel build ":$1-semanticdb-info"
1919

20-
output_path="$bazel_bin/plugins/semanticdb/semanticdb-$1-semanticdb-info.txt"
20+
output_path="$bazel_bin/plugins/semanticdb/$1-semanticdb-info.txt"
2121
reported_semanticdb_files="$(jq -r '.semanticDbFiles[]' "$output_path" | sed -E 's_^bazel-out/[^\n/]+/bin/__g')"
22-
semanticdb_file_directory="plugins/semanticdb/semanticdb-$1/semanticdb/META-INF/semanticdb/plugins/semanticdb"
22+
semanticdb_file_directory="plugins/semanticdb/$1/semanticdb/META-INF/semanticdb/plugins/semanticdb"
2323

24-
[ "$(jq '.targetRoot' "$output_path")" = "\"plugins/semanticdb/semanticdb-$1/semanticdb\"" ]
24+
[ "$(jq '.targetRoot' "$output_path")" = "\"plugins/semanticdb/$1/semanticdb\"" ]
2525
[ "$reported_semanticdb_files" = "$semanticdb_file_directory/A.scala.semanticdb"$'\n'"$semanticdb_file_directory/B.scala.semanticdb" ]
2626
}
2727

28-
bazel build :semanticdb-2_13
29-
check_for_semanticdb_files 2_13
30-
check_semanticdb_info 2_13
28+
works_with_scala_2_13() {
29+
bazel build :semanticdb-2_13
30+
check_for_semanticdb_files semanticdb-2_13
31+
check_semanticdb_info semanticdb-2_13
32+
}
33+
34+
works_with_scala_3() {
35+
bazel build :semanticdb-3
36+
check_for_semanticdb_files semanticdb-3
37+
check_semanticdb_info semanticdb-3
38+
}
39+
40+
works_with_no_sources() {
41+
bazel build :semanticdb-empty
42+
}
43+
44+
does_not_produce_semanticdb_for_source_jars() {
45+
bazel build :semanticdb-sourcejar-semanticdb-info
3146

32-
bazel build :semanticdb-3
33-
check_for_semanticdb_files '3'
34-
check_semanticdb_info '3'
47+
semanticdb_info_path="$bazel_bin/plugins/semanticdb/semanticdb-sourcejar-semanticdb-info.txt"
48+
49+
[ "$(jq '.semanticDbFiles' "$semanticdb_info_path")" = '[]' ]
50+
[ "$(jq '.targetRoot' "$semanticdb_info_path")" = '"plugins/semanticdb/semanticdb-sourcejar/semanticdb"' ]
51+
}
3552

36-
bazel build :semanticdb-empty
53+
works_with_scala_2_13
54+
works_with_scala_3
55+
works_with_no_sources
56+
does_not_produce_semanticdb_for_source_jars

0 commit comments

Comments
 (0)