Redo FileType @AutoCodec: it is risky to assume that all subclasses are totally described by their extensions, since many are not. Instead, explicitly @AutoCodec those that are, and leave the rest to be individually handled. This also allows us to do equality checking. There is a slight memory penalty here, but there are ~100s of FileTypes in a large build, so it should be negligible. PiperOrigin-RevId: 190477427
diff --git a/src/main/java/com/google/devtools/build/lib/util/FileType.java b/src/main/java/com/google/devtools/build/lib/util/FileType.java index 6cfead9..599851d 100644 --- a/src/main/java/com/google/devtools/build/lib/util/FileType.java +++ b/src/main/java/com/google/devtools/build/lib/util/FileType.java
@@ -20,6 +20,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; +import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -27,9 +28,9 @@ /** A base class for FileType matchers. */ @Immutable -@AutoCodec public abstract class FileType implements Predicate<String> { // A special file type + @AutoCodec @VisibleForSerialization public static final FileType NO_EXTENSION = new FileType() { @Override @@ -40,37 +41,48 @@ }; public static FileType of(final String ext) { - return new FileType() { - @Override - public boolean apply(String path) { - return path.endsWith(ext); - } - - @Override - public List<String> getExtensions() { - return ImmutableList.of(ext); - } - }; + return new ListFileType(ImmutableList.of(ext)); } - @AutoCodec.Instantiator public static FileType of(final List<String> extensions) { - return new FileType() { - @Override - public boolean apply(String path) { - for (String ext : extensions) { - if (path.endsWith(ext)) { - return true; - } - } - return false; - } + return new ListFileType(ImmutableList.copyOf(extensions)); + } - @Override - public List<String> getExtensions() { - return ImmutableList.copyOf(extensions); + @AutoCodec.VisibleForSerialization + @AutoCodec + static final class ListFileType extends FileType { + private final ImmutableList<String> extensions; + + @AutoCodec.VisibleForSerialization + ListFileType(ImmutableList<String> extensions) { + this.extensions = Preconditions.checkNotNull(extensions); + } + + @Override + public boolean apply(String path) { + for (String ext : extensions) { + if (path.endsWith(ext)) { + return true; + } } - }; + return false; + } + + @Override + public List<String> getExtensions() { + return ImmutableList.copyOf(extensions); + } + + @Override + public int hashCode() { + return extensions.hashCode(); + } + + @Override + public boolean equals(Object obj) { + return (obj instanceof ListFileType + && this.extensions.equals(((ListFileType) obj).extensions)); + } } public static FileType of(final String... extensions) {