diff options
Diffstat (limited to 'src/main/java/com/google/devtools/build')
5 files changed, 84 insertions, 20 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetBuilder.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetBuilder.java index a4a830e7cd..47d0eb3449 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetBuilder.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetBuilder.java @@ -396,11 +396,7 @@ public final class RuleConfiguredTargetBuilder { checkSkylarkObjectSafe(entry.getValue()); } return; - } else if (object instanceof ClassObject && !(object instanceof BuildConfiguration)) { - // We had to make BuildConfiguration implement ClassObject in order to allow access to - // individual fragments as fields. - // However, we don't want to expose it to the outside world, thus forcing us to add this - // explicit check here. + } else if (object instanceof ClassObject) { ClassObject struct = (ClassObject) object; for (String key : struct.getKeys()) { checkSkylarkObjectSafe(struct.getValue(key)); diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java index 92b3dbd89f..bddb2c2bb5 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java @@ -16,6 +16,7 @@ package com.google.devtools.build.lib.analysis; import com.google.common.base.Preconditions; import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableCollection; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableListMultimap; import com.google.common.collect.ImmutableMap; @@ -264,6 +265,16 @@ public final class RuleContext extends TargetContext return getConfiguration().getFragment(fragment); } + @Nullable + public Fragment getSkylarkFragment(String name) { + Class<? extends Fragment> fragmentClass = getConfiguration().getSkylarkFragmentByName(name); + return (fragmentClass == null) ? null : getFragment(fragmentClass); + } + + public ImmutableCollection<String> getSkylarkFragmentNames() { + return getConfiguration().getSkylarkFragmentNames(); + } + public <T extends Fragment> boolean isLegalFragment(Class<T> fragment) { return rule.getRuleClassObject().isLegalConfigurationFragment(fragment); } diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java index 8c3caa8e97..71f5175bb8 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java @@ -45,7 +45,6 @@ import com.google.devtools.build.lib.packages.Rule; import com.google.devtools.build.lib.packages.RuleClass; import com.google.devtools.build.lib.packages.Target; import com.google.devtools.build.lib.rules.test.TestActionBuilder; -import com.google.devtools.build.lib.syntax.ClassObject; import com.google.devtools.build.lib.syntax.Label; import com.google.devtools.build.lib.syntax.Label.SyntaxException; import com.google.devtools.build.lib.syntax.SkylarkCallable; @@ -108,7 +107,7 @@ import javax.annotation.Nullable; @SkylarkModule(name = "configuration", doc = "Data required for the analysis of a target that comes from targets that " + "depend on it and not targets that it depends on.") -public final class BuildConfiguration implements ClassObject { +public final class BuildConfiguration { /** * An interface for language-specific configurations. @@ -1929,21 +1928,11 @@ public final class BuildConfiguration implements ClassObject { return options.targetEnvironments; } - @Override - @Nullable - public Object getValue(String name) { - Class<? extends Fragment> fragmentClass = skylarkVisibleFragments.get(name); - return (fragmentClass == null) ? null : fragments.get(fragmentClass); + public Class<? extends Fragment> getSkylarkFragmentByName(String name) { + return skylarkVisibleFragments.get(name); } - @Override - public ImmutableCollection<String> getKeys() { + public ImmutableCollection<String> getSkylarkFragmentNames() { return skylarkVisibleFragments.keySet(); } - - @Override - @Nullable - public String errorMessage(String name) { - return String.format("There is no configuration fragment named '%s'", name); - } } diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/FragmentCollection.java b/src/main/java/com/google/devtools/build/lib/analysis/config/FragmentCollection.java new file mode 100644 index 0000000000..655aff90fa --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/analysis/config/FragmentCollection.java @@ -0,0 +1,58 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package com.google.devtools.build.lib.analysis.config; + +import com.google.common.base.Joiner; +import com.google.common.collect.ImmutableCollection; +import com.google.devtools.build.lib.analysis.RuleContext; +import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; +import com.google.devtools.build.lib.syntax.ClassObject; +import com.google.devtools.build.lib.syntax.SkylarkModule; + +import javax.annotation.Nullable; + +/** + * Represents a collection of configuration fragments in Skylark. + */ +@Immutable +@SkylarkModule(name = "fragments", doc = "Allows access to configuration fragments.") +public class FragmentCollection implements ClassObject { + private final RuleContext ruleContext; + + public FragmentCollection(RuleContext ruleContext) { + this.ruleContext = ruleContext; + } + + @Override + @Nullable + public Object getValue(String name) { + return ruleContext.getSkylarkFragment(name); + } + + @Override + public ImmutableCollection<String> getKeys() { + return ruleContext.getSkylarkFragmentNames(); + } + + @Override + @Nullable + public String errorMessage(String name) { + return String.format("There is no configuration fragment named '%s'. Available fragments: %s", + name, printKeys()); + } + + private String printKeys() { + return String.format("'%s'", Joiner.on("', '").join(getKeys())); + } +}
\ No newline at end of file diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java index 43b42ca9df..385b04d8ca 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java +++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java @@ -33,6 +33,7 @@ import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; import com.google.devtools.build.lib.analysis.config.BuildConfiguration; +import com.google.devtools.build.lib.analysis.config.FragmentCollection; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.packages.Attribute; import com.google.devtools.build.lib.packages.ImplicitOutputsFunction; @@ -93,6 +94,8 @@ public final class SkylarkRuleContext { }); private final RuleContext ruleContext; + + private final FragmentCollection fragments; // TODO(bazel-team): support configurable attributes. private final SkylarkClassObject attrObject; @@ -128,6 +131,7 @@ public final class SkylarkRuleContext { */ public SkylarkRuleContext(RuleContext ruleContext) throws EvalException { this.ruleContext = Preconditions.checkNotNull(ruleContext); + fragments = new FragmentCollection(ruleContext); HashMap<String, Object> outputsBuilder = new HashMap<>(); if (ruleContext.getRule().getRuleClassObject().outputsDefaultExecutable()) { @@ -318,6 +322,12 @@ public final class SkylarkRuleContext { return ruleContext.getLabel(); } + @SkylarkCallable( + name = "fragments", structField = true, doc = "Allows access to configuration fragments.") + public FragmentCollection getFragments() { + return fragments; + } + @SkylarkCallable(name = "configuration", structField = true, doc = "Returns the default configuration. See the <a href=\"#modules.configuration\">" + "configuration</a> type for more details.") |