Rename Root to ArtifactRoot.

This is slightly more descriptive, and we will potentially want to use the name Root for a broader concept shared between ArtifactRoot and RootedPath.

PiperOrigin-RevId: 182082367
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/AnalysisEnvironment.java b/src/main/java/com/google/devtools/build/lib/analysis/AnalysisEnvironment.java
index 2d7466d..098a04e 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/AnalysisEnvironment.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/AnalysisEnvironment.java
@@ -21,8 +21,8 @@
 import com.google.devtools.build.lib.actions.ActionKeyContext;
 import com.google.devtools.build.lib.actions.ActionRegistry;
 import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.actions.MiddlemanFactory;
-import com.google.devtools.build.lib.actions.Root;
 import com.google.devtools.build.lib.analysis.buildinfo.BuildInfoFactory.BuildInfoKey;
 import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
 import com.google.devtools.build.lib.events.ExtendedEventHandler;
@@ -52,10 +52,11 @@
   /**
    * Returns the artifact for the derived file {@code rootRelativePath}.
    *
-   * <p><b>DO NOT USE</b> in rule implementations. Use
-   * {@link RuleContext#getPackageRelativeArtifact(PathFragment, Root)} or
-   * {@link RuleContext#getUniqueDirectoryArtifact(String, PathFragment, Root)}, or, if there is
-   * really no other way, {@link RuleContext#getShareableArtifact(PathFragment, Root)} instead.
+   * <p><b>DO NOT USE</b> in rule implementations. Use {@link
+   * RuleContext#getPackageRelativeArtifact(PathFragment, ArtifactRoot)} or {@link
+   * RuleContext#getUniqueDirectoryArtifact(String, PathFragment, ArtifactRoot)}, or, if there is
+   * really no other way, {@link RuleContext#getShareableArtifact(PathFragment, ArtifactRoot)}
+   * instead.
    *
    * <p>Creates the artifact if necessary and sets the root of that artifact to {@code root}.
    *
@@ -63,33 +64,32 @@
    * artifacts generated by two different rules to clash. To avoid this, use the artifact creation
    * method on {@link RuleContext} mentioned above.
    */
-  Artifact getDerivedArtifact(PathFragment rootRelativePath, Root root);
+  Artifact getDerivedArtifact(PathFragment rootRelativePath, ArtifactRoot root);
 
   /**
-   * Returns an artifact for the derived file {@code rootRelativePath} whose changes do not cause
-   * a rebuild.
+   * Returns an artifact for the derived file {@code rootRelativePath} whose changes do not cause a
+   * rebuild.
    *
    * <p>Creates the artifact if necessary and sets the root of that artifact to {@code root}.
    *
    * <p>This is useful for files that store data that changes very frequently (e.g. current time)
    * but does not substantially affect the result of the build.
    */
-  Artifact getConstantMetadataArtifact(PathFragment rootRelativePath,
-      Root root);
+  Artifact getConstantMetadataArtifact(PathFragment rootRelativePath, ArtifactRoot root);
 
   /**
    * Returns the artifact for the derived TreeArtifact with directory {@code rootRelativePath},
-   * creating it if necessary, and setting the root of that artifact to
-   * {@code root}. The artifact will be a TreeArtifact.
+   * creating it if necessary, and setting the root of that artifact to {@code root}. The artifact
+   * will be a TreeArtifact.
    */
-  Artifact getTreeArtifact(PathFragment rootRelativePath, Root root);
+  Artifact getTreeArtifact(PathFragment rootRelativePath, ArtifactRoot root);
 
   /**
-   * Returns the artifact for the derived file {@code rootRelativePath},
-   * creating it if necessary, and setting the root of that artifact to
-   * {@code root}. The artifact will represent the output directory of a {@code Fileset}.
+   * Returns the artifact for the derived file {@code rootRelativePath}, creating it if necessary,
+   * and setting the root of that artifact to {@code root}. The artifact will represent the output
+   * directory of a {@code Fileset}.
    */
