From 4958192c09874104cc06f264f6354d1e2e97b64b Mon Sep 17 00:00:00 2001 From: mjhalupka Date: Wed, 28 Feb 2018 11:04:31 -0800 Subject: Tag RuleClassNamePredicate with @AutoCodec by switching to lazy initialization of the Predicates, and storing the set of strings the predicates are based on. PiperOrigin-RevId: 187351700 --- .../devtools/build/lib/packages/RuleClass.java | 83 +++++++++++++++------- 1 file changed, 57 insertions(+), 26 deletions(-) (limited to 'src/main') diff --git a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java index 2d0cd749d1..51db54310a 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java +++ b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java @@ -42,6 +42,8 @@ import com.google.devtools.build.lib.packages.Attribute.SkylarkComputedDefaultTe import com.google.devtools.build.lib.packages.BuildType.SelectorList; import com.google.devtools.build.lib.packages.ConfigurationFragmentPolicy.MissingFragmentPolicy; import com.google.devtools.build.lib.packages.RuleFactory.AttributeValues; +import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; +import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization; import com.google.devtools.build.lib.syntax.Argument; import com.google.devtools.build.lib.syntax.BaseFunction; import com.google.devtools.build.lib.syntax.Environment; @@ -65,6 +67,7 @@ import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.regex.Pattern; import javax.annotation.Nullable; @@ -381,38 +384,69 @@ public class RuleClass { } /** A predicate that filters rule classes based on their names. */ + @AutoCodec public static class RuleClassNamePredicate { + private static final RuleClassNamePredicate UNSPECIFIED_INSTANCE = + new RuleClassNamePredicate(ImmutableSet.of(), PredicateType.UNSPECIFIED, null); + + private final ImmutableSet ruleClassNames; + + private final PredicateType predicateType; + private final Predicate ruleClassNamePredicate; private final Predicate ruleClassPredicate; // if non-null, used ONLY for checking overlap @Nullable private final Set overlappable; - private RuleClassNamePredicate( - Predicate ruleClassNamePredicate, @Nullable Set overlappable) { - this( - ruleClassNamePredicate, - new DescribedPredicate<>( - Predicates.compose(ruleClassNamePredicate, RuleClass::getName), - ruleClassNamePredicate.toString()), - overlappable); + @VisibleForSerialization + enum PredicateType { + ONLY, + All_EXCEPT, + UNSPECIFIED } - private RuleClassNamePredicate( - Predicate ruleClassNamePredicate, - Predicate ruleClassPredicate, - @Nullable Set overlappable) { - this.ruleClassNamePredicate = ruleClassNamePredicate; - this.ruleClassPredicate = ruleClassPredicate; + @VisibleForSerialization + RuleClassNamePredicate( + ImmutableSet ruleClassNames, PredicateType predicateType, Set overlappable) { + this.ruleClassNames = ruleClassNames; + this.predicateType = predicateType; this.overlappable = overlappable; + + switch (predicateType) { + case All_EXCEPT: + Predicate containing = only(ruleClassNames).asPredicateOfRuleClassName(); + ruleClassNamePredicate = + new DescribedPredicate<>( + Predicates.not(containing), "all but " + containing.toString()); + ruleClassPredicate = + new DescribedPredicate<>( + Predicates.compose(ruleClassNamePredicate, RuleClass::getName), + ruleClassNamePredicate.toString()); + break; + case ONLY: + ruleClassNamePredicate = + new DescribedPredicate<>( + Predicates.in(ruleClassNames), StringUtil.joinEnglishList(ruleClassNames)); + ruleClassPredicate = + new DescribedPredicate<>( + Predicates.compose(ruleClassNamePredicate, RuleClass::getName), + ruleClassNamePredicate.toString()); + break; + case UNSPECIFIED: + ruleClassNamePredicate = Predicates.alwaysTrue(); + ruleClassPredicate = Predicates.alwaysTrue(); + break; + default: + // This shouldn't happen normally since the constructor is private and within this file. + throw new IllegalArgumentException( + "Predicate type was not specified when constructing a RuleClassNamePredicate."); + } } public static RuleClassNamePredicate only(Iterable ruleClassNamesAsIterable) { ImmutableSet ruleClassNames = ImmutableSet.copyOf(ruleClassNamesAsIterable); - return new RuleClassNamePredicate( - new DescribedPredicate<>( - Predicates.in(ruleClassNames), StringUtil.joinEnglishList(ruleClassNames)), - ruleClassNames); + return new RuleClassNamePredicate(ruleClassNames, PredicateType.ONLY, ruleClassNames); } public static RuleClassNamePredicate only(String... ruleClasses) { @@ -422,11 +456,7 @@ public class RuleClass { public static RuleClassNamePredicate allExcept(String... ruleClasses) { ImmutableSet ruleClassNames = ImmutableSet.copyOf(ruleClasses); Preconditions.checkState(!ruleClassNames.isEmpty(), "Use unspecified() instead"); - Predicate containing = only(ruleClassNames).asPredicateOfRuleClassName(); - return new RuleClassNamePredicate( - new DescribedPredicate<>( - Predicates.not(containing), "all but " + containing.toString()), - null); + return new RuleClassNamePredicate(ruleClassNames, PredicateType.All_EXCEPT, null); } /** @@ -436,7 +466,7 @@ public class RuleClass { * Predicates.alwaysTrue()}, which is a sentinel value for other parts of bazel. */ public static RuleClassNamePredicate unspecified() { - return new RuleClassNamePredicate(Predicates.alwaysTrue(), Predicates.alwaysTrue(), null); + return UNSPECIFIED_INSTANCE; } public final Predicate asPredicateOfRuleClassName() { @@ -463,7 +493,7 @@ public class RuleClass { @Override public int hashCode() { - return ruleClassNamePredicate.hashCode(); + return Objects.hash(ruleClassNames, predicateType); } @Override @@ -471,7 +501,8 @@ public class RuleClass { // NOTE: Specifically not checking equality of ruleClassPredicate. // By construction, if the name predicates are equals, the rule class predicates are, too. return obj instanceof RuleClassNamePredicate - && ruleClassNamePredicate.equals(((RuleClassNamePredicate) obj).ruleClassNamePredicate); + && ruleClassNames.equals(((RuleClassNamePredicate) obj).ruleClassNames) + && predicateType.equals(((RuleClassNamePredicate) obj).predicateType); } @Override -- cgit v1.2.3