From caceacd984a3f86b623ea726f4df36bd81998d25 Mon Sep 17 00:00:00 2001 From: cparsons Date: Sat, 4 Nov 2017 01:00:59 +0100 Subject: Expose late-bound-attributes to Skylark. RELNOTES: Late-bound attributes are exposed to skylark. This is a new API (`configuration_field()`) to depend on certain configuration-defined targets from skylark rules. PiperOrigin-RevId: 174534104 --- .../build/lib/packages/AbstractAttributeMapper.java | 21 +++++++++++++++++++++ .../devtools/build/lib/packages/Attribute.java | 6 ++++-- .../devtools/build/lib/packages/RuleClass.java | 2 ++ .../build/lib/packages/RuleClassProvider.java | 6 ++++++ 4 files changed, 33 insertions(+), 2 deletions(-) (limited to 'src/main/java/com/google/devtools/build/lib/packages') diff --git a/src/main/java/com/google/devtools/build/lib/packages/AbstractAttributeMapper.java b/src/main/java/com/google/devtools/build/lib/packages/AbstractAttributeMapper.java index 8b99d8182b..ec03962931 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/AbstractAttributeMapper.java +++ b/src/main/java/com/google/devtools/build/lib/packages/AbstractAttributeMapper.java @@ -58,6 +58,8 @@ public abstract class AbstractAttributeMapper implements AttributeMap { Object value = attributes.getAttributeValue(index); if (value instanceof Attribute.ComputedDefault) { value = ((Attribute.ComputedDefault) value).getDefault(this); + } else if (value instanceof Attribute.LateBoundDefault) { + value = ((Attribute.LateBoundDefault) value).getDefault(); } try { return type.cast(value); @@ -87,6 +89,25 @@ public abstract class AbstractAttributeMapper implements AttributeMap { } } + /** + * Returns the given attribute if it's a {@link Attribute.LateBoundDefault}, null otherwise. + * + * @throws IllegalArgumentException if the given attribute doesn't exist with the specified + * type. This happens whether or not it's a late bound default. + */ + @Nullable + @SuppressWarnings("unchecked") + public Attribute.LateBoundDefault getLateBoundDefault( + String attributeName, Type type) { + int index = getIndexWithTypeCheck(attributeName, type); + Object value = attributes.getAttributeValue(index); + if (value instanceof Attribute.LateBoundDefault) { + return (Attribute.LateBoundDefault) value; + } else { + return null; + } + } + @Override public Iterable getAttributeNames() { ImmutableList.Builder names = ImmutableList.builder(); diff --git a/src/main/java/com/google/devtools/build/lib/packages/Attribute.java b/src/main/java/com/google/devtools/build/lib/packages/Attribute.java index 54f6255226..9b158e6a58 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/Attribute.java +++ b/src/main/java/com/google/devtools/build/lib/packages/Attribute.java @@ -680,7 +680,6 @@ public final class Attribute implements Comparable { */ public Builder value(LateBoundDefault defaultValue) { Preconditions.checkState(!valueSet, "the default value is already set"); - Preconditions.checkState(name.isEmpty() || isLateBound(name)); value = defaultValue; valueSource = AttributeValueSource.LATE_BOUND; valueSet = true; @@ -1082,6 +1081,9 @@ public final class Attribute implements Comparable { */ public Attribute build(String name) { Preconditions.checkState(!name.isEmpty(), "name has not been set"); + if (valueSource == AttributeValueSource.LATE_BOUND) { + Preconditions.checkState(isLateBound(name)); + } // TODO(bazel-team): Set the default to be no file type, then remove this check, and also // remove all allowedFileTypes() calls without parameters. @@ -1715,7 +1717,7 @@ public final class Attribute implements Comparable { private static final LateBoundDefault ALWAYS_NULL = new SimpleLateBoundDefault<>(false, Void.class, null, (rule, attributes, unused) -> null); - private LateBoundDefault( + protected LateBoundDefault( boolean useHostConfiguration, Class fragmentClass, ValueT defaultValue) { diff --git a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java index 7dd8acba2d..bf99b43ade 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java +++ b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java @@ -1601,6 +1601,8 @@ public class RuleClass { // that depends on non-computed default attribute values, and that condition predicate is // evaluated by the call to Attribute#getDefaultValue. attrsWithComputedDefaults.add(attr); + } else if (attr.isLateBound()) { + rule.setAttributeValue(attr, attr.getLateBoundDefault(), /*explicit=*/ false); } else { Object defaultValue = getAttributeNoncomputedDefaultValue(attr, pkgBuilder); rule.setAttributeValue(attr, defaultValue, /*explicit=*/ false); diff --git a/src/main/java/com/google/devtools/build/lib/packages/RuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/packages/RuleClassProvider.java index 5235523d53..302b05bde2 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/RuleClassProvider.java +++ b/src/main/java/com/google/devtools/build/lib/packages/RuleClassProvider.java @@ -93,4 +93,10 @@ public interface RuleClassProvider { * Retrieves an aspect from the aspect factory map using the key provided */ NativeAspectClass getNativeAspectClass(String key); + + /** + * Retrieves a {@link Map} from skylark configuration fragment name to configuration fragment + * class. + */ + Map> getConfigurationFragmentMap(); } -- cgit v1.2.3