-  Artifact getFilesetArtifact(PathFragment rootRelativePath, Root root);
+  Artifact getFilesetArtifact(PathFragment rootRelativePath, ArtifactRoot root);
 
   /**
    * Returns the middleman factory associated with the build.
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/BlazeDirectories.java b/src/main/java/com/google/devtools/build/lib/analysis/BlazeDirectories.java
index 3e7df15..bbae6b4 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/BlazeDirectories.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/BlazeDirectories.java
@@ -16,7 +16,7 @@
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.hash.HashCode;
-import com.google.devtools.build.lib.actions.Root;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
 import com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodec;
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
@@ -171,8 +171,8 @@
    * Returns the configuration-independent root where the build-data should be placed, given the
    * {@link BlazeDirectories} of this server instance. Nothing else should be placed here.
    */
-  public Root getBuildDataDirectory(String workspaceName) {
-    return Root.asDerivedRoot(getExecRoot(workspaceName), getOutputPath(workspaceName));
+  public ArtifactRoot getBuildDataDirectory(String workspaceName) {
+    return ArtifactRoot.asDerivedRoot(getExecRoot(workspaceName), getOutputPath(workspaceName));
   }
 
   /**
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/CachingAnalysisEnvironment.java b/src/main/java/com/google/devtools/build/lib/analysis/CachingAnalysisEnvironment.java
index 81d5d2e..94cc572 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/CachingAnalysisEnvironment.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/CachingAnalysisEnvironment.java
@@ -23,8 +23,8 @@
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.actions.ArtifactFactory;
 import com.google.devtools.build.lib.actions.ArtifactOwner;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.actions.MiddlemanFactory;
-import com.google.devtools.build.lib.actions.Root;
 import com.google.devtools.build.lib.analysis.buildinfo.BuildInfoCollection;
 import com.google.devtools.build.lib.analysis.buildinfo.BuildInfoFactory;
 import com.google.devtools.build.lib.analysis.buildinfo.BuildInfoFactory.BuildInfoKey;
@@ -233,7 +233,7 @@
   }
 
   @Override
-  public Artifact getDerivedArtifact(PathFragment rootRelativePath, Root root) {
+  public Artifact getDerivedArtifact(PathFragment rootRelativePath, ArtifactRoot root) {
     Preconditions.checkState(enabled);
     return trackArtifactAndOrigin(
         artifactFactory.getDerivedArtifact(rootRelativePath, root, getOwner()),
@@ -241,7 +241,7 @@
   }
 
   @Override
-  public Artifact getTreeArtifact(PathFragment rootRelativePath, Root root) {
+  public Artifact getTreeArtifact(PathFragment rootRelativePath, ArtifactRoot root) {
     Preconditions.checkState(enabled);
     return trackArtifactAndOrigin(
         artifactFactory.getTreeArtifact(rootRelativePath, root, getOwner()),
@@ -249,7 +249,7 @@
   }
 
   @Override
-  public Artifact getFilesetArtifact(PathFragment rootRelativePath, Root root) {
+  public Artifact getFilesetArtifact(PathFragment rootRelativePath, ArtifactRoot root) {
     Preconditions.checkState(enabled);
     return trackArtifactAndOrigin(
         artifactFactory.getFilesetArtifact(rootRelativePath, root, getOwner()),
@@ -257,7 +257,7 @@
   }
 
   @Override
-  public Artifact getConstantMetadataArtifact(PathFragment rootRelativePath, Root root) {
+  public Artifact getConstantMetadataArtifact(PathFragment rootRelativePath, ArtifactRoot root) {
     return artifactFactory.getConstantMetadataArtifact(rootRelativePath, root, getOwner());
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java
index 3ad0240..af99802 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java
@@ -22,8 +22,8 @@
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.actions.ArtifactFactory;
 import com.google.devtools.build.lib.actions.ArtifactOwner;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.actions.FailAction;
-import com.google.devtools.build.lib.actions.Root;
 import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
 import com.google.devtools.build.lib.analysis.config.BuildConfiguration.Fragment;
 import com.google.devtools.build.lib.analysis.config.ConfigMatchingProvider;
@@ -163,9 +163,10 @@
       BuildConfiguration configuration, boolean isFileset, ArtifactFactory artifactFactory)
       throws InterruptedException {
     Rule rule = outputFile.getAssociatedRule();
-    Root root = rule.hasBinaryOutput()
-        ? configuration.getBinDirectory(rule.getRepository())
-        : configuration.getGenfilesDirectory(rule.getRepository());
+    ArtifactRoot root =
+        rule.hasBinaryOutput()
+            ? configuration.getBinDirectory(rule.getRepository())
+            : configuration.getGenfilesDirectory(rule.getRepository());
     ArtifactOwner owner =
         ConfiguredTargetKey.of(
             rule.getLabel(),
@@ -276,7 +277,7 @@
       Artifact artifact =
           artifactFactory.getSourceArtifact(
               inputFile.getExecPath(),
-              Root.asSourceRoot(inputFile.getPackage().getSourceRoot()),
+              ArtifactRoot.asSourceRoot(inputFile.getPackage().getSourceRoot()),
               ConfiguredTargetKey.of(target.getLabel(), config));
 
       return new InputFileConfiguredTarget(targetContext, inputFile, artifact);
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
index 2e366d9..674fd55 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
@@ -37,7 +37,7 @@
 import com.google.devtools.build.lib.actions.ActionRegistry;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.actions.ArtifactOwner;
-import com.google.devtools.build.lib.actions.Root;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider.PrerequisiteValidator;
 import com.google.devtools.build.lib.analysis.actions.ActionConstructionContext;
 import com.google.devtools.build.lib.analysis.buildinfo.BuildInfoFactory.BuildInfoKey;
@@ -269,12 +269,12 @@
   }
 
   @Override
-  public Root getBinDirectory() {
+  public ArtifactRoot getBinDirectory() {
     return getConfiguration().getBinDirectory(rule.getRepository());
   }
 
   @Override
-  public Root getMiddlemanDirectory() {
+  public ArtifactRoot getMiddlemanDirectory() {
     return getConfiguration().getMiddlemanDirectory(rule.getRepository());
   }
 
@@ -565,27 +565,26 @@
         target.getLabel().getPackageIdentifier().equals(getLabel().getPackageIdentifier()),
         "Creating output artifact for target '%s' in different package than the rule '%s' "
             + "being analyzed", target.getLabel(), getLabel());
-    Root root = getBinOrGenfilesDirectory();
+    ArtifactRoot root = getBinOrGenfilesDirectory();
     return getPackageRelativeArtifact(target.getName(), root);
   }
 
   /**
-   * Returns the root of either the "bin" or "genfiles"
-   * tree, based on this target and the current configuration.
-   * The choice of which tree to use is based on the rule with
-   * which this target (which must be an OutputFile or a Rule) is associated.
+   * Returns the root of either the "bin" or "genfiles" tree, based on this target and the current
+   * configuration. The choice of which tree to use is based on the rule with which this target
+   * (which must be an OutputFile or a Rule) is associated.
    */
-  public Root getBinOrGenfilesDirectory() {
+  public ArtifactRoot getBinOrGenfilesDirectory() {
     return rule.hasBinaryOutput()
         ? getConfiguration().getBinDirectory(rule.getRepository())
         : getConfiguration().getGenfilesDirectory(rule.getRepository());
   }
 
   /**
-   * Creates an artifact in a directory that is unique to the package that contains the rule,
-   * thus guaranteeing that it never clashes with artifacts created by rules in other packages.
+   * Creates an artifact in a directory that is unique to the package that contains the rule, thus
+   * guaranteeing that it never clashes with artifacts created by rules in other packages.
    */
-  public Artifact getPackageRelativeArtifact(String relative, Root root) {
+  public Artifact getPackageRelativeArtifact(String relative, ArtifactRoot root) {
     return getPackageRelativeArtifact(PathFragment.create(relative), root);
   }
 
@@ -620,18 +619,18 @@
    * option.
    *
    * <p>This artifact can be created anywhere in the output tree, which, in addition to making
-   * sharing possible, opens up the possibility of action conflicts and makes it impossible to
-   * infer the label of the rule creating the artifact from the path of the artifact.
+   * sharing possible, opens up the possibility of action conflicts and makes it impossible to infer
+   * the label of the rule creating the artifact from the path of the artifact.
    */
-  public Artifact getShareableArtifact(PathFragment rootRelativePath, Root root) {
+  public Artifact getShareableArtifact(PathFragment rootRelativePath, ArtifactRoot root) {
     return getAnalysisEnvironment().getDerivedArtifact(rootRelativePath, root);
   }
 
   /**
-   * Creates an artifact in a directory that is unique to the package that contains the rule,
-   * thus guaranteeing that it never clashes with artifacts created by rules in other packages.
+   * Creates an artifact in a directory that is unique to the package that contains the rule, thus
+   * guaranteeing that it never clashes with artifacts created by rules in other packages.
    */
-  public Artifact getPackageRelativeArtifact(PathFragment relative, Root root) {
+  public Artifact getPackageRelativeArtifact(PathFragment relative, ArtifactRoot root) {
     return getDerivedArtifact(getPackageDirectory().getRelative(relative), root);
   }
 
@@ -639,15 +638,16 @@
    * Returns the root-relative path fragment under which output artifacts of this rule should go.
    *
    * <p>Note that:
+   *
    * <ul>
    *   <li>This doesn't guarantee that there are no clashes with rules in the same package.
-   *   <li>If possible, {@link #getPackageRelativeArtifact(PathFragment, Root)} should be used
-   *   instead of this method.
+   *   <li>If possible, {@link #getPackageRelativeArtifact(PathFragment, ArtifactRoot)} should be
+   *       used instead of this method.
    * </ul>
    *
    * Ideally, user-visible artifacts should all have corresponding output file targets, all others
-   * should go into a rule-specific directory.
-   * {@link #getUniqueDirectoryArtifact(String, PathFragment, Root)}) ensures that this is the case.
+   * should go into a rule-specific directory. {@link #getUniqueDirectoryArtifact(String,
+   * PathFragment, ArtifactRoot)}) ensures that this is the case.
    */
   public PathFragment getPackageDirectory() {
     return getLabel().getPackageIdentifier().getSourceRoot();
@@ -661,7 +661,7 @@
    * method.
    */
   @Override
-  public Artifact getDerivedArtifact(PathFragment rootRelativePath, Root root) {
+  public Artifact getDerivedArtifact(PathFragment rootRelativePath, ArtifactRoot root) {
     Preconditions.checkState(rootRelativePath.startsWith(getPackageDirectory()),
         "Output artifact '%s' not under package directory '%s' for target '%s'",
         rootRelativePath, getPackageDirectory(), getLabel());
@@ -675,7 +675,7 @@
    * thus ensuring that it doesn't clash with other artifacts generated by other rules using this
    * method.
    */
-  public Artifact getTreeArtifact(PathFragment rootRelativePath, Root root) {
+  public Artifact getTreeArtifact(PathFragment rootRelativePath, ArtifactRoot root) {
     Preconditions.checkState(rootRelativePath.startsWith(getPackageDirectory()),
         "Output artifact '%s' not under package directory '%s' for target '%s'",
         rootRelativePath, getPackageDirectory(), getLabel());
@@ -686,7 +686,7 @@
    * Creates a tree artifact in a directory that is unique to the package that contains the rule,
    * thus guaranteeing that it never clashes with artifacts created by rules in other packages.
    */
-  public Artifact getPackageRelativeTreeArtifact(PathFragment relative, Root root) {
+  public Artifact getPackageRelativeTreeArtifact(PathFragment relative, ArtifactRoot root) {
     return getTreeArtifact(getPackageDirectory().getRelative(relative), root);
   }
 
@@ -695,7 +695,7 @@
    * clashes with artifacts created by other rules.
    */
   public Artifact getUniqueDirectoryArtifact(
-      String uniqueDirectory, String relative, Root root) {
+      String uniqueDirectory, String relative, ArtifactRoot root) {
     return getUniqueDirectoryArtifact(uniqueDirectory, PathFragment.create(relative), root);
   }
 
@@ -704,7 +704,7 @@
    * clashes with artifacts created by other rules.
    */
   public Artifact getUniqueDirectoryArtifact(
-      String uniqueDirectory, PathFragment relative, Root root) {
+      String uniqueDirectory, PathFragment relative, ArtifactRoot root) {
     return getDerivedArtifact(getUniqueDirectory(uniqueDirectory).getRelative(relative), root);
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/SkyframePackageRootResolver.java b/src/main/java/com/google/devtools/build/lib/analysis/SkyframePackageRootResolver.java
index 9a9eee3..082c122 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/SkyframePackageRootResolver.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/SkyframePackageRootResolver.java
@@ -14,8 +14,8 @@
 
 package com.google.devtools.build.lib.analysis;
 
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.actions.PackageRootResolver;
-import com.google.devtools.build.lib.actions.Root;
 import com.google.devtools.build.lib.events.ExtendedEventHandler;
 import com.google.devtools.build.lib.skyframe.SkyframeExecutor;
 import com.google.devtools.build.lib.vfs.PathFragment;
@@ -37,14 +37,14 @@
   }
 
   @Override
-  public Map<PathFragment, Root> findPackageRootsForFiles(Iterable<PathFragment> execPaths)
+  public Map<PathFragment, ArtifactRoot> findPackageRootsForFiles(Iterable<PathFragment> execPaths)
       throws InterruptedException {
     return executor.getArtifactRootsForFiles(eventHandler, execPaths);
   }
-  
+
   @Override
   @Nullable
-  public Map<PathFragment, Root> findPackageRoots(Iterable<PathFragment> execPaths)
+  public Map<PathFragment, ArtifactRoot> findPackageRoots(Iterable<PathFragment> execPaths)
       throws InterruptedException {
     return executor.getArtifactRoots(eventHandler, execPaths);
   }
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/actions/ActionConstructionContext.java b/src/main/java/com/google/devtools/build/lib/analysis/actions/ActionConstructionContext.java
index 3b10c5a..1eefb53 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/actions/ActionConstructionContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/actions/ActionConstructionContext.java
@@ -15,7 +15,7 @@
 
 import com.google.devtools.build.lib.actions.ActionOwner;
 import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.actions.Root;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.analysis.AnalysisEnvironment;
 import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
 import com.google.devtools.build.lib.analysis.platform.PlatformInfo;
@@ -28,15 +28,11 @@
  */
 public interface ActionConstructionContext {
 
-  /**
-   * Returns the bin directory for constructed actions.
-   */
-  Root getBinDirectory();
+  /** Returns the bin directory for constructed actions. */
+  ArtifactRoot getBinDirectory();
 
-  /**
-   * Returns the internal directory (used for middlemen) for constructed actions.
-   */
-  Root getMiddlemanDirectory();
+  /** Returns the internal directory (used for middlemen) for constructed actions. */
+  ArtifactRoot getMiddlemanDirectory();
 
   /** Returns the action owner that should be used for actions. */
   ActionOwner getActionOwner();
@@ -54,7 +50,7 @@
    * thus ensuring that it doesn't clash with other artifacts generated by other rules using this
    * method.
    */
-  Artifact getDerivedArtifact(PathFragment rootRelativePath, Root root);
+  Artifact getDerivedArtifact(PathFragment rootRelativePath, ArtifactRoot root);
 
   /** Returns the {@link PlatformInfo} describing the execution platform this action should use. */
   @Nullable
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/buildinfo/BuildInfoFactory.java b/src/main/java/com/google/devtools/build/lib/analysis/buildinfo/BuildInfoFactory.java
index 07e9918..468fb27 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/buildinfo/BuildInfoFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/buildinfo/BuildInfoFactory.java
@@ -14,11 +14,10 @@
 package com.google.devtools.build.lib.analysis.buildinfo;
 
 import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.actions.Root;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
 import com.google.devtools.build.lib.cmdline.RepositoryName;
 import com.google.devtools.build.lib.vfs.PathFragment;
-
 import java.io.Serializable;
 
 /**
@@ -47,7 +46,8 @@
    * Context for the creation of build-info artifacts.
    */
   interface BuildInfoContext {
-    Artifact getBuildInfoArtifact(PathFragment rootRelativePath, Root root, BuildInfoType type);
+    Artifact getBuildInfoArtifact(
+        PathFragment rootRelativePath, ArtifactRoot root, BuildInfoType type);
   }
 
   /**
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java
index 9b6f5d1..10daadd 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java
@@ -34,7 +34,7 @@
 import com.google.common.collect.Multimap;
 import com.google.common.collect.MutableClassToInstanceMap;
 import com.google.devtools.build.lib.actions.ActionEnvironment;
-import com.google.devtools.build.lib.actions.Root;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.analysis.BlazeDirectories;
 import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
 import com.google.devtools.build.lib.analysis.RuleContext;
@@ -1185,8 +1185,10 @@
       this.middleman = false;
     }
 
-    Root getRoot(
-        RepositoryName repositoryName, String outputDirName, BlazeDirectories directories,
+    ArtifactRoot getRoot(
+        RepositoryName repositoryName,
+        String outputDirName,
+        BlazeDirectories directories,
         RepositoryName mainRepositoryName) {
       // e.g., execroot/repo1
       Path execRoot = directories.getExecRoot(mainRepositoryName.strippedName());
@@ -1194,10 +1196,11 @@
       Path outputDir = execRoot.getRelative(directories.getRelativeOutputPath())
           .getRelative(outputDirName);
       if (middleman) {
-        return INTERNER.intern(Root.middlemanRoot(execRoot, outputDir));
+        return INTERNER.intern(ArtifactRoot.middlemanRoot(execRoot, outputDir));
       }
       // e.g., [[execroot/repo1]/bazel-out/config/bin]
-      return INTERNER.intern(Root.asDerivedRoot(execRoot, outputDir.getRelative(nameFragment)));
+      return INTERNER.intern(
+          ArtifactRoot.asDerivedRoot(execRoot, outputDir.getRelative(nameFragment)));
     }
   }
 
@@ -1206,16 +1209,16 @@
 
   // We intern the roots for non-main repositories, so we don't keep around thousands of copies of
   // the same root.
-  private static Interner<Root> INTERNER = Interners.newWeakInterner();
+  private static Interner<ArtifactRoot> INTERNER = Interners.newWeakInterner();
 
   // We precompute the roots for the main repository, since that's the common case.
-  private final Root outputDirectoryForMainRepository;
-  private final Root binDirectoryForMainRepository;
-  private final Root includeDirectoryForMainRepository;
-  private final Root genfilesDirectoryForMainRepository;
-  private final Root coverageDirectoryForMainRepository;
-  private final Root testlogsDirectoryForMainRepository;
-  private final Root middlemanDirectoryForMainRepository;
+  private final ArtifactRoot outputDirectoryForMainRepository;
+  private final ArtifactRoot binDirectoryForMainRepository;
+  private final ArtifactRoot includeDirectoryForMainRepository;
+  private final ArtifactRoot genfilesDirectoryForMainRepository;
+  private final ArtifactRoot coverageDirectoryForMainRepository;
+  private final ArtifactRoot testlogsDirectoryForMainRepository;
+  private final ArtifactRoot middlemanDirectoryForMainRepository;
 
   private final boolean separateGenfilesDirectory;
 
@@ -1575,22 +1578,18 @@
     return platformName;
   }
 
-  /**
-   * Returns the output directory for this build configuration.
-   */
-  public Root getOutputDirectory(RepositoryName repositoryName) {
+  /** Returns the output directory for this build configuration. */
+  public ArtifactRoot getOutputDirectory(RepositoryName repositoryName) {
     return repositoryName.isMain() || repositoryName.equals(mainRepositoryName)
         ? outputDirectoryForMainRepository
         : OutputDirectory.OUTPUT.getRoot(
             repositoryName, outputDirName, directories, mainRepositoryName);
   }
 
-  /**
-   * Returns the bin directory for this build configuration.
-   */
+  /** Returns the bin directory for this build configuration. */
   @SkylarkCallable(name = "bin_dir", structField = true, documented = false)
   @Deprecated
-  public Root getBinDirectory() {
+  public ArtifactRoot getBinDirectory() {
     return getBinDirectory(RepositoryName.MAIN);
   }
 
@@ -1600,7 +1599,7 @@
    * issue right now because it only effects Blaze's include scanning (internal) and Bazel's
    * repositories (external) but will need to be fixed.
    */
-  public Root getBinDirectory(RepositoryName repositoryName) {
+  public ArtifactRoot getBinDirectory(RepositoryName repositoryName) {
     return repositoryName.isMain() || repositoryName.equals(mainRepositoryName)
         ? binDirectoryForMainRepository
         : OutputDirectory.BIN.getRoot(
@@ -1614,26 +1613,22 @@
     return getBinDirectory().getExecPath();
   }
 
-  /**
-   * Returns the include directory for this build configuration.
-   */
-  public Root getIncludeDirectory(RepositoryName repositoryName) {
+  /** Returns the include directory for this build configuration. */
+  public ArtifactRoot getIncludeDirectory(RepositoryName repositoryName) {
     return repositoryName.isMain() || repositoryName.equals(mainRepositoryName)
         ? includeDirectoryForMainRepository
         : OutputDirectory.INCLUDE.getRoot(
             repositoryName, outputDirName, directories, mainRepositoryName);
   }
 
-  /**
-   * Returns the genfiles directory for this build configuration.
-   */
+  /** Returns the genfiles directory for this build configuration. */
   @SkylarkCallable(name = "genfiles_dir", structField = true, documented = false)
   @Deprecated
-  public Root getGenfilesDirectory() {
+  public ArtifactRoot getGenfilesDirectory() {
     return getGenfilesDirectory(RepositoryName.MAIN);
   }
 
-  public Root getGenfilesDirectory(RepositoryName repositoryName) {
+  public ArtifactRoot getGenfilesDirectory(RepositoryName repositoryName) {
     if (!separateGenfilesDirectory) {
       return getBinDirectory(repositoryName);
     }
@@ -1645,21 +1640,19 @@
   }
 
   /**
-   * Returns the directory where coverage-related artifacts and metadata files
-   * should be stored. This includes for example uninstrumented class files
-   * needed for Jacoco's coverage reporting tools.
+   * Returns the directory where coverage-related artifacts and metadata files should be stored.
+   * This includes for example uninstrumented class files needed for Jacoco's coverage reporting
+   * tools.
    */
-  public Root getCoverageMetadataDirectory(RepositoryName repositoryName) {
+  public ArtifactRoot getCoverageMetadataDirectory(RepositoryName repositoryName) {
     return repositoryName.isMain() || repositoryName.equals(mainRepositoryName)
         ? coverageDirectoryForMainRepository
         : OutputDirectory.COVERAGE.getRoot(
             repositoryName, outputDirName, directories, mainRepositoryName);
   }
 
-  /**
-   * Returns the testlogs directory for this build configuration.
-   */
-  public Root getTestLogsDirectory(RepositoryName repositoryName) {
+  /** Returns the testlogs directory for this build configuration. */
+  public ArtifactRoot getTestLogsDirectory(RepositoryName repositoryName) {
     return repositoryName.isMain() || repositoryName.equals(mainRepositoryName)
         ? testlogsDirectoryForMainRepository
         : OutputDirectory.TESTLOGS.getRoot(
@@ -1686,10 +1679,8 @@
     return OS.getCurrent() == OS.WINDOWS ? ";" : ":";
   }
 
-  /**
-   * Returns the internal directory (used for middlemen) for this build configuration.
-   */
-  public Root getMiddlemanDirectory(RepositoryName repositoryName) {
+  /** Returns the internal directory (used for middlemen) for this build configuration. */
+  public ArtifactRoot getMiddlemanDirectory(RepositoryName repositoryName) {
     return repositoryName.isMain() || repositoryName.equals(mainRepositoryName)
         ? middlemanDirectoryForMainRepository
         : OutputDirectory.MIDDLEMAN.getRoot(
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkActionFactory.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkActionFactory.java
index e77b159..4bf9999 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkActionFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkActionFactory.java
@@ -18,8 +18,8 @@
 import com.google.devtools.build.lib.actions.Action;
 import com.google.devtools.build.lib.actions.ActionAnalysisMetadata;
 import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.actions.ParameterFile.ParameterFileType;
-import com.google.devtools.build.lib.actions.Root;
 import com.google.devtools.build.lib.actions.RunfilesSupplier;
 import com.google.devtools.build.lib.actions.extra.SpawnInfo;
 import com.google.devtools.build.lib.analysis.CommandHelper;
@@ -94,7 +94,7 @@
     this.ruleContext = ruleContext;
   }
 
-  Root newFileRoot() throws EvalException {
+  ArtifactRoot newFileRoot() throws EvalException {
     return context.isForAspect()
         ? ruleContext.getConfiguration().getBinDirectory(ruleContext.getRule().getRepository())
         : ruleContext.getBinOrGenfilesDirectory();
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleContext.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleContext.java
index 3dbb8d9..de2bd46 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleContext.java
@@ -25,7 +25,7 @@
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Ordering;
 import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.actions.Root;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.analysis.ActionsProvider;
 import com.google.devtools.build.lib.analysis.ConfigurationMakeVariableContext;
 import com.google.devtools.build.lib.analysis.DefaultInfo;
@@ -708,16 +708,22 @@
     return ImmutableList.copyOf(ruleContext.getFeatures());
   }
 
-  @SkylarkCallable(name = "bin_dir", structField = true,
-      doc = "The root corresponding to bin directory.")
-  public Root getBinDirectory() throws EvalException {
+  @SkylarkCallable(
+    name = "bin_dir",
+    structField = true,
+    doc = "The root corresponding to bin directory."
+  )
+  public ArtifactRoot getBinDirectory() throws EvalException {
     checkMutable("bin_dir");
     return getConfiguration().getBinDirectory(ruleContext.getRule().getRepository());
   }
 
-  @SkylarkCallable(name = "genfiles_dir", structField = true,
-      doc = "The root corresponding to genfiles directory.")
-  public Root getGenfilesDirectory() throws EvalException {
+  @SkylarkCallable(
+    name = "genfiles_dir",
+    structField = true,
+    doc = "The root corresponding to genfiles directory."
+  )
+  public ArtifactRoot getGenfilesDirectory() throws EvalException {
     checkMutable("genfiles_dir");
     return getConfiguration().getGenfilesDirectory(ruleContext.getRule().getRepository());
   }
@@ -845,7 +851,7 @@
 
   // Kept for compatibility with old code.
   @SkylarkCallable(documented = false)
-  public Artifact newFile(Root root, String filename) throws EvalException {
+  public Artifact newFile(ArtifactRoot root, String filename) throws EvalException {
     checkMutable("new_file");
     return ruleContext.getPackageRelativeArtifact(filename, root);
   }
@@ -877,7 +883,8 @@
 
   // Kept for compatibility with old code.
   @SkylarkCallable(documented = false)
-  public Artifact newFile(Root root, Artifact baseArtifact, String suffix) throws EvalException {
+  public Artifact newFile(ArtifactRoot root, Artifact baseArtifact, String suffix)
+      throws EvalException {
     checkMutable("new_file");
     PathFragment original = baseArtifact.getRootRelativePath();
     PathFragment fragment = original.replaceName(original.getBaseName() + suffix);
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/test/TestActionBuilder.java b/src/main/java/com/google/devtools/build/lib/analysis/test/TestActionBuilder.java
index 81d6993..37cfbbe 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/test/TestActionBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/test/TestActionBuilder.java
@@ -21,7 +21,7 @@
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.actions.Root;
+import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.analysis.AnalysisEnvironment;
 import com.google.devtools.build.lib.analysis.FileProvider;
 import com.google.devtools.build.lib.analysis.FilesToRunProvider;
@@ -187,7 +187,7 @@
     PathFragment targetName = PathFragment.create(ruleContext.getLabel().getName());
     BuildConfiguration config = ruleContext.getConfiguration();
     AnalysisEnvironment env = ruleContext.getAnalysisEnvironment();
-    Root root = config.getTestLogsDirectory(ruleContext.getRule().getRepository());
+    ArtifactRoot root = config.getTestLogsDirectory(ruleContext.getRule().getRepository());
 
     NestedSetBuilder<Artifact> inputsBuilder = NestedSetBuilder.stableOrder();
     inputsBuilder.addTransitive(