Skip to content

Commit f938141

Browse files
authored
Fix diagnostics for Scala 2.13.12 (#1522)
* Fix diagnostics for Scala 2.13.12 * Fix sha256sum for org.scalameta:semanticdb-scalac_2_11:4.8.6 * Add Tally as an adopter * Fix ProtoReporter issue with semanticdb in Scala 2.12.x
1 parent 9c0f6b9 commit f938141

File tree

10 files changed

+304
-10
lines changed

10 files changed

+304
-10
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ Here's a (non-exhaustive) list of companies that use `rules_scala` in production
280280
* [Meetup](https://meetup.com/)
281281
* [Spotify](https://www.spotify.com/)
282282
* [Stripe](https://stripe.com/)
283+
* [Tally](https://www.meettally.com/)
283284
* [Twitter](https://twitter.com/)
284285
* [VSCO](https://vsco.co)
285286
* [Wix](https://www.wix.com/)

src/java/io/bazel/rulesscala/scalac/reporter/BUILD

+9-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
load("@rules_proto//proto:defs.bzl", "proto_library")
22
load("@rules_java//java:defs.bzl", "java_library", "java_proto_library")
3-
load("@io_bazel_rules_scala_config//:config.bzl", "SCALA_MAJOR_VERSION")
3+
load("@io_bazel_rules_scala_config//:config.bzl", "SCALA_MAJOR_VERSION", "SCALA_MINOR_VERSION")
44

55
java_library(
66
name = "reporter",
77
srcs = [
88
"//src/java/io/bazel/rulesscala/scalac/deps_tracking_reporter",
9-
"ProtoReporter.java",
10-
] if SCALA_MAJOR_VERSION.startswith("2") else ["PlaceholderForEmptyScala3Lib.java"],
9+
"before_2_12_13/ProtoReporter.java",
10+
] if SCALA_MAJOR_VERSION.startswith("2.11") or (SCALA_MAJOR_VERSION.startswith("2.12") and int(SCALA_MINOR_VERSION) < 13) else [
11+
"//src/java/io/bazel/rulesscala/scalac/deps_tracking_reporter",
12+
"after_2_12_13_and_before_2_13_12/ProtoReporter.java",
13+
] if ((SCALA_MAJOR_VERSION.startswith("2.12") and int(SCALA_MINOR_VERSION) >= 13) or (SCALA_MAJOR_VERSION.startswith("2.13") and int(SCALA_MINOR_VERSION) < 12)) else [
14+
"//src/java/io/bazel/rulesscala/scalac/deps_tracking_reporter",
15+
"after_2_13_12/ProtoReporter.java",
16+
] if (SCALA_MAJOR_VERSION.startswith("2.13") and int(SCALA_MINOR_VERSION) >= 12) else ["PlaceholderForEmptyScala3Lib.java"],
1117
visibility = ["//visibility:public"],
1218
deps = [
1319
":scala_deps_java_proto",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package io.bazel.rulesscala.scalac.reporter;
2+
3+
import io.bazel.rules_scala.diagnostics.Diagnostics;
4+
import java.io.IOException;
5+
import java.nio.file.Files;
6+
import java.nio.file.Path;
7+
import java.nio.file.StandardOpenOption;
8+
import java.util.*;
9+
import scala.reflect.internal.util.Position;
10+
import scala.reflect.internal.util.RangePosition;
11+
import scala.tools.nsc.Settings;
12+
import scala.tools.nsc.reporters.ConsoleReporter;
13+
14+
public class ProtoReporter extends ConsoleReporter {
15+
16+
private final Map<String, List<Diagnostics.Diagnostic>> builder;
17+
18+
public ProtoReporter(Settings settings) {
19+
super(settings);
20+
builder = new LinkedHashMap<>();
21+
}
22+
23+
@Override
24+
public void reset() {
25+
super.reset();
26+
}
27+
28+
public void writeTo(Path path) throws IOException {
29+
Diagnostics.TargetDiagnostics.Builder targetDiagnostics =
30+
Diagnostics.TargetDiagnostics.newBuilder();
31+
for (Map.Entry<String, List<Diagnostics.Diagnostic>> entry : builder.entrySet()) {
32+
targetDiagnostics.addDiagnostics(
33+
Diagnostics.FileDiagnostics.newBuilder()
34+
.setPath(entry.getKey())
35+
.addAllDiagnostics(entry.getValue()));
36+
}
37+
Files.write(
38+
path,
39+
targetDiagnostics.build().toByteArray(),
40+
StandardOpenOption.CREATE,
41+
StandardOpenOption.APPEND);
42+
}
43+
44+
@Override
45+
public void info0(Position pos, String msg, Severity severity, boolean force) {
46+
doReport(pos, msg, severity);
47+
}
48+
49+
@Override
50+
public void doReport(Position pos, String msg, Severity severity) {
51+
super.doReport(pos, msg, severity);
52+
53+
Diagnostics.Diagnostic diagnostic =
54+
Diagnostics.Diagnostic.newBuilder()
55+
.setRange(positionToRange(pos))
56+
.setSeverity(convertSeverity(severity))
57+
.setMessage(msg)
58+
.build();
59+
// TODO: Handle generated files
60+
String uri = "workspace-root://" + pos.source().file().path();
61+
List<Diagnostics.Diagnostic> diagnostics = builder.computeIfAbsent(uri, key -> new ArrayList());
62+
diagnostics.add(diagnostic);
63+
}
64+
65+
private Diagnostics.Severity convertSeverity(Object severity) {
66+
String stringified = severity.toString().toLowerCase();
67+
if ("error".equals(stringified)) {
68+
return Diagnostics.Severity.ERROR;
69+
} else if ("warning".equals(stringified)) {
70+
return Diagnostics.Severity.WARNING;
71+
} else if ("info".equals(stringified)) {
72+
return Diagnostics.Severity.INFORMATION;
73+
}
74+
throw new RuntimeException("Unknown severity: " + stringified);
75+
}
76+
77+
private Diagnostics.Range positionToRange(Position pos) {
78+
if (pos instanceof RangePosition) {
79+
RangePosition rangePos = (RangePosition) pos;
80+
int startLine = pos.source().offsetToLine(rangePos.start());
81+
int endLine = pos.source().offsetToLine(rangePos.end());
82+
return Diagnostics.Range.newBuilder()
83+
.setStart(
84+
Diagnostics.Position.newBuilder()
85+
.setLine(startLine)
86+
.setCharacter(rangePos.start() - pos.source().lineToOffset(startLine)))
87+
.setEnd(
88+
Diagnostics.Position.newBuilder()
89+
.setLine(endLine)
90+
.setCharacter(rangePos.end() - pos.source().lineToOffset(endLine))
91+
.build())
92+
.build();
93+
}
94+
return Diagnostics.Range.newBuilder()
95+
.setStart(
96+
Diagnostics.Position.newBuilder()
97+
.setLine(pos.line() - 1)
98+
.setCharacter(pos.column() - 1))
99+
.setEnd(Diagnostics.Position.newBuilder().setLine(pos.line()))
100+
.build();
101+
}
102+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package io.bazel.rulesscala.scalac.reporter;
2+
3+
import io.bazel.rules_scala.diagnostics.Diagnostics;
4+
import java.io.IOException;
5+
import java.nio.file.Files;
6+
import java.nio.file.Path;
7+
import java.nio.file.StandardOpenOption;
8+
import java.util.*;
9+
import scala.collection.immutable.List$;
10+
import scala.reflect.internal.util.CodeAction;
11+
import scala.reflect.internal.util.Position;
12+
import scala.reflect.internal.util.RangePosition;
13+
import scala.tools.nsc.Settings;
14+
import scala.tools.nsc.reporters.ConsoleReporter;
15+
16+
public class ProtoReporter extends ConsoleReporter {
17+
18+
private final Map<String, List<Diagnostics.Diagnostic>> builder;
19+
20+
public ProtoReporter(Settings settings) {
21+
super(settings);
22+
builder = new LinkedHashMap<>();
23+
}
24+
25+
@Override
26+
public void reset() {
27+
super.reset();
28+
}
29+
30+
public void writeTo(Path path) throws IOException {
31+
Diagnostics.TargetDiagnostics.Builder targetDiagnostics =
32+
Diagnostics.TargetDiagnostics.newBuilder();
33+
for (Map.Entry<String, List<Diagnostics.Diagnostic>> entry : builder.entrySet()) {
34+
targetDiagnostics.addDiagnostics(
35+
Diagnostics.FileDiagnostics.newBuilder()
36+
.setPath(entry.getKey())
37+
.addAllDiagnostics(entry.getValue()));
38+
}
39+
Files.write(
40+
path,
41+
targetDiagnostics.build().toByteArray(),
42+
StandardOpenOption.CREATE,
43+
StandardOpenOption.APPEND);
44+
}
45+
46+
@Override
47+
public void doReport(Position pos, String msg, Severity severity, scala.collection.immutable.List<CodeAction> actions) {
48+
super.doReport(pos, msg, severity, List$.MODULE$.<CodeAction>empty());
49+
50+
Diagnostics.Diagnostic diagnostic =
51+
Diagnostics.Diagnostic.newBuilder()
52+
.setRange(positionToRange(pos))
53+
.setSeverity(convertSeverity(severity))
54+
.setMessage(msg)
55+
.build();
56+
// TODO: Handle generated files
57+
String uri = "workspace-root://" + pos.source().file().path();
58+
List<Diagnostics.Diagnostic> diagnostics = builder.computeIfAbsent(uri, key -> new ArrayList());
59+
diagnostics.add(diagnostic);
60+
}
61+
62+
private Diagnostics.Severity convertSeverity(Object severity) {
63+
String stringified = severity.toString().toLowerCase();
64+
if ("error".equals(stringified)) {
65+
return Diagnostics.Severity.ERROR;
66+
} else if ("warning".equals(stringified)) {
67+
return Diagnostics.Severity.WARNING;
68+
} else if ("info".equals(stringified)) {
69+
return Diagnostics.Severity.INFORMATION;
70+
}
71+
throw new RuntimeException("Unknown severity: " + stringified);
72+
}
73+
74+
private Diagnostics.Range positionToRange(Position pos) {
75+
if (pos instanceof RangePosition) {
76+
RangePosition rangePos = (RangePosition) pos;
77+
int startLine = pos.source().offsetToLine(rangePos.start());
78+
int endLine = pos.source().offsetToLine(rangePos.end());
79+
return Diagnostics.Range.newBuilder()
80+
.setStart(
81+
Diagnostics.Position.newBuilder()
82+
.setLine(startLine)
83+
.setCharacter(rangePos.start() - pos.source().lineToOffset(startLine)))
84+
.setEnd(
85+
Diagnostics.Position.newBuilder()
86+
.setLine(endLine)
87+
.setCharacter(rangePos.end() - pos.source().lineToOffset(endLine))
88+
.build())
89+
.build();
90+
}
91+
return Diagnostics.Range.newBuilder()
92+
.setStart(
93+
Diagnostics.Position.newBuilder()
94+
.setLine(pos.line() - 1)
95+
.setCharacter(pos.column() - 1))
96+
.setEnd(Diagnostics.Position.newBuilder().setLine(pos.line()))
97+
.build();
98+
}
99+
}

src/java/io/bazel/rulesscala/scalac/reporter/ProtoReporter.java renamed to src/java/io/bazel/rulesscala/scalac/reporter/before_2_12_13/ProtoReporter.java

+9-5
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
11
package io.bazel.rulesscala.scalac.reporter;
22

33
import io.bazel.rules_scala.diagnostics.Diagnostics;
4-
import java.io.IOException;
5-
import java.nio.file.Files;
6-
import java.nio.file.Path;
7-
import java.nio.file.StandardOpenOption;
8-
import java.util.*;
94
import scala.reflect.internal.util.Position;
105
import scala.reflect.internal.util.RangePosition;
116
import scala.tools.nsc.Settings;
127
import scala.tools.nsc.reporters.ConsoleReporter;
138

9+
import java.io.IOException;
10+
import java.nio.file.Files;
11+
import java.nio.file.Path;
12+
import java.nio.file.StandardOpenOption;
13+
import java.util.ArrayList;
14+
import java.util.LinkedHashMap;
15+
import java.util.List;
16+
import java.util.Map;
17+
1418
public class ProtoReporter extends ConsoleReporter {
1519

1620
private final Map<String, List<Diagnostics.Diagnostic>> builder;

test/diagnostics_reporter/BUILD

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
load("@rules_java//java:defs.bzl", "java_binary")
2+
load("@io_bazel_rules_scala_config//:config.bzl", "SCALA_MAJOR_VERSION", "SCALA_MINOR_VERSION")
23

34
java_binary(
45
name = "diagnostics_reporter_test",
56
srcs = [
6-
"DiagnosticsReporterTest.java",
7+
"before_2_13_12/DiagnosticsReporterTest.java",
8+
"VerifyDiagnosticsOutput.java",
9+
] if SCALA_MAJOR_VERSION.startswith("2.11") or SCALA_MAJOR_VERSION.startswith("2.12") or (SCALA_MAJOR_VERSION.startswith("2.13") and int(SCALA_MINOR_VERSION) < 12) else [
10+
"after_2_13_12/DiagnosticsReporterTest.java",
711
"VerifyDiagnosticsOutput.java",
812
],
913
main_class = "diagnostics_reporter.DiagnosticsReporterTest",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package diagnostics_reporter;
2+
3+
import io.bazel.rules_scala.diagnostics.Diagnostics;
4+
import java.io.IOException;
5+
import java.util.HashMap;
6+
import java.util.List;
7+
import java.util.Map;
8+
9+
public class DiagnosticsReporterTest {
10+
@SuppressWarnings("DoubleBraceInitialization")
11+
private static final Map<String, diagnostics_reporter.VerifyDiagnosticsOutput[]> tests =
12+
new HashMap<String, diagnostics_reporter.VerifyDiagnosticsOutput[]>() {
13+
{
14+
put(
15+
"error_file",
16+
new diagnostics_reporter.VerifyDiagnosticsOutput[] {
17+
new diagnostics_reporter.VerifyDiagnosticsOutput(
18+
Diagnostics.Severity.ERROR, 5, 2, 6, 0)
19+
});
20+
put(
21+
"two_errors_file",
22+
new diagnostics_reporter.VerifyDiagnosticsOutput[] {
23+
new diagnostics_reporter.VerifyDiagnosticsOutput(
24+
Diagnostics.Severity.ERROR, 4, 4, 4, 10),
25+
new diagnostics_reporter.VerifyDiagnosticsOutput(
26+
Diagnostics.Severity.ERROR, 5, 4, 5, 9)
27+
});
28+
put(
29+
"warning_file",
30+
new diagnostics_reporter.VerifyDiagnosticsOutput[] {
31+
new diagnostics_reporter.VerifyDiagnosticsOutput(
32+
Diagnostics.Severity.WARNING, 0, 0, 0, 26)
33+
});
34+
put(
35+
"error_and_warning_file",
36+
new diagnostics_reporter.VerifyDiagnosticsOutput[] {
37+
new diagnostics_reporter.VerifyDiagnosticsOutput(
38+
Diagnostics.Severity.WARNING, 0, 0, 0, 26),
39+
new diagnostics_reporter.VerifyDiagnosticsOutput(
40+
Diagnostics.Severity.ERROR, 4, 4, 4, 10)
41+
});
42+
put(
43+
"info_file",
44+
new diagnostics_reporter.VerifyDiagnosticsOutput[] {
45+
new diagnostics_reporter.VerifyDiagnosticsOutput(
46+
Diagnostics.Severity.INFORMATION, -1, -1, 0, 0)
47+
});
48+
}
49+
};
50+
51+
public static void main(String[] args) throws IOException {
52+
if (args.length != 1) throw new IllegalArgumentException("Args: <diagnostics_output>");
53+
54+
String diagnosticsOutput = args[0];
55+
for (Map.Entry<String, VerifyDiagnosticsOutput[]> entry : tests.entrySet()) {
56+
String test = entry.getKey();
57+
VerifyDiagnosticsOutput[] expectedDiagnosticsOutputs = entry.getValue();
58+
List<Diagnostics.Diagnostic> diagnostics =
59+
VerifyDiagnosticsOutput.getDiagnostics(
60+
diagnosticsOutput + "/" + test + ".diagnosticsproto");
61+
for (VerifyDiagnosticsOutput expectedDiagnostic : expectedDiagnosticsOutputs) {
62+
expectedDiagnostic.testOutput(diagnostics);
63+
}
64+
}
65+
}
66+
}

test_version.sh

+12
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,15 @@ test_reporter() {
6868
run_in_test_repo "compilation_should_fail build //... --repo_env=SCALA_VERSION=${SCALA_VERSION} --extra_toolchains=${SCALA_TOOLCHAIN}" "reporter" "test_reporter/"
6969
}
7070

71+
test_diagnostic_proto_files() {
72+
local SCALA_VERSION="$1"
73+
local SCALA_TOOLCHAIN="$2"
74+
75+
compilation_should_fail build --build_event_publish_all_actions -k --repo_env=SCALA_VERSION=${SCALA_VERSION} --extra_toolchains=${SCALA_TOOLCHAIN} //test_expect_failure/diagnostics_reporter:all
76+
diagnostics_output="$(bazel info bazel-bin)/test_expect_failure/diagnostics_reporter"
77+
bazel run --repo_env=SCALA_VERSION=${SCALA_VERSION} //test/diagnostics_reporter:diagnostics_reporter_test "$diagnostics_output"
78+
}
79+
7180
test_twitter_scrooge_versions() {
7281
local version_under_test=$1
7382

@@ -111,3 +120,6 @@ TEST_TIMEOUT=15 $runner test_reporter "${scala_2_13_version}" "${no_diagnostics_
111120
TEST_TIMEOUT=15 $runner test_reporter "${scala_2_11_version}" "${diagnostics_reporter_toolchain}"
112121
TEST_TIMEOUT=15 $runner test_reporter "${scala_2_12_version}" "${diagnostics_reporter_toolchain}"
113122
TEST_TIMEOUT=15 $runner test_reporter "${scala_2_13_version}" "${diagnostics_reporter_toolchain}"
123+
124+
TEST_TIMEOUT=15 $runner test_diagnostic_proto_files "${scala_2_12_version}" "//test_expect_failure/diagnostics_reporter:diagnostics_reporter_toolchain"
125+
TEST_TIMEOUT=15 $runner test_diagnostic_proto_files "${scala_2_13_version}" "//test_expect_failure/diagnostics_reporter:diagnostics_reporter_toolchain"

third_party/repositories/scala_2_11.bzl

+1-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ artifacts = {
7979
},
8080
"org_scalameta_semanticdb_scalac": {
8181
"artifact": "org.scalameta:semanticdb-scalac_%s:4.8.6" % scala_version,
82-
"sha256": "1253abd1e8c8b3ec0720995d378846bbc439d168e7ea815fe91da6bef8b1de9d",
82+
"sha256": "5700b0b425eac8e1d0c27660ae96879ef688731cc0d2f2e8cdc7e20496f87670",
8383
"deps": [
8484
"@io_bazel_rules_scala_scala_library",
8585
],

0 commit comments

Comments
 (0)