aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Googler <noreply@google.com>2016-09-21 04:20:51 +0000
committerGravatar Laszlo Csomor <laszlocsomor@google.com>2016-09-21 07:14:44 +0000
commitc07af7aba8734a0690fa769e482f080ddd447b78 (patch)
tree996c3572dcc2615a857ff74235c37a1356434bdf
parent2e5ec0fd99ac4bfd930da99f6089dc5faf778464 (diff)
Mark unresolved classes in jdeps as Kind.INCOMPLETE.
Currently, all classes from the symbol table are added to jdeps, even if some of them haven't been resolved and as such aren't actually used. This causes siblings from other jars (such as R.java) to be added to jdeps, even though they are not actually referenced. Mark these with Kind.UNRESOLVED to allow code to discard these. All non-test code that references Kind.IMPLICIT has been modified to also check for Kind.INCOMPLETE to keep the current behavior unchanged. Eg: jar liba.jar: package a; class A { void test() { // Use R.id } } jar liba_resources.jar: package a; class R { } package b; import a; class MyClass { A a = new A(); } ---> jdeps will contain both liba.jar, liba_resources.jar the latter will now have Kind.INCOMPLETE. -- MOS_MIGRATED_REVID=133791687
-rw-r--r--src/java_tools/buildjar/java/com/google/devtools/build/buildjar/javac/plugins/dependency/DependencyModule.java4
-rw-r--r--src/java_tools/buildjar/java/com/google/devtools/build/buildjar/javac/plugins/dependency/ImplicitDependencyExtractor.java64
-rw-r--r--src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/javac/JavacTurbineTest.java6
-rw-r--r--src/main/protobuf/deps.proto2
4 files changed, 44 insertions, 32 deletions
diff --git a/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/javac/plugins/dependency/DependencyModule.java b/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/javac/plugins/dependency/DependencyModule.java
index efb7a439e9..e5e82264e2 100644
--- a/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/javac/plugins/dependency/DependencyModule.java
+++ b/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/javac/plugins/dependency/DependencyModule.java
@@ -299,7 +299,9 @@ public final class DependencyModule {
throw new IOException("Could not parse Deps.Dependencies message from proto.");
}
for (Deps.Dependency dep : deps.getDependencyList()) {
- if (dep.getKind() == Kind.EXPLICIT || dep.getKind() == Kind.IMPLICIT) {
+ if (dep.getKind() == Kind.EXPLICIT
+ || dep.getKind() == Kind.IMPLICIT
+ || dep.getKind() == Kind.INCOMPLETE) {
requiredClasspath.add(dep.getPath());
}
}
diff --git a/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/javac/plugins/dependency/ImplicitDependencyExtractor.java b/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/javac/plugins/dependency/ImplicitDependencyExtractor.java
index 07a9ff9614..850d94ba52 100644
--- a/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/javac/plugins/dependency/ImplicitDependencyExtractor.java
+++ b/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/javac/plugins/dependency/ImplicitDependencyExtractor.java
@@ -50,29 +50,29 @@ public class ImplicitDependencyExtractor {
private final Set<String> depsSet;
/** Map collecting dependency information, used for the proto output */
private final Map<String, Deps.Dependency> depsMap;
+
private final TypeVisitor typeVisitor = new TypeVisitor();
private final JavaFileManager fileManager;
/**
- * ImplicitDependencyExtractor does not guarantee any ordering of the reported
- * dependencies. Clients should preserve the original classpath ordering
- * if trying to minimize their classpaths using this information.
+ * ImplicitDependencyExtractor does not guarantee any ordering of the reported dependencies.
+ * Clients should preserve the original classpath ordering if trying to minimize their classpaths
+ * using this information.
*/
- public ImplicitDependencyExtractor(Set<String> depsSet, Map<String, Deps.Dependency> depsMap,
- JavaFileManager fileManager) {
+ public ImplicitDependencyExtractor(
+ Set<String> depsSet, Map<String, Deps.Dependency> depsMap, JavaFileManager fileManager) {
this.depsSet = depsSet;
this.depsMap = depsMap;
this.fileManager = fileManager;
}
/**
- * Collects the implicit dependencies of the given set of ClassSymbol roots.
- * As we're interested in differentiating between symbols that were just
- * resolved vs. symbols that were fully completed by the compiler, we start
- * the analysis by finding all the implicit dependencies reachable from the
- * given set of roots. For completeness, we then walk the symbol table
- * associated with the given context and collect the jar files of the
- * remaining class symbols found there.
+ * Collects the implicit dependencies of the given set of ClassSymbol roots. As we're interested
+ * in differentiating between symbols that were just resolved vs. symbols that were fully
+ * completed by the compiler, we start the analysis by finding all the implicit dependencies
+ * reachable from the given set of roots. For completeness, we then walk the symbol table
+ * associated with the given context and collect the jar files of the remaining class symbols
+ * found there.
*
* @param context compilation context
* @param roots root classes in the implicit dependency collection
@@ -92,17 +92,18 @@ public class ImplicitDependencyExtractor {
// Collect all other partially resolved types
for (ClassSymbol cs : symtab.classes.values()) {
+ // When recording we want to differentiate between jar references through completed symbols
+ // and incomplete symbols
+ boolean completed = cs.isCompleted();
if (cs.classfile != null) {
- collectJarOf(cs.classfile, platformJars);
+ collectJarOf(cs.classfile, platformJars, completed);
} else if (cs.sourcefile != null) {
- collectJarOf(cs.sourcefile, platformJars);
+ collectJarOf(cs.sourcefile, platformJars, completed);
}
}
}
- /**
- * Collect the set of jars on the compilation bootclasspath.
- */
+ /** Collect the set of jars on the compilation bootclasspath. */
public static Set<String> getPlatformJars(JavaFileManager fileManager) {
if (fileManager instanceof StandardJavaFileManager) {
@@ -125,18 +126,19 @@ public class ImplicitDependencyExtractor {
// TODO(cushon): Assuming JavacPathFileManager or StandardJavaFileManager is slightly brittle,
// but in practice those are the only implementations that matter.
- throw new IllegalStateException("Unsupported file manager type: "
- + fileManager.getClass().toString());
+ throw new IllegalStateException(
+ "Unsupported file manager type: " + fileManager.getClass().getName());
}
/**
- * Attempts to add the jar associated with the given JavaFileObject, if any,
- * to the collection, filtering out jars on the compilation bootclasspath.
+ * Attempts to add the jar associated with the given JavaFileObject, if any, to the collection,
+ * filtering out jars on the compilation bootclasspath.
*
* @param reference JavaFileObject representing a class or source file
* @param platformJars classes on javac's bootclasspath
+ * @param completed whether the jar was referenced through a completed symbol
*/
- private void collectJarOf(JavaFileObject reference, Set<String> platformJars) {
+ private void collectJarOf(JavaFileObject reference, Set<String> platformJars, boolean completed) {
String name = getJarName(fileManager, reference);
if (name == null) {
@@ -149,11 +151,18 @@ public class ImplicitDependencyExtractor {
}
depsSet.add(name);
- if (!depsMap.containsKey(name)) {
- depsMap.put(name, Deps.Dependency.newBuilder()
- .setKind(Deps.Dependency.Kind.IMPLICIT)
- .setPath(name)
- .build());
+ Deps.Dependency currentDep = depsMap.get(name);
+
+ // If the dep hasn't been recorded we add it to the map
+ // If it's been recorded as INCOMPLETE but is now complete we upgrade the dependency
+ if (currentDep == null
+ || (completed && currentDep.getKind() == Deps.Dependency.Kind.INCOMPLETE)) {
+ depsMap.put(
+ name,
+ Deps.Dependency.newBuilder()
+ .setKind(completed ? Deps.Dependency.Kind.IMPLICIT : Deps.Dependency.Kind.INCOMPLETE)
+ .setPath(name)
+ .build());
}
}
@@ -182,7 +191,6 @@ public class ImplicitDependencyExtractor {
return null;
}
-
private static class TypeVisitor extends SimpleTypeVisitor7<Void, Void> {
// TODO(bazel-team): Override the visitor methods we're interested in.
}
diff --git a/src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/javac/JavacTurbineTest.java b/src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/javac/JavacTurbineTest.java
index 395835efbc..2e6d453083 100644
--- a/src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/javac/JavacTurbineTest.java
+++ b/src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/javac/JavacTurbineTest.java
@@ -407,8 +407,8 @@ public class JavacTurbineTest {
.containsExactlyEntriesIn(
ImmutableMap.of(
libA.toString(), Deps.Dependency.Kind.EXPLICIT,
- libB.toString(), Deps.Dependency.Kind.IMPLICIT,
- libC.toString(), Deps.Dependency.Kind.IMPLICIT));
+ libB.toString(), Deps.Dependency.Kind.INCOMPLETE,
+ libC.toString(), Deps.Dependency.Kind.INCOMPLETE));
}
private Map<String, Deps.Dependency.Kind> getEntries(Deps.Dependencies deps) {
@@ -555,7 +555,7 @@ public class JavacTurbineTest {
libA.toString(),
Deps.Dependency.Kind.EXPLICIT,
libB.toString(),
- Deps.Dependency.Kind.IMPLICIT));
+ Deps.Dependency.Kind.INCOMPLETE));
}
}
diff --git a/src/main/protobuf/deps.proto b/src/main/protobuf/deps.proto
index af35bea8b2..8c688a7c23 100644
--- a/src/main/protobuf/deps.proto
+++ b/src/main/protobuf/deps.proto
@@ -36,6 +36,8 @@ message Dependency {
IMPLICIT = 1;
// Unused dependency.
UNUSED = 2;
+ // Implicit dependency considered by the compiler but not completed.
+ INCOMPLETE = 3;
}
// Path to the artifact representing this dependency.