aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/google/devtools/build')
-rw-r--r--src/main/java/com/google/devtools/build/lib/cmdline/TargetPattern.java49
-rw-r--r--src/main/java/com/google/devtools/build/lib/query2/SkyQueryEnvironment.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternsFunction.java39
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternsValue.java7
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/SkyframeTargetPatternEvaluator.java24
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/TargetPatternFunction.java9
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/TargetPatternValue.java154
7 files changed, 208 insertions, 77 deletions
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 deeec7940c..dee9659e8d 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
@@ -53,6 +53,7 @@ public abstract class TargetPattern implements Serializable {
private static final Parser DEFAULT_PARSER = new Parser("");
private final Type type;
+ private final String originalPattern;
/**
* Returns a parser with no offset. Note that the Parser class is immutable, so this method may
@@ -104,9 +105,10 @@ public abstract class TargetPattern implements Serializable {
return SLASH_JOINER.join(pieces);
}
- private TargetPattern(Type type) {
+ private TargetPattern(Type type, String originalPattern) {
// Don't allow inheritance outside this class.
this.type = type;
+ this.originalPattern = Preconditions.checkNotNull(originalPattern);
}
/**
@@ -118,6 +120,13 @@ public abstract class TargetPattern implements Serializable {
}
/**
+ * Return the string that was parsed into this pattern.
+ */
+ public String getOriginalPattern() {
+ return originalPattern;
+ }
+
+ /**
* Evaluates the current target pattern and returns the result.
*/
public <T> ResolvedTargets<T> eval(TargetPatternResolver<T> resolver)
@@ -160,8 +169,8 @@ public abstract class TargetPattern implements Serializable {
private final String targetName;
private final String directory;
- private SingleTarget(String targetName, String directory) {
- super(Type.SINGLE_TARGET);
+ private SingleTarget(String targetName, String directory, String originalPattern) {
+ super(Type.SINGLE_TARGET, originalPattern);
this.targetName = Preconditions.checkNotNull(targetName);
this.directory = Preconditions.checkNotNull(directory);
}
@@ -172,7 +181,7 @@ public abstract class TargetPattern implements Serializable {
throws TargetParsingException, InterruptedException {
Preconditions.checkArgument(excludedSubdirectories.isEmpty(),
"Target pattern \"%s\" of type %s cannot be evaluated with excluded subdirectories: %s.",
- targetName, getType(), excludedSubdirectories);
+ getOriginalPattern(), getType(), excludedSubdirectories);
return resolver.getExplicitTarget(targetName);
}
@@ -208,8 +217,8 @@ public abstract class TargetPattern implements Serializable {
private final String path;
- private InterpretPathAsTarget(String path) {
- super(Type.PATH_AS_TARGET);
+ private InterpretPathAsTarget(String path, String originalPattern) {
+ super(Type.PATH_AS_TARGET, originalPattern);
this.path = normalize(Preconditions.checkNotNull(path));
}
@@ -219,7 +228,7 @@ public abstract class TargetPattern implements Serializable {
throws TargetParsingException, InterruptedException {
Preconditions.checkArgument(excludedSubdirectories.isEmpty(),
"Target pattern \"%s\" of type %s cannot be evaluated with excluded subdirectories: %s.",
- path, getType(), excludedSubdirectories);
+ getOriginalPattern(), getType(), excludedSubdirectories);
if (resolver.isPackage(path)) {
// User has specified a package name. lookout for default target.
return resolver.getExplicitTarget("//" + path);
@@ -271,7 +280,6 @@ public abstract class TargetPattern implements Serializable {
private static final class TargetsInPackage extends TargetPattern {
- private final String originalPattern;
private final String pattern;
private final String suffix;
private final boolean isAbsolute;
@@ -280,8 +288,7 @@ public abstract class TargetPattern implements Serializable {
private TargetsInPackage(String originalPattern, String pattern, String suffix,
boolean isAbsolute, boolean rulesOnly, boolean checkWildcardConflict) {
- super(Type.TARGETS_IN_PACKAGE);
- this.originalPattern = Preconditions.checkNotNull(originalPattern);
+ super(Type.TARGETS_IN_PACKAGE, originalPattern);
this.pattern = Preconditions.checkNotNull(pattern);
this.suffix = Preconditions.checkNotNull(suffix);
this.isAbsolute = isAbsolute;
@@ -295,14 +302,14 @@ public abstract class TargetPattern implements Serializable {
throws TargetParsingException, InterruptedException {
Preconditions.checkArgument(excludedSubdirectories.isEmpty(),
"Target pattern \"%s\" of type %s cannot be evaluated with excluded subdirectories: %s.",
- originalPattern, getType(), excludedSubdirectories);
+ getOriginalPattern(), getType(), excludedSubdirectories);
if (checkWildcardConflict) {
ResolvedTargets<T> targets = getWildcardConflict(resolver);
if (targets != null) {
return targets;
}
}
- return resolver.getTargetsInPackage(originalPattern, removeSuffix(pattern, suffix),
+ return resolver.getTargetsInPackage(getOriginalPattern(), removeSuffix(pattern, suffix),
rulesOnly);
}
@@ -327,13 +334,13 @@ public abstract class TargetPattern implements Serializable {
TargetsInPackage that = (TargetsInPackage) o;
return isAbsolute == that.isAbsolute && rulesOnly == that.rulesOnly
&& checkWildcardConflict == that.checkWildcardConflict
- && originalPattern.equals(that.originalPattern)
+ && getOriginalPattern().equals(that.getOriginalPattern())
&& pattern.equals(that.pattern) && suffix.equals(that.suffix);
}
@Override
public int hashCode() {
- return Objects.hash(getType(), originalPattern, pattern, suffix, isAbsolute, rulesOnly,
+ return Objects.hash(getType(), getOriginalPattern(), pattern, suffix, isAbsolute, rulesOnly,
checkWildcardConflict);
}
@@ -373,13 +380,11 @@ public abstract class TargetPattern implements Serializable {
private static final class TargetsBelowDirectory extends TargetPattern {
- private final String originalPattern;
private final String directory;
private final boolean rulesOnly;
private TargetsBelowDirectory(String originalPattern, String directory, boolean rulesOnly) {
- super(Type.TARGETS_BELOW_DIRECTORY);
- this.originalPattern = Preconditions.checkNotNull(originalPattern);
+ super(Type.TARGETS_BELOW_DIRECTORY, originalPattern);
this.directory = Preconditions.checkNotNull(directory);
this.rulesOnly = rulesOnly;
}
@@ -388,7 +393,7 @@ public abstract class TargetPattern implements Serializable {
public <T> ResolvedTargets<T> eval(TargetPatternResolver<T> resolver,
ImmutableSet<String> excludedSubdirectories)
throws TargetParsingException, InterruptedException {
- return resolver.findTargetsBeneathDirectory(originalPattern, directory, rulesOnly,
+ return resolver.findTargetsBeneathDirectory(getOriginalPattern(), directory, rulesOnly,
excludedSubdirectories);
}
@@ -415,13 +420,13 @@ public abstract class TargetPattern implements Serializable {
return false;
}
TargetsBelowDirectory that = (TargetsBelowDirectory) o;
- return rulesOnly == that.rulesOnly && originalPattern.equals(that.originalPattern)
+ return rulesOnly == that.rulesOnly && getOriginalPattern().equals(that.getOriginalPattern())
&& directory.equals(that.directory);
}
@Override
public int hashCode() {
- return Objects.hash(getType(), originalPattern, directory, rulesOnly);
+ return Objects.hash(getType(), getOriginalPattern(), directory, rulesOnly);
}
}
@@ -557,7 +562,7 @@ public abstract class TargetPattern implements Serializable {
String error = "invalid target format '" + originalPattern + "': " + e.getMessage();
throw new TargetParsingException(error);
}
- return new SingleTarget(fullLabel, packageAndTarget.getPackageName());
+ return new SingleTarget(fullLabel, packageAndTarget.getPackageName(), originalPattern);
}
// This is a stripped-down version of interpretPathAsTarget that does no I/O. We have a basic
@@ -575,7 +580,7 @@ public abstract class TargetPattern implements Serializable {
throw new TargetParsingException("Bad target pattern '" + originalPattern + "': " +
errorMessage);
}
- return new InterpretPathAsTarget(pattern);
+ return new InterpretPathAsTarget(pattern, originalPattern);
}
/**
diff --git a/src/main/java/com/google/devtools/build/lib/query2/SkyQueryEnvironment.java b/src/main/java/com/google/devtools/build/lib/query2/SkyQueryEnvironment.java
index ec84e1fd90..c3faec8e40 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/SkyQueryEnvironment.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/SkyQueryEnvironment.java
@@ -361,11 +361,10 @@ public class SkyQueryEnvironment extends AbstractBlazeQueryEnvironment<Target> {
} else {
// If the graph doesn't contain a value for this target pattern, try to directly evaluate
// it, by making use of packages already present in the graph.
- TargetPattern.Parser parser = new TargetPattern.Parser(targetPatternKey.getOffset());
RecursivePackageProviderBackedTargetPatternResolver resolver =
new RecursivePackageProviderBackedTargetPatternResolver(provider, eventHandler,
targetPatternKey.getPolicy(), pkgPath);
- TargetPattern parsedPattern = parser.parse(targetPatternKey.getPattern());
+ TargetPattern parsedPattern = targetPatternKey.getParsedPattern();
try {
result.put(pattern, parsedPattern.eval(resolver));
} catch (TargetParsingException e) {
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternsFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternsFunction.java
index bd280dd9cf..6653c48933 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternsFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternsFunction.java
@@ -15,6 +15,7 @@ package com.google.devtools.build.lib.skyframe;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.cmdline.ResolvedTargets;
import com.google.devtools.build.lib.cmdline.TargetParsingException;
import com.google.devtools.build.lib.events.Event;
@@ -24,6 +25,7 @@ import com.google.devtools.build.lib.packages.NoSuchTargetException;
import com.google.devtools.build.lib.pkgcache.ParseFailureListener;
import com.google.devtools.build.lib.skyframe.PrepareDepsOfPatternsValue.TargetPatternSequence;
import com.google.devtools.build.lib.skyframe.TargetPatternValue.TargetPatternKey;
+import com.google.devtools.build.lib.skyframe.TargetPatternValue.TargetPatternSkyKeyOrException;
import com.google.devtools.build.lib.syntax.Label;
import com.google.devtools.build.skyframe.SkyFunction;
import com.google.devtools.build.skyframe.SkyKey;
@@ -50,20 +52,32 @@ public class PrepareDepsOfPatternsFunction implements SkyFunction {
@Nullable
@Override
public SkyValue compute(SkyKey skyKey, Environment env) throws InterruptedException {
+ EventHandler eventHandler = env.getListener();
+ boolean handlerIsParseFailureListener = eventHandler instanceof ParseFailureListener;
TargetPatternSequence targetPatternSequence = (TargetPatternSequence) skyKey.argument();
- Iterable<SkyKey> patternSkyKeys = TargetPatternValue.keys(targetPatternSequence.getPatterns(),
- targetPatternSequence.getPolicy(), targetPatternSequence.getOffset());
+ Iterable<TargetPatternSkyKeyOrException> keysMaybe =
+ TargetPatternValue.keys(targetPatternSequence.getPatterns(),
+ targetPatternSequence.getPolicy(), targetPatternSequence.getOffset());
+
+ ImmutableList.Builder<SkyKey> skyKeyBuilder = ImmutableList.builder();
+ for (TargetPatternSkyKeyOrException skyKeyOrException : keysMaybe) {
+ try {
+ skyKeyBuilder.add(skyKeyOrException.getSkyKey());
+ } catch (TargetParsingException e) {
+ handleTargetParsingException(eventHandler, handlerIsParseFailureListener,
+ skyKeyOrException.getOriginalPattern(), e);
+ }
+ }
+ ImmutableList<SkyKey> skyKeys = skyKeyBuilder.build();
+
Map<SkyKey, ValueOrException<TargetParsingException>> targetPatternValuesByKey =
- env.getValuesOrThrow(patternSkyKeys, TargetParsingException.class);
+ env.getValuesOrThrow(skyKeys, TargetParsingException.class);
if (env.valuesMissing()) {
return null;
}
- EventHandler eventHandler = env.getListener();
- boolean handlerIsParseFailureListener = eventHandler instanceof ParseFailureListener;
-
ResolvedTargets.Builder<Label> builder = ResolvedTargets.builder();
- for (SkyKey key : patternSkyKeys) {
+ for (SkyKey key : skyKeys) {
try {
// The only exception type throwable by TargetPatternFunction is TargetParsingException.
// Therefore all ValueOrException values in the map will either be non-null or throw
@@ -102,13 +116,18 @@ public class PrepareDepsOfPatternsFunction implements SkyFunction {
private static void handleTargetParsingException(EventHandler eventHandler,
boolean handlerIsParseFailureListener, SkyKey key, TargetParsingException e) {
- TargetPatternKey pattern = (TargetPatternKey) key.argument();
- String rawPattern = pattern.getPattern();
+ TargetPatternKey patternKey = (TargetPatternKey) key.argument();
+ String rawPattern = patternKey.getPattern();
+ handleTargetParsingException(eventHandler, handlerIsParseFailureListener, rawPattern, e);
+ }
+
+ private static void handleTargetParsingException(EventHandler eventHandler,
+ boolean handlerIsParseFailureListener, String rawPattern, TargetParsingException e) {
String errorMessage = e.getMessage();
eventHandler.handle(Event.error("Skipping '" + rawPattern + "': " + errorMessage));
if (handlerIsParseFailureListener) {
ParseFailureListener parseListener = (ParseFailureListener) eventHandler;
- parseListener.parsingError(rawPattern, errorMessage);
+ parseListener.parsingError(rawPattern, errorMessage);
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternsValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternsValue.java
index 88f034cee2..918b31fd15 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternsValue.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternsValue.java
@@ -37,8 +37,7 @@ public final class PrepareDepsOfPatternsValue implements SkyValue {
}
@ThreadSafe
- public static SkyKey key(ImmutableList<String> patterns, FilteringPolicy policy,
- String offset) {
+ public static SkyKey key(ImmutableList<String> patterns, FilteringPolicy policy, String offset) {
return new SkyKey(SkyFunctions.PREPARE_DEPS_OF_PATTERNS,
new TargetPatternSequence(patterns, policy, offset));
}
@@ -50,8 +49,8 @@ public final class PrepareDepsOfPatternsValue implements SkyValue {
private final FilteringPolicy policy;
private final String offset;
- public TargetPatternSequence(ImmutableList<String> patterns,
- FilteringPolicy policy, String offset) {
+ private TargetPatternSequence(ImmutableList<String> patterns, FilteringPolicy policy,
+ String offset) {
this.patterns = patterns;
this.policy = policy;
this.offset = offset;
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeTargetPatternEvaluator.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeTargetPatternEvaluator.java
index 979f322b19..d166126038 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeTargetPatternEvaluator.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeTargetPatternEvaluator.java
@@ -30,6 +30,7 @@ import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.pkgcache.FilteringPolicy;
import com.google.devtools.build.lib.pkgcache.ParseFailureListener;
import com.google.devtools.build.lib.pkgcache.TargetPatternEvaluator;
+import com.google.devtools.build.lib.skyframe.TargetPatternValue.TargetPatternSkyKeyOrException;
import com.google.devtools.build.lib.syntax.Label;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.skyframe.ErrorInfo;
@@ -99,8 +100,27 @@ final class SkyframeTargetPatternEvaluator implements TargetPatternEvaluator {
ResolvedTargets<Target> parseTargetPatternList(String offset, EventHandler eventHandler,
List<String> targetPatterns, FilteringPolicy policy, boolean keepGoing)
throws InterruptedException, TargetParsingException {
- return parseTargetPatternKeys(TargetPatternValue.keys(targetPatterns, policy, offset),
- SkyframeExecutor.DEFAULT_THREAD_COUNT, keepGoing, eventHandler);
+ Iterable<TargetPatternSkyKeyOrException> keysMaybe =
+ TargetPatternValue.keys(targetPatterns, policy, offset);
+
+ ImmutableList.Builder<SkyKey> builder = ImmutableList.builder();
+ for (TargetPatternSkyKeyOrException skyKeyOrException : keysMaybe) {
+ try {
+ builder.add(skyKeyOrException.getSkyKey());
+ } catch (TargetParsingException e) {
+ if (!keepGoing) {
+ throw e;
+ }
+ String pattern = skyKeyOrException.getOriginalPattern();
+ eventHandler.handle(Event.error("Skipping '" + pattern + "': " + e.getMessage()));
+ if (eventHandler instanceof ParseFailureListener) {
+ ((ParseFailureListener) eventHandler).parsingError(pattern, e.getMessage());
+ }
+ }
+ }
+ ImmutableList<SkyKey> skyKeys = builder.build();
+ return parseTargetPatternKeys(skyKeys, SkyframeExecutor.DEFAULT_THREAD_COUNT, keepGoing,
+ eventHandler);
}
private static Map<PackageIdentifier, Package> getPackages(
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/TargetPatternFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/TargetPatternFunction.java
index 97aef9845f..d805a91695 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/TargetPatternFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/TargetPatternFunction.java
@@ -14,6 +14,7 @@
package com.google.devtools.build.lib.skyframe;
import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.cmdline.ResolvedTargets;
import com.google.devtools.build.lib.cmdline.TargetParsingException;
import com.google.devtools.build.lib.cmdline.TargetPattern;
@@ -47,16 +48,16 @@ public class TargetPatternFunction implements SkyFunction {
InterruptedException {
TargetPatternValue.TargetPatternKey patternKey =
((TargetPatternValue.TargetPatternKey) key.argument());
- TargetPattern.Parser parser = new TargetPattern.Parser(patternKey.getOffset());
- ResolvedTargets<Target> resolvedTargets = null;
+ ResolvedTargets<Target> resolvedTargets;
try {
EnvironmentBackedRecursivePackageProvider provider =
new EnvironmentBackedRecursivePackageProvider(env);
RecursivePackageProviderBackedTargetPatternResolver resolver =
new RecursivePackageProviderBackedTargetPatternResolver(provider, env.getListener(),
patternKey.getPolicy(), pkgPath.get());
- TargetPattern resolvedPattern = parser.parse(patternKey.getPattern());
- resolvedTargets = resolvedPattern.eval(resolver);
+ TargetPattern parsedPattern = patternKey.getParsedPattern();
+ ImmutableSet<String> excludedSubdirectories = patternKey.getExcludedSubdirectories();
+ resolvedTargets = parsedPattern.eval(resolver, excludedSubdirectories);
} catch (TargetParsingException e) {
throw new TargetPatternFunctionException(e);
} catch (MissingDepException e) {
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/TargetPatternValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/TargetPatternValue.java
index 1463140d3c..1f665e0152 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/TargetPatternValue.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/TargetPatternValue.java
@@ -14,9 +14,13 @@
package com.google.devtools.build.lib.skyframe;
import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.cmdline.ResolvedTargets;
import com.google.devtools.build.lib.cmdline.ResolvedTargets.Builder;
+import com.google.devtools.build.lib.cmdline.TargetParsingException;
+import com.google.devtools.build.lib.cmdline.TargetPattern;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe;
import com.google.devtools.build.lib.pkgcache.FilteringPolicies;
@@ -31,7 +35,6 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.List;
import java.util.Objects;
@@ -93,42 +96,54 @@ public final class TargetPatternValue implements SkyValue {
}
/**
- * Create a target pattern value key.
+ * Create a target pattern {@link SkyKey}. Throws {@link TargetParsingException} if the provided
+ * {@code pattern} cannot be parsed.
*
- * @param pattern The pattern, eg "-foo/biz...". If the first character is "-", the pattern
- * is treated as a negative pattern.
+ * @param pattern The pattern, eg "-foo/biz...". If the first character is "-", the pattern is
+ * treated as a negative pattern.
* @param policy The filtering policy, eg "only return test targets"
* @param offset The offset to apply to relative target patterns.
*/
@ThreadSafe
- public static SkyKey key(String pattern,
- FilteringPolicy policy,
- String offset) {
- return new SkyKey(SkyFunctions.TARGET_PATTERN,
- pattern.startsWith("-")
- // Don't apply filters to negative patterns.
- ? new TargetPatternKey(pattern.substring(1), FilteringPolicies.NO_FILTER, true, offset)
- : new TargetPatternKey(pattern, policy, false, offset));
+ public static SkyKey key(String pattern, FilteringPolicy policy, String offset)
+ throws TargetParsingException {
+ return Iterables.getOnlyElement(keys(ImmutableList.of(pattern), policy, offset)).getSkyKey();
}
/**
- * Like above, but accepts a collection of target patterns for the same filtering policy.
+ * Returns an iterable of {@link TargetPatternSkyKeyOrException}, with {@link TargetPatternKey}
+ * arguments, in the same order as the list of patterns provided as input. If a provided pattern
+ * fails to parse, the element in the returned iterable corresponding to it will throw when its
+ * {@link TargetPatternSkyKeyOrException#getSkyKey} method is called.
*
- * @param patterns The collection of patterns, eg "-foo/biz...". If the first character is "-",
- * the pattern is treated as a negative pattern.
+ * @param patterns The list of patterns, eg "-foo/biz...". If a pattern's first character is "-",
+ * it is treated as a negative pattern.
* @param policy The filtering policy, eg "only return test targets"
* @param offset The offset to apply to relative target patterns.
*/
@ThreadSafe
- public static Iterable<SkyKey> keys(Collection<String> patterns,
- FilteringPolicy policy,
- String offset) {
- List<SkyKey> keys = Lists.newArrayListWithCapacity(patterns.size());
+ public static Iterable<TargetPatternSkyKeyOrException> keys(List<String> patterns,
+ FilteringPolicy policy, String offset) {
+ TargetPattern.Parser parser = new TargetPattern.Parser(offset);
+ ImmutableList.Builder<TargetPatternSkyKeyOrException> builder = ImmutableList.builder();
for (String pattern : patterns) {
- keys.add(key(pattern, policy, offset));
+ boolean positive = !pattern.startsWith("-");
+ String absoluteValueOfPattern = positive ? pattern : pattern.substring(1);
+ TargetPattern targetPattern;
+ try {
+ targetPattern = parser.parse(absoluteValueOfPattern);
+ } catch (TargetParsingException e) {
+ builder.add(new TargetPatternSkyKeyException(e, absoluteValueOfPattern));
+ continue;
+ }
+ TargetPatternKey targetPatternKey = new TargetPatternKey(targetPattern,
+ positive ? policy : FilteringPolicies.NO_FILTER, /*isNegative=*/!positive, offset,
+ ImmutableSet.<String>of());
+ SkyKey skyKey = new SkyKey(SkyFunctions.TARGET_PATTERN, targetPatternKey);
+ builder.add(new TargetPatternSkyKeyValue(skyKey));
}
- return keys;
- }
+ return builder.build();
+ }
public ResolvedTargets<Label> getTargets() {
return targets;
@@ -136,26 +151,33 @@ public final class TargetPatternValue implements SkyValue {
/**
* A TargetPatternKey is a tuple of pattern (eg, "foo/..."), filtering policy, a relative pattern
- * offset, and whether it is a positive or negative match.
+ * offset, whether it is a positive or negative match, and a set of excluded subdirectories.
*/
@ThreadSafe
public static class TargetPatternKey implements Serializable {
- private final String pattern;
+
+ private final TargetPattern parsedPattern;
private final FilteringPolicy policy;
private final boolean isNegative;
private final String offset;
+ private final ImmutableSet<String> excludedSubdirectories;
- public TargetPatternKey(String pattern, FilteringPolicy policy,
- boolean isNegative, String offset) {
- this.pattern = Preconditions.checkNotNull(pattern);
+ public TargetPatternKey(TargetPattern parsedPattern, FilteringPolicy policy,
+ boolean isNegative, String offset, ImmutableSet<String> excludedSubdirectories) {
+ this.parsedPattern = Preconditions.checkNotNull(parsedPattern);
this.policy = Preconditions.checkNotNull(policy);
this.isNegative = isNegative;
this.offset = offset;
+ this.excludedSubdirectories = Preconditions.checkNotNull(excludedSubdirectories);
}
public String getPattern() {
- return pattern;
+ return parsedPattern.getOriginalPattern();
+ }
+
+ public TargetPattern getParsedPattern() {
+ return parsedPattern;
}
public boolean isNegative() {
@@ -170,14 +192,19 @@ public final class TargetPatternValue implements SkyValue {
return offset;
}
+ public ImmutableSet<String> getExcludedSubdirectories() {
+ return excludedSubdirectories;
+ }
+
@Override
public String toString() {
- return (isNegative ? "-" : "") + pattern;
+ return (isNegative ? "-" : "") + parsedPattern.getOriginalPattern();
}
@Override
public int hashCode() {
- return Objects.hash(pattern, isNegative, policy, offset);
+ return Objects.hash(parsedPattern, isNegative, policy, offset,
+ excludedSubdirectories);
}
@Override
@@ -187,8 +214,69 @@ public final class TargetPatternValue implements SkyValue {
}
TargetPatternKey other = (TargetPatternKey) obj;
- return other.isNegative == this.isNegative && other.pattern.equals(this.pattern) &&
- other.offset.equals(this.offset) && other.policy.equals(this.policy);
+ return other.isNegative == this.isNegative && other.parsedPattern.equals(this.parsedPattern)
+ && other.offset.equals(this.offset) && other.policy.equals(this.policy)
+ && other.excludedSubdirectories.equals(this.excludedSubdirectories);
+ }
+ }
+
+ /**
+ * Wrapper for a target pattern {@link SkyKey} or the {@link TargetParsingException} thrown when
+ * trying to compute it.
+ */
+ public interface TargetPatternSkyKeyOrException {
+
+ /**
+ * Returns the stored {@link SkyKey} or throws {@link TargetParsingException} if one was thrown
+ * when computing the key.
+ */
+ SkyKey getSkyKey() throws TargetParsingException;
+
+ /**
+ * Returns the pattern that resulted in the stored {@link SkyKey} or {@link
+ * TargetParsingException}.
+ */
+ String getOriginalPattern();
+ }
+
+ private static final class TargetPatternSkyKeyValue implements TargetPatternSkyKeyOrException {
+
+ private final SkyKey value;
+
+ private TargetPatternSkyKeyValue(SkyKey value) {
+ this.value = value;
+ }
+
+ @Override
+ public SkyKey getSkyKey() throws TargetParsingException {
+ return value;
+ }
+
+ @Override
+ public String getOriginalPattern() {
+ return ((TargetPatternKey) value.argument()).getPattern();
+ }
+ }
+
+ private static final class TargetPatternSkyKeyException implements
+ TargetPatternSkyKeyOrException {
+
+ private final TargetParsingException exception;
+ private final String originalPattern;
+
+ private TargetPatternSkyKeyException(TargetParsingException exception, String originalPattern) {
+ this.exception = exception;
+ this.originalPattern = originalPattern;
+ }
+
+ @Override
+ public SkyKey getSkyKey() throws TargetParsingException {
+ throw exception;
+ }
+
+ @Override
+ public String getOriginalPattern() {
+ return originalPattern;
}
}
}