Fix genclass' handling of class names that contain '$'
Previously it was assuming '$' was only present for inner classes,
but that isn't the case. This was causing problems specifically for
AutoValue extensions, which generate class names that start with '$'.
--
PiperOrigin-RevId: 142468150
MOS_MIGRATED_REVID=142468150
diff --git a/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/genclass/GenClass.java b/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/genclass/GenClass.java
index a0e053c..3a1c941 100644
--- a/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/genclass/GenClass.java
+++ b/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/genclass/GenClass.java
@@ -126,12 +126,8 @@
if (!name.endsWith(".class")) {
continue;
}
- String prefix = name.substring(0, name.length() - ".class".length());
- int idx = prefix.indexOf('$');
- if (idx > 0) {
- prefix = prefix.substring(0, idx);
- }
- if (generatedPrefixes.contains(prefix)) {
+ String className = name.substring(0, name.length() - ".class".length());
+ if (prefixesContains(generatedPrefixes, className)) {
Files.createDirectories(tempDir.resolve(name).getParent());
Files.copy(jar.getInputStream(entry), tempDir.resolve(name));
}
@@ -139,6 +135,23 @@
}
}
+ /**
+ * We want to include inner classes for generated source files, but a class whose name contains
+ * '$' isn't necessarily an inner class. Check whether any prefix of the class name that ends with
+ * '$' matches one of the top-level class names.
+ */
+ private static boolean prefixesContains(ImmutableSet<String> prefixes, String className) {
+ if (prefixes.contains(className)) {
+ return true;
+ }
+ for (int i = className.indexOf('$'); i != -1; i = className.indexOf('$', i + 1)) {
+ if (prefixes.contains(className.substring(0, i))) {
+ return true;
+ }
+ }
+ return false;
+ }
+
/** Writes the generated class files to the output jar. */
private static void writeOutputJar(GenClassOptions options) throws IOException {
JarCreator output = new JarCreator(options.outputJar().toString());