/* * Copyright 2012-present Facebook, Inc. * * 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.facebook.buck.rules; import com.facebook.buck.io.ProjectFilesystem; import com.facebook.buck.model.BuildTarget; import com.facebook.buck.model.Flavor; import com.google.common.base.Supplier; import com.google.common.base.Suppliers; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSortedSet; import com.google.common.collect.Sets; import java.util.Set; /** Standard set of parameters that is passed to all build rules. */ public class BuildRuleParams { private final BuildTarget buildTarget; private final Supplier<ImmutableSortedSet<BuildRule>> declaredDeps; private final Supplier<ImmutableSortedSet<BuildRule>> extraDeps; private final Supplier<ImmutableSortedSet<BuildRule>> totalBuildDeps; private final ImmutableSortedSet<BuildRule> targetGraphOnlyDeps; private final ProjectFilesystem projectFilesystem; public BuildRuleParams( BuildTarget buildTarget, final Supplier<ImmutableSortedSet<BuildRule>> declaredDeps, final Supplier<ImmutableSortedSet<BuildRule>> extraDeps, ImmutableSortedSet<BuildRule> targetGraphOnlyDeps, ProjectFilesystem projectFilesystem) { this.buildTarget = buildTarget; this.declaredDeps = Suppliers.memoize(declaredDeps); this.extraDeps = Suppliers.memoize(extraDeps); this.projectFilesystem = projectFilesystem; this.targetGraphOnlyDeps = targetGraphOnlyDeps; this.totalBuildDeps = Suppliers.memoize( () -> ImmutableSortedSet.<BuildRule>naturalOrder() .addAll(declaredDeps.get()) .addAll(extraDeps.get()) .build()); } private BuildRuleParams( BuildRuleParams baseForDeps, BuildTarget buildTarget, ProjectFilesystem projectFilesystem) { this.buildTarget = buildTarget; this.projectFilesystem = projectFilesystem; this.declaredDeps = baseForDeps.declaredDeps; this.extraDeps = baseForDeps.extraDeps; this.targetGraphOnlyDeps = baseForDeps.targetGraphOnlyDeps; this.totalBuildDeps = baseForDeps.totalBuildDeps; } public BuildRuleParams copyReplacingExtraDeps(Supplier<ImmutableSortedSet<BuildRule>> extraDeps) { return copyReplacingDeclaredAndExtraDeps(declaredDeps, extraDeps); } public BuildRuleParams copyAppendingExtraDeps( final Supplier<? extends Iterable<? extends BuildRule>> additional) { return copyReplacingDeclaredAndExtraDeps( declaredDeps, () -> ImmutableSortedSet.<BuildRule>naturalOrder() .addAll(extraDeps.get()) .addAll(additional.get()) .build()); } /** * @return a copy of these {@link BuildRuleParams} with the deps removed to prevent using them to * as the deps in constructed {@link BuildRule}s. */ public BuildRuleParams copyInvalidatingDeps() { Supplier<ImmutableSortedSet<BuildRule>> throwingDeps = () -> { throw new IllegalStateException( String.format( "%s: Access to target-node level `BuildRuleParam` deps. " + "Please compose application-specific deps from the constructor arg instead.", getBuildTarget())); }; return copyReplacingDeclaredAndExtraDeps(throwingDeps, throwingDeps); } public BuildRuleParams copyAppendingExtraDeps(Iterable<? extends BuildRule> additional) { return copyAppendingExtraDeps(Suppliers.ofInstance(additional)); } public BuildRuleParams copyAppendingExtraDeps(BuildRule... additional) { return copyAppendingExtraDeps(Suppliers.ofInstance(ImmutableList.copyOf(additional))); } public BuildRuleParams copyReplacingDeclaredAndExtraDeps( Supplier<ImmutableSortedSet<BuildRule>> declaredDeps, Supplier<ImmutableSortedSet<BuildRule>> extraDeps) { return new BuildRuleParams( buildTarget, declaredDeps, extraDeps, targetGraphOnlyDeps, projectFilesystem); } public BuildRuleParams withBuildTarget(BuildTarget target) { return new BuildRuleParams(this, target, projectFilesystem); } public BuildRuleParams withoutFlavor(Flavor flavor) { Set<Flavor> flavors = Sets.newHashSet(getBuildTarget().getFlavors()); flavors.remove(flavor); BuildTarget target = BuildTarget.builder(getBuildTarget().getUnflavoredBuildTarget()) .addAllFlavors(flavors) .build(); return new BuildRuleParams(this, target, projectFilesystem); } public BuildRuleParams withAppendedFlavor(Flavor flavor) { Set<Flavor> flavors = Sets.newHashSet(getBuildTarget().getFlavors()); flavors.add(flavor); BuildTarget target = BuildTarget.builder(getBuildTarget().getUnflavoredBuildTarget()) .addAllFlavors(flavors) .build(); return new BuildRuleParams(this, target, projectFilesystem); } public BuildTarget getBuildTarget() { return buildTarget; } /** @return all BuildRules which must be built before this one can be. */ public ImmutableSortedSet<BuildRule> getBuildDeps() { return totalBuildDeps.get(); } public Supplier<ImmutableSortedSet<BuildRule>> getTotalBuildDeps() { return totalBuildDeps; } public Supplier<ImmutableSortedSet<BuildRule>> getDeclaredDeps() { return declaredDeps; } public Supplier<ImmutableSortedSet<BuildRule>> getExtraDeps() { return extraDeps; } /** See {@link TargetNode#getTargetGraphOnlyDeps}. */ public ImmutableSortedSet<BuildRule> getTargetGraphOnlyDeps() { return targetGraphOnlyDeps; } public ProjectFilesystem getProjectFilesystem() { return projectFilesystem; } }