blob: 2d13abd9ec3fe5766299ef346e7309f18f189d3b [file] [log] [blame]
Damien Martin-Guillerezf88f4d82015-09-25 13:56:55 +00001// Copyright 2014 The Bazel Authors. All rights reserved.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +01002//
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.
14package com.google.devtools.build.lib.analysis;
15
Googler58505032015-03-19 16:12:34 +000016import static com.google.common.base.Preconditions.checkArgument;
17import static com.google.common.base.Preconditions.checkNotNull;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010018import static com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType.ABSTRACT;
19import static com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType.TEST;
20
Ulf Adams345e15e2016-07-07 13:27:28 +000021import com.google.common.base.Preconditions;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010022import com.google.common.cache.CacheBuilder;
23import com.google.common.cache.CacheLoader;
24import com.google.common.cache.LoadingCache;
Cal Peyserf296e872016-05-03 17:36:54 +000025import com.google.common.collect.ImmutableBiMap;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010026import com.google.common.collect.ImmutableList;
27import com.google.common.collect.ImmutableMap;
Greg Estrenc396f9c2016-10-04 18:01:01 +000028import com.google.common.collect.ImmutableSet;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010029import com.google.devtools.build.lib.analysis.buildinfo.BuildInfoFactory;
Greg Estrenc5a352f2015-11-13 17:25:36 +000030import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010031import com.google.devtools.build.lib.analysis.config.BuildOptions;
32import com.google.devtools.build.lib.analysis.config.ConfigurationFragmentFactory;
33import com.google.devtools.build.lib.analysis.config.DefaultsPackage;
gregce490b0952017-07-06 18:44:38 -040034import com.google.devtools.build.lib.analysis.config.DynamicTransitionMapper;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010035import com.google.devtools.build.lib.analysis.config.FragmentOptions;
Lukacs Berki6e91eb92015-09-21 09:12:37 +000036import com.google.devtools.build.lib.cmdline.Label;
Lukacs Berkia6434362015-09-15 13:56:14 +000037import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
Michael Staib8618b9d2016-09-16 19:36:49 +000038import com.google.devtools.build.lib.cmdline.PackageIdentifier;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010039import com.google.devtools.build.lib.events.EventHandler;
40import com.google.devtools.build.lib.graph.Digraph;
41import com.google.devtools.build.lib.graph.Node;
42import com.google.devtools.build.lib.packages.Attribute;
Luis Fernando Pino Duquee82713d2016-04-26 16:22:38 +000043import com.google.devtools.build.lib.packages.NativeAspectClass;
Michael Staib8618b9d2016-09-16 19:36:49 +000044import com.google.devtools.build.lib.packages.NonconfigurableAttributeMapper;
45import com.google.devtools.build.lib.packages.OutputFile;
46import com.google.devtools.build.lib.packages.Rule;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010047import com.google.devtools.build.lib.packages.RuleClass;
48import com.google.devtools.build.lib.packages.RuleClassProvider;
Michael Staib8618b9d2016-09-16 19:36:49 +000049import com.google.devtools.build.lib.packages.RuleErrorConsumer;
50import com.google.devtools.build.lib.packages.Target;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010051import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory;
52import com.google.devtools.build.lib.rules.SkylarkModules;
Janak Ramakrishnanb92c0972016-03-23 16:47:13 +000053import com.google.devtools.build.lib.runtime.proto.InvocationPolicyOuterClass.InvocationPolicy;
Francois-Rene Rideau89312fb2015-09-10 18:53:03 +000054import com.google.devtools.build.lib.syntax.Environment;
55import com.google.devtools.build.lib.syntax.Environment.Extension;
Luis Fernando Pino Duque3fedf9e2016-04-28 15:47:29 +000056import com.google.devtools.build.lib.syntax.Environment.Phase;
Francois-Rene Rideau89312fb2015-09-10 18:53:03 +000057import com.google.devtools.build.lib.syntax.Mutability;
brandjonb712f332017-04-29 16:03:32 +020058import com.google.devtools.build.lib.syntax.SkylarkSemanticsOptions;
Laurent Le Bruna31bc4e2016-10-27 12:48:22 +000059import com.google.devtools.build.lib.syntax.SkylarkUtils;
Michael Staib8618b9d2016-09-16 19:36:49 +000060import com.google.devtools.build.lib.syntax.Type;
brandjonb712f332017-04-29 16:03:32 +020061import com.google.devtools.common.options.Options;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010062import com.google.devtools.common.options.OptionsClassProvider;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010063import java.lang.reflect.Constructor;
64import java.lang.reflect.InvocationTargetException;
65import java.util.ArrayList;
Kristina Chodorow8612a272015-12-14 15:37:24 +000066import java.util.Collection;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010067import java.util.HashMap;
68import java.util.List;
69import java.util.Map;
Greg Estrenc396f9c2016-10-04 18:01:01 +000070import java.util.Set;
Ulf Adams345e15e2016-07-07 13:27:28 +000071import java.util.TreeMap;
Ulf Adams345e15e2016-07-07 13:27:28 +000072import javax.annotation.Nullable;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010073
74/**
75 * Knows about every rule Blaze supports and the associated configuration options.
76 *
77 * <p>This class is initialized on server startup and the set of rules, build info factories
78 * and configuration options is guarantees not to change over the life time of the Blaze server.
79 */
80public class ConfiguredRuleClassProvider implements RuleClassProvider {
Kristina Chodorow8612a272015-12-14 15:37:24 +000081
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010082 /**
83 * Custom dependency validation logic.
84 */
Kristina Chodorow8612a272015-12-14 15:37:24 +000085 public interface PrerequisiteValidator {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010086 /**
87 * Checks whether the rule in {@code contextBuilder} is allowed to depend on
88 * {@code prerequisite} through the attribute {@code attribute}.
89 *
90 * <p>Can be used for enforcing any organization-specific policies about the layout of the
91 * workspace.
92 */
93 void validate(
94 RuleContext.Builder contextBuilder, ConfiguredTarget prerequisite, Attribute attribute);
95 }
96
Michael Staib8618b9d2016-09-16 19:36:49 +000097 /** Validator to check for and warn on the deprecation of dependencies. */
98 public static final class DeprecationValidator implements PrerequisiteValidator {
99 /** Checks if the given prerequisite is deprecated and prints a warning if so. */
100 @Override
101 public void validate(
102 RuleContext.Builder contextBuilder, ConfiguredTarget prerequisite, Attribute attribute) {
103 validateDirectPrerequisiteForDeprecation(
Michael Staib2707a882016-09-16 21:06:40 +0000104 contextBuilder, contextBuilder.getRule(), prerequisite, contextBuilder.forAspect());
Michael Staib8618b9d2016-09-16 19:36:49 +0000105 }
106
107 /**
108 * Returns whether two packages are considered the same for purposes of deprecation warnings.
109 * Dependencies within the same package do not print deprecation warnings; a package in the
110 * javatests directory may also depend on its corresponding java package without a warning.
111 */
112 public static boolean isSameLogicalPackage(
113 PackageIdentifier thisPackage, PackageIdentifier prerequisitePackage) {
114 if (thisPackage.equals(prerequisitePackage)) {
115 // If the packages are equal, they are the same logical package (and just the same package).
116 return true;
117 }
118 if (!thisPackage.getRepository().equals(prerequisitePackage.getRepository())) {
119 // If the packages are in different repositories, they are not the same logical package.
120 return false;
121 }
122 // If the packages are in the same repository, it's allowed iff this package is the javatests
123 // companion to the prerequisite java package.
124 String thisPackagePath = thisPackage.getPackageFragment().getPathString();
125 String prerequisitePackagePath = prerequisitePackage.getPackageFragment().getPathString();
126 return thisPackagePath.startsWith("javatests/")
127 && prerequisitePackagePath.startsWith("java/")
128 && thisPackagePath.substring("javatests/".length()).equals(
129 prerequisitePackagePath.substring("java/".length()));
130 }
131
132 /** Returns whether a deprecation warning should be printed for the prerequisite described. */
133 private static boolean shouldEmitDeprecationWarningFor(
134 String thisDeprecation, PackageIdentifier thisPackage,
Michael Staib2707a882016-09-16 21:06:40 +0000135 String prerequisiteDeprecation, PackageIdentifier prerequisitePackage,
136 boolean forAspect) {
Michael Staib8618b9d2016-09-16 19:36:49 +0000137 // Don't report deprecation edges from javatests to java or within a package;
138 // otherwise tests of deprecated code generate nuisance warnings.
Michael Staib2707a882016-09-16 21:06:40 +0000139 // Don't report deprecation if the current target is also deprecated,
140 // or if the current context is evaluating an aspect,
141 // as the base target would have already printed the deprecation warnings.
142 return (!forAspect
143 && prerequisiteDeprecation != null
Michael Staib8618b9d2016-09-16 19:36:49 +0000144 && !isSameLogicalPackage(thisPackage, prerequisitePackage)
145 && thisDeprecation == null);
146 }
147
148 /** Checks if the given prerequisite is deprecated and prints a warning if so. */
149 public static void validateDirectPrerequisiteForDeprecation(
Michael Staib2707a882016-09-16 21:06:40 +0000150 RuleErrorConsumer errors, Rule rule, ConfiguredTarget prerequisite, boolean forAspect) {
Michael Staib8618b9d2016-09-16 19:36:49 +0000151 Target prerequisiteTarget = prerequisite.getTarget();
152 Label prerequisiteLabel = prerequisiteTarget.getLabel();
153 PackageIdentifier thatPackage = prerequisiteLabel.getPackageIdentifier();
154 PackageIdentifier thisPackage = rule.getLabel().getPackageIdentifier();
155
156 if (prerequisiteTarget instanceof Rule) {
157 Rule prerequisiteRule = (Rule) prerequisiteTarget;
158 String thisDeprecation =
159 NonconfigurableAttributeMapper.of(rule).get("deprecation", Type.STRING);
160 String thatDeprecation =
161 NonconfigurableAttributeMapper.of(prerequisiteRule).get("deprecation", Type.STRING);
162 if (shouldEmitDeprecationWarningFor(
Michael Staib2707a882016-09-16 21:06:40 +0000163 thisDeprecation, thisPackage, thatDeprecation, thatPackage, forAspect)) {
Michael Staib8618b9d2016-09-16 19:36:49 +0000164 errors.ruleWarning("target '" + rule.getLabel() + "' depends on deprecated target '"
165 + prerequisiteLabel + "': " + thatDeprecation);
166 }
167 }
168
169 if (prerequisiteTarget instanceof OutputFile) {
170 Rule generatingRule = ((OutputFile) prerequisiteTarget).getGeneratingRule();
171 String thisDeprecation =
172 NonconfigurableAttributeMapper.of(rule).get("deprecation", Type.STRING);
173 String thatDeprecation =
174 NonconfigurableAttributeMapper.of(generatingRule).get("deprecation", Type.STRING);
175 if (shouldEmitDeprecationWarningFor(
Michael Staib2707a882016-09-16 21:06:40 +0000176 thisDeprecation, thisPackage, thatDeprecation, thatPackage, forAspect)) {
Michael Staib8618b9d2016-09-16 19:36:49 +0000177 errors.ruleWarning("target '" + rule.getLabel() + "' depends on the output file "
178 + prerequisiteLabel + " of a deprecated rule " + generatingRule.getLabel()
179 + "': " + thatDeprecation);
180 }
181 }
182 }
183 }
184
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100185 /**
Ulf Adamse3b4af22016-10-18 12:51:15 +0000186 * A coherent set of options, fragments, aspects and rules; each of these may declare a dependency
187 * on other such sets.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100188 */
Ulf Adamse3b4af22016-10-18 12:51:15 +0000189 public static interface RuleSet {
190 /** Add stuff to the configured rule class provider builder. */
191 void init(ConfiguredRuleClassProvider.Builder builder);
192
193 /** List of required modules. */
194 ImmutableList<RuleSet> requires();
195 }
196
197 /** Builder for {@link ConfiguredRuleClassProvider}. */
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100198 public static class Builder implements RuleDefinitionEnvironment {
Ulf Adamsf04cbe32016-10-28 13:23:41 +0000199 private String productName;
Damien Martin-Guillerez585c87b2016-03-31 08:24:37 +0000200 private final StringBuilder defaultWorkspaceFilePrefix = new StringBuilder();
201 private final StringBuilder defaultWorkspaceFileSuffix = new StringBuilder();
John Fielda97e17f2015-11-13 02:19:52 +0000202 private Label preludeLabel;
Ulf Adamsd13207c2015-09-04 14:53:43 +0000203 private String runfilesPrefix;
Luis Fernando Pino Duque90511e12016-01-28 10:49:58 +0000204 private String toolsRepository;
Ulf Adams8d0be892016-10-14 13:56:46 +0000205 private final List<ConfigurationFragmentFactory> configurationFragmentFactories =
206 new ArrayList<>();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100207 private final List<BuildInfoFactory> buildInfoFactories = new ArrayList<>();
208 private final List<Class<? extends FragmentOptions>> configurationOptions = new ArrayList<>();
209
210 private final Map<String, RuleClass> ruleClassMap = new HashMap<>();
Luis Fernando Pino Duque2b0b5cc2016-04-26 09:31:27 +0000211 private final Map<String, RuleDefinition> ruleDefinitionMap = new HashMap<>();
Luis Fernando Pino Duquee82713d2016-04-26 16:22:38 +0000212 private final Map<String, NativeAspectClass> nativeAspectClassMap =
Dmitry Lomove2033b12015-08-19 16:57:49 +0000213 new HashMap<>();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100214 private final Map<Class<? extends RuleDefinition>, RuleClass> ruleMap = new HashMap<>();
215 private final Digraph<Class<? extends RuleDefinition>> dependencyGraph =
216 new Digraph<>();
217 private ConfigurationCollectionFactory configurationCollectionFactory;
gregce490b0952017-07-06 18:44:38 -0400218 private ImmutableMap.Builder<Attribute.Transition, Attribute.Transition> dynamicTransitionMaps
219 = ImmutableMap.builder();
Greg Estrenc5a352f2015-11-13 17:25:36 +0000220 private Class<? extends BuildConfiguration.Fragment> universalFragment;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100221 private PrerequisiteValidator prerequisiteValidator;
Ulf Adamsfd53b612016-07-06 07:23:59 +0000222 private ImmutableMap.Builder<String, Object> skylarkAccessibleTopLevels =
223 ImmutableMap.builder();
Damien Martin-Guillerezf81c6752016-02-15 10:50:12 +0000224 private ImmutableList.Builder<Class<?>> skylarkModules =
225 ImmutableList.<Class<?>>builder().addAll(SkylarkModules.MODULES);
Ulf Adamsfd53b612016-07-06 07:23:59 +0000226 private ImmutableBiMap.Builder<String, Class<? extends TransitiveInfoProvider>>
227 registeredSkylarkProviders = ImmutableBiMap.builder();
Ulf Adams345e15e2016-07-07 13:27:28 +0000228 private Map<String, String> platformRegexps = new TreeMap<>();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100229
Yun Pengc2c938a2017-07-28 10:22:57 +0200230 // TODO(pcloudy): Remove this field after Bazel rule definitions are not used internally.
231 private String nativeLauncherLabel;
232
Ulf Adamsf04cbe32016-10-28 13:23:41 +0000233 public Builder setProductName(String productName) {
234 this.productName = productName;
235 return this;
236 }
237
Yun Pengc2c938a2017-07-28 10:22:57 +0200238 public Builder setNativeLauncherLabel(String label) {
239 this.nativeLauncherLabel = label;
240 return this;
241 }
242
Damien Martin-Guillerez585c87b2016-03-31 08:24:37 +0000243 public void addWorkspaceFilePrefix(String contents) {
244 defaultWorkspaceFilePrefix.append(contents);
245 }
246
247 public void addWorkspaceFileSuffix(String contents) {
248 defaultWorkspaceFileSuffix.append(contents);
Kristina Chodorowbc4b4b12015-02-11 15:54:50 +0000249 }
250
John Fielda97e17f2015-11-13 02:19:52 +0000251 public Builder setPrelude(String preludeLabelString) {
252 try {
253 this.preludeLabel = Label.parseAbsolute(preludeLabelString);
254 } catch (LabelSyntaxException e) {
255 String errorMsg =
256 String.format("Prelude label '%s' is invalid: %s", preludeLabelString, e.getMessage());
257 throw new IllegalArgumentException(errorMsg);
258 }
Ulf Adamsfdfdd922015-09-01 08:36:29 +0000259 return this;
260 }
261
Ulf Adamsd13207c2015-09-04 14:53:43 +0000262 public Builder setRunfilesPrefix(String runfilesPrefix) {
263 this.runfilesPrefix = runfilesPrefix;
264 return this;
265 }
Luis Fernando Pino Duque18d13222016-02-08 14:55:28 +0000266
Luis Fernando Pino Duque90511e12016-01-28 10:49:58 +0000267 public Builder setToolsRepository(String toolsRepository) {
268 this.toolsRepository = toolsRepository;
269 return this;
270 }
Ulf Adamsd13207c2015-09-04 14:53:43 +0000271
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100272 public Builder setPrerequisiteValidator(PrerequisiteValidator prerequisiteValidator) {
273 this.prerequisiteValidator = prerequisiteValidator;
274 return this;
275 }
276
277 public Builder addBuildInfoFactory(BuildInfoFactory factory) {
278 buildInfoFactories.add(factory);
279 return this;
280 }
281
Googler58505032015-03-19 16:12:34 +0000282 public Builder addRuleDefinition(RuleDefinition ruleDefinition) {
283 Class<? extends RuleDefinition> ruleDefinitionClass = ruleDefinition.getClass();
Luis Fernando Pino Duque2b0b5cc2016-04-26 09:31:27 +0000284 ruleDefinitionMap.put(ruleDefinitionClass.getName(), ruleDefinition);
Googler58505032015-03-19 16:12:34 +0000285 dependencyGraph.createNode(ruleDefinitionClass);
286 for (Class<? extends RuleDefinition> ancestor : ruleDefinition.getMetadata().ancestors()) {
287 dependencyGraph.addEdge(ancestor, ruleDefinitionClass);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100288 }
289
290 return this;
291 }
292
Luis Fernando Pino Duquee82713d2016-04-26 16:22:38 +0000293 public Builder addNativeAspectClass(NativeAspectClass aspectFactoryClass) {
294 nativeAspectClassMap.put(aspectFactoryClass.getName(), aspectFactoryClass);
Dmitry Lomove2033b12015-08-19 16:57:49 +0000295 return this;
296 }
297
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100298 public Builder addConfigurationOptions(Class<? extends FragmentOptions> configurationOptions) {
299 this.configurationOptions.add(configurationOptions);
300 return this;
301 }
302
Ulf Adamsbbcfa2f2016-10-18 07:24:13 +0000303 /**
304 * Adds an options class and a corresponding factory. There's usually a 1:1:1 correspondence
305 * between option classes, factories, and fragments, such that the factory depends only on the
306 * options class and creates the fragment. This method provides a convenient way of adding both
307 * the options class and the factory in a single call.
308 */
309 public Builder addConfig(
310 Class<? extends FragmentOptions> options, ConfigurationFragmentFactory factory) {
311 // Enforce that the factory requires the options.
312 Preconditions.checkState(factory.requiredOptions().contains(options));
313 this.configurationOptions.add(options);
314 this.configurationFragmentFactories.add(factory);
315 return this;
316 }
317
Ulf Adams378abb22016-06-22 16:01:57 +0000318 public Builder addConfigurationOptions(
319 Collection<Class<? extends FragmentOptions>> optionsClasses) {
320 this.configurationOptions.addAll(optionsClasses);
321 return this;
322 }
323
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100324 public Builder addConfigurationFragment(ConfigurationFragmentFactory factory) {
Ulf Adams8d0be892016-10-14 13:56:46 +0000325 configurationFragmentFactories.add(factory);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100326 return this;
327 }
328
329 public Builder setConfigurationCollectionFactory(ConfigurationCollectionFactory factory) {
330 this.configurationCollectionFactory = factory;
331 return this;
332 }
333
gregce490b0952017-07-06 18:44:38 -0400334 public Builder addDynamicTransitionMaps(Map<Attribute.Transition, Attribute.Transition> maps) {
335 dynamicTransitionMaps.putAll(maps);
336 return this;
337 }
338
Greg Estrenc5a352f2015-11-13 17:25:36 +0000339 public Builder setUniversalConfigurationFragment(
340 Class<? extends BuildConfiguration.Fragment> fragment) {
341 this.universalFragment = fragment;
342 return this;
343 }
344
Ulf Adamsfd53b612016-07-06 07:23:59 +0000345 public Builder addSkylarkAccessibleTopLevels(String name, Object object) {
346 this.skylarkAccessibleTopLevels.put(name, object);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100347 return this;
348 }
349
Damien Martin-Guillerezf81c6752016-02-15 10:50:12 +0000350 public Builder addSkylarkModule(Class<?>... modules) {
351 this.skylarkModules.add(modules);
352 return this;
353 }
354
Cal Peyserf296e872016-05-03 17:36:54 +0000355 /**
Ulf Adams345e15e2016-07-07 13:27:28 +0000356 * Do not use - this only exists for backwards compatibility! Platform regexps are part of a
357 * legacy mechanism - {@code vardef} - that is not exposed in Bazel.
358 *
359 * <p>{@code vardef} needs explicit support in the rule implementations, and cannot express
360 * conditional dependencies, only conditional attribute values. This mechanism will be
361 * supplanted by configuration dependent attributes, and its effect can usually also be achieved
362 * with select().
363 *
364 * <p>This is a map of platform names to regexps. When a name is used as the third argument to
365 * {@code vardef}, the corresponding regexp is used to match on the C++ abi, and the variable is
366 * only set to that value if the regexp matches. For example, the entry
367 * {@code "oldlinux": "i[34]86-libc[345]-linux"} might define a set of platforms representing
368 * certain older linux releases.
369 */
370 public Builder addPlatformRegexps(Map<String, String> platformRegexps) {
371 this.platformRegexps.putAll(Preconditions.checkNotNull(platformRegexps));
372 return this;
373 }
374
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100375 private RuleConfiguredTargetFactory createFactory(
376 Class<? extends RuleConfiguredTargetFactory> factoryClass) {
377 try {
378 Constructor<? extends RuleConfiguredTargetFactory> ctor = factoryClass.getConstructor();
379 return ctor.newInstance();
380 } catch (NoSuchMethodException | IllegalAccessException | InstantiationException
381 | InvocationTargetException e) {
382 throw new IllegalStateException(e);
383 }
384 }
385
386 private RuleClass commitRuleDefinition(Class<? extends RuleDefinition> definitionClass) {
Luis Fernando Pino Duque2b0b5cc2016-04-26 09:31:27 +0000387 RuleDefinition instance = checkNotNull(ruleDefinitionMap.get(definitionClass.getName()),
Googler58505032015-03-19 16:12:34 +0000388 "addRuleDefinition(new %s()) should be called before build()", definitionClass.getName());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100389
Googler58505032015-03-19 16:12:34 +0000390 RuleDefinition.Metadata metadata = instance.getMetadata();
391 checkArgument(ruleClassMap.get(metadata.name()) == null, metadata.name());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100392
Googler58505032015-03-19 16:12:34 +0000393 List<Class<? extends RuleDefinition>> ancestors = metadata.ancestors();
394
395 checkArgument(
396 metadata.type() == ABSTRACT ^ metadata.factoryClass()
397 != RuleConfiguredTargetFactory.class);
398 checkArgument(
399 (metadata.type() != TEST)
400 || ancestors.contains(BaseRuleClasses.TestBaseRule.class));
401
402 RuleClass[] ancestorClasses = new RuleClass[ancestors.size()];
403 for (int i = 0; i < ancestorClasses.length; i++) {
404 ancestorClasses[i] = ruleMap.get(ancestors.get(i));
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100405 if (ancestorClasses[i] == null) {
406 // Ancestors should have been initialized by now
Googler58505032015-03-19 16:12:34 +0000407 throw new IllegalStateException("Ancestor " + ancestors.get(i) + " of "
408 + metadata.name() + " is not initialized");
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100409 }
410 }
411
412 RuleConfiguredTargetFactory factory = null;
Googler58505032015-03-19 16:12:34 +0000413 if (metadata.type() != ABSTRACT) {
414 factory = createFactory(metadata.factoryClass());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100415 }
416
417 RuleClass.Builder builder = new RuleClass.Builder(
Googler58505032015-03-19 16:12:34 +0000418 metadata.name(), metadata.type(), false, ancestorClasses);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100419 builder.factory(factory);
420 RuleClass ruleClass = instance.build(builder, this);
421 ruleMap.put(definitionClass, ruleClass);
422 ruleClassMap.put(ruleClass.getName(), ruleClass);
Luis Fernando Pino Duque2b0b5cc2016-04-26 09:31:27 +0000423 ruleDefinitionMap.put(ruleClass.getName(), instance);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100424
425 return ruleClass;
426 }
427
428 public ConfiguredRuleClassProvider build() {
429 for (Node<Class<? extends RuleDefinition>> ruleDefinition :
Googler58505032015-03-19 16:12:34 +0000430 dependencyGraph.getTopologicalOrder()) {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100431 commitRuleDefinition(ruleDefinition.getLabel());
432 }
433
434 return new ConfiguredRuleClassProvider(
Ulf Adamsf04cbe32016-10-28 13:23:41 +0000435 productName,
John Fielda97e17f2015-11-13 02:19:52 +0000436 preludeLabel,
Ulf Adamsd13207c2015-09-04 14:53:43 +0000437 runfilesPrefix,
Luis Fernando Pino Duque90511e12016-01-28 10:49:58 +0000438 toolsRepository,
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100439 ImmutableMap.copyOf(ruleClassMap),
440 ImmutableMap.copyOf(ruleDefinitionMap),
Luis Fernando Pino Duquee82713d2016-04-26 16:22:38 +0000441 ImmutableMap.copyOf(nativeAspectClassMap),
Damien Martin-Guillerez585c87b2016-03-31 08:24:37 +0000442 defaultWorkspaceFilePrefix.toString(),
443 defaultWorkspaceFileSuffix.toString(),
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100444 ImmutableList.copyOf(buildInfoFactories),
445 ImmutableList.copyOf(configurationOptions),
Ulf Adams8d0be892016-10-14 13:56:46 +0000446 ImmutableList.copyOf(configurationFragmentFactories),
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100447 configurationCollectionFactory,
gregce490b0952017-07-06 18:44:38 -0400448 new DynamicTransitionMapper(dynamicTransitionMaps.build()),
Greg Estrenc5a352f2015-11-13 17:25:36 +0000449 universalFragment,
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100450 prerequisiteValidator,
Ulf Adamsfd53b612016-07-06 07:23:59 +0000451 skylarkAccessibleTopLevels.build(),
dslomovf6a7e5a2017-07-05 07:23:31 -0400452 skylarkModules.build());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100453 }
454
455 @Override
456 public Label getLabel(String labelValue) {
457 return LABELS.getUnchecked(labelValue);
458 }
Luis Fernando Pino Duque18d13222016-02-08 14:55:28 +0000459
Luis Fernando Pino Duque90511e12016-01-28 10:49:58 +0000460 @Override
Luis Fernando Pino Duque18d13222016-02-08 14:55:28 +0000461 public Label getToolsLabel(String labelValue) {
462 return getLabel(toolsRepository + labelValue);
Luis Fernando Pino Duque90511e12016-01-28 10:49:58 +0000463 }
Luis Fernando Pino Duque207ba4a2016-07-01 15:07:23 +0000464
465 @Override
Yun Pengc2c938a2017-07-28 10:22:57 +0200466 public Label getLauncherLabel() {
467 if (nativeLauncherLabel == null) {
468 return null;
469 }
470 return getToolsLabel(nativeLauncherLabel);
471 }
472
473 @Override
Luis Fernando Pino Duque207ba4a2016-07-01 15:07:23 +0000474 public String getToolsRepository() {
475 return toolsRepository;
476 }
Ulf Adams345e15e2016-07-07 13:27:28 +0000477
478 @Nullable
479 public Map<String, String> getPlatformRegexps() {
480 return platformRegexps.isEmpty() ? null : ImmutableMap.copyOf(platformRegexps);
481 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100482 }
483
484 /**
485 * Used to make the label instances unique, so that we don't create a new
486 * instance for every rule.
487 */
Francois-Rene Rideau6e7160d2015-08-26 17:22:35 +0000488 private static final LoadingCache<String, Label> LABELS = CacheBuilder.newBuilder().build(
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100489 new CacheLoader<String, Label>() {
490 @Override
491 public Label load(String from) {
492 try {
493 return Label.parseAbsolute(from);
Lukacs Berkia6434362015-09-15 13:56:14 +0000494 } catch (LabelSyntaxException e) {
Philipp Wollermannf2512bb2015-10-22 20:33:44 +0000495 throw new IllegalArgumentException(from, e);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100496 }
497 }
498 });
499
Ulf Adamsf04cbe32016-10-28 13:23:41 +0000500 private final String productName;
501
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100502 /**
Damien Martin-Guillerez585c87b2016-03-31 08:24:37 +0000503 * Default content that should be added at the beginning of the WORKSPACE file.
Kristina Chodorowbc4b4b12015-02-11 15:54:50 +0000504 */
Damien Martin-Guillerez585c87b2016-03-31 08:24:37 +0000505 private final String defaultWorkspaceFilePrefix;
506
507 /**
508 * Default content that should be added at the end of the WORKSPACE file.
509 */
510 private final String defaultWorkspaceFileSuffix;
511
Kristina Chodorowbc4b4b12015-02-11 15:54:50 +0000512
513 /**
John Fielda97e17f2015-11-13 02:19:52 +0000514 * Label for the prelude file.
Ulf Adamsfdfdd922015-09-01 08:36:29 +0000515 */
John Fielda97e17f2015-11-13 02:19:52 +0000516 private final Label preludeLabel;
Ulf Adamsfdfdd922015-09-01 08:36:29 +0000517
518 /**
Ulf Adamsd13207c2015-09-04 14:53:43 +0000519 * The default runfiles prefix.
520 */
521 private final String runfilesPrefix;
Luis Fernando Pino Duque18d13222016-02-08 14:55:28 +0000522
Luis Fernando Pino Duque90511e12016-01-28 10:49:58 +0000523 /**
524 * The path to the tools repository.
525 */
526 private final String toolsRepository;
Ulf Adamsd13207c2015-09-04 14:53:43 +0000527
528 /**
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100529 * Maps rule class name to the metaclass instance for that rule.
530 */
531 private final ImmutableMap<String, RuleClass> ruleClassMap;
532
533 /**
Luis Fernando Pino Duque2b0b5cc2016-04-26 09:31:27 +0000534 * Maps rule class name to the rule definition objects.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100535 */
Luis Fernando Pino Duque2b0b5cc2016-04-26 09:31:27 +0000536 private final ImmutableMap<String, RuleDefinition> ruleDefinitionMap;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100537
538 /**
Dmitry Lomove2033b12015-08-19 16:57:49 +0000539 * Maps aspect name to the aspect factory meta class.
540 */
Luis Fernando Pino Duquee82713d2016-04-26 16:22:38 +0000541 private final ImmutableMap<String, NativeAspectClass> nativeAspectClassMap;
Dmitry Lomove2033b12015-08-19 16:57:49 +0000542
543 /**
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100544 * The configuration options that affect the behavior of the rules.
545 */
546 private final ImmutableList<Class<? extends FragmentOptions>> configurationOptions;
547
Ulf Adams8d0be892016-10-14 13:56:46 +0000548 /** The set of configuration fragment factories. */
549 private final ImmutableList<ConfigurationFragmentFactory> configurationFragmentFactories;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100550
551 /**
552 * The factory that creates the configuration collection.
553 */
554 private final ConfigurationCollectionFactory configurationCollectionFactory;
555
Greg Estrenc5a352f2015-11-13 17:25:36 +0000556 /**
gregce490b0952017-07-06 18:44:38 -0400557 * The dynamic configuration transition mapper.
558 */
559 private final DynamicTransitionMapper dynamicTransitionMapper;
560
561 /**
Greg Estrenc5a352f2015-11-13 17:25:36 +0000562 * A configuration fragment that should be available to all rules even when they don't
563 * explicitly require it.
564 */
565 private final Class<? extends BuildConfiguration.Fragment> universalFragment;
566
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100567 private final ImmutableList<BuildInfoFactory> buildInfoFactories;
568
569 private final PrerequisiteValidator prerequisiteValidator;
570
Francois-Rene Rideau89312fb2015-09-10 18:53:03 +0000571 private final Environment.Frame globals;
Janak Ramakrishnanb6e33bc2015-09-06 21:05:23 +0000572
Kristina Chodorow8612a272015-12-14 15:37:24 +0000573 private ConfiguredRuleClassProvider(
Ulf Adamsf04cbe32016-10-28 13:23:41 +0000574 String productName,
John Fielda97e17f2015-11-13 02:19:52 +0000575 Label preludeLabel,
Ulf Adamsd13207c2015-09-04 14:53:43 +0000576 String runfilesPrefix,
Luis Fernando Pino Duque90511e12016-01-28 10:49:58 +0000577 String toolsRepository,
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100578 ImmutableMap<String, RuleClass> ruleClassMap,
Luis Fernando Pino Duque2b0b5cc2016-04-26 09:31:27 +0000579 ImmutableMap<String, RuleDefinition> ruleDefinitionMap,
Luis Fernando Pino Duquee82713d2016-04-26 16:22:38 +0000580 ImmutableMap<String, NativeAspectClass> nativeAspectClassMap,
Damien Martin-Guillerez585c87b2016-03-31 08:24:37 +0000581 String defaultWorkspaceFilePrefix,
582 String defaultWorkspaceFileSuffix,
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100583 ImmutableList<BuildInfoFactory> buildInfoFactories,
584 ImmutableList<Class<? extends FragmentOptions>> configurationOptions,
585 ImmutableList<ConfigurationFragmentFactory> configurationFragments,
586 ConfigurationCollectionFactory configurationCollectionFactory,
gregce490b0952017-07-06 18:44:38 -0400587 DynamicTransitionMapper dynamicTransitionMapper,
Greg Estrenc5a352f2015-11-13 17:25:36 +0000588 Class<? extends BuildConfiguration.Fragment> universalFragment,
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100589 PrerequisiteValidator prerequisiteValidator,
Dmitry Lomov899416d2016-04-22 12:40:30 +0000590 ImmutableMap<String, Object> skylarkAccessibleJavaClasses,
dslomovf6a7e5a2017-07-05 07:23:31 -0400591 ImmutableList<Class<?>> skylarkModules) {
Ulf Adamsf04cbe32016-10-28 13:23:41 +0000592 this.productName = productName;
John Fielda97e17f2015-11-13 02:19:52 +0000593 this.preludeLabel = preludeLabel;
Ulf Adamsd13207c2015-09-04 14:53:43 +0000594 this.runfilesPrefix = runfilesPrefix;
Luis Fernando Pino Duque90511e12016-01-28 10:49:58 +0000595 this.toolsRepository = toolsRepository;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100596 this.ruleClassMap = ruleClassMap;
597 this.ruleDefinitionMap = ruleDefinitionMap;
Luis Fernando Pino Duquee82713d2016-04-26 16:22:38 +0000598 this.nativeAspectClassMap = nativeAspectClassMap;
Damien Martin-Guillerez585c87b2016-03-31 08:24:37 +0000599 this.defaultWorkspaceFilePrefix = defaultWorkspaceFilePrefix;
600 this.defaultWorkspaceFileSuffix = defaultWorkspaceFileSuffix;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100601 this.buildInfoFactories = buildInfoFactories;
602 this.configurationOptions = configurationOptions;
Ulf Adams8d0be892016-10-14 13:56:46 +0000603 this.configurationFragmentFactories = configurationFragments;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100604 this.configurationCollectionFactory = configurationCollectionFactory;
gregce490b0952017-07-06 18:44:38 -0400605 this.dynamicTransitionMapper = dynamicTransitionMapper;
Greg Estrenc5a352f2015-11-13 17:25:36 +0000606 this.universalFragment = universalFragment;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100607 this.prerequisiteValidator = prerequisiteValidator;
Damien Martin-Guillerezf81c6752016-02-15 10:50:12 +0000608 this.globals = createGlobals(skylarkAccessibleJavaClasses, skylarkModules);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100609 }
610
Ulf Adamsf04cbe32016-10-28 13:23:41 +0000611 public String getProductName() {
612 return productName;
613 }
614
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100615 public PrerequisiteValidator getPrerequisiteValidator() {
616 return prerequisiteValidator;
617 }
618
619 @Override
John Fielda97e17f2015-11-13 02:19:52 +0000620 public Label getPreludeLabel() {
621 return preludeLabel;
Ulf Adamsfdfdd922015-09-01 08:36:29 +0000622 }
623
624 @Override
Ulf Adamsd13207c2015-09-04 14:53:43 +0000625 public String getRunfilesPrefix() {
626 return runfilesPrefix;
627 }
Luis Fernando Pino Duque18d13222016-02-08 14:55:28 +0000628
Luis Fernando Pino Duque90511e12016-01-28 10:49:58 +0000629 @Override
630 public String getToolsRepository() {
631 return toolsRepository;
632 }
Ulf Adamsd13207c2015-09-04 14:53:43 +0000633
634 @Override
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100635 public Map<String, RuleClass> getRuleClassMap() {
636 return ruleClassMap;
637 }
638
Dmitry Lomove2033b12015-08-19 16:57:49 +0000639 @Override
Luis Fernando Pino Duquee82713d2016-04-26 16:22:38 +0000640 public Map<String, NativeAspectClass> getNativeAspectClassMap() {
641 return nativeAspectClassMap;
642 }
643
644 @Override
645 public NativeAspectClass getNativeAspectClass(String key) {
646 return nativeAspectClassMap.get(key);
Dmitry Lomove2033b12015-08-19 16:57:49 +0000647 }
648
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100649 /**
650 * Returns a list of build info factories that are needed for the supported languages.
651 */
652 public ImmutableList<BuildInfoFactory> getBuildInfoFactories() {
653 return buildInfoFactories;
654 }
655
656 /**
657 * Returns the set of configuration fragments provided by this module.
658 */
659 public ImmutableList<ConfigurationFragmentFactory> getConfigurationFragments() {
Ulf Adams8d0be892016-10-14 13:56:46 +0000660 return configurationFragmentFactories;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100661 }
662
663 /**
664 * Returns the set of configuration options that are supported in this module.
665 */
666 public ImmutableList<Class<? extends FragmentOptions>> getConfigurationOptions() {
667 return configurationOptions;
668 }
669
670 /**
671 * Returns the definition of the rule class definition with the specified name.
672 */
Luis Fernando Pino Duque2b0b5cc2016-04-26 09:31:27 +0000673 public RuleDefinition getRuleClassDefinition(String ruleClassName) {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100674 return ruleDefinitionMap.get(ruleClassName);
675 }
676
677 /**
678 * Returns the configuration collection creator.
679 */
680 public ConfigurationCollectionFactory getConfigurationCollectionFactory() {
681 return configurationCollectionFactory;
682 }
683
684 /**
gregce490b0952017-07-06 18:44:38 -0400685 * Returns the dynamic configuration transition mapper.
686 */
687 public DynamicTransitionMapper getDynamicTransitionMapper() {
688 return dynamicTransitionMapper;
689 }
690
691 /**
Greg Estrenc5a352f2015-11-13 17:25:36 +0000692 * Returns the configuration fragment that should be available to all rules even when they
693 * don't explicitly require it.
694 */
695 public Class<? extends BuildConfiguration.Fragment> getUniversalFragment() {
696 return universalFragment;
697 }
698
699 /**
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100700 * Returns the defaults package for the default settings.
701 */
Janak Ramakrishnanb92c0972016-03-23 16:47:13 +0000702 public String getDefaultsPackageContent(InvocationPolicy invocationPolicy) {
703 return DefaultsPackage.getDefaultsPackageContent(configurationOptions, invocationPolicy);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100704 }
705
706 /**
707 * Returns the defaults package for the given options taken from an optionsProvider.
708 */
709 public String getDefaultsPackageContent(OptionsClassProvider optionsProvider) {
710 return DefaultsPackage.getDefaultsPackageContent(
711 BuildOptions.of(configurationOptions, optionsProvider));
712 }
713
714 /**
715 * Creates a BuildOptions class for the given options taken from an optionsProvider.
716 */
717 public BuildOptions createBuildOptions(OptionsClassProvider optionsProvider) {
gregce9a3028c2017-07-26 00:19:10 +0200718 return BuildOptions.of(configurationOptions, optionsProvider);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100719 }
720
Francois-Rene Rideau89312fb2015-09-10 18:53:03 +0000721 private Environment.Frame createGlobals(
Dmitry Lomov899416d2016-04-22 12:40:30 +0000722 ImmutableMap<String, Object> skylarkAccessibleToplLevels,
Damien Martin-Guillerezf81c6752016-02-15 10:50:12 +0000723 ImmutableList<Class<?>> modules) {
Francois-Rene Rideau89312fb2015-09-10 18:53:03 +0000724 try (Mutability mutability = Mutability.create("ConfiguredRuleClassProvider globals")) {
725 Environment env = createSkylarkRuleClassEnvironment(
brandjonb712f332017-04-29 16:03:32 +0200726 mutability,
727 SkylarkModules.getGlobals(modules),
728 Options.getDefaults(SkylarkSemanticsOptions.class),
729 /*eventHandler=*/ null,
730 /*astFileContentHashCode=*/ null,
731 /*importMap=*/ null);
Dmitry Lomov899416d2016-04-22 12:40:30 +0000732 for (Map.Entry<String, Object> entry : skylarkAccessibleToplLevels.entrySet()) {
733 env.setup(entry.getKey(), entry.getValue());
Francois-Rene Rideau89312fb2015-09-10 18:53:03 +0000734 }
735 return env.getGlobals();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100736 }
Francois-Rene Rideau89312fb2015-09-10 18:53:03 +0000737 }
738
739 private Environment createSkylarkRuleClassEnvironment(
740 Mutability mutability,
741 Environment.Frame globals,
brandjonb712f332017-04-29 16:03:32 +0200742 SkylarkSemanticsOptions skylarkSemantics,
Francois-Rene Rideau89312fb2015-09-10 18:53:03 +0000743 EventHandler eventHandler,
744 String astFileContentHashCode,
John Field1ea7fc32015-12-22 19:37:19 +0000745 Map<String, Extension> importMap) {
Laurent Le Bruna31bc4e2016-10-27 12:48:22 +0000746 Environment env =
747 Environment.builder(mutability)
Laurent Le Bruna31bc4e2016-10-27 12:48:22 +0000748 .setGlobals(globals)
brandjonb712f332017-04-29 16:03:32 +0200749 .setSemantics(skylarkSemantics)
Laurent Le Bruna31bc4e2016-10-27 12:48:22 +0000750 .setEventHandler(eventHandler)
751 .setFileContentHashCode(astFileContentHashCode)
752 .setImportedExtensions(importMap)
753 .setPhase(Phase.LOADING)
754 .build();
755 SkylarkUtils.setToolsRepository(env, toolsRepository);
756 return env;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100757 }
758
759 @Override
Francois-Rene Rideau89312fb2015-09-10 18:53:03 +0000760 public Environment createSkylarkRuleClassEnvironment(
brandjonb712f332017-04-29 16:03:32 +0200761 Label extensionLabel,
762 Mutability mutability,
763 SkylarkSemanticsOptions skylarkSemantics,
Francois-Rene Rideau89312fb2015-09-10 18:53:03 +0000764 EventHandler eventHandler,
765 String astFileContentHashCode,
John Field1ea7fc32015-12-22 19:37:19 +0000766 Map<String, Extension> importMap) {
Francois-Rene Rideau89312fb2015-09-10 18:53:03 +0000767 return createSkylarkRuleClassEnvironment(
brandjonb712f332017-04-29 16:03:32 +0200768 mutability,
brandjoncc0f6a62017-05-08 13:19:21 -0400769 globals.withLabel(extensionLabel),
brandjonb712f332017-04-29 16:03:32 +0200770 skylarkSemantics,
771 eventHandler,
772 astFileContentHashCode,
773 importMap);
Janak Ramakrishnanb6e33bc2015-09-06 21:05:23 +0000774 }
775
Damien Martin-Guillerez585c87b2016-03-31 08:24:37 +0000776 @Override
777 public String getDefaultWorkspacePrefix() {
778 return defaultWorkspaceFilePrefix;
779 }
Francois-Rene Rideau89312fb2015-09-10 18:53:03 +0000780
Janak Ramakrishnanb6e33bc2015-09-06 21:05:23 +0000781 @Override
Damien Martin-Guillerez585c87b2016-03-31 08:24:37 +0000782 public String getDefaultWorkspaceSuffix() {
783 return defaultWorkspaceFileSuffix;
Kristina Chodorowbc4b4b12015-02-11 15:54:50 +0000784 }
Greg Estrenc396f9c2016-10-04 18:01:01 +0000785
786 /**
787 * Returns all registered {@link BuildConfiguration.Fragment} classes.
788 */
789 public Set<Class<? extends BuildConfiguration.Fragment>> getAllFragments() {
790 ImmutableSet.Builder<Class<? extends BuildConfiguration.Fragment>> fragmentsBuilder =
791 ImmutableSet.builder();
792 for (ConfigurationFragmentFactory factory : getConfigurationFragments()) {
793 fragmentsBuilder.add(factory.creates());
794 }
795 fragmentsBuilder.add(getUniversalFragment());
796 return fragmentsBuilder.build();
797 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100798}