Skip to content

Commit edc4ad6

Browse files
committed
Upgrade to Scala 2.13.12
1 parent cb25892 commit edc4ad6

File tree

12 files changed

+358
-35
lines changed

12 files changed

+358
-35
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,13 +145,13 @@ Previous minor versions may work but are supported only on a best effort basis.
145145
To configure Scala version you must call `scala_config(scala_version = "2.xx.xx")` and configure
146146
dependencies by declaring [scala_toolchain](docs/scala_toolchain.md).
147147
For a quick start you can use `scala_repositories()` and `scala_register_toolchains()`, which have
148-
dependency providers configured for `2.11.12`, `2.12.18` and `2.13.11` versions.
148+
dependency providers configured for `2.11.12`, `2.12.18` and `2.13.12` versions.
149149

150150

151151
```starlark
152152
# WORKSPACE
153153
load("@io_bazel_rules_scala//:scala_config.bzl", "scala_config")
154-
scala_config(scala_version = "2.13.11")
154+
scala_config(scala_version = "2.13.12")
155155

156156
load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies", "rules_proto_toolchains")
157157
rules_proto_dependencies()

dt_patches/dt_patch_test.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ run_test_local test_compiler_patch 2.13.7
109109
run_test_local test_compiler_patch 2.13.8
110110
run_test_local test_compiler_patch 2.13.10
111111
run_test_local test_compiler_patch 2.13.11
112+
run_test_local test_compiler_patch 2.13.12
112113

113114
run_test_local test_compiler_srcjar_error 2.12.11
114115
run_test_local test_compiler_srcjar_error 2.12.12
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
load("@io_bazel_rules_scala_config//:config.bzl", "SCALA_MAJOR_VERSION", "SCALA_MINOR_VERSION")
2+
3+
filegroup(
4+
name = "deps_tracking_reporter",
5+
srcs = [
6+
"before_2_13_12/DepsTrackingReporter.java",
7+
] 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 [
8+
"after_2_13_12/DepsTrackingReporter.java",
9+
],
10+
visibility = ["//visibility:public"],
11+
)
Lines changed: 314 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,314 @@
1+
package io.bazel.rulesscala.scalac.reporter;
2+
3+
import io.bazel.rulesscala.deps.proto.ScalaDeps;
4+
import io.bazel.rulesscala.deps.proto.ScalaDeps.Dependency;
5+
import io.bazel.rulesscala.deps.proto.ScalaDeps.Dependency.Kind;
6+
import io.bazel.rulesscala.scalac.compileoptions.CompileOptions;
7+
import scala.collection.immutable.List$;
8+
import scala.reflect.internal.util.CodeAction;
9+
import scala.reflect.internal.util.NoPosition$;
10+
import scala.reflect.internal.util.Position;
11+
import scala.tools.nsc.Settings;
12+
import scala.tools.nsc.reporters.ConsoleReporter;
13+
import scala.tools.nsc.reporters.Reporter;
14+
15+
import java.io.BufferedOutputStream;
16+
import java.io.IOException;
17+
import java.io.OutputStream;
18+
import java.nio.file.Files;
19+
import java.nio.file.Paths;
20+
import java.util.*;
21+
import java.util.jar.JarFile;
22+
import java.util.stream.Collectors;
23+
24+
public class DepsTrackingReporter extends ConsoleReporter {
25+
26+
private static final String HJAR_JAR_SUFFIX = "-hjar.jar";
27+
private static final String IJAR_JAR_SUFFIX = "-ijar.jar";
28+
private final Set<String> usedJars = new HashSet<>();
29+
30+
private final Map<String, String> jarToTarget = new HashMap<>();
31+
private final Map<String, String> indirectJarToTarget = new HashMap<>();
32+
33+
private final Set<String> ignoredTargets;
34+
private final Set<String> directTargets;
35+
36+
private final CompileOptions ops;
37+
public final Reporter delegateReporter;
38+
private Set<String> astUsedJars = new HashSet<>();
39+
40+
public DepsTrackingReporter(Settings settings, CompileOptions ops, Reporter delegate) {
41+
super(settings);
42+
this.ops = ops;
43+
this.delegateReporter = delegate;
44+
45+
if (ops.directJars.length == ops.directTargets.length) {
46+
for (int i = 0; i < ops.directJars.length; i++) {
47+
jarToTarget.put(ops.directJars[i], ops.directTargets[i]);
48+
}
49+
} else {
50+
throw new IllegalArgumentException(
51+
"mismatched size: directJars " + ops.directJars.length + " vs directTargets"
52+
+ ops.directTargets.length);
53+
}
54+
55+
if (ops.indirectJars.length == ops.indirectTargets.length) {
56+
for (int i = 0; i < ops.indirectJars.length; i++) {
57+
indirectJarToTarget.put(ops.indirectJars[i], ops.indirectTargets[i]);
58+
}
59+
} else {
60+
throw new IllegalArgumentException(
61+
"mismatched size: indirectJars " + ops.directJars.length + " vs indirectTargets "
62+
+ ops.directTargets.length);
63+
}
64+
65+
ignoredTargets = Arrays.stream(ops.unusedDepsIgnoredTargets).collect(Collectors.toSet());
66+
directTargets = Arrays.stream(ops.directTargets).collect(Collectors.toSet());
67+
}
68+
69+
private boolean isDependencyTrackingOn() {
70+
return "ast-plus".equals(ops.dependencyTrackingMethod)
71+
&& (!"off".equals(ops.strictDepsMode) || !"off".equals(ops.unusedDependencyCheckerMode));
72+
}
73+
74+
@Override
75+
public void info0(Position pos, String msg, Severity severity, boolean force) {
76+
if (msg.startsWith("DT:")) {
77+
if (isDependencyTrackingOn()) {
78+
parseOpenedJar(msg);
79+
}
80+
} else {
81+
if (delegateReporter != null) {
82+
delegateReporter.info0(pos, msg, severity, force);
83+
} else {
84+
super.info0(pos, msg, severity, force);
85+
}
86+
}
87+
}
88+
89+
private void parseOpenedJar(String msg) {
90+
String jar = msg.split(":")[1];
91+
92+
//normalize path separators (scalac passes os-specific path separators.)
93+
jar = jar.replace("\\", "/");
94+
95+
// track only jars from dependency targets
96+
// this should exclude things like rt.jar which come from JDK
97+
if (jarToTarget.containsKey(jar) || indirectJarToTarget.containsKey(jar)) {
98+
usedJars.add(jar);
99+
}
100+
}
101+
102+
public void prepareReport() throws IOException {
103+
Set<String> usedTargets = new HashSet<>();
104+
Set<Dependency> usedDeps = new HashSet<>();
105+
106+
for (String jar : usedJars) {
107+
String target = jarToTarget.get(jar);
108+
109+
if (target == null) {
110+
target = indirectJarToTarget.get(jar);
111+
}
112+
113+
if (target.startsWith("Unknown")) {
114+
target = jarLabel(jar);
115+
}
116+
117+
if (target == null) {
118+
// probably a bug if we get here
119+
continue;
120+
}
121+
122+
Dependency dep = buildDependency(
123+
jar,
124+
target,
125+
astUsedJars.contains(jar) ? Kind.EXPLICIT : Kind.IMPLICIT,
126+
ignoredTargets.contains(target)
127+
);
128+
129+
usedTargets.add(target);
130+
usedDeps.add(dep);
131+
}
132+
133+
Set<Dependency> unusedDeps = new HashSet<>();
134+
for (int i = 0; i < ops.directTargets.length; i++) {
135+
String directTarget = ops.directTargets[i];
136+
if (usedTargets.contains(directTarget)) {
137+
continue;
138+
}
139+
140+
unusedDeps.add(
141+
buildDependency(
142+
ops.directJars[i],
143+
directTarget,
144+
Kind.UNUSED,
145+
ignoredTargets.contains(directTarget) || "off".equals(ops.unusedDependencyCheckerMode)
146+
)
147+
);
148+
}
149+
150+
writeSdepsFile(usedDeps, unusedDeps);
151+
152+
Reporter reporter = this.delegateReporter != null ? this.delegateReporter : this;
153+
reportDeps(usedDeps, unusedDeps, reporter);
154+
}
155+
156+
private Dependency buildDependency(String jar, String target, Kind kind, boolean ignored) {
157+
ScalaDeps.Dependency.Builder dependecyBuilder = ScalaDeps.Dependency.newBuilder();
158+
159+
dependecyBuilder.setKind(kind);
160+
dependecyBuilder.setLabel(target);
161+
dependecyBuilder.setIjarPath(jar);
162+
dependecyBuilder.setPath(guessFullJarPath(jar));
163+
dependecyBuilder.setIgnored(ignored);
164+
165+
return dependecyBuilder.build();
166+
}
167+
168+
private void writeSdepsFile(Collection<Dependency> usedDeps, Collection<Dependency> unusedDeps)
169+
throws IOException {
170+
171+
ScalaDeps.Dependencies.Builder builder = ScalaDeps.Dependencies.newBuilder();
172+
builder.setRuleLabel(ops.currentTarget);
173+
builder.setDependencyTrackingMethod(ops.dependencyTrackingMethod);
174+
builder.addAllDependency(usedDeps);
175+
builder.addAllDependency(unusedDeps);
176+
177+
try (OutputStream outputStream = new BufferedOutputStream(
178+
Files.newOutputStream(Paths.get(ops.scalaDepsFile)))) {
179+
outputStream.write(builder.build().toByteArray());
180+
}
181+
}
182+
183+
private void reportDeps(Collection<Dependency> usedDeps, Collection<Dependency> unusedDeps,
184+
Reporter reporter) {
185+
if (ops.dependencyTrackingMethod.equals("ast-plus")) {
186+
187+
if (!ops.strictDepsMode.equals("off")) {
188+
boolean isWarning = ops.strictDepsMode.equals("warn");
189+
StringBuilder strictDepsReport = new StringBuilder("Missing strict dependencies:\n");
190+
StringBuilder compilerDepsReport = new StringBuilder("Missing compiler dependencies:\n");
191+
int strictDepsCount = 0;
192+
int compilerDepsCount = 0;
193+
for (Dependency dep : usedDeps) {
194+
String depReport = addDepMessage(dep);
195+
if (dep.getIgnored()) {
196+
continue;
197+
}
198+
199+
if (directTargets.contains(dep.getLabel())) {
200+
continue;
201+
}
202+
203+
if (dep.getKind() == Kind.EXPLICIT) {
204+
strictDepsCount++;
205+
strictDepsReport
206+
.append(isWarning ? "warning: " : "error: ")
207+
.append(depReport);
208+
} else {
209+
compilerDepsCount++;
210+
compilerDepsReport
211+
.append(isWarning ? "warning: " : "error: ")
212+
.append(depReport);
213+
}
214+
}
215+
216+
if (strictDepsCount > 0) {
217+
if (ops.strictDepsMode.equals("warn")) {
218+
reporter.warning(NoPosition$.MODULE$, strictDepsReport.toString(), List$.MODULE$.<CodeAction>empty());
219+
} else {
220+
reporter.error(NoPosition$.MODULE$, strictDepsReport.toString(), List$.MODULE$.<CodeAction>empty());
221+
}
222+
}
223+
224+
if (!ops.compilerDepsMode.equals("off") && compilerDepsCount > 0) {
225+
if (ops.compilerDepsMode.equals("warn")) {
226+
reporter.warning(NoPosition$.MODULE$, compilerDepsReport.toString(), List$.MODULE$.<CodeAction>empty());
227+
} else {
228+
reporter.error(NoPosition$.MODULE$, compilerDepsReport.toString(), List$.MODULE$.<CodeAction>empty());
229+
}
230+
}
231+
}
232+
233+
if (!ops.unusedDependencyCheckerMode.equals("off")) {
234+
boolean isWarning = ops.unusedDependencyCheckerMode.equals("warn");
235+
StringBuilder unusedDepsReport = new StringBuilder("Unused dependencies:\n");
236+
int count = 0;
237+
for (Dependency dep : unusedDeps) {
238+
if (dep.getIgnored()) {
239+
continue;
240+
}
241+
count++;
242+
unusedDepsReport
243+
.append(isWarning ? "warning: " : "error: ")
244+
.append(removeDepMessage(dep));
245+
}
246+
if (count > 0) {
247+
if (isWarning) {
248+
reporter.warning(NoPosition$.MODULE$, unusedDepsReport.toString(), List$.MODULE$.<CodeAction>empty());
249+
} else if (ops.unusedDependencyCheckerMode.equals("error")) {
250+
//reporter.error(NoPosition$.MODULE$, unusedDepsReport.toString(), List$.MODULE$.<CodeAction>empty());
251+
}
252+
}
253+
}
254+
}
255+
}
256+
257+
private String addDepMessage(Dependency dep) {
258+
String target = dep.getLabel();
259+
String jar = dep.getPath();
260+
261+
String message = "Target '" + target + "' (via jar: ' " + jar + " ') "
262+
+ "is being used by " + ops.currentTarget
263+
+ " but is is not specified as a dependency, please add it to the deps.\n"
264+
+ "You can use the following buildozer command:\n";
265+
String command = "buildozer 'add deps " + target + "' " + ops.currentTarget + "\n";
266+
return message + command;
267+
}
268+
269+
private String removeDepMessage(Dependency dep) {
270+
String target = dep.getLabel();
271+
String jar = dep.getPath();
272+
273+
String message = "Target '" + target + "' (via jar: ' " + jar + " ') "
274+
+ "is specified as a dependency to " + ops.currentTarget
275+
+ " but isn't used, please remove it from the deps.\n"
276+
+ "You can use the following buildozer command:\n";
277+
String command = "buildozer 'remove deps " + target + "' " + ops.currentTarget + "\n";
278+
279+
return message + command;
280+
}
281+
282+
private String guessFullJarPath(String jar) {
283+
if (jar.endsWith(IJAR_JAR_SUFFIX)) {
284+
return stripIjarSuffix(jar, IJAR_JAR_SUFFIX);
285+
} else if (jar.endsWith(HJAR_JAR_SUFFIX)) {
286+
return stripIjarSuffix(jar, HJAR_JAR_SUFFIX);
287+
} else {
288+
return jar;
289+
}
290+
}
291+
292+
private static String stripIjarSuffix(String jar, String suffix) {
293+
return jar.substring(0, jar.length() - suffix.length()) + ".jar";
294+
}
295+
296+
private String jarLabel(String path) throws IOException {
297+
try (JarFile jar = new JarFile(path)) {
298+
return jar.getManifest().getMainAttributes().getValue("Target-Label");
299+
}
300+
}
301+
302+
public void registerAstUsedJars(Set<String> jars) {
303+
astUsedJars = jars;
304+
}
305+
306+
public void writeDiagnostics(String diagnosticsFile) throws IOException {
307+
if (delegateReporter == null) {
308+
return;
309+
}
310+
311+
ProtoReporter protoReporter = (ProtoReporter) delegateReporter;
312+
protoReporter.writeTo(Paths.get(diagnosticsFile));
313+
}
314+
}

src/java/io/bazel/rulesscala/scalac/reporter/DepsTrackingReporter.java renamed to src/java/io/bazel/rulesscala/scalac/deps_tracking_reporter/before_2_13_12/DepsTrackingReporter.java

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,21 @@
44
import io.bazel.rulesscala.deps.proto.ScalaDeps.Dependency;
55
import io.bazel.rulesscala.deps.proto.ScalaDeps.Dependency.Kind;
66
import io.bazel.rulesscala.scalac.compileoptions.CompileOptions;
7+
import io.bazel.rulesscala.scalac.reporter.ProtoReporter;
8+
import scala.reflect.internal.util.NoPosition$;
9+
import scala.reflect.internal.util.Position;
10+
import scala.tools.nsc.Settings;
11+
import scala.tools.nsc.reporters.ConsoleReporter;
12+
import scala.tools.nsc.reporters.Reporter;
13+
714
import java.io.BufferedOutputStream;
815
import java.io.IOException;
916
import java.io.OutputStream;
1017
import java.nio.file.Files;
1118
import java.nio.file.Paths;
12-
import java.util.Arrays;
13-
import java.util.Collection;
14-
import java.util.HashMap;
15-
import java.util.HashSet;
16-
import java.util.Map;
17-
import java.util.Set;
19+
import java.util.*;
1820
import java.util.jar.JarFile;
1921
import java.util.stream.Collectors;
20-
import scala.reflect.internal.util.NoPosition$;
21-
import scala.reflect.internal.util.Position;
22-
import scala.tools.nsc.Settings;
23-
import scala.tools.nsc.reporters.ConsoleReporter;
24-
import scala.tools.nsc.reporters.Reporter;
2522

2623
public class DepsTrackingReporter extends ConsoleReporter {
2724

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ load("@io_bazel_rules_scala_config//:config.bzl", "SCALA_MAJOR_VERSION")
55
java_library(
66
name = "reporter",
77
srcs = [
8-
"DepsTrackingReporter.java",
8+
"//src/java/io/bazel/rulesscala/scalac/deps_tracking_reporter",
99
"ProtoReporter.java",
1010
] if SCALA_MAJOR_VERSION.startswith("2") else ["PlaceholderForEmptyScala3Lib.java"],
1111
visibility = ["//visibility:public"],

0 commit comments

Comments
 (0)