Clean up absolutize and make it public for use in a subsequent change.
--
MOS_MIGRATED_REVID=116058328
diff --git a/src/main/java/com/google/devtools/build/lib/cmdline/TargetPattern.java b/src/main/java/com/google/devtools/build/lib/cmdline/TargetPattern.java
index 8b49a2a..f8c1a83 100644
--- a/src/main/java/com/google/devtools/build/lib/cmdline/TargetPattern.java
+++ b/src/main/java/com/google/devtools/build/lib/cmdline/TargetPattern.java
@@ -31,6 +31,7 @@
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
+import java.util.regex.Pattern;
import javax.annotation.concurrent.Immutable;
@@ -334,17 +335,17 @@
private final PackageIdentifier packageIdentifier;
private final String suffix;
- private final boolean isAbsolute;
+ private final boolean wasOriginallyAbsolute;
private final boolean rulesOnly;
private final boolean checkWildcardConflict;
private TargetsInPackage(String originalPattern, String offset,
- PackageIdentifier packageIdentifier, String suffix, boolean isAbsolute, boolean rulesOnly,
- boolean checkWildcardConflict) {
+ PackageIdentifier packageIdentifier, String suffix, boolean wasOriginallyAbsolute,
+ boolean rulesOnly, boolean checkWildcardConflict) {
super(Type.TARGETS_IN_PACKAGE, originalPattern, offset);
this.packageIdentifier = packageIdentifier;
this.suffix = Preconditions.checkNotNull(suffix);
- this.isAbsolute = isAbsolute;
+ this.wasOriginallyAbsolute = wasOriginallyAbsolute;
this.rulesOnly = rulesOnly;
this.checkWildcardConflict = checkWildcardConflict;
}
@@ -396,7 +397,7 @@
return false;
}
TargetsInPackage that = (TargetsInPackage) o;
- return isAbsolute == that.isAbsolute && rulesOnly == that.rulesOnly
+ return wasOriginallyAbsolute == that.wasOriginallyAbsolute && rulesOnly == that.rulesOnly
&& checkWildcardConflict == that.checkWildcardConflict
&& getOriginalPattern().equals(that.getOriginalPattern())
&& packageIdentifier.equals(that.packageIdentifier) && suffix.equals(that.suffix);
@@ -404,8 +405,8 @@
@Override
public int hashCode() {
- return Objects.hash(getType(), getOriginalPattern(), packageIdentifier, suffix, isAbsolute,
- rulesOnly, checkWildcardConflict);
+ return Objects.hash(getType(), getOriginalPattern(), packageIdentifier, suffix,
+ wasOriginallyAbsolute, rulesOnly, checkWildcardConflict);
}
/**
@@ -417,7 +418,7 @@
*/
private <T> ResolvedTargets<T> getWildcardConflict(TargetPatternResolver<T> resolver)
throws InterruptedException {
- if (!isAbsolute) {
+ if (!wasOriginallyAbsolute) {
return null;
}
@@ -515,6 +516,10 @@
@Immutable
public static final class Parser {
+ // A valid pattern either starts with exactly 0 slashes (relative pattern) or exactly two
+ // slashes (absolute pattern).
+ private static final Pattern VALID_SLASH_PREFIX = Pattern.compile("(//)?([^/]|$)");
+
// TODO(bazel-team): Merge the Label functionality that requires similar constants into this
// class.
/**
@@ -600,14 +605,16 @@
pattern = pattern.substring(pkgStart);
}
- final boolean isAbsolute = pattern.startsWith("//");
- // We now absolutize non-absolute target patterns.
- pattern = isAbsolute ? pattern.substring(2) : absolutize(pattern);
- // Check for common errors.
- if (pattern.startsWith("/")) {
- throw new TargetParsingException("not a relative path or label: '" + pattern + "'");
+ if (!VALID_SLASH_PREFIX.matcher(pattern).lookingAt()) {
+ throw new TargetParsingException("not a valid absolute pattern (absolute target patterns "
+ + "must start with exactly two slashes): '" + pattern + "'");
}
+
+ final boolean wasOriginallyAbsolute = pattern.startsWith("//");
+ // We now ensure the relativeDirectory is applied to relative patterns.
+ pattern = absolutize(pattern).substring(2);
+
if (pattern.isEmpty()) {
throw new TargetParsingException("the empty string is not a valid target");
}
@@ -659,7 +666,7 @@
"Invalid package name '" + packagePart + "': " + e.getMessage());
}
return new TargetsInPackage(originalPattern, relativeDirectory, packageIdentifier,
- targetPart, isAbsolute, true, true);
+ targetPart, wasOriginallyAbsolute, true, true);
}
if (ALL_TARGETS_IN_SUFFIXES.contains(targetPart)) {
@@ -671,10 +678,10 @@
"Invalid package name '" + packagePart + "': " + e.getMessage());
}
return new TargetsInPackage(originalPattern, relativeDirectory, packageIdentifier,
- targetPart, isAbsolute, false, true);
+ targetPart, wasOriginallyAbsolute, false, true);
}
- if (includesRepo || isAbsolute || pattern.contains(":")) {
+ if (includesRepo || wasOriginallyAbsolute || pattern.contains(":")) {
PackageIdentifier packageIdentifier;
String fullLabel = repository.getName() + "//" + pattern;
try {
@@ -710,19 +717,20 @@
/**
* Absolutizes the target pattern to the offset.
- * Patterns starting with "/" are absolute and not modified.
+ * Patterns starting with "//" are absolute and not modified.
+ * Assumes the given pattern is not invalid wrt leading "/"s.
*
* If the offset is "foo":
- * absolutize(":bar") --> "foo:bar"
- * absolutize("bar") --> "foo/bar"
- * absolutize("/biz/bar") --> "biz/bar" (absolute)
- * absolutize("biz:bar") --> "foo/biz:bar"
+ * absolutize(":bar") --> "//foo:bar"
+ * absolutize("bar") --> "//foo/bar"
+ * absolutize("//biz/bar") --> "//biz/bar" (absolute)
+ * absolutize("biz:bar") --> "//foo/biz:bar"
*
* @param pattern The target pattern to parse.
* @return the pattern, absolutized to the offset if approprate.
*/
- private String absolutize(String pattern) {
- if (relativeDirectory.isEmpty() || pattern.startsWith("/")) {
+ public String absolutize(String pattern) {
+ if (pattern.startsWith("//")) {
return pattern;
}
@@ -730,9 +738,9 @@
// but it doesn't work when the pattern starts with ":".
// "foo".getRelative(":all") would return "foo/:all", where we
// really want "foo:all".
- return pattern.startsWith(":")
- ? relativeDirectory + pattern
- : relativeDirectory + "/" + pattern;
+ return pattern.startsWith(":") || relativeDirectory.isEmpty()
+ ? "//" + relativeDirectory + pattern
+ : "//" + relativeDirectory + "/" + pattern;
}
}