| // Copyright 2014 The Bazel Authors. All rights reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| package com.google.devtools.build.lib.pkgcache; |
| |
| import com.google.auto.value.AutoValue; |
| import com.google.common.base.Preconditions; |
| import com.google.devtools.build.lib.packages.Rule; |
| import com.google.devtools.build.lib.packages.Target; |
| import com.google.devtools.build.lib.packages.TargetUtils; |
| import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; |
| import java.util.Objects; |
| |
| /** |
| * Utility class for predefined filtering policies. |
| */ |
| public final class FilteringPolicies { |
| public static final FilteringPolicy NO_FILTER = new NoFilter(); |
| public static final FilteringPolicy FILTER_MANUAL = new FilterManual(); |
| public static final FilteringPolicy FILTER_TESTS = new FilterTests(); |
| public static final FilteringPolicy RULES_ONLY = new RulesOnly(); |
| |
| /** Returns the result of applying y, if target passes x. */ |
| public static FilteringPolicy and(final FilteringPolicy x, final FilteringPolicy y) { |
| if (x.equals(NO_FILTER)) { |
| return y; |
| } |
| if (y.equals(NO_FILTER)) { |
| return x; |
| } |
| return new AndFilteringPolicy(x, y); |
| } |
| |
| public static FilteringPolicy ruleType(String ruleName, boolean keepExplicit) { |
| return RuleTypeFilter.create(ruleName, keepExplicit); |
| } |
| |
| private FilteringPolicies() { |
| } |
| |
| /** Base class for singleton filtering policies. */ |
| private abstract static class AbstractFilteringPolicy extends FilteringPolicy { |
| private final int hashCode = getClass().getSimpleName().hashCode(); |
| |
| @Override |
| public int hashCode() { |
| return hashCode; |
| } |
| |
| @Override |
| public boolean equals(Object obj) { |
| if (obj == null) { |
| return false; |
| } |
| if (obj == this) { |
| return true; |
| } |
| return getClass().equals(obj.getClass()); |
| } |
| } |
| |
| private static class NoFilter extends AbstractFilteringPolicy { |
| @Override |
| public boolean shouldRetain(Target target, boolean explicit) { |
| return true; |
| } |
| |
| @Override |
| public String toString() { |
| return "[]"; |
| } |
| } |
| |
| private static class FilterManual extends AbstractFilteringPolicy { |
| @Override |
| public boolean shouldRetain(Target target, boolean explicit) { |
| return explicit || !(TargetUtils.hasManualTag(target)); |
| } |
| } |
| |
| private static class FilterTests extends AbstractFilteringPolicy { |
| @Override |
| public boolean shouldRetain(Target target, boolean explicit) { |
| return TargetUtils.isTestOrTestSuiteRule(target) |
| && FILTER_MANUAL.shouldRetain(target, explicit); |
| } |
| } |
| |
| private static class RulesOnly extends AbstractFilteringPolicy { |
| @Override |
| public boolean shouldRetain(Target target, boolean explicit) { |
| return target instanceof Rule; |
| } |
| } |
| |
| /** FilteringPolicy that only matches a specific rule name. */ |
| @AutoValue |
| @AutoCodec |
| abstract static class RuleTypeFilter extends FilteringPolicy { |
| abstract String ruleName(); |
| |
| abstract boolean keepExplicit(); |
| |
| @Override |
| public boolean shouldRetain(Target target, boolean explicit) { |
| if (explicit && keepExplicit()) { |
| return true; |
| } |
| |
| if (target.getAssociatedRule().getRuleClass().equals(ruleName())) { |
| return true; |
| } |
| |
| return false; |
| } |
| |
| @AutoCodec.Instantiator |
| static RuleTypeFilter create(String ruleName, boolean keepExplicit) { |
| return new AutoValue_FilteringPolicies_RuleTypeFilter(ruleName, keepExplicit); |
| } |
| } |
| |
| /** FilteringPolicy for combining FilteringPolicies. */ |
| public static class AndFilteringPolicy extends FilteringPolicy { |
| private final FilteringPolicy firstPolicy; |
| private final FilteringPolicy secondPolicy; |
| |
| private AndFilteringPolicy(FilteringPolicy firstPolicy, FilteringPolicy secondPolicy) { |
| this.firstPolicy = Preconditions.checkNotNull(firstPolicy); |
| this.secondPolicy = Preconditions.checkNotNull(secondPolicy); |
| } |
| |
| @Override |
| public boolean shouldRetain(Target target, boolean explicit) { |
| return firstPolicy.shouldRetain(target, explicit) |
| && secondPolicy.shouldRetain(target, explicit); |
| } |
| |
| public FilteringPolicy getFirstPolicy() { |
| return firstPolicy; |
| } |
| |
| public FilteringPolicy getSecondPolicy() { |
| return secondPolicy; |
| } |
| |
| @Override |
| public int hashCode() { |
| return Objects.hash(firstPolicy, secondPolicy); |
| } |
| |
| @Override |
| public boolean equals(Object obj) { |
| if (!(obj instanceof AndFilteringPolicy)) { |
| return false; |
| } |
| AndFilteringPolicy other = (AndFilteringPolicy) obj; |
| return other.firstPolicy.equals(firstPolicy) && other.secondPolicy.equals(secondPolicy); |
| } |
| |
| @Override |
| public String toString() { |
| return String.format("and_filter(%s, %s)", firstPolicy, secondPolicy); |
| } |
| } |
| } |