Don't require direct deps for types used in `var`
@@ -44,6 +44,7 @@ import com.sun.tools.javac.util.Name;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UncheckedIOException;
+import java.lang.reflect.Method;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Comparator;
@@ -52,6 +53,7 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
+import java.util.function.Predicate;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
@@ -353,6 +355,43 @@ public final class StrictJavaDepsPlugin extends BlazeJavaCompilerPlugin {
}
}
+ @Override
+ public void visitVarDef(JCTree.JCVariableDecl variable) {
+ scan(variable.mods);
+ if (!declaredUsingVar(variable)) {
+ scan(variable.vartype);
+ }
+ scan(variable.nameexpr);
+ scan(variable.init);
+ }
+
+ private static boolean declaredUsingVar(JCTree.JCVariableDecl variableTree) {
+ return DECLARED_USING_VAR.test(variableTree);
+ }
+
+ private static final Predicate<JCTree.JCVariableDecl> DECLARED_USING_VAR =
+ getDeclaredUsingVar();
+
+ private static Predicate<JCTree.JCVariableDecl> getDeclaredUsingVar() {
+ Method method;
+ try {
+ method = JCTree.JCVariableDecl.class.getMethod("declaredUsingVar");
+ } catch (ReflectiveOperationException e) {
+ // The method in JCVariableDecl is only available in stock JDK 17.
+ // There are no good options for earlier versions, short of looking at the source code and
+ // re-parsing the variable declaration, which would be complicated and expensive. For now,
+ // continue to enforce SJD on var for JDK < 17.
+ return variableTree -> false;
+ }
+ return variableTree -> {
+ try {
+ return (boolean) method.invoke(variableTree);
+ } catch (ReflectiveOperationException e) {
+ throw new LinkageError(e.getMessage(), e);
+ }
+ };
+ }
+
/** Visits an identifier in the AST. We only care about type symbols. */
@Override
public void visitIdent(JCTree.JCIdent tree) {
