Damien Martin-Guillerez | f88f4d8 | 2015-09-25 13:56:55 +0000 | [diff] [blame] | 1 | // Copyright 2014 The Bazel Authors. All rights reserved. |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 2 | // |
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | // you may not use this file except in compliance with the License. |
| 5 | // You may obtain a copy of the License at |
| 6 | // |
| 7 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | // |
| 9 | // Unless required by applicable law or agreed to in writing, software |
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | // See the License for the specific language governing permissions and |
| 13 | // limitations under the License. |
| 14 | package com.google.devtools.build.lib.analysis; |
| 15 | |
Googler | 5850503 | 2015-03-19 16:12:34 +0000 | [diff] [blame] | 16 | import static com.google.common.base.Preconditions.checkArgument; |
| 17 | import static com.google.common.base.Preconditions.checkNotNull; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 18 | import static com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType.ABSTRACT; |
| 19 | import static com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType.TEST; |
| 20 | |
mstaib | 4a07a47 | 2018-04-19 14:16:41 -0700 | [diff] [blame] | 21 | import com.google.common.annotations.VisibleForTesting; |
Ulf Adams | 345e15e | 2016-07-07 13:27:28 +0000 | [diff] [blame] | 22 | import com.google.common.base.Preconditions; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 23 | import com.google.common.collect.ImmutableList; |
| 24 | import com.google.common.collect.ImmutableMap; |
lberki | 406199f | 2018-04-09 03:16:19 -0700 | [diff] [blame] | 25 | import com.google.common.collect.ImmutableSet; |
janakr | 9fcef03 | 2018-01-23 13:38:24 -0800 | [diff] [blame] | 26 | import com.google.common.collect.ImmutableSortedSet; |
lberki | 8626623 | 2018-04-11 00:33:42 -0700 | [diff] [blame] | 27 | import com.google.devtools.build.lib.actions.ActionEnvironment; |
jcater | 0de1097 | 2020-04-07 12:15:05 -0700 | [diff] [blame] | 28 | import com.google.devtools.build.lib.analysis.RuleContext.PrerequisiteValidator; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 29 | import com.google.devtools.build.lib.analysis.buildinfo.BuildInfoFactory; |
jcater | 1865d89 | 2020-04-14 10:04:29 -0700 | [diff] [blame] | 30 | import com.google.devtools.build.lib.analysis.buildinfo.BuildInfoKey; |
Greg Estren | c5a352f | 2015-11-13 17:25:36 +0000 | [diff] [blame] | 31 | import com.google.devtools.build.lib.analysis.config.BuildConfiguration; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 32 | import com.google.devtools.build.lib.analysis.config.BuildOptions; |
brandjon | 8a60360 | 2019-12-04 10:40:38 -0800 | [diff] [blame] | 33 | import com.google.devtools.build.lib.analysis.config.ConvenienceSymlinks.SymlinkDefinition; |
jcater | a666f00 | 2020-04-14 14:55:20 -0700 | [diff] [blame] | 34 | import com.google.devtools.build.lib.analysis.config.Fragment; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 35 | import com.google.devtools.build.lib.analysis.config.FragmentOptions; |
jcater | fad3cda | 2020-04-15 10:48:19 -0700 | [diff] [blame] | 36 | import com.google.devtools.build.lib.analysis.config.FragmentProvider; |
John Cater | b3b3e8b | 2019-04-03 09:18:42 -0700 | [diff] [blame] | 37 | import com.google.devtools.build.lib.analysis.config.transitions.ComposingTransitionFactory; |
gregce | 477d965 | 2019-06-05 13:40:21 -0700 | [diff] [blame] | 38 | import com.google.devtools.build.lib.analysis.config.transitions.PatchTransition; |
John Cater | b3b3e8b | 2019-04-03 09:18:42 -0700 | [diff] [blame] | 39 | import com.google.devtools.build.lib.analysis.config.transitions.TransitionFactory; |
gregce | 6acfe4e | 2018-05-25 08:38:39 -0700 | [diff] [blame] | 40 | import com.google.devtools.build.lib.analysis.constraints.ConstraintSemantics; |
jcater | 802551e | 2020-04-15 09:59:58 -0700 | [diff] [blame] | 41 | import com.google.devtools.build.lib.analysis.constraints.RuleContextConstraintSemantics; |
gregce | eefc91c | 2020-06-19 13:33:43 -0700 | [diff] [blame] | 42 | import com.google.devtools.build.lib.analysis.starlark.StarlarkModules; |
Lukacs Berki | 6e91eb9 | 2015-09-21 09:12:37 +0000 | [diff] [blame] | 43 | import com.google.devtools.build.lib.cmdline.Label; |
Lukacs Berki | a643436 | 2015-09-15 13:56:14 +0000 | [diff] [blame] | 44 | import com.google.devtools.build.lib.cmdline.LabelSyntaxException; |
dannark | d102a39 | 2019-01-09 13:12:01 -0800 | [diff] [blame] | 45 | import com.google.devtools.build.lib.cmdline.RepositoryName; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 46 | import com.google.devtools.build.lib.graph.Digraph; |
| 47 | import com.google.devtools.build.lib.graph.Node; |
Googler | 995ef63 | 2019-09-04 12:25:41 -0700 | [diff] [blame] | 48 | import com.google.devtools.build.lib.packages.BazelStarlarkContext; |
Luis Fernando Pino Duque | e82713d | 2016-04-26 16:22:38 +0000 | [diff] [blame] | 49 | import com.google.devtools.build.lib.packages.NativeAspectClass; |
Michael Staib | 8618b9d | 2016-09-16 19:36:49 +0000 | [diff] [blame] | 50 | import com.google.devtools.build.lib.packages.Rule; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 51 | import com.google.devtools.build.lib.packages.RuleClass; |
gregce | 4aa059a | 2019-02-26 13:20:47 -0800 | [diff] [blame] | 52 | import com.google.devtools.build.lib.packages.RuleClass.Builder.ThirdPartyLicenseExistencePolicy; |
Googler | 995ef63 | 2019-09-04 12:25:41 -0700 | [diff] [blame] | 53 | import com.google.devtools.build.lib.packages.SymbolGenerator; |
gregce | cf3a923 | 2020-07-20 15:17:52 -0700 | [diff] [blame] | 54 | import com.google.devtools.build.lib.starlarkbuildapi.core.Bootstrap; |
mstaib | 2d7c0ff | 2019-02-28 08:28:11 -0800 | [diff] [blame] | 55 | import com.google.devtools.common.options.Option; |
mstaib | 6cf6278 | 2018-11-14 11:54:33 -0800 | [diff] [blame] | 56 | import com.google.devtools.common.options.OptionDefinition; |
juliexxia | 618a076 | 2018-08-17 08:33:52 -0700 | [diff] [blame] | 57 | import com.google.devtools.common.options.OptionsProvider; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 58 | import java.lang.reflect.Constructor; |
mstaib | 2d7c0ff | 2019-02-28 08:28:11 -0800 | [diff] [blame] | 59 | import java.lang.reflect.Field; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 60 | import java.lang.reflect.InvocationTargetException; |
| 61 | import java.util.ArrayList; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 62 | import java.util.HashMap; |
mstaib | 2d7c0ff | 2019-02-28 08:28:11 -0800 | [diff] [blame] | 63 | import java.util.LinkedHashMap; |
gregce | d6aa04d | 2019-01-02 12:42:28 -0800 | [diff] [blame] | 64 | import java.util.LinkedHashSet; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 65 | import java.util.List; |
| 66 | import java.util.Map; |
lberki | 406199f | 2018-04-09 03:16:19 -0700 | [diff] [blame] | 67 | import java.util.Set; |
| 68 | import java.util.TreeSet; |
mstaib | 4a07a47 | 2018-04-19 14:16:41 -0700 | [diff] [blame] | 69 | import javax.annotation.Nullable; |
adonovan | b63c0f2 | 2020-10-14 13:01:18 -0700 | [diff] [blame] | 70 | import net.starlark.java.annot.StarlarkAnnotations; |
adonovan | b017468 | 2020-05-18 16:01:53 -0700 | [diff] [blame] | 71 | import net.starlark.java.annot.StarlarkBuiltin; |
adonovan | 450c7ad | 2020-09-14 13:00:21 -0700 | [diff] [blame] | 72 | import net.starlark.java.eval.StarlarkThread; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 73 | |
| 74 | /** |
| 75 | * Knows about every rule Blaze supports and the associated configuration options. |
| 76 | * |
Googler | bffb687 | 2019-10-22 11:14:46 -0700 | [diff] [blame] | 77 | * <p>This class is initialized on server startup and the set of rules, build info factories and |
| 78 | * configuration options is guaranteed not to change over the life time of the Blaze server. |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 79 | */ |
Googler | bffb687 | 2019-10-22 11:14:46 -0700 | [diff] [blame] | 80 | // This class has no subclasses except those created by the evil that is mockery. |
jcater | fad3cda | 2020-04-15 10:48:19 -0700 | [diff] [blame] | 81 | public /*final*/ class ConfiguredRuleClassProvider implements FragmentProvider { |
Kristina Chodorow | 8612a27 | 2015-12-14 15:37:24 +0000 | [diff] [blame] | 82 | |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 83 | /** |
Ulf Adams | e3b4af2 | 2016-10-18 12:51:15 +0000 | [diff] [blame] | 84 | * A coherent set of options, fragments, aspects and rules; each of these may declare a dependency |
| 85 | * on other such sets. |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 86 | */ |
brandjon | 32d359f | 2018-01-22 10:50:45 -0800 | [diff] [blame] | 87 | public interface RuleSet { |
Ulf Adams | e3b4af2 | 2016-10-18 12:51:15 +0000 | [diff] [blame] | 88 | /** Add stuff to the configured rule class provider builder. */ |
| 89 | void init(ConfiguredRuleClassProvider.Builder builder); |
| 90 | |
| 91 | /** List of required modules. */ |
| 92 | ImmutableList<RuleSet> requires(); |
| 93 | } |
| 94 | |
| 95 | /** Builder for {@link ConfiguredRuleClassProvider}. */ |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 96 | public static class Builder implements RuleDefinitionEnvironment { |
Damien Martin-Guillerez | 585c87b | 2016-03-31 08:24:37 +0000 | [diff] [blame] | 97 | private final StringBuilder defaultWorkspaceFilePrefix = new StringBuilder(); |
| 98 | private final StringBuilder defaultWorkspaceFileSuffix = new StringBuilder(); |
John Field | a97e17f | 2015-11-13 02:19:52 +0000 | [diff] [blame] | 99 | private Label preludeLabel; |
Ulf Adams | d13207c | 2015-09-04 14:53:43 +0000 | [diff] [blame] | 100 | private String runfilesPrefix; |
Luis Fernando Pino Duque | 90511e1 | 2016-01-28 10:49:58 +0000 | [diff] [blame] | 101 | private String toolsRepository; |
brandjon | 39ca727 | 2020-12-03 14:40:09 -0800 | [diff] [blame] | 102 | private String builtinsPackagePathInSource; |
gregce | 4ed65b0 | 2020-11-18 07:06:25 -0800 | [diff] [blame] | 103 | private final List<Class<? extends Fragment>> configurationFragmentClasses = new ArrayList<>(); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 104 | private final List<BuildInfoFactory> buildInfoFactories = new ArrayList<>(); |
gregce | d6aa04d | 2019-01-02 12:42:28 -0800 | [diff] [blame] | 105 | private final Set<Class<? extends FragmentOptions>> configurationOptions = |
| 106 | new LinkedHashSet<>(); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 107 | |
| 108 | private final Map<String, RuleClass> ruleClassMap = new HashMap<>(); |
Luis Fernando Pino Duque | 2b0b5cc | 2016-04-26 09:31:27 +0000 | [diff] [blame] | 109 | private final Map<String, RuleDefinition> ruleDefinitionMap = new HashMap<>(); |
Luis Fernando Pino Duque | e82713d | 2016-04-26 16:22:38 +0000 | [diff] [blame] | 110 | private final Map<String, NativeAspectClass> nativeAspectClassMap = |
Dmitry Lomov | e2033b1 | 2015-08-19 16:57:49 +0000 | [diff] [blame] | 111 | new HashMap<>(); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 112 | private final Map<Class<? extends RuleDefinition>, RuleClass> ruleMap = new HashMap<>(); |
| 113 | private final Digraph<Class<? extends RuleDefinition>> dependencyGraph = |
| 114 | new Digraph<>(); |
brandjon | 79712cb | 2019-12-04 10:01:17 -0800 | [diff] [blame] | 115 | private final List<Class<? extends Fragment>> universalFragments = new ArrayList<>(); |
gregce | 477d965 | 2019-06-05 13:40:21 -0700 | [diff] [blame] | 116 | @Nullable private TransitionFactory<Rule> trimmingTransitionFactory = null; |
| 117 | @Nullable private PatchTransition toolchainTaggedTrimmingTransition = null; |
mstaib | 6cf6278 | 2018-11-14 11:54:33 -0800 | [diff] [blame] | 118 | private OptionsDiffPredicate shouldInvalidateCacheForOptionDiff = |
mstaib | a9b5585 | 2018-06-18 13:37:49 -0700 | [diff] [blame] | 119 | OptionsDiffPredicate.ALWAYS_INVALIDATE; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 120 | private PrerequisiteValidator prerequisiteValidator; |
gregce | 47a99f3 | 2020-05-13 12:35:26 -0700 | [diff] [blame] | 121 | private final ImmutableList.Builder<Bootstrap> starlarkBootstraps = ImmutableList.builder(); |
| 122 | private ImmutableMap.Builder<String, Object> starlarkAccessibleTopLevels = |
Ulf Adams | fd53b61 | 2016-07-06 07:23:59 +0000 | [diff] [blame] | 123 | ImmutableMap.builder(); |
brandjon | 8a60360 | 2019-12-04 10:40:38 -0800 | [diff] [blame] | 124 | private final ImmutableList.Builder<SymlinkDefinition> symlinkDefinitions = |
| 125 | ImmutableList.builder(); |
lberki | 406199f | 2018-04-09 03:16:19 -0700 | [diff] [blame] | 126 | private Set<String> reservedActionMnemonics = new TreeSet<>(); |
lberki | 8626623 | 2018-04-11 00:33:42 -0700 | [diff] [blame] | 127 | private BuildConfiguration.ActionEnvironmentProvider actionEnvironmentProvider = |
| 128 | (BuildOptions options) -> ActionEnvironment.EMPTY; |
jcater | 802551e | 2020-04-15 09:59:58 -0700 | [diff] [blame] | 129 | private ConstraintSemantics<RuleContext> constraintSemantics = |
| 130 | new RuleContextConstraintSemantics(); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 131 | |
gregce | 4aa059a | 2019-02-26 13:20:47 -0800 | [diff] [blame] | 132 | private ThirdPartyLicenseExistencePolicy thirdPartyLicenseExistencePolicy = |
| 133 | ThirdPartyLicenseExistencePolicy.USER_CONTROLLABLE; |
jcater | 0321a15 | 2019-07-08 12:47:19 -0700 | [diff] [blame] | 134 | private boolean enableExecutionTransition = false; |
gregce | 4aa059a | 2019-02-26 13:20:47 -0800 | [diff] [blame] | 135 | |
cpeyser | a7f8a91 | 2017-11-06 23:10:36 +0100 | [diff] [blame] | 136 | public Builder addWorkspaceFilePrefix(String contents) { |
Damien Martin-Guillerez | 585c87b | 2016-03-31 08:24:37 +0000 | [diff] [blame] | 137 | defaultWorkspaceFilePrefix.append(contents); |
cpeyser | a7f8a91 | 2017-11-06 23:10:36 +0100 | [diff] [blame] | 138 | return this; |
Damien Martin-Guillerez | 585c87b | 2016-03-31 08:24:37 +0000 | [diff] [blame] | 139 | } |
| 140 | |
cpeyser | a7f8a91 | 2017-11-06 23:10:36 +0100 | [diff] [blame] | 141 | public Builder addWorkspaceFileSuffix(String contents) { |
Damien Martin-Guillerez | 585c87b | 2016-03-31 08:24:37 +0000 | [diff] [blame] | 142 | defaultWorkspaceFileSuffix.append(contents); |
cpeyser | a7f8a91 | 2017-11-06 23:10:36 +0100 | [diff] [blame] | 143 | return this; |
Kristina Chodorow | bc4b4b1 | 2015-02-11 15:54:50 +0000 | [diff] [blame] | 144 | } |
| 145 | |
Klaus Aehlig | a55714c | 2018-10-23 02:16:02 -0700 | [diff] [blame] | 146 | @VisibleForTesting |
| 147 | public Builder clearWorkspaceFileSuffixForTesting() { |
| 148 | defaultWorkspaceFileSuffix.delete(0, defaultWorkspaceFileSuffix.length()); |
| 149 | return this; |
| 150 | } |
| 151 | |
John Field | a97e17f | 2015-11-13 02:19:52 +0000 | [diff] [blame] | 152 | public Builder setPrelude(String preludeLabelString) { |
| 153 | try { |
dannark | 90e2b4b | 2018-06-27 13:35:04 -0700 | [diff] [blame] | 154 | this.preludeLabel = Label.parseAbsolute(preludeLabelString, ImmutableMap.of()); |
John Field | a97e17f | 2015-11-13 02:19:52 +0000 | [diff] [blame] | 155 | } catch (LabelSyntaxException e) { |
| 156 | String errorMsg = |
| 157 | String.format("Prelude label '%s' is invalid: %s", preludeLabelString, e.getMessage()); |
| 158 | throw new IllegalArgumentException(errorMsg); |
| 159 | } |
Ulf Adams | fdfdd92 | 2015-09-01 08:36:29 +0000 | [diff] [blame] | 160 | return this; |
| 161 | } |
| 162 | |
Ulf Adams | d13207c | 2015-09-04 14:53:43 +0000 | [diff] [blame] | 163 | public Builder setRunfilesPrefix(String runfilesPrefix) { |
| 164 | this.runfilesPrefix = runfilesPrefix; |
| 165 | return this; |
| 166 | } |
Luis Fernando Pino Duque | 18d1322 | 2016-02-08 14:55:28 +0000 | [diff] [blame] | 167 | |
Luis Fernando Pino Duque | 90511e1 | 2016-01-28 10:49:58 +0000 | [diff] [blame] | 168 | public Builder setToolsRepository(String toolsRepository) { |
| 169 | this.toolsRepository = toolsRepository; |
| 170 | return this; |
| 171 | } |
Ulf Adams | d13207c | 2015-09-04 14:53:43 +0000 | [diff] [blame] | 172 | |
brandjon | 39ca727 | 2020-12-03 14:40:09 -0800 | [diff] [blame] | 173 | // This is required if the rule class provider will be used with |
| 174 | // "--experimental_builtins_bzl_path=%workspace%", but can be skipped in unit tests. |
| 175 | public Builder setBuiltinsPackagePathInSource(String path) { |
| 176 | this.builtinsPackagePathInSource = path; |
| 177 | return this; |
| 178 | } |
| 179 | |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 180 | public Builder setPrerequisiteValidator(PrerequisiteValidator prerequisiteValidator) { |
| 181 | this.prerequisiteValidator = prerequisiteValidator; |
| 182 | return this; |
| 183 | } |
| 184 | |
| 185 | public Builder addBuildInfoFactory(BuildInfoFactory factory) { |
| 186 | buildInfoFactories.add(factory); |
| 187 | return this; |
| 188 | } |
| 189 | |
Googler | 5850503 | 2015-03-19 16:12:34 +0000 | [diff] [blame] | 190 | public Builder addRuleDefinition(RuleDefinition ruleDefinition) { |
| 191 | Class<? extends RuleDefinition> ruleDefinitionClass = ruleDefinition.getClass(); |
Luis Fernando Pino Duque | 2b0b5cc | 2016-04-26 09:31:27 +0000 | [diff] [blame] | 192 | ruleDefinitionMap.put(ruleDefinitionClass.getName(), ruleDefinition); |
Googler | 5850503 | 2015-03-19 16:12:34 +0000 | [diff] [blame] | 193 | dependencyGraph.createNode(ruleDefinitionClass); |
| 194 | for (Class<? extends RuleDefinition> ancestor : ruleDefinition.getMetadata().ancestors()) { |
| 195 | dependencyGraph.addEdge(ancestor, ruleDefinitionClass); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 196 | } |
| 197 | |
| 198 | return this; |
| 199 | } |
| 200 | |
Luis Fernando Pino Duque | e82713d | 2016-04-26 16:22:38 +0000 | [diff] [blame] | 201 | public Builder addNativeAspectClass(NativeAspectClass aspectFactoryClass) { |
| 202 | nativeAspectClassMap.put(aspectFactoryClass.getName(), aspectFactoryClass); |
Dmitry Lomov | e2033b1 | 2015-08-19 16:57:49 +0000 | [diff] [blame] | 203 | return this; |
| 204 | } |
| 205 | |
Ulf Adams | bbcfa2f | 2016-10-18 07:24:13 +0000 | [diff] [blame] | 206 | /** |
gregce | 4ed65b0 | 2020-11-18 07:06:25 -0800 | [diff] [blame] | 207 | * Adds a configuration fragment and all build options required by its fragment. |
cparsons | caceacd | 2017-11-04 01:00:59 +0100 | [diff] [blame] | 208 | * |
gregce | ca48e9a | 2020-04-14 08:54:38 -0700 | [diff] [blame] | 209 | * <p>Note that configuration fragments annotated with a Starlark name must have a unique name; |
gregce | d6aa04d | 2019-01-02 12:42:28 -0800 | [diff] [blame] | 210 | * no two different configuration fragments can share the same name. |
cparsons | caceacd | 2017-11-04 01:00:59 +0100 | [diff] [blame] | 211 | */ |
gregce | 4ed65b0 | 2020-11-18 07:06:25 -0800 | [diff] [blame] | 212 | public Builder addConfigurationFragment(Class<? extends Fragment> fragmentClass) { |
| 213 | this.configurationOptions.addAll(Fragment.requiredOptions(fragmentClass)); |
| 214 | configurationFragmentClasses.add(fragmentClass); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 215 | return this; |
| 216 | } |
| 217 | |
gregce | d6aa04d | 2019-01-02 12:42:28 -0800 | [diff] [blame] | 218 | /** |
| 219 | * Adds configuration options that aren't required by configuration fragments. |
| 220 | * |
gregce | 4ed65b0 | 2020-11-18 07:06:25 -0800 | [diff] [blame] | 221 | * <p>If {@link #addConfigurationFragment} adds a fragment that also requires these options, |
| 222 | * this method is redundant. |
gregce | d6aa04d | 2019-01-02 12:42:28 -0800 | [diff] [blame] | 223 | */ |
| 224 | public Builder addConfigurationOptions(Class<? extends FragmentOptions> configurationOptions) { |
| 225 | this.configurationOptions.add(configurationOptions); |
| 226 | return this; |
| 227 | } |
| 228 | |
brandjon | 79712cb | 2019-12-04 10:01:17 -0800 | [diff] [blame] | 229 | public Builder addUniversalConfigurationFragment(Class<? extends Fragment> fragment) { |
lberki | 78651d4 | 2018-04-06 01:52:58 -0700 | [diff] [blame] | 230 | this.universalFragments.add(fragment); |
Greg Estren | c5a352f | 2015-11-13 17:25:36 +0000 | [diff] [blame] | 231 | return this; |
| 232 | } |
| 233 | |
gregce | 47a99f3 | 2020-05-13 12:35:26 -0700 | [diff] [blame] | 234 | public Builder addStarlarkBootstrap(Bootstrap bootstrap) { |
| 235 | this.starlarkBootstraps.add(bootstrap); |
cparsons | fc47454 | 2018-06-01 12:05:28 -0700 | [diff] [blame] | 236 | return this; |
| 237 | } |
| 238 | |
gregce | 47a99f3 | 2020-05-13 12:35:26 -0700 | [diff] [blame] | 239 | public Builder addStarlarkAccessibleTopLevels(String name, Object object) { |
| 240 | this.starlarkAccessibleTopLevels.put(name, object); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 241 | return this; |
| 242 | } |
| 243 | |
brandjon | 8a60360 | 2019-12-04 10:40:38 -0800 | [diff] [blame] | 244 | public Builder addSymlinkDefinition(SymlinkDefinition symlinkDefinition) { |
| 245 | this.symlinkDefinitions.add(symlinkDefinition); |
| 246 | return this; |
| 247 | } |
| 248 | |
lberki | 406199f | 2018-04-09 03:16:19 -0700 | [diff] [blame] | 249 | public Builder addReservedActionMnemonic(String mnemonic) { |
| 250 | this.reservedActionMnemonics.add(mnemonic); |
| 251 | return this; |
| 252 | } |
| 253 | |
lberki | 8626623 | 2018-04-11 00:33:42 -0700 | [diff] [blame] | 254 | public Builder setActionEnvironmentProvider( |
| 255 | BuildConfiguration.ActionEnvironmentProvider actionEnvironmentProvider) { |
| 256 | this.actionEnvironmentProvider = actionEnvironmentProvider; |
| 257 | return this; |
| 258 | } |
| 259 | |
Cal Peyser | f296e87 | 2016-05-03 17:36:54 +0000 | [diff] [blame] | 260 | /** |
gregce | 6acfe4e | 2018-05-25 08:38:39 -0700 | [diff] [blame] | 261 | * Sets the logic that lets rules declare which environments they support and validates rules |
| 262 | * don't depend on rules that aren't compatible with the same environments. Defaults to |
| 263 | * {@ConstraintSemantics}. See {@ConstraintSemantics} for more details. |
| 264 | */ |
jcater | 802551e | 2020-04-15 09:59:58 -0700 | [diff] [blame] | 265 | public Builder setConstraintSemantics(ConstraintSemantics<RuleContext> constraintSemantics) { |
gregce | 6acfe4e | 2018-05-25 08:38:39 -0700 | [diff] [blame] | 266 | this.constraintSemantics = constraintSemantics; |
| 267 | return this; |
| 268 | } |
| 269 | |
| 270 | /** |
gregce | 4aa059a | 2019-02-26 13:20:47 -0800 | [diff] [blame] | 271 | * Sets the policy for checking if third_party rules declare <code>licenses()</code>. See {@link |
| 272 | * #thirdPartyLicenseExistencePolicy} for the default value. |
| 273 | */ |
| 274 | public Builder setThirdPartyLicenseExistencePolicy(ThirdPartyLicenseExistencePolicy policy) { |
| 275 | this.thirdPartyLicenseExistencePolicy = policy; |
| 276 | return this; |
| 277 | } |
| 278 | |
| 279 | /** |
mstaib | e59cbd0 | 2018-06-01 15:23:00 -0700 | [diff] [blame] | 280 | * Adds a transition factory that produces a trimming transition to be run over all targets |
mstaib | 4a07a47 | 2018-04-19 14:16:41 -0700 | [diff] [blame] | 281 | * after other transitions. |
| 282 | * |
mstaib | e59cbd0 | 2018-06-01 15:23:00 -0700 | [diff] [blame] | 283 | * <p>Transitions are run in the order they're added. |
| 284 | * |
| 285 | * <p>This is a temporary measure for supporting trimming of test rules and manual trimming of |
| 286 | * feature flags, and support for this transition factory will likely be removed at some point |
| 287 | * in the future (whenever automatic trimming is sufficiently workable). |
mstaib | 4a07a47 | 2018-04-19 14:16:41 -0700 | [diff] [blame] | 288 | */ |
John Cater | b3b3e8b | 2019-04-03 09:18:42 -0700 | [diff] [blame] | 289 | public Builder addTrimmingTransitionFactory(TransitionFactory<Rule> factory) { |
| 290 | Preconditions.checkNotNull(factory); |
| 291 | Preconditions.checkArgument(!factory.isSplit()); |
mstaib | e59cbd0 | 2018-06-01 15:23:00 -0700 | [diff] [blame] | 292 | if (trimmingTransitionFactory == null) { |
John Cater | b3b3e8b | 2019-04-03 09:18:42 -0700 | [diff] [blame] | 293 | trimmingTransitionFactory = factory; |
mstaib | e59cbd0 | 2018-06-01 15:23:00 -0700 | [diff] [blame] | 294 | } else { |
John Cater | b3b3e8b | 2019-04-03 09:18:42 -0700 | [diff] [blame] | 295 | trimmingTransitionFactory = |
| 296 | ComposingTransitionFactory.of(trimmingTransitionFactory, factory); |
mstaib | e59cbd0 | 2018-06-01 15:23:00 -0700 | [diff] [blame] | 297 | } |
mstaib | 4a07a47 | 2018-04-19 14:16:41 -0700 | [diff] [blame] | 298 | return this; |
| 299 | } |
| 300 | |
gregce | 477d965 | 2019-06-05 13:40:21 -0700 | [diff] [blame] | 301 | /** Sets the transition manual feature flag trimming should apply to toolchain deps. */ |
| 302 | public Builder setToolchainTaggedTrimmingTransition(PatchTransition transition) { |
| 303 | Preconditions.checkNotNull(transition); |
| 304 | Preconditions.checkState(toolchainTaggedTrimmingTransition == null); |
| 305 | this.toolchainTaggedTrimmingTransition = transition; |
| 306 | return this; |
| 307 | } |
| 308 | |
mstaib | 4a07a47 | 2018-04-19 14:16:41 -0700 | [diff] [blame] | 309 | /** |
| 310 | * Overrides the transition factory run over all targets. |
| 311 | * |
John Cater | b3b3e8b | 2019-04-03 09:18:42 -0700 | [diff] [blame] | 312 | * @see {@link #addTrimmingTransitionFactory(TransitionFactory<Rule>)} |
mstaib | 4a07a47 | 2018-04-19 14:16:41 -0700 | [diff] [blame] | 313 | */ |
hlopko | 8820d3a | 2018-06-15 09:10:05 -0700 | [diff] [blame] | 314 | @VisibleForTesting(/* for testing trimming transition factories without relying on prod use */ ) |
John Cater | b3b3e8b | 2019-04-03 09:18:42 -0700 | [diff] [blame] | 315 | public Builder overrideTrimmingTransitionFactoryForTesting(TransitionFactory<Rule> factory) { |
mstaib | 4a07a47 | 2018-04-19 14:16:41 -0700 | [diff] [blame] | 316 | trimmingTransitionFactory = null; |
mstaib | e59cbd0 | 2018-06-01 15:23:00 -0700 | [diff] [blame] | 317 | return this.addTrimmingTransitionFactory(factory); |
mstaib | 4a07a47 | 2018-04-19 14:16:41 -0700 | [diff] [blame] | 318 | } |
| 319 | |
mstaib | a9b5585 | 2018-06-18 13:37:49 -0700 | [diff] [blame] | 320 | /** |
| 321 | * Sets the predicate which determines whether the analysis cache should be invalidated for the |
| 322 | * given options diff. |
| 323 | */ |
mstaib | 6cf6278 | 2018-11-14 11:54:33 -0800 | [diff] [blame] | 324 | public Builder setShouldInvalidateCacheForOptionDiff( |
| 325 | OptionsDiffPredicate shouldInvalidateCacheForOptionDiff) { |
mstaib | a9b5585 | 2018-06-18 13:37:49 -0700 | [diff] [blame] | 326 | Preconditions.checkState( |
mstaib | 6cf6278 | 2018-11-14 11:54:33 -0800 | [diff] [blame] | 327 | this.shouldInvalidateCacheForOptionDiff.equals(OptionsDiffPredicate.ALWAYS_INVALIDATE), |
mstaib | a9b5585 | 2018-06-18 13:37:49 -0700 | [diff] [blame] | 328 | "Cache invalidation function was already set"); |
mstaib | 6cf6278 | 2018-11-14 11:54:33 -0800 | [diff] [blame] | 329 | this.shouldInvalidateCacheForOptionDiff = shouldInvalidateCacheForOptionDiff; |
mstaib | a9b5585 | 2018-06-18 13:37:49 -0700 | [diff] [blame] | 330 | return this; |
| 331 | } |
| 332 | |
jcater | 0321a15 | 2019-07-08 12:47:19 -0700 | [diff] [blame] | 333 | @Override |
| 334 | public boolean enableExecutionTransition() { |
| 335 | return enableExecutionTransition; |
| 336 | } |
| 337 | |
| 338 | public Builder enableExecutionTransition(boolean flag) { |
| 339 | this.enableExecutionTransition = flag; |
| 340 | return this; |
| 341 | } |
| 342 | |
mstaib | a9b5585 | 2018-06-18 13:37:49 -0700 | [diff] [blame] | 343 | /** |
| 344 | * Overrides the predicate which determines whether the analysis cache should be invalidated for |
| 345 | * the given options diff. |
| 346 | */ |
| 347 | @VisibleForTesting(/* for testing cache invalidation without relying on prod use */ ) |
mstaib | 6cf6278 | 2018-11-14 11:54:33 -0800 | [diff] [blame] | 348 | public Builder overrideShouldInvalidateCacheForOptionDiffForTesting( |
| 349 | OptionsDiffPredicate shouldInvalidateCacheForOptionDiff) { |
| 350 | this.shouldInvalidateCacheForOptionDiff = OptionsDiffPredicate.ALWAYS_INVALIDATE; |
| 351 | return this.setShouldInvalidateCacheForOptionDiff(shouldInvalidateCacheForOptionDiff); |
mstaib | a9b5585 | 2018-06-18 13:37:49 -0700 | [diff] [blame] | 352 | } |
| 353 | |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 354 | private RuleConfiguredTargetFactory createFactory( |
| 355 | Class<? extends RuleConfiguredTargetFactory> factoryClass) { |
| 356 | try { |
| 357 | Constructor<? extends RuleConfiguredTargetFactory> ctor = factoryClass.getConstructor(); |
| 358 | return ctor.newInstance(); |
| 359 | } catch (NoSuchMethodException | IllegalAccessException | InstantiationException |
| 360 | | InvocationTargetException e) { |
| 361 | throw new IllegalStateException(e); |
| 362 | } |
| 363 | } |
| 364 | |
| 365 | private RuleClass commitRuleDefinition(Class<? extends RuleDefinition> definitionClass) { |
Luis Fernando Pino Duque | 2b0b5cc | 2016-04-26 09:31:27 +0000 | [diff] [blame] | 366 | RuleDefinition instance = checkNotNull(ruleDefinitionMap.get(definitionClass.getName()), |
Googler | 5850503 | 2015-03-19 16:12:34 +0000 | [diff] [blame] | 367 | "addRuleDefinition(new %s()) should be called before build()", definitionClass.getName()); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 368 | |
Googler | 5850503 | 2015-03-19 16:12:34 +0000 | [diff] [blame] | 369 | RuleDefinition.Metadata metadata = instance.getMetadata(); |
lpino | 92cb829 | 2017-10-27 14:38:10 +0200 | [diff] [blame] | 370 | checkArgument( |
| 371 | ruleClassMap.get(metadata.name()) == null, |
| 372 | "The rule " + metadata.name() + " was committed already, use another name"); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 373 | |
Googler | 5850503 | 2015-03-19 16:12:34 +0000 | [diff] [blame] | 374 | List<Class<? extends RuleDefinition>> ancestors = metadata.ancestors(); |
| 375 | |
| 376 | checkArgument( |
| 377 | metadata.type() == ABSTRACT ^ metadata.factoryClass() |
| 378 | != RuleConfiguredTargetFactory.class); |
| 379 | checkArgument( |
| 380 | (metadata.type() != TEST) |
| 381 | || ancestors.contains(BaseRuleClasses.TestBaseRule.class)); |
| 382 | |
| 383 | RuleClass[] ancestorClasses = new RuleClass[ancestors.size()]; |
| 384 | for (int i = 0; i < ancestorClasses.length; i++) { |
| 385 | ancestorClasses[i] = ruleMap.get(ancestors.get(i)); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 386 | if (ancestorClasses[i] == null) { |
| 387 | // Ancestors should have been initialized by now |
Googler | 5850503 | 2015-03-19 16:12:34 +0000 | [diff] [blame] | 388 | throw new IllegalStateException("Ancestor " + ancestors.get(i) + " of " |
| 389 | + metadata.name() + " is not initialized"); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 390 | } |
| 391 | } |
| 392 | |
| 393 | RuleConfiguredTargetFactory factory = null; |
Googler | 5850503 | 2015-03-19 16:12:34 +0000 | [diff] [blame] | 394 | if (metadata.type() != ABSTRACT) { |
| 395 | factory = createFactory(metadata.factoryClass()); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 396 | } |
| 397 | |
| 398 | RuleClass.Builder builder = new RuleClass.Builder( |
Googler | 5850503 | 2015-03-19 16:12:34 +0000 | [diff] [blame] | 399 | metadata.name(), metadata.type(), false, ancestorClasses); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 400 | builder.factory(factory); |
gregce | 4aa059a | 2019-02-26 13:20:47 -0800 | [diff] [blame] | 401 | builder.setThirdPartyLicenseExistencePolicy(thirdPartyLicenseExistencePolicy); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 402 | RuleClass ruleClass = instance.build(builder, this); |
| 403 | ruleMap.put(definitionClass, ruleClass); |
| 404 | ruleClassMap.put(ruleClass.getName(), ruleClass); |
Luis Fernando Pino Duque | 2b0b5cc | 2016-04-26 09:31:27 +0000 | [diff] [blame] | 405 | ruleDefinitionMap.put(ruleClass.getName(), instance); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 406 | |
| 407 | return ruleClass; |
| 408 | } |
| 409 | |
| 410 | public ConfiguredRuleClassProvider build() { |
| 411 | for (Node<Class<? extends RuleDefinition>> ruleDefinition : |
Googler | 5850503 | 2015-03-19 16:12:34 +0000 | [diff] [blame] | 412 | dependencyGraph.getTopologicalOrder()) { |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 413 | commitRuleDefinition(ruleDefinition.getLabel()); |
| 414 | } |
| 415 | |
| 416 | return new ConfiguredRuleClassProvider( |
John Field | a97e17f | 2015-11-13 02:19:52 +0000 | [diff] [blame] | 417 | preludeLabel, |
Ulf Adams | d13207c | 2015-09-04 14:53:43 +0000 | [diff] [blame] | 418 | runfilesPrefix, |
Luis Fernando Pino Duque | 90511e1 | 2016-01-28 10:49:58 +0000 | [diff] [blame] | 419 | toolsRepository, |
brandjon | 39ca727 | 2020-12-03 14:40:09 -0800 | [diff] [blame] | 420 | builtinsPackagePathInSource, |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 421 | ImmutableMap.copyOf(ruleClassMap), |
| 422 | ImmutableMap.copyOf(ruleDefinitionMap), |
Luis Fernando Pino Duque | e82713d | 2016-04-26 16:22:38 +0000 | [diff] [blame] | 423 | ImmutableMap.copyOf(nativeAspectClassMap), |
Damien Martin-Guillerez | 585c87b | 2016-03-31 08:24:37 +0000 | [diff] [blame] | 424 | defaultWorkspaceFilePrefix.toString(), |
| 425 | defaultWorkspaceFileSuffix.toString(), |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 426 | ImmutableList.copyOf(buildInfoFactories), |
| 427 | ImmutableList.copyOf(configurationOptions), |
gregce | 4ed65b0 | 2020-11-18 07:06:25 -0800 | [diff] [blame] | 428 | ImmutableList.copyOf(configurationFragmentClasses), |
lberki | 78651d4 | 2018-04-06 01:52:58 -0700 | [diff] [blame] | 429 | ImmutableList.copyOf(universalFragments), |
mstaib | 4a07a47 | 2018-04-19 14:16:41 -0700 | [diff] [blame] | 430 | trimmingTransitionFactory, |
gregce | 477d965 | 2019-06-05 13:40:21 -0700 | [diff] [blame] | 431 | toolchainTaggedTrimmingTransition, |
mstaib | 6cf6278 | 2018-11-14 11:54:33 -0800 | [diff] [blame] | 432 | shouldInvalidateCacheForOptionDiff, |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 433 | prerequisiteValidator, |
gregce | 47a99f3 | 2020-05-13 12:35:26 -0700 | [diff] [blame] | 434 | starlarkAccessibleTopLevels.build(), |
| 435 | starlarkBootstraps.build(), |
brandjon | 8a60360 | 2019-12-04 10:40:38 -0800 | [diff] [blame] | 436 | symlinkDefinitions.build(), |
lberki | 406199f | 2018-04-09 03:16:19 -0700 | [diff] [blame] | 437 | ImmutableSet.copyOf(reservedActionMnemonics), |
gregce | 6acfe4e | 2018-05-25 08:38:39 -0700 | [diff] [blame] | 438 | actionEnvironmentProvider, |
gregce | 4aa059a | 2019-02-26 13:20:47 -0800 | [diff] [blame] | 439 | constraintSemantics, |
| 440 | thirdPartyLicenseExistencePolicy); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 441 | } |
| 442 | |
| 443 | @Override |
Luis Fernando Pino Duque | 18d1322 | 2016-02-08 14:55:28 +0000 | [diff] [blame] | 444 | public Label getToolsLabel(String labelValue) { |
janakr | c19284e | 2018-06-20 15:22:33 -0700 | [diff] [blame] | 445 | return Label.parseAbsoluteUnchecked(toolsRepository + labelValue); |
Luis Fernando Pino Duque | 90511e1 | 2016-01-28 10:49:58 +0000 | [diff] [blame] | 446 | } |
Luis Fernando Pino Duque | 207ba4a | 2016-07-01 15:07:23 +0000 | [diff] [blame] | 447 | |
| 448 | @Override |
| 449 | public String getToolsRepository() { |
| 450 | return toolsRepository; |
| 451 | } |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 452 | } |
| 453 | |
| 454 | /** |
Damien Martin-Guillerez | 585c87b | 2016-03-31 08:24:37 +0000 | [diff] [blame] | 455 | * Default content that should be added at the beginning of the WORKSPACE file. |
Kristina Chodorow | bc4b4b1 | 2015-02-11 15:54:50 +0000 | [diff] [blame] | 456 | */ |
Damien Martin-Guillerez | 585c87b | 2016-03-31 08:24:37 +0000 | [diff] [blame] | 457 | private final String defaultWorkspaceFilePrefix; |
| 458 | |
| 459 | /** |
| 460 | * Default content that should be added at the end of the WORKSPACE file. |
| 461 | */ |
| 462 | private final String defaultWorkspaceFileSuffix; |
| 463 | |
Kristina Chodorow | bc4b4b1 | 2015-02-11 15:54:50 +0000 | [diff] [blame] | 464 | |
| 465 | /** |
John Field | a97e17f | 2015-11-13 02:19:52 +0000 | [diff] [blame] | 466 | * Label for the prelude file. |
Ulf Adams | fdfdd92 | 2015-09-01 08:36:29 +0000 | [diff] [blame] | 467 | */ |
John Field | a97e17f | 2015-11-13 02:19:52 +0000 | [diff] [blame] | 468 | private final Label preludeLabel; |
Ulf Adams | fdfdd92 | 2015-09-01 08:36:29 +0000 | [diff] [blame] | 469 | |
| 470 | /** |
Ulf Adams | d13207c | 2015-09-04 14:53:43 +0000 | [diff] [blame] | 471 | * The default runfiles prefix. |
| 472 | */ |
| 473 | private final String runfilesPrefix; |
Luis Fernando Pino Duque | 18d1322 | 2016-02-08 14:55:28 +0000 | [diff] [blame] | 474 | |
Luis Fernando Pino Duque | 90511e1 | 2016-01-28 10:49:58 +0000 | [diff] [blame] | 475 | /** |
| 476 | * The path to the tools repository. |
| 477 | */ |
| 478 | private final String toolsRepository; |
Ulf Adams | d13207c | 2015-09-04 14:53:43 +0000 | [diff] [blame] | 479 | |
brandjon | 39ca727 | 2020-12-03 14:40:09 -0800 | [diff] [blame] | 480 | /** The relative location of the builtins_bzl directory within a Bazel source tree. */ |
| 481 | private final String builtinsPackagePathInSource; |
| 482 | |
Ulf Adams | d13207c | 2015-09-04 14:53:43 +0000 | [diff] [blame] | 483 | /** |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 484 | * Maps rule class name to the metaclass instance for that rule. |
| 485 | */ |
| 486 | private final ImmutableMap<String, RuleClass> ruleClassMap; |
| 487 | |
| 488 | /** |
Luis Fernando Pino Duque | 2b0b5cc | 2016-04-26 09:31:27 +0000 | [diff] [blame] | 489 | * Maps rule class name to the rule definition objects. |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 490 | */ |
Luis Fernando Pino Duque | 2b0b5cc | 2016-04-26 09:31:27 +0000 | [diff] [blame] | 491 | private final ImmutableMap<String, RuleDefinition> ruleDefinitionMap; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 492 | |
| 493 | /** |
Dmitry Lomov | e2033b1 | 2015-08-19 16:57:49 +0000 | [diff] [blame] | 494 | * Maps aspect name to the aspect factory meta class. |
| 495 | */ |
Luis Fernando Pino Duque | e82713d | 2016-04-26 16:22:38 +0000 | [diff] [blame] | 496 | private final ImmutableMap<String, NativeAspectClass> nativeAspectClassMap; |
Dmitry Lomov | e2033b1 | 2015-08-19 16:57:49 +0000 | [diff] [blame] | 497 | |
| 498 | /** |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 499 | * The configuration options that affect the behavior of the rules. |
| 500 | */ |
| 501 | private final ImmutableList<Class<? extends FragmentOptions>> configurationOptions; |
| 502 | |
Ulf Adams | 8d0be89 | 2016-10-14 13:56:46 +0000 | [diff] [blame] | 503 | /** The set of configuration fragment factories. */ |
gregce | 4ed65b0 | 2020-11-18 07:06:25 -0800 | [diff] [blame] | 504 | private final ImmutableList<Class<? extends Fragment>> configurationFragmentClasses; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 505 | |
mstaib | 2d7c0ff | 2019-02-28 08:28:11 -0800 | [diff] [blame] | 506 | /** |
| 507 | * Maps build option names to matching config fragments. This is used to determine correct |
| 508 | * fragment requirements for config_setting rules, which are unique in that their dependencies are |
| 509 | * triggered by string representations of option names. |
| 510 | */ |
| 511 | private final Map<String, Class<? extends Fragment>> optionsToFragmentMap; |
| 512 | |
mstaib | 4a07a47 | 2018-04-19 14:16:41 -0700 | [diff] [blame] | 513 | /** The transition factory used to produce the transition that will trim targets. */ |
John Cater | b3b3e8b | 2019-04-03 09:18:42 -0700 | [diff] [blame] | 514 | @Nullable private final TransitionFactory<Rule> trimmingTransitionFactory; |
mstaib | 4a07a47 | 2018-04-19 14:16:41 -0700 | [diff] [blame] | 515 | |
gregce | 477d965 | 2019-06-05 13:40:21 -0700 | [diff] [blame] | 516 | /** The transition to apply to toolchain deps for manual trimming. */ |
| 517 | @Nullable private final PatchTransition toolchainTaggedTrimmingTransition; |
| 518 | |
mstaib | a9b5585 | 2018-06-18 13:37:49 -0700 | [diff] [blame] | 519 | /** The predicate used to determine whether a diff requires the cache to be invalidated. */ |
mstaib | 6cf6278 | 2018-11-14 11:54:33 -0800 | [diff] [blame] | 520 | private final OptionsDiffPredicate shouldInvalidateCacheForOptionDiff; |
mstaib | a9b5585 | 2018-06-18 13:37:49 -0700 | [diff] [blame] | 521 | |
gregce | 490b095 | 2017-07-06 18:44:38 -0400 | [diff] [blame] | 522 | /** |
brandjon | 79712cb | 2019-12-04 10:01:17 -0800 | [diff] [blame] | 523 | * Configuration fragments that should be available to all rules even when they don't explicitly |
| 524 | * require it. |
Greg Estren | c5a352f | 2015-11-13 17:25:36 +0000 | [diff] [blame] | 525 | */ |
brandjon | 79712cb | 2019-12-04 10:01:17 -0800 | [diff] [blame] | 526 | private final ImmutableList<Class<? extends Fragment>> universalFragments; |
Greg Estren | c5a352f | 2015-11-13 17:25:36 +0000 | [diff] [blame] | 527 | |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 528 | private final ImmutableList<BuildInfoFactory> buildInfoFactories; |
| 529 | |
| 530 | private final PrerequisiteValidator prerequisiteValidator; |
| 531 | |
brandjon | a0c6f81 | 2020-06-06 14:13:19 -0700 | [diff] [blame] | 532 | private final ImmutableMap<String, Object> nativeRuleSpecificBindings; |
| 533 | |
Googler | bffb687 | 2019-10-22 11:14:46 -0700 | [diff] [blame] | 534 | private final ImmutableMap<String, Object> environment; |
Janak Ramakrishnan | b6e33bc | 2015-09-06 21:05:23 +0000 | [diff] [blame] | 535 | |
brandjon | 8a60360 | 2019-12-04 10:40:38 -0800 | [diff] [blame] | 536 | private final ImmutableList<SymlinkDefinition> symlinkDefinitions; |
| 537 | |
lberki | 406199f | 2018-04-09 03:16:19 -0700 | [diff] [blame] | 538 | private final ImmutableSet<String> reservedActionMnemonics; |
| 539 | |
lberki | 8626623 | 2018-04-11 00:33:42 -0700 | [diff] [blame] | 540 | private final BuildConfiguration.ActionEnvironmentProvider actionEnvironmentProvider; |
| 541 | |
cparsons | caceacd | 2017-11-04 01:00:59 +0100 | [diff] [blame] | 542 | private final ImmutableMap<String, Class<?>> configurationFragmentMap; |
| 543 | |
jcater | 802551e | 2020-04-15 09:59:58 -0700 | [diff] [blame] | 544 | private final ConstraintSemantics<RuleContext> constraintSemantics; |
gregce | 6acfe4e | 2018-05-25 08:38:39 -0700 | [diff] [blame] | 545 | |
gregce | 4aa059a | 2019-02-26 13:20:47 -0800 | [diff] [blame] | 546 | private final ThirdPartyLicenseExistencePolicy thirdPartyLicenseExistencePolicy; |
| 547 | |
Kristina Chodorow | 8612a27 | 2015-12-14 15:37:24 +0000 | [diff] [blame] | 548 | private ConfiguredRuleClassProvider( |
John Field | a97e17f | 2015-11-13 02:19:52 +0000 | [diff] [blame] | 549 | Label preludeLabel, |
Ulf Adams | d13207c | 2015-09-04 14:53:43 +0000 | [diff] [blame] | 550 | String runfilesPrefix, |
Luis Fernando Pino Duque | 90511e1 | 2016-01-28 10:49:58 +0000 | [diff] [blame] | 551 | String toolsRepository, |
brandjon | 39ca727 | 2020-12-03 14:40:09 -0800 | [diff] [blame] | 552 | String builtinsPackagePathInSource, |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 553 | ImmutableMap<String, RuleClass> ruleClassMap, |
Luis Fernando Pino Duque | 2b0b5cc | 2016-04-26 09:31:27 +0000 | [diff] [blame] | 554 | ImmutableMap<String, RuleDefinition> ruleDefinitionMap, |
Luis Fernando Pino Duque | e82713d | 2016-04-26 16:22:38 +0000 | [diff] [blame] | 555 | ImmutableMap<String, NativeAspectClass> nativeAspectClassMap, |
Damien Martin-Guillerez | 585c87b | 2016-03-31 08:24:37 +0000 | [diff] [blame] | 556 | String defaultWorkspaceFilePrefix, |
| 557 | String defaultWorkspaceFileSuffix, |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 558 | ImmutableList<BuildInfoFactory> buildInfoFactories, |
| 559 | ImmutableList<Class<? extends FragmentOptions>> configurationOptions, |
gregce | 4ed65b0 | 2020-11-18 07:06:25 -0800 | [diff] [blame] | 560 | ImmutableList<Class<? extends Fragment>> configurationFragmentClasses, |
brandjon | 79712cb | 2019-12-04 10:01:17 -0800 | [diff] [blame] | 561 | ImmutableList<Class<? extends Fragment>> universalFragments, |
John Cater | b3b3e8b | 2019-04-03 09:18:42 -0700 | [diff] [blame] | 562 | @Nullable TransitionFactory<Rule> trimmingTransitionFactory, |
gregce | 477d965 | 2019-06-05 13:40:21 -0700 | [diff] [blame] | 563 | PatchTransition toolchainTaggedTrimmingTransition, |
mstaib | 6cf6278 | 2018-11-14 11:54:33 -0800 | [diff] [blame] | 564 | OptionsDiffPredicate shouldInvalidateCacheForOptionDiff, |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 565 | PrerequisiteValidator prerequisiteValidator, |
gregce | 47a99f3 | 2020-05-13 12:35:26 -0700 | [diff] [blame] | 566 | ImmutableMap<String, Object> starlarkAccessibleJavaClasses, |
| 567 | ImmutableList<Bootstrap> starlarkBootstraps, |
brandjon | 8a60360 | 2019-12-04 10:40:38 -0800 | [diff] [blame] | 568 | ImmutableList<SymlinkDefinition> symlinkDefinitions, |
lberki | 406199f | 2018-04-09 03:16:19 -0700 | [diff] [blame] | 569 | ImmutableSet<String> reservedActionMnemonics, |
gregce | 6acfe4e | 2018-05-25 08:38:39 -0700 | [diff] [blame] | 570 | BuildConfiguration.ActionEnvironmentProvider actionEnvironmentProvider, |
jcater | 802551e | 2020-04-15 09:59:58 -0700 | [diff] [blame] | 571 | ConstraintSemantics<RuleContext> constraintSemantics, |
gregce | 4aa059a | 2019-02-26 13:20:47 -0800 | [diff] [blame] | 572 | ThirdPartyLicenseExistencePolicy thirdPartyLicenseExistencePolicy) { |
John Field | a97e17f | 2015-11-13 02:19:52 +0000 | [diff] [blame] | 573 | this.preludeLabel = preludeLabel; |
Ulf Adams | d13207c | 2015-09-04 14:53:43 +0000 | [diff] [blame] | 574 | this.runfilesPrefix = runfilesPrefix; |
Luis Fernando Pino Duque | 90511e1 | 2016-01-28 10:49:58 +0000 | [diff] [blame] | 575 | this.toolsRepository = toolsRepository; |
brandjon | 39ca727 | 2020-12-03 14:40:09 -0800 | [diff] [blame] | 576 | this.builtinsPackagePathInSource = builtinsPackagePathInSource; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 577 | this.ruleClassMap = ruleClassMap; |
| 578 | this.ruleDefinitionMap = ruleDefinitionMap; |
Luis Fernando Pino Duque | e82713d | 2016-04-26 16:22:38 +0000 | [diff] [blame] | 579 | this.nativeAspectClassMap = nativeAspectClassMap; |
Damien Martin-Guillerez | 585c87b | 2016-03-31 08:24:37 +0000 | [diff] [blame] | 580 | this.defaultWorkspaceFilePrefix = defaultWorkspaceFilePrefix; |
| 581 | this.defaultWorkspaceFileSuffix = defaultWorkspaceFileSuffix; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 582 | this.buildInfoFactories = buildInfoFactories; |
| 583 | this.configurationOptions = configurationOptions; |
gregce | 4ed65b0 | 2020-11-18 07:06:25 -0800 | [diff] [blame] | 584 | this.configurationFragmentClasses = configurationFragmentClasses; |
| 585 | this.optionsToFragmentMap = computeOptionsToFragmentMap(configurationFragmentClasses); |
lberki | 78651d4 | 2018-04-06 01:52:58 -0700 | [diff] [blame] | 586 | this.universalFragments = universalFragments; |
mstaib | 4a07a47 | 2018-04-19 14:16:41 -0700 | [diff] [blame] | 587 | this.trimmingTransitionFactory = trimmingTransitionFactory; |
gregce | 477d965 | 2019-06-05 13:40:21 -0700 | [diff] [blame] | 588 | this.toolchainTaggedTrimmingTransition = toolchainTaggedTrimmingTransition; |
mstaib | 6cf6278 | 2018-11-14 11:54:33 -0800 | [diff] [blame] | 589 | this.shouldInvalidateCacheForOptionDiff = shouldInvalidateCacheForOptionDiff; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 590 | this.prerequisiteValidator = prerequisiteValidator; |
brandjon | a0c6f81 | 2020-06-06 14:13:19 -0700 | [diff] [blame] | 591 | this.nativeRuleSpecificBindings = |
| 592 | createNativeRuleSpecificBindings(starlarkAccessibleJavaClasses, starlarkBootstraps); |
| 593 | this.environment = createEnvironment(nativeRuleSpecificBindings); |
brandjon | 8a60360 | 2019-12-04 10:40:38 -0800 | [diff] [blame] | 594 | this.symlinkDefinitions = symlinkDefinitions; |
lberki | 406199f | 2018-04-09 03:16:19 -0700 | [diff] [blame] | 595 | this.reservedActionMnemonics = reservedActionMnemonics; |
lberki | 8626623 | 2018-04-11 00:33:42 -0700 | [diff] [blame] | 596 | this.actionEnvironmentProvider = actionEnvironmentProvider; |
gregce | 4ed65b0 | 2020-11-18 07:06:25 -0800 | [diff] [blame] | 597 | this.configurationFragmentMap = createFragmentMap(configurationFragmentClasses); |
gregce | 6acfe4e | 2018-05-25 08:38:39 -0700 | [diff] [blame] | 598 | this.constraintSemantics = constraintSemantics; |
gregce | 4aa059a | 2019-02-26 13:20:47 -0800 | [diff] [blame] | 599 | this.thirdPartyLicenseExistencePolicy = thirdPartyLicenseExistencePolicy; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 600 | } |
| 601 | |
mstaib | 2d7c0ff | 2019-02-28 08:28:11 -0800 | [diff] [blame] | 602 | /** |
| 603 | * Computes the option name --> config fragments map. Note that this mapping is technically |
| 604 | * one-to-many: a single option may be required by multiple fragments (e.g. Java options are used |
| 605 | * by both JavaConfiguration and Jvm). In such cases, we arbitrarily choose one fragment since |
| 606 | * that's all that's needed to satisfy the config_setting. |
| 607 | */ |
| 608 | private static Map<String, Class<? extends Fragment>> computeOptionsToFragmentMap( |
gregce | 4ed65b0 | 2020-11-18 07:06:25 -0800 | [diff] [blame] | 609 | ImmutableList<Class<? extends Fragment>> configurationFragments) { |
mstaib | 2d7c0ff | 2019-02-28 08:28:11 -0800 | [diff] [blame] | 610 | Map<String, Class<? extends Fragment>> result = new LinkedHashMap<>(); |
| 611 | Map<Class<? extends FragmentOptions>, Integer> visitedOptionsClasses = new HashMap<>(); |
gregce | 4ed65b0 | 2020-11-18 07:06:25 -0800 | [diff] [blame] | 612 | for (Class<? extends Fragment> fragment : configurationFragments) { |
| 613 | Set<Class<? extends FragmentOptions>> requiredOpts = Fragment.requiredOptions(fragment); |
mstaib | 2d7c0ff | 2019-02-28 08:28:11 -0800 | [diff] [blame] | 614 | for (Class<? extends FragmentOptions> optionsClass : requiredOpts) { |
| 615 | Integer previousBest = visitedOptionsClasses.get(optionsClass); |
| 616 | if (previousBest != null && previousBest <= requiredOpts.size()) { |
| 617 | // Multiple config fragments may require the same options class, but we only need one of |
| 618 | // them to guarantee that class makes it into the configuration. Pick one that depends |
| 619 | // on as few options classes as possible (not necessarily unique). |
| 620 | continue; |
| 621 | } |
| 622 | visitedOptionsClasses.put(optionsClass, requiredOpts.size()); |
| 623 | for (Field field : optionsClass.getFields()) { |
| 624 | if (field.isAnnotationPresent(Option.class)) { |
gregce | 4ed65b0 | 2020-11-18 07:06:25 -0800 | [diff] [blame] | 625 | result.put(field.getAnnotation(Option.class).name(), fragment); |
mstaib | 2d7c0ff | 2019-02-28 08:28:11 -0800 | [diff] [blame] | 626 | } |
| 627 | } |
| 628 | } |
| 629 | } |
| 630 | return result; |
| 631 | } |
| 632 | |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 633 | public PrerequisiteValidator getPrerequisiteValidator() { |
| 634 | return prerequisiteValidator; |
| 635 | } |
| 636 | |
| 637 | @Override |
John Field | a97e17f | 2015-11-13 02:19:52 +0000 | [diff] [blame] | 638 | public Label getPreludeLabel() { |
| 639 | return preludeLabel; |
Ulf Adams | fdfdd92 | 2015-09-01 08:36:29 +0000 | [diff] [blame] | 640 | } |
| 641 | |
| 642 | @Override |
Ulf Adams | d13207c | 2015-09-04 14:53:43 +0000 | [diff] [blame] | 643 | public String getRunfilesPrefix() { |
| 644 | return runfilesPrefix; |
| 645 | } |
Luis Fernando Pino Duque | 18d1322 | 2016-02-08 14:55:28 +0000 | [diff] [blame] | 646 | |
Luis Fernando Pino Duque | 90511e1 | 2016-01-28 10:49:58 +0000 | [diff] [blame] | 647 | @Override |
| 648 | public String getToolsRepository() { |
| 649 | return toolsRepository; |
| 650 | } |
Ulf Adams | d13207c | 2015-09-04 14:53:43 +0000 | [diff] [blame] | 651 | |
| 652 | @Override |
brandjon | 39ca727 | 2020-12-03 14:40:09 -0800 | [diff] [blame] | 653 | public String getBuiltinsPackagePathInSource() { |
| 654 | return builtinsPackagePathInSource; |
| 655 | } |
| 656 | |
| 657 | @Override |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 658 | public Map<String, RuleClass> getRuleClassMap() { |
| 659 | return ruleClassMap; |
| 660 | } |
| 661 | |
Dmitry Lomov | e2033b1 | 2015-08-19 16:57:49 +0000 | [diff] [blame] | 662 | @Override |
Luis Fernando Pino Duque | e82713d | 2016-04-26 16:22:38 +0000 | [diff] [blame] | 663 | public Map<String, NativeAspectClass> getNativeAspectClassMap() { |
| 664 | return nativeAspectClassMap; |
| 665 | } |
| 666 | |
| 667 | @Override |
| 668 | public NativeAspectClass getNativeAspectClass(String key) { |
| 669 | return nativeAspectClassMap.get(key); |
Dmitry Lomov | e2033b1 | 2015-08-19 16:57:49 +0000 | [diff] [blame] | 670 | } |
| 671 | |
ulfjack | 3740768 | 2019-09-17 06:30:49 -0700 | [diff] [blame] | 672 | public Map<BuildInfoKey, BuildInfoFactory> getBuildInfoFactoriesAsMap() { |
| 673 | ImmutableMap.Builder<BuildInfoKey, BuildInfoFactory> factoryMapBuilder = ImmutableMap.builder(); |
| 674 | for (BuildInfoFactory factory : buildInfoFactories) { |
| 675 | factoryMapBuilder.put(factory.getKey(), factory); |
| 676 | } |
| 677 | return factoryMapBuilder.build(); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 678 | } |
| 679 | |
David Ostrovsky | a138877 | 2020-07-08 12:11:01 -0700 | [diff] [blame] | 680 | /** Returns the set of configuration fragments provided by this module. */ |
| 681 | @Override |
gregce | 4ed65b0 | 2020-11-18 07:06:25 -0800 | [diff] [blame] | 682 | public ImmutableList<Class<? extends Fragment>> getConfigurationFragments() { |
| 683 | return configurationFragmentClasses; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 684 | } |
| 685 | |
mstaib | 2d7c0ff | 2019-02-28 08:28:11 -0800 | [diff] [blame] | 686 | @Nullable |
| 687 | public Class<? extends Fragment> getConfigurationFragmentForOption(String requiredOption) { |
| 688 | return optionsToFragmentMap.get(requiredOption); |
| 689 | } |
| 690 | |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 691 | /** |
mstaib | 4a07a47 | 2018-04-19 14:16:41 -0700 | [diff] [blame] | 692 | * Returns the transition factory used to produce the transition to trim targets. |
| 693 | * |
John Cater | b3b3e8b | 2019-04-03 09:18:42 -0700 | [diff] [blame] | 694 | * <p>This is a temporary measure for supporting manual trimming of feature flags, and support for |
| 695 | * this transition factory will likely be removed at some point in the future (whenever automatic |
| 696 | * trimming is sufficiently workable |
mstaib | 4a07a47 | 2018-04-19 14:16:41 -0700 | [diff] [blame] | 697 | */ |
| 698 | @Nullable |
John Cater | b3b3e8b | 2019-04-03 09:18:42 -0700 | [diff] [blame] | 699 | public TransitionFactory<Rule> getTrimmingTransitionFactory() { |
mstaib | 4a07a47 | 2018-04-19 14:16:41 -0700 | [diff] [blame] | 700 | return trimmingTransitionFactory; |
| 701 | } |
| 702 | |
gregce | 477d965 | 2019-06-05 13:40:21 -0700 | [diff] [blame] | 703 | /** |
| 704 | * Returns the transition manual feature flag trimming should apply to toolchain deps. |
| 705 | * |
| 706 | * <p>See extra notes on {@link #getTrimmingTransitionFactory()}. |
| 707 | */ |
| 708 | @Nullable |
| 709 | public PatchTransition getToolchainTaggedTrimmingTransition() { |
| 710 | return toolchainTaggedTrimmingTransition; |
| 711 | } |
| 712 | |
mstaib | 6cf6278 | 2018-11-14 11:54:33 -0800 | [diff] [blame] | 713 | /** Returns whether the analysis cache should be invalidated for the given option diff. */ |
| 714 | public boolean shouldInvalidateCacheForOptionDiff( |
| 715 | BuildOptions newOptions, OptionDefinition changedOption, Object oldValue, Object newValue) { |
| 716 | return shouldInvalidateCacheForOptionDiff.apply(newOptions, changedOption, oldValue, newValue); |
mstaib | a9b5585 | 2018-06-18 13:37:49 -0700 | [diff] [blame] | 717 | } |
| 718 | |
mstaib | 4a07a47 | 2018-04-19 14:16:41 -0700 | [diff] [blame] | 719 | /** |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 720 | * Returns the set of configuration options that are supported in this module. |
| 721 | */ |
| 722 | public ImmutableList<Class<? extends FragmentOptions>> getConfigurationOptions() { |
| 723 | return configurationOptions; |
| 724 | } |
| 725 | |
| 726 | /** |
| 727 | * Returns the definition of the rule class definition with the specified name. |
| 728 | */ |
Luis Fernando Pino Duque | 2b0b5cc | 2016-04-26 09:31:27 +0000 | [diff] [blame] | 729 | public RuleDefinition getRuleClassDefinition(String ruleClassName) { |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 730 | return ruleDefinitionMap.get(ruleClassName); |
| 731 | } |
| 732 | |
| 733 | /** |
brandjon | 79712cb | 2019-12-04 10:01:17 -0800 | [diff] [blame] | 734 | * Returns the configuration fragment that should be available to all rules even when they don't |
| 735 | * explicitly require it. |
Greg Estren | c5a352f | 2015-11-13 17:25:36 +0000 | [diff] [blame] | 736 | */ |
brandjon | 79712cb | 2019-12-04 10:01:17 -0800 | [diff] [blame] | 737 | public ImmutableList<Class<? extends Fragment>> getUniversalFragments() { |
lberki | 78651d4 | 2018-04-06 01:52:58 -0700 | [diff] [blame] | 738 | return universalFragments; |
Greg Estren | c5a352f | 2015-11-13 17:25:36 +0000 | [diff] [blame] | 739 | } |
| 740 | |
| 741 | /** |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 742 | * Creates a BuildOptions class for the given options taken from an optionsProvider. |
| 743 | */ |
juliexxia | 618a076 | 2018-08-17 08:33:52 -0700 | [diff] [blame] | 744 | public BuildOptions createBuildOptions(OptionsProvider optionsProvider) { |
gregce | 9a3028c | 2017-07-26 00:19:10 +0200 | [diff] [blame] | 745 | return BuildOptions.of(configurationOptions, optionsProvider); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 746 | } |
| 747 | |
brandjon | a0c6f81 | 2020-06-06 14:13:19 -0700 | [diff] [blame] | 748 | private static ImmutableMap<String, Object> createNativeRuleSpecificBindings( |
gregce | 47a99f3 | 2020-05-13 12:35:26 -0700 | [diff] [blame] | 749 | ImmutableMap<String, Object> starlarkAccessibleTopLevels, |
cparsons | d2e0a94 | 2018-06-11 11:01:51 -0700 | [diff] [blame] | 750 | ImmutableList<Bootstrap> bootstraps) { |
brandjon | a0c6f81 | 2020-06-06 14:13:19 -0700 | [diff] [blame] | 751 | ImmutableMap.Builder<String, Object> bindings = ImmutableMap.builder(); |
| 752 | bindings.putAll(starlarkAccessibleTopLevels); |
| 753 | for (Bootstrap bootstrap : bootstraps) { |
| 754 | bootstrap.addBindingsToBuilder(bindings); |
| 755 | } |
| 756 | return bindings.build(); |
| 757 | } |
cparsons | cf3e59d | 2018-05-23 10:01:20 -0700 | [diff] [blame] | 758 | |
brandjon | a0c6f81 | 2020-06-06 14:13:19 -0700 | [diff] [blame] | 759 | private static ImmutableMap<String, Object> createEnvironment( |
| 760 | ImmutableMap<String, Object> nativeRuleSpecificBindings) { |
| 761 | ImmutableMap.Builder<String, Object> envBuilder = ImmutableMap.builder(); |
adonovan | 09d1370 | 2020-05-19 08:26:55 -0700 | [diff] [blame] | 762 | // Add predeclared symbols of the Bazel build language. |
adonovan | 5a40ab6 | 2020-09-18 12:29:25 -0700 | [diff] [blame] | 763 | StarlarkModules.addPredeclared(envBuilder); |
brandjon | a0c6f81 | 2020-06-06 14:13:19 -0700 | [diff] [blame] | 764 | // Add all the extensions registered with the rule class provider. |
| 765 | envBuilder.putAll(nativeRuleSpecificBindings); |
Googler | bffb687 | 2019-10-22 11:14:46 -0700 | [diff] [blame] | 766 | return envBuilder.build(); |
Francois-Rene Rideau | 89312fb | 2015-09-10 18:53:03 +0000 | [diff] [blame] | 767 | } |
| 768 | |
cparsons | caceacd | 2017-11-04 01:00:59 +0100 | [diff] [blame] | 769 | private static ImmutableMap<String, Class<?>> createFragmentMap( |
gregce | 4ed65b0 | 2020-11-18 07:06:25 -0800 | [diff] [blame] | 770 | Iterable<Class<? extends Fragment>> configurationFragments) { |
cparsons | caceacd | 2017-11-04 01:00:59 +0100 | [diff] [blame] | 771 | ImmutableMap.Builder<String, Class<?>> mapBuilder = ImmutableMap.builder(); |
gregce | 4ed65b0 | 2020-11-18 07:06:25 -0800 | [diff] [blame] | 772 | for (Class<? extends Fragment> fragmentClass : configurationFragments) { |
adonovan | b63c0f2 | 2020-10-14 13:01:18 -0700 | [diff] [blame] | 773 | StarlarkBuiltin fragmentModule = StarlarkAnnotations.getStarlarkBuiltin(fragmentClass); |
cparsons | 1442054 | 2018-05-07 05:47:23 -0700 | [diff] [blame] | 774 | if (fragmentModule != null) { |
| 775 | mapBuilder.put(fragmentModule.name(), fragmentClass); |
cparsons | caceacd | 2017-11-04 01:00:59 +0100 | [diff] [blame] | 776 | } |
| 777 | } |
| 778 | return mapBuilder.build(); |
| 779 | } |
| 780 | |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 781 | @Override |
brandjon | a0c6f81 | 2020-06-06 14:13:19 -0700 | [diff] [blame] | 782 | public ImmutableMap<String, Object> getNativeRuleSpecificBindings() { |
| 783 | // Include rule-related stuff like CcInfo, but not core stuff like rule(). Essentially, this |
| 784 | // is intended to include things that could in principle be migrated to Starlark (and hence |
brandjon | 5a33c63 | 2020-10-23 22:09:26 -0700 | [diff] [blame] | 785 | // should be overridable by @_builtins); in practice it means anything specifically |
| 786 | // registered with the RuleClassProvider. |
brandjon | a0c6f81 | 2020-06-06 14:13:19 -0700 | [diff] [blame] | 787 | return nativeRuleSpecificBindings; |
| 788 | } |
| 789 | |
| 790 | @Override |
Googler | bffb687 | 2019-10-22 11:14:46 -0700 | [diff] [blame] | 791 | public ImmutableMap<String, Object> getEnvironment() { |
| 792 | return environment; |
| 793 | } |
| 794 | |
| 795 | @Override |
adonovan | 6774154 | 2020-05-08 11:37:13 -0700 | [diff] [blame] | 796 | public void setStarlarkThreadContext( |
| 797 | StarlarkThread thread, |
Googler | 7fa0dd2 | 2019-09-24 20:07:53 -0700 | [diff] [blame] | 798 | Label fileLabel, |
dannark | d102a39 | 2019-01-09 13:12:01 -0800 | [diff] [blame] | 799 | ImmutableMap<RepositoryName, RepositoryName> repoMapping) { |
Googler | 7fa0dd2 | 2019-09-24 20:07:53 -0700 | [diff] [blame] | 800 | new BazelStarlarkContext( |
adonovan | b23b8c7 | 2019-12-12 11:42:14 -0800 | [diff] [blame] | 801 | BazelStarlarkContext.Phase.LOADING, |
Googler | 7fa0dd2 | 2019-09-24 20:07:53 -0700 | [diff] [blame] | 802 | toolsRepository, |
| 803 | configurationFragmentMap, |
| 804 | repoMapping, |
nharmata | fecf56f | 2020-12-15 06:47:26 -0800 | [diff] [blame^] | 805 | /*convertedLabelsInPackage=*/ new HashMap<>(), |
Googler | 7fa0dd2 | 2019-09-24 20:07:53 -0700 | [diff] [blame] | 806 | new SymbolGenerator<>(fileLabel), |
ajurkowski | 9f2cab5 | 2020-05-12 12:00:24 -0700 | [diff] [blame] | 807 | /*analysisRuleLabel=*/ null) |
Googler | a3421e2 | 2019-09-26 06:48:32 -0700 | [diff] [blame] | 808 | .storeInThread(thread); |
Janak Ramakrishnan | b6e33bc | 2015-09-06 21:05:23 +0000 | [diff] [blame] | 809 | } |
| 810 | |
Damien Martin-Guillerez | 585c87b | 2016-03-31 08:24:37 +0000 | [diff] [blame] | 811 | @Override |
| 812 | public String getDefaultWorkspacePrefix() { |
| 813 | return defaultWorkspaceFilePrefix; |
| 814 | } |
Francois-Rene Rideau | 89312fb | 2015-09-10 18:53:03 +0000 | [diff] [blame] | 815 | |
Janak Ramakrishnan | b6e33bc | 2015-09-06 21:05:23 +0000 | [diff] [blame] | 816 | @Override |
Damien Martin-Guillerez | 585c87b | 2016-03-31 08:24:37 +0000 | [diff] [blame] | 817 | public String getDefaultWorkspaceSuffix() { |
| 818 | return defaultWorkspaceFileSuffix; |
Kristina Chodorow | bc4b4b1 | 2015-02-11 15:54:50 +0000 | [diff] [blame] | 819 | } |
Greg Estren | c396f9c | 2016-10-04 18:01:01 +0000 | [diff] [blame] | 820 | |
cparsons | caceacd | 2017-11-04 01:00:59 +0100 | [diff] [blame] | 821 | @Override |
| 822 | public Map<String, Class<?>> getConfigurationFragmentMap() { |
| 823 | return configurationFragmentMap; |
| 824 | } |
| 825 | |
brandjon | 8a60360 | 2019-12-04 10:40:38 -0800 | [diff] [blame] | 826 | /** |
| 827 | * Returns the symlink definitions introduced by the fragments registered with this rule class |
| 828 | * provider. |
| 829 | * |
| 830 | * <p>This only includes definitions added by {@link #addSymlinkDefinition}, not the standard |
| 831 | * symlinks in {@link ConvenienceSymlinks#getStandardLinkDefinitions}. |
| 832 | * |
| 833 | * <p>Note: Usages of custom symlink definitions should be rare. Currently it is only used to |
| 834 | * implement the py2-bin / py3-bin symlinks. |
| 835 | */ |
| 836 | public ImmutableList<SymlinkDefinition> getSymlinkDefinitions() { |
| 837 | return symlinkDefinitions; |
| 838 | } |
| 839 | |
jcater | 802551e | 2020-04-15 09:59:58 -0700 | [diff] [blame] | 840 | public ConstraintSemantics<RuleContext> getConstraintSemantics() { |
gregce | 6acfe4e | 2018-05-25 08:38:39 -0700 | [diff] [blame] | 841 | return constraintSemantics; |
| 842 | } |
| 843 | |
gregce | 4aa059a | 2019-02-26 13:20:47 -0800 | [diff] [blame] | 844 | @Override |
| 845 | public ThirdPartyLicenseExistencePolicy getThirdPartyLicenseExistencePolicy() { |
| 846 | return thirdPartyLicenseExistencePolicy; |
| 847 | } |
| 848 | |
brandjon | 79712cb | 2019-12-04 10:01:17 -0800 | [diff] [blame] | 849 | /** Returns all registered {@link Fragment} classes. */ |
| 850 | public ImmutableSortedSet<Class<? extends Fragment>> getAllFragments() { |
| 851 | ImmutableSortedSet.Builder<Class<? extends Fragment>> fragmentsBuilder = |
janakr | 9fcef03 | 2018-01-23 13:38:24 -0800 | [diff] [blame] | 852 | ImmutableSortedSet.orderedBy(BuildConfiguration.lexicalFragmentSorter); |
gregce | 4ed65b0 | 2020-11-18 07:06:25 -0800 | [diff] [blame] | 853 | fragmentsBuilder.addAll(getConfigurationFragments()); |
lberki | 78651d4 | 2018-04-06 01:52:58 -0700 | [diff] [blame] | 854 | fragmentsBuilder.addAll(getUniversalFragments()); |
Greg Estren | c396f9c | 2016-10-04 18:01:01 +0000 | [diff] [blame] | 855 | return fragmentsBuilder.build(); |
| 856 | } |
brandjon | 32d359f | 2018-01-22 10:50:45 -0800 | [diff] [blame] | 857 | |
gregce | ca48e9a | 2020-04-14 08:54:38 -0700 | [diff] [blame] | 858 | /** Returns a reserved set of action mnemonics. These cannot be used from a Starlark action. */ |
lberki | 406199f | 2018-04-09 03:16:19 -0700 | [diff] [blame] | 859 | public ImmutableSet<String> getReservedActionMnemonics() { |
| 860 | return reservedActionMnemonics; |
| 861 | } |
| 862 | |
lberki | 8626623 | 2018-04-11 00:33:42 -0700 | [diff] [blame] | 863 | public BuildConfiguration.ActionEnvironmentProvider getActionEnvironmentProvider() { |
| 864 | return actionEnvironmentProvider; |
| 865 | } |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 866 | } |