Break dependency on vfs from the interface of syntax and cmdline.
These libs are exposed externally, implying that the vfs is also exposed externally.
We break out PathFragment from vfs to still use this in their interface. This class is a much smaller dependency than the entire vfs.
PiperOrigin-RevId: 174729373
diff --git a/src/main/java/com/google/devtools/build/lib/vfs/BUILD b/src/main/java/com/google/devtools/build/lib/vfs/BUILD
index 37bb571..1e6c5a9 100644
--- a/src/main/java/com/google/devtools/build/lib/vfs/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/vfs/BUILD
@@ -6,17 +6,45 @@
visibility = ["//src/main/java/com/google/devtools/build/lib:__pkg__"],
)
-# Virtual file system; do not use externally!
+PATH_FRAGMENT_SOURCES = [
+ "Canonicalizer.java",
+ "PathFragment.java",
+ "PathFragmentSerializationProxy.java",
+ "UnixPathFragment.java",
+ "WindowsPathFragment.java",
+]
+
java_library(
- name = "vfs",
- srcs = glob([
- "*.java",
- ]),
- visibility = ["//visibility:public"],
+ name = "pathfragment",
+ srcs = PATH_FRAGMENT_SOURCES,
deps = [
"//src/main/java/com/google/devtools/build/lib:base-util",
"//src/main/java/com/google/devtools/build/lib:os_util",
"//src/main/java/com/google/devtools/build/lib:preconditions",
+ "//src/main/java/com/google/devtools/build/lib:skylarkinterface",
+ "//src/main/java/com/google/devtools/build/lib/concurrent",
+ "//third_party:guava",
+ ],
+)
+
+# Virtual file system; do not use externally!
+java_library(
+ name = "vfs",
+ srcs = glob(
+ [
+ "*.java",
+ ],
+ exclude = PATH_FRAGMENT_SOURCES,
+ ),
+ visibility = ["//visibility:public"],
+ exports = [
+ ":pathfragment",
+ ],
+ deps = [
+ ":pathfragment",
+ "//src/main/java/com/google/devtools/build/lib:base-util",
+ "//src/main/java/com/google/devtools/build/lib:preconditions",
+ "//src/main/java/com/google/devtools/build/lib:skylarkinterface",
"//src/main/java/com/google/devtools/build/lib/clock",
"//src/main/java/com/google/devtools/build/lib/concurrent",
"//src/main/java/com/google/devtools/build/lib/profiler",
diff --git a/src/main/java/com/google/devtools/build/lib/vfs/Path.java b/src/main/java/com/google/devtools/build/lib/vfs/Path.java
index 52b8af3..ab5ad5c 100644
--- a/src/main/java/com/google/devtools/build/lib/vfs/Path.java
+++ b/src/main/java/com/google/devtools/build/lib/vfs/Path.java
@@ -15,6 +15,8 @@
import com.google.common.base.Predicate;
import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkPrintable;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
import com.google.devtools.build.lib.util.Preconditions;
import com.google.devtools.build.lib.util.StringCanonicalizer;
import com.google.devtools.build.lib.vfs.FileSystem.HashFunction;
@@ -37,21 +39,20 @@
import java.util.Objects;
/**
- * <p>Instances of this class represent pathnames, forming a tree
- * structure to implement sharing of common prefixes (parent directory names).
- * A node in these trees is something like foo, bar, .., ., or /. If the
- * instance is not a root path, it will have a parent path. A path can also
- * have children, which are indexed by name in a map.
+ * Instances of this class represent pathnames, forming a tree structure to implement sharing of
+ * common prefixes (parent directory names). A node in these trees is something like foo, bar, ..,
+ * ., or /. If the instance is not a root path, it will have a parent path. A path can also have
+ * children, which are indexed by name in a map.
*
- * <p>There is some limited support for Windows-style paths. Most importantly, drive identifiers
- * in front of a path (c:/abc) are supported. However, Windows-style backslash separators
+ * <p>There is some limited support for Windows-style paths. Most importantly, drive identifiers in
+ * front of a path (c:/abc) are supported. However, Windows-style backslash separators
* (C:\\foo\\bar) and drive-relative paths ("C:foo") are explicitly not supported, same with
* advanced features like \\\\network\\paths and \\\\?\\unc\\paths.
*
* <p>{@link FileSystem} implementations maintain pointers into this graph.
*/
@ThreadSafe
-public class Path implements Comparable<Path>, Serializable {
+public class Path implements Comparable<Path>, Serializable, SkylarkPrintable {
/** Filesystem-specific factory for {@link Path} objects. */
public static interface PathFactory {
@@ -427,6 +428,11 @@
return builder.toString();
}
+ @Override
+ public void repr(SkylarkPrinter printer) {
+ printer.append(getPathString());
+ }
+
/**
* Returns the path as a string.
*/
diff --git a/src/main/java/com/google/devtools/build/lib/vfs/PathFragment.java b/src/main/java/com/google/devtools/build/lib/vfs/PathFragment.java
index c47a5f7..a6d6b2b 100644
--- a/src/main/java/com/google/devtools/build/lib/vfs/PathFragment.java
+++ b/src/main/java/com/google/devtools/build/lib/vfs/PathFragment.java
@@ -20,6 +20,8 @@
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkPrintable;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
import com.google.devtools.build.lib.util.OS;
import com.google.devtools.build.lib.util.Preconditions;
import com.google.devtools.build.lib.util.StringCanonicalizer;
@@ -45,7 +47,8 @@
*/
@Immutable
@ThreadSafe
-public abstract class PathFragment implements Comparable<PathFragment>, Serializable {
+public abstract class PathFragment
+ implements Comparable<PathFragment>, Serializable, SkylarkPrintable {
private static final Helper HELPER =
OS.getCurrent() == OS.WINDOWS ? WindowsPathFragment.HELPER : UnixPathFragment.HELPER;
@@ -451,18 +454,17 @@
}
/**
- * Returns the path formed by appending the single non-special segment
- * "baseName" to this path.
+ * Returns the path formed by appending the single non-special segment "baseName" to this path.
*
- * <p>You should almost always use {@link #getRelative} instead, which has
- * the same performance characteristics if the given name is a valid base
- * name, and which also works for '.', '..', and strings containing '/'.
+ * <p>You should almost always use {@link #getRelative} instead, which has the same performance
+ * characteristics if the given name is a valid base name, and which also works for '.', '..', and
+ * strings containing '/'.
*
- * @throws IllegalArgumentException if {@code baseName} is not a valid base
- * name according to {@link FileSystemUtils#checkBaseName}
+ * @throws IllegalArgumentException if {@code baseName} is not a valid base name according to
+ * {@link #checkBaseName}
*/
public PathFragment getChild(String baseName) {
- FileSystemUtils.checkBaseName(baseName);
+ checkBaseName(baseName);
baseName = StringCanonicalizer.intern(baseName);
String[] newSegments = Arrays.copyOf(segments, segments.length + 1);
newSegments[newSegments.length - 1] = baseName;
@@ -734,4 +736,21 @@
public String toString() {
return getPathString();
}
+
+ @Override
+ public void repr(SkylarkPrinter printer) {
+ printer.append(getPathString());
+ }
+
+ private static void checkBaseName(String baseName) {
+ if (baseName.length() == 0) {
+ throw new IllegalArgumentException("Child must not be empty string ('')");
+ }
+ if (baseName.equals(".") || baseName.equals("..")) {
+ throw new IllegalArgumentException("baseName must not be '" + baseName + "'");
+ }
+ if (baseName.indexOf('/') != -1) {
+ throw new IllegalArgumentException("baseName must not contain a slash: '" + baseName + "'");
+ }
+ }
}