Introduce TreeFileArtifact, which represents files under TreeArtifacts.
Remove ArtifactFile, which is rendered obsolete by TreeFileArtifact.
--
MOS_MIGRATED_REVID=119789154
diff --git a/src/main/java/com/google/devtools/build/lib/actions/ActionExecutionContextFactory.java b/src/main/java/com/google/devtools/build/lib/actions/ActionExecutionContextFactory.java
index e87d72e..fd5f2dd 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/ActionExecutionContextFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/ActionExecutionContextFactory.java
@@ -25,5 +25,5 @@
*/
public interface ActionExecutionContextFactory {
ActionExecutionContext getContext(ActionInputFileCache graphFileCache,
- MetadataHandler metadataHandler, Map<Artifact, Collection<ArtifactFile>> expandedInputs);
+ MetadataHandler metadataHandler, Map<Artifact, Collection<Artifact>> expandedInputs);
}
diff --git a/src/main/java/com/google/devtools/build/lib/actions/ActionInputHelper.java b/src/main/java/com/google/devtools/build/lib/actions/ActionInputHelper.java
index 4471c4c..a4a85d2 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/ActionInputHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/ActionInputHelper.java
@@ -21,6 +21,7 @@
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.Artifact.ArtifactExpander;
+import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact;
import com.google.devtools.build.lib.util.Preconditions;
import com.google.devtools.build.lib.vfs.PathFragment;
@@ -41,7 +42,7 @@
final ActionGraph actionGraph) {
return new ArtifactExpander() {
@Override
- public void expand(Artifact mm, Collection<? super ArtifactFile> output) {
+ public void expand(Artifact mm, Collection<? super Artifact> output) {
// Skyframe is stricter in that it checks that "mm" is a input of the action, because
// it cannot expand arbitrary middlemen without access to a global action graph.
// We could check this constraint here too, but it seems unnecessary. This code is
@@ -129,60 +130,57 @@
}
/**
- * Instantiates a concrete ArtifactFile with the given parent Artifact and path
+ * Instantiates a concrete TreeFileArtifact with the given parent Artifact and path
* relative to that Artifact.
*/
- public static ArtifactFile artifactFile(Artifact parent, PathFragment relativePath) {
+ public static TreeFileArtifact treeFileArtifact(
+ Artifact parent, PathFragment relativePath) {
Preconditions.checkState(parent.isTreeArtifact(),
"Given parent %s must be a TreeArtifact", parent);
- return new TreeArtifactFile(parent, relativePath);
+ return new TreeFileArtifact(parent, relativePath);
+ }
+
+ public static TreeFileArtifact treeFileArtifact(
+ Artifact parent, PathFragment relativePath, ArtifactOwner artifactOwner) {
+ Preconditions.checkState(parent.isTreeArtifact(),
+ "Given parent %s must be a TreeArtifact", parent);
+ return new TreeFileArtifact(
+ parent,
+ relativePath,
+ artifactOwner);
}
/**
- * Instantiates a concrete ArtifactFile with the given parent Artifact and path
+ * Instantiates a concrete TreeFileArtifact with the given parent Artifact and path
* relative to that Artifact.
*/
- public static ArtifactFile artifactFile(Artifact parent, String relativePath) {
- return artifactFile(parent, new PathFragment(relativePath));
+ public static TreeFileArtifact treeFileArtifact(Artifact parent, String relativePath) {
+ return treeFileArtifact(parent, new PathFragment(relativePath));
}
- /** Returns an Iterable of ArtifactFiles with the given parent and parent relative paths. */
- public static Iterable<ArtifactFile> asArtifactFiles(
+ /** Returns an Iterable of TreeFileArtifacts with the given parent and parent relative paths. */
+ public static Iterable<TreeFileArtifact> asTreeFileArtifacts(
final Artifact parent, Iterable<? extends PathFragment> parentRelativePaths) {
Preconditions.checkState(parent.isTreeArtifact(),
"Given parent %s must be a TreeArtifact", parent);
return Iterables.transform(parentRelativePaths,
- new Function<PathFragment, ArtifactFile>() {
+ new Function<PathFragment, TreeFileArtifact>() {
@Override
- public ArtifactFile apply(PathFragment pathFragment) {
- return artifactFile(parent, pathFragment);
+ public TreeFileArtifact apply(PathFragment pathFragment) {
+ return treeFileArtifact(parent, pathFragment);
}
});
}
- /** Returns an Collection of ArtifactFiles with the given parent and parent-relative paths. */
- public static Collection<ArtifactFile> asArtifactFiles(
- final Artifact parent, Collection<? extends PathFragment> parentRelativePaths) {
- Preconditions.checkState(parent.isTreeArtifact(),
- "Given parent %s must be a TreeArtifact", parent);
- return Collections2.transform(parentRelativePaths,
- new Function<PathFragment, ArtifactFile>() {
- @Override
- public ArtifactFile apply(PathFragment pathFragment) {
- return artifactFile(parent, pathFragment);
- }
- });
- }
-
- /** Returns a Set of ArtifactFiles with the given parent and parent relative paths. */
- public static Set<ArtifactFile> asArtifactFiles(
+ /** Returns a Set of TreeFileArtifacts with the given parent and parent-relative paths. */
+ public static Set<TreeFileArtifact> asTreeFileArtifacts(
final Artifact parent, Set<? extends PathFragment> parentRelativePaths) {
Preconditions.checkState(parent.isTreeArtifact(),
"Given parent %s must be a TreeArtifact", parent);
- ImmutableSet.Builder<ArtifactFile> builder = ImmutableSet.builder();
+ ImmutableSet.Builder<TreeFileArtifact> builder = ImmutableSet.builder();
for (PathFragment path : parentRelativePaths) {
- builder.add(artifactFile(parent, path));
+ builder.add(treeFileArtifact(parent, path));
}
return builder.build();
diff --git a/src/main/java/com/google/devtools/build/lib/actions/Artifact.java b/src/main/java/com/google/devtools/build/lib/actions/Artifact.java
index 4e8989f..f28683b 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/Artifact.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/Artifact.java
@@ -70,7 +70,7 @@
* In the usual case, an Artifact represents a single file. However, an Artifact may
* also represent the following:
* <ul>
- * <li>A TreeArtifact, which is a directory containing a tree of unknown {@link ArtifactFile}s.
+ * <li>A TreeArtifact, which is a directory containing a tree of unknown {@link Artifact}s.
* In the future, Actions will be able to examine these files as inputs and declare them as outputs
* at execution time, but this is not yet implemented. This is used for Actions where
* the inputs and/or outputs might not be discoverable except during Action execution.
@@ -87,8 +87,8 @@
* by new rule implementations.
* </ul>
* <p/>
- * This class implements {@link ArtifactFile}, and is modeled as an Artifact "containing" itself
- * as an ArtifactFile.
+ * This class implements {@link Artifact}, and is modeled as an Artifact "containing" itself
+ * as an Artifact.
* <p/>
* <p>This class is "theoretically" final; it should not be subclassed except by
* {@link SpecialArtifact}.
@@ -98,7 +98,7 @@
doc = "This type represents a file used by the build system. It can be "
+ "either a source file or a derived file produced by a rule.")
public class Artifact
- implements FileType.HasFilename, ArtifactFile, SkylarkValue , Comparable<Object> {
+ implements FileType.HasFilename, ActionInput, SkylarkValue, Comparable<Object> {
/**
* Compares artifact according to their exec paths. Sorts null values first.
@@ -136,7 +136,7 @@
* <p>{@code artifact.isMiddlemanArtifact() || artifact.isTreeArtifact()} must be true.
* Only aggregating middlemen and tree artifacts are expanded.
*/
- void expand(Artifact artifact, Collection<? super ArtifactFile> output);
+ void expand(Artifact artifact, Collection<? super Artifact> output);
}
public static final ImmutableList<Artifact> NO_ARTIFACTS = ImmutableList.of();
@@ -239,20 +239,20 @@
root.getExecPath().getRelative(rootRelativePath), ArtifactOwner.NULL_OWNER);
}
- @Override
public final Path getPath() {
return path;
}
+ public boolean hasParent() {
+ return getParent() != null;
+ }
+
/**
- * Returns the Artifact containing this ArtifactFile. Since normal Artifacts correspond
- * to only one ArtifactFile -- itself -- for normal Artifacts, this method returns {@code this}.
- * For special artifacts, throws {@link UnsupportedOperationException}.
- * See also {@link ArtifactFile#getParent()}.
+ * Returns the parent Artifact containing this Artifact. Artifacts without parents shall
+ * return null.
*/
- @Override
- public Artifact getParent() throws UnsupportedOperationException {
- return this;
+ @Nullable public Artifact getParent() {
+ return null;
}
/**
@@ -307,7 +307,6 @@
* package-path entries (for source Artifacts), or one of the bin, genfiles or includes dirs
* (for derived Artifacts). It will always be an ancestor of getPath().
*/
- @Override
@SkylarkCallable(name = "root", structField = true,
doc = "The root beneath which this file resides."
)
@@ -315,18 +314,16 @@
return root;
}
- @Override
public final PathFragment getExecPath() {
return execPath;
}
/**
- * Returns the path of this ArtifactFile relative to this containing Artifact. Since
- * ordinary Artifacts correspond to only one ArtifactFile -- itself -- for ordinary Artifacts,
+ * Returns the path of this Artifact relative to this containing Artifact. Since
+ * ordinary Artifacts correspond to only one Artifact -- itself -- for ordinary Artifacts,
* this just returns the empty path. For special Artifacts, throws
- * {@link UnsupportedOperationException}. See also {@link ArtifactFile#getParentRelativePath()}.
+ * {@link UnsupportedOperationException}. See also {@link Artifact#getParentRelativePath()}.
*/
- @Override
public PathFragment getParentRelativePath() {
return PathFragment.EMPTY_FRAGMENT;
}
@@ -350,7 +347,7 @@
}
/**
- * Returns true iff this is a TreeArtifact representing a directory tree containing ArtifactFiles.
+ * Returns true iff this is a TreeArtifact representing a directory tree containing Artifacts.
*/
public boolean isTreeArtifact() {
return false;
@@ -418,13 +415,77 @@
}
@Override
+ public boolean hasParent() {
+ return false;
+ }
+
+ @Override
+ @Nullable
public Artifact getParent() {
- throw new UnsupportedOperationException();
+ return null;
+ }
+
+ @Override
+ @Nullable
+ public PathFragment getParentRelativePath() {
+ return null;
+ }
+ }
+
+ /**
+ * A special kind of artifact that represents a concrete file created at execution time under
+ * its associated TreeArtifact.
+ *
+ * <p> TreeFileArtifacts should be only created during execution time inside some special actions
+ * to support action inputs and outputs that are unpredictable at analysis time.
+ * TreeFileArtifacts should not be created directly by any rules at analysis time.
+ *
+ * <p>We subclass {@link Artifact} instead of storing the extra fields directly inside in order
+ * to save memory. The proportion of TreeFileArtifacts is very small, and by not having to keep
+ * around the extra fields for the rest we save some memory.
+ */
+ @Immutable
+ public static final class TreeFileArtifact extends Artifact {
+ private final Artifact parentTreeArtifact;
+ private final PathFragment parentRelativePath;
+
+ /**
+ * Constructs a TreeFileArtifact with the given parent-relative path under the given parent
+ * TreeArtifact. The {@link ArtifactOwner} of the TreeFileArtifact is the {@link ArtifactOwner}
+ * of the parent TreeArtifact.
+ */
+ TreeFileArtifact(Artifact parent, PathFragment parentRelativePath) {
+ this(parent, parentRelativePath, parent.getArtifactOwner());
+ }
+
+ /**
+ * Constructs a TreeFileArtifact with the given parent-relative path under the given parent
+ * TreeArtifact, owned by the given {@code artifactOwner}.
+ */
+ TreeFileArtifact(Artifact parent, PathFragment parentRelativePath,
+ ArtifactOwner artifactOwner) {
+ super(
+ parent.getPath().getRelative(parentRelativePath),
+ parent.getRoot(),
+ parent.getExecPath().getRelative(parentRelativePath),
+ artifactOwner);
+ Preconditions.checkState(
+ parent.isTreeArtifact(),
+ "The parent of TreeFileArtifact (parent-relative path: %s) is not a TreeArtifact: %s",
+ parentRelativePath,
+ parent);
+ this.parentTreeArtifact = parent;
+ this.parentRelativePath = parentRelativePath;
+ }
+
+ @Override
+ public Artifact getParent() {
+ return parentTreeArtifact;
}
@Override
public PathFragment getParentRelativePath() {
- throw new UnsupportedOperationException();
+ return parentRelativePath;
}
}
@@ -432,7 +493,6 @@
* Returns the relative path to this artifact relative to its root. (Useful
* when deriving output filenames from input files, etc.)
*/
- @Override
public final PathFragment getRootRelativePath() {
return rootRelativePath;
}
@@ -478,7 +538,6 @@
return getRootRelativePath().getPathString();
}
- @Override
public final String prettyPrint() {
// toDetailString would probably be more useful to users, but lots of tests rely on the
// current values.
@@ -550,26 +609,26 @@
/**
* Formatter for execPath PathFragment output.
*/
- private static final Function<ArtifactFile, PathFragment> EXEC_PATH_FORMATTER =
- new Function<ArtifactFile, PathFragment>() {
+ private static final Function<Artifact, PathFragment> EXEC_PATH_FORMATTER =
+ new Function<Artifact, PathFragment>() {
@Override
- public PathFragment apply(ArtifactFile input) {
+ public PathFragment apply(Artifact input) {
return input.getExecPath();
}
};
- public static final Function<ArtifactFile, String> ROOT_RELATIVE_PATH_STRING =
- new Function<ArtifactFile, String>() {
+ public static final Function<Artifact, String> ROOT_RELATIVE_PATH_STRING =
+ new Function<Artifact, String>() {
@Override
- public String apply(ArtifactFile artifact) {
+ public String apply(Artifact artifact) {
return artifact.getRootRelativePath().getPathString();
}
};
- public static final Function<ArtifactFile, String> ABSOLUTE_PATH_STRING =
- new Function<ArtifactFile, String>() {
+ public static final Function<Artifact, String> ABSOLUTE_PATH_STRING =
+ new Function<Artifact, String>() {
@Override
- public String apply(ArtifactFile artifact) {
+ public String apply(Artifact artifact) {
return artifact.getPath().getPathString();
}
};
@@ -654,8 +713,8 @@
* {@link MiddlemanType#AGGREGATING_MIDDLEMAN} middleman actions expanded once.
*/
public static void addExpandedArtifacts(Iterable<Artifact> artifacts,
- Collection<? super ArtifactFile> output, ArtifactExpander artifactExpander) {
- addExpandedArtifacts(artifacts, output, Functions.<ArtifactFile>identity(), artifactExpander);
+ Collection<? super Artifact> output, ArtifactExpander artifactExpander) {
+ addExpandedArtifacts(artifacts, output, Functions.<Artifact>identity(), artifactExpander);
}
/**
@@ -690,7 +749,7 @@
*/
private static <E> void addExpandedArtifacts(Iterable<? extends Artifact> artifacts,
Collection<? super E> output,
- Function<? super ArtifactFile, E> outputFormatter,
+ Function<? super Artifact, E> outputFormatter,
ArtifactExpander artifactExpander) {
for (Artifact artifact : artifacts) {
if (artifact.isMiddlemanArtifact() || artifact.isTreeArtifact()) {
@@ -703,12 +762,12 @@
private static <E> void expandArtifact(Artifact middleman,
Collection<? super E> output,
- Function<? super ArtifactFile, E> outputFormatter,
+ Function<? super Artifact, E> outputFormatter,
ArtifactExpander artifactExpander) {
Preconditions.checkArgument(middleman.isMiddlemanArtifact() || middleman.isTreeArtifact());
- List<ArtifactFile> artifacts = new ArrayList<>();
+ List<Artifact> artifacts = new ArrayList<>();
artifactExpander.expand(middleman, artifacts);
- for (ArtifactFile artifact : artifacts) {
+ for (Artifact artifact : artifacts) {
output.add(outputFormatter.apply(artifact));
}
}
@@ -785,7 +844,7 @@
/**
* Converts artifacts into their exec paths. Returns an immutable list.
*/
- public static List<PathFragment> asPathFragments(Iterable<? extends ArtifactFile> artifacts) {
+ public static List<PathFragment> asPathFragments(Iterable<? extends Artifact> artifacts) {
return ImmutableList.copyOf(Iterables.transform(artifacts, EXEC_PATH_FORMATTER));
}
diff --git a/src/main/java/com/google/devtools/build/lib/actions/ArtifactFile.java b/src/main/java/com/google/devtools/build/lib/actions/ArtifactFile.java
deleted file mode 100644
index be165fb..0000000
--- a/src/main/java/com/google/devtools/build/lib/actions/ArtifactFile.java
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright 2016 The Bazel Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.devtools.build.lib.actions;
-
-import com.google.devtools.build.lib.vfs.Path;
-import com.google.devtools.build.lib.vfs.PathFragment;
-
-/**
- * An ArtifactFile represents a file used by the build system during execution of Actions.
- * An ArtifactFile may be a source file or a derived (output) file.
- *
- * During the creation of {@link com.google.devtools.build.lib.analysis.ConfiguredTarget}s and
- * {@link com.google.devtools.build.lib.analysis.ConfiguredAspect}s, generally one
- * is only interested in {@link Artifact}s. Most Actions are only interested in Artifacts as well.
- * During action execution, however, some Artifacts (notably
- * TreeArtifacts) may correspond to more than one ArtifactFile. This is for the benefit
- * of some Actions which only know their inputs or outputs at execution time, via the
- * TreeArtifact mechanism.
- * <ul><li>
- * Generally, most Artifacts represent a file on the filesystem, and correspond to exactly one
- * ArtifactFile. For ease of use, Artifact itself implements ArtifactFile, and is modeled
- * as an Artifact containing itself.
- * </li><li>
- * Some Artifacts are so-called TreeArtifacts, for which the method
- * {@link Artifact#isTreeArtifact()} returns true. These artifacts contain a (possibly empty)
- * tree of ArtifactFiles, which are unknown until Action execution time.
- * </li><li>
- * Some 'special artifacts' do not meaningfully represent a file or tree of files.
- * </li></ul>
- */
-public interface ArtifactFile extends ActionInput {
- /**
- * Returns the exec path of this ArtifactFile. The exec path is a relative path
- * that is suitable for accessing this artifact relative to the execution
- * directory for this build.
- */
- PathFragment getExecPath();
-
- /**
- * Returns the path of this ArtifactFile relative to its containing Artifact.
- * See {@link #getParent()}.
- * */
- PathFragment getParentRelativePath();
-
- /** Returns the location of this ArtifactFile on the filesystem. */
- Path getPath();
-
- /**
- * Returns the relative path to this ArtifactFile relative to its root. Useful
- * when deriving output filenames from input files, etc.
- */
- PathFragment getRootRelativePath();
-
- /**
- * Returns the root beneath which this ArtifactFile resides, if any. This may be one of the
- * package-path entries (for files belonging to source {@link Artifact}s), or one of the bin
- * genfiles or includes dirs (for files belonging to derived {@link Artifact}s). It will always be
- * an ancestor of {@link #getPath()}.
- */
- Root getRoot();
-
- /**
- * Returns the Artifact containing this File. For Artifacts which are files, returns
- * {@code this}. Otherwise, returns a Artifact whose path and root relative path
- * are an ancestor of this ArtifactFile's path, and for which {@link Artifact#isTreeArtifact()}
- * returns true.
- * <p/>
- * For ArtifactFiles which are special artifacts (including TreeArtifacts),
- * this method throws UnsupportedOperationException, because the ArtifactFile abstraction
- * fails for those cases.
- */
- Artifact getParent() throws UnsupportedOperationException;
-
- /**
- * Returns a pretty string representation of the path denoted by this ArtifactFile, suitable for
- * use in user error messages. ArtifactFiles beneath a root will be printed relative to that root;
- * other ArtifactFiles will be printed as an absolute path.
- *
- * <p>(The toString method is intended for developer messages since its more informative.)
- */
- String prettyPrint();
-
- /**
- * Two ArtifactFiles are equal if their parent Artifacts and parent relative paths
- * are equal. If this ArtifactFile is itself an Artifact, see {@link Artifact#equals(Object)}.
- * Note that within a build, two ArtifactFiles produced by the build system will be equal
- * if and only if their full paths are equal.
- */
- @Override
- boolean equals(Object o);
-
- /**
- * An ArtifactFile's hash code should be equal to
- * {@code {@link #getParent().hashCode()} * 257 +
- * {@link #getParentRelativePath().hashCode()}}. If this ArtifactFile is itself an Artifact,
- * see {@link Artifact#hashCode()}.
- * <p/>
- * 257 is chosen because it is a Fermat prime, and has minimal 'bit overlap' with the Mersenne
- * prime of 31 used in {@link Path#hashCode()} and {@link String#hashCode()}.
- */
- @Override
- int hashCode();
-}
diff --git a/src/main/java/com/google/devtools/build/lib/actions/TreeArtifactFile.java b/src/main/java/com/google/devtools/build/lib/actions/TreeArtifactFile.java
deleted file mode 100644
index 8b4cde8..0000000
--- a/src/main/java/com/google/devtools/build/lib/actions/TreeArtifactFile.java
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2016 The Bazel Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.devtools.build.lib.actions;
-
-import com.google.devtools.build.lib.util.Preconditions;
-import com.google.devtools.build.lib.vfs.Path;
-import com.google.devtools.build.lib.vfs.PathFragment;
-
-/** An ArtifactFile implementation for descendants of TreeArtifacts. */
-final class TreeArtifactFile implements ArtifactFile {
- private final Artifact parent;
- private final PathFragment parentRelativePath;
-
- TreeArtifactFile(Artifact parent, PathFragment parentRelativePath) {
- Preconditions.checkArgument(parent.isTreeArtifact(), "%s must be a TreeArtifact", parent);
- this.parent = parent;
- this.parentRelativePath = parentRelativePath;
- }
-
- @Override
- public PathFragment getExecPath() {
- return parent.getExecPath().getRelative(parentRelativePath);
- }
-
- @Override
- public PathFragment getParentRelativePath() {
- return parentRelativePath;
- }
-
- @Override
- public Path getPath() {
- return parent.getPath().getRelative(parentRelativePath);
- }
-
- @Override
- public PathFragment getRootRelativePath() {
- return parent.getRootRelativePath().getRelative(parentRelativePath);
- }
-
- @Override
- public Root getRoot() {
- return parent.getRoot();
- }
-
- @Override
- public Artifact getParent() {
- return parent;
- }
-
- @Override
- public String prettyPrint() {
- return getRootRelativePath().toString();
- }
-
- @Override
- public String getExecPathString() {
- return getExecPath().toString();
- }
-
- @Override
- public String toString() {
- return "ArtifactFile:[" + parent.toDetailString() + "]" + parentRelativePath;
- }
-
- @Override
- public boolean equals(Object other) {
- if (!(other instanceof ArtifactFile)) {
- return false;
- }
-
- ArtifactFile that = (ArtifactFile) other;
- return this.getParent().equals(that.getParent())
- && this.getParentRelativePath().equals(that.getParentRelativePath());
- }
-
- @Override
- public int hashCode() {
- return getParent().hashCode() * 257 + getParentRelativePath().hashCode();
- }
-}
diff --git a/src/main/java/com/google/devtools/build/lib/actions/cache/MetadataHandler.java b/src/main/java/com/google/devtools/build/lib/actions/cache/MetadataHandler.java
index e75ab9a..6fcb964 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/cache/MetadataHandler.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/cache/MetadataHandler.java
@@ -15,7 +15,7 @@
import com.google.devtools.build.lib.actions.ActionInput;
import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.actions.ArtifactFile;
+import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact;
import com.google.devtools.build.lib.actions.MiddlemanAction;
import com.google.devtools.build.lib.vfs.FileStatus;
@@ -52,9 +52,8 @@
/**
* Registers the given output as contents of a TreeArtifact, without injecting its digest.
* Prefer {@link #injectDigest} when the digest is available.
- * @throws IllegalStateException if the given output does not have a TreeArtifact parent.
*/
- void addExpandedTreeOutput(ArtifactFile output) throws IllegalStateException;
+ void addExpandedTreeOutput(TreeFileArtifact output);
/**
* Injects provided digest into the metadata handler, simultaneously caching lstat() data as well.
@@ -83,14 +82,14 @@
boolean artifactOmitted(Artifact artifact);
/**
- * @return Whether the ArtifactFile's data was injected.
- * @throws IOException if implementation tried to stat the ArtifactFile which threw an exception.
+ * @return Whether the artifact's data was injected.
+ * @throws IOException if implementation tried to stat the Artifact which threw an exception.
* Technically, this means that the artifact could not have been injected, but by throwing
* here we save the caller trying to stat this file on their own and throwing the same
* exception. Implementations are not guaranteed to throw in this case if they are able to
* determine that the artifact is not injected without statting it.
*/
- boolean isInjected(ArtifactFile file) throws IOException;
+ boolean isInjected(Artifact file) throws IOException;
/**
* Discards all known output artifact metadata, presumably because outputs will be modified.