diff options
21 files changed, 147 insertions, 121 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java index 04c3c1a1a9..2fd2617367 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java @@ -46,7 +46,6 @@ import com.google.devtools.build.lib.graph.Digraph; import com.google.devtools.build.lib.graph.Node; import com.google.devtools.build.lib.packages.Attribute; import com.google.devtools.build.lib.packages.NativeAspectClass; -import com.google.devtools.build.lib.packages.NativeProvider; import com.google.devtools.build.lib.packages.NonconfigurableAttributeMapper; import com.google.devtools.build.lib.packages.OutputFile; import com.google.devtools.build.lib.packages.Rule; @@ -243,7 +242,6 @@ public class ConfiguredRuleClassProvider implements RuleClassProvider { ImmutableMap.builder(); private ImmutableList.Builder<Class<?>> skylarkModules = ImmutableList.<Class<?>>builder(); - private ImmutableList.Builder<NativeProvider> nativeProviders = ImmutableList.builder(); private Set<String> reservedActionMnemonics = new TreeSet<>(); private BuildConfiguration.ActionEnvironmentProvider actionEnvironmentProvider = (BuildOptions options) -> ActionEnvironment.EMPTY; @@ -371,11 +369,6 @@ public class ConfiguredRuleClassProvider implements RuleClassProvider { return this; } - public Builder addNativeProvider(NativeProvider provider) { - this.nativeProviders.add(provider); - return this; - } - public Builder addReservedActionMnemonic(String mnemonic) { this.reservedActionMnemonics.add(mnemonic); return this; @@ -514,8 +507,7 @@ public class ConfiguredRuleClassProvider implements RuleClassProvider { skylarkAccessibleTopLevels.build(), skylarkModules.build(), ImmutableSet.copyOf(reservedActionMnemonics), - actionEnvironmentProvider, - nativeProviders.build()); + actionEnvironmentProvider); } @Override @@ -628,8 +620,6 @@ public class ConfiguredRuleClassProvider implements RuleClassProvider { private final BuildConfiguration.ActionEnvironmentProvider actionEnvironmentProvider; - private final ImmutableList<NativeProvider> nativeProviders; - private final ImmutableMap<String, Class<?>> configurationFragmentMap; private ConfiguredRuleClassProvider( @@ -651,8 +641,7 @@ public class ConfiguredRuleClassProvider implements RuleClassProvider { ImmutableMap<String, Object> skylarkAccessibleJavaClasses, ImmutableList<Class<?>> skylarkModules, ImmutableSet<String> reservedActionMnemonics, - BuildConfiguration.ActionEnvironmentProvider actionEnvironmentProvider, - ImmutableList<NativeProvider> nativeProviders) { + BuildConfiguration.ActionEnvironmentProvider actionEnvironmentProvider) { this.preludeLabel = preludeLabel; this.runfilesPrefix = runfilesPrefix; this.toolsRepository = toolsRepository; @@ -671,7 +660,6 @@ public class ConfiguredRuleClassProvider implements RuleClassProvider { this.globals = createGlobals(skylarkAccessibleJavaClasses, skylarkModules); this.reservedActionMnemonics = reservedActionMnemonics; this.actionEnvironmentProvider = actionEnvironmentProvider; - this.nativeProviders = nativeProviders; this.configurationFragmentMap = createFragmentMap(configurationFragmentFactories); } @@ -896,12 +884,4 @@ public class ConfiguredRuleClassProvider implements RuleClassProvider { public BuildConfiguration.ActionEnvironmentProvider getActionEnvironmentProvider() { return actionEnvironmentProvider; } - - /** - * Returns all registered {@link NativeProvider} instances, i.e. all built-in provider types that - * are based on {@link Provider} rather than {@link TransitiveInfoProvider}. - */ - public ImmutableList<NativeProvider> getNativeProviders() { - return nativeProviders; - } } diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkAttributesCollection.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkAttributesCollection.java index ae13ebf460..6ee03b72d3 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkAttributesCollection.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkAttributesCollection.java @@ -23,7 +23,7 @@ import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.packages.Attribute; import com.google.devtools.build.lib.packages.BuildType; import com.google.devtools.build.lib.packages.Info; -import com.google.devtools.build.lib.packages.NativeProvider; +import com.google.devtools.build.lib.packages.StructProvider; import com.google.devtools.build.lib.skylarkbuildapi.SkylarkAttributesCollectionApi; import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter; import com.google.devtools.build.lib.syntax.Environment; @@ -59,21 +59,21 @@ class SkylarkAttributesCollection implements SkylarkAttributesCollectionApi { this.skylarkRuleContext = skylarkRuleContext; this.ruleClassName = ruleClassName; attrObject = - NativeProvider.STRUCT.create( + StructProvider.STRUCT.create( attrs, "No attribute '%s' in attr. Make sure you declared a rule attribute with this name."); executableObject = - NativeProvider.STRUCT.create( + StructProvider.STRUCT.create( executables, "No attribute '%s' in executable. Make sure there is a label type attribute marked " + "as 'executable' with this name"); fileObject = - NativeProvider.STRUCT.create( + StructProvider.STRUCT.create( singleFiles, "No attribute '%s' in file. Make sure there is a label type attribute marked " + "as 'single_file' with this name"); filesObject = - NativeProvider.STRUCT.create( + StructProvider.STRUCT.create( files, "No attribute '%s' in files. Make sure there is a label or label_list type attribute " + "with this name"); diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkModules.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkModules.java index 9271102017..3450283635 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkModules.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkModules.java @@ -17,6 +17,7 @@ package com.google.devtools.build.lib.analysis.skylark; import com.google.common.collect.ImmutableMap; import com.google.devtools.build.lib.packages.BazelLibrary; import com.google.devtools.build.lib.packages.SkylarkNativeModule; +import com.google.devtools.build.lib.packages.StructProvider; import com.google.devtools.build.lib.skylarkbuildapi.TopLevelBootstrap; /** @@ -26,15 +27,15 @@ public final class SkylarkModules { private SkylarkModules() { } - /** - * A bootstrap for non-rules-specific globals of the build API. - */ - private static TopLevelBootstrap topLevelBootstrap = new TopLevelBootstrap( - BazelBuildApiGlobals.class, - SkylarkAttr.class, - SkylarkCommandLine.class, - SkylarkNativeModule.class, - SkylarkRuleClassFunctions.class); + /** A bootstrap for non-rules-specific globals of the build API. */ + private static TopLevelBootstrap topLevelBootstrap = + new TopLevelBootstrap( + BazelBuildApiGlobals.class, + SkylarkAttr.class, + SkylarkCommandLine.class, + SkylarkNativeModule.class, + SkylarkRuleClassFunctions.class, + StructProvider.STRUCT); /** * Adds bindings for skylark built-ins and non-rules-specific globals of the build API to diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java index 561055f7d1..b995abf65b 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java @@ -51,7 +51,6 @@ import com.google.devtools.build.lib.packages.AttributeMap; import com.google.devtools.build.lib.packages.AttributeValueSource; import com.google.devtools.build.lib.packages.ImplicitOutputsFunction.SkylarkImplicitOutputsFunctionWithCallback; import com.google.devtools.build.lib.packages.ImplicitOutputsFunction.SkylarkImplicitOutputsFunctionWithMap; -import com.google.devtools.build.lib.packages.Info; import com.google.devtools.build.lib.packages.NativeProvider; import com.google.devtools.build.lib.packages.Package.NameConflictException; import com.google.devtools.build.lib.packages.PackageFactory; @@ -73,7 +72,6 @@ import com.google.devtools.build.lib.packages.TargetUtils; import com.google.devtools.build.lib.packages.TestSize; import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; import com.google.devtools.build.lib.skylarkbuildapi.SkylarkRuleFunctionsApi; -import com.google.devtools.build.lib.skylarkinterface.Param; import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter; import com.google.devtools.build.lib.skylarkinterface.SkylarkSignature; import com.google.devtools.build.lib.syntax.BaseFunction; @@ -209,19 +207,6 @@ public class SkylarkRuleClassFunctions implements SkylarkRuleFunctionsApi<Artifa }; @SkylarkSignature( - name = "struct", - returnType = Info.class, - doc = - "Creates an immutable struct using the keyword arguments as attributes. It is used to " - + "group multiple values together. Example:<br>" - + "<pre class=\"language-python\">s = struct(x = 2, y = 3)\n" - + "return s.x + getattr(s, \"y\") # returns 5</pre>", - extraKeywords = @Param(name = "kwargs", doc = "the struct attributes."), - useLocation = true - ) - private static final NativeProvider<?> struct = NativeProvider.STRUCT; - - @SkylarkSignature( name = "DefaultInfo", returnType = Provider.class, doc = diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleConfiguredTargetUtil.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleConfiguredTargetUtil.java index 5dd147985f..2c9b62fe6b 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleConfiguredTargetUtil.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleConfiguredTargetUtil.java @@ -39,6 +39,7 @@ import com.google.devtools.build.lib.packages.NativeProvider; import com.google.devtools.build.lib.packages.Rule; import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException; import com.google.devtools.build.lib.packages.SkylarkProviderIdentifier; +import com.google.devtools.build.lib.packages.StructProvider; import com.google.devtools.build.lib.packages.TargetUtils; import com.google.devtools.build.lib.skylarkinterface.SkylarkValue; import com.google.devtools.build.lib.syntax.BaseFunction; @@ -295,7 +296,7 @@ public final class SkylarkRuleConfiguredTargetUtil { SkylarkRuleContext context, RuleConfiguredTargetBuilder builder, Object target, Location loc) throws EvalException { - Info oldStyleProviders = NativeProvider.STRUCT.createEmpty(loc); + Info oldStyleProviders = StructProvider.STRUCT.createEmpty(loc); ArrayList<Info> declaredProviders = new ArrayList<>(); if (target instanceof Info) { @@ -303,7 +304,7 @@ public final class SkylarkRuleConfiguredTargetUtil { Info struct = (Info) target; // Use the creation location of this struct as a better reference in error messages loc = struct.getCreationLoc(); - if (struct.getProvider().getKey().equals(NativeProvider.STRUCT.getKey())) { + if (struct.getProvider().getKey().equals(StructProvider.STRUCT.getKey())) { // Old-style struct, but it may contain declared providers oldStyleProviders = struct; diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleContext.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleContext.java index 75e4f635d3..df2b386c4f 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleContext.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleContext.java @@ -56,11 +56,11 @@ import com.google.devtools.build.lib.packages.BuildType; import com.google.devtools.build.lib.packages.ImplicitOutputsFunction; import com.google.devtools.build.lib.packages.ImplicitOutputsFunction.SkylarkImplicitOutputsFunction; import com.google.devtools.build.lib.packages.Info; -import com.google.devtools.build.lib.packages.NativeProvider; import com.google.devtools.build.lib.packages.OutputFile; import com.google.devtools.build.lib.packages.Package; import com.google.devtools.build.lib.packages.Provider; import com.google.devtools.build.lib.packages.RawAttributeMapper; +import com.google.devtools.build.lib.packages.StructProvider; import com.google.devtools.build.lib.shell.ShellUtils; import com.google.devtools.build.lib.shell.ShellUtils.TokenizationException; import com.google.devtools.build.lib.skylarkbuildapi.FileApi; @@ -452,7 +452,7 @@ public final class SkylarkRuleContext implements SkylarkRuleContextApi { } } - return NativeProvider.STRUCT.create( + return StructProvider.STRUCT.create( splitAttrInfos.build(), "No attribute '%s' in split_attr. Make sure that this attribute is defined with a " + "split configuration."); diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContext.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContext.java index a3f70b3813..b796384896 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContext.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContext.java @@ -27,8 +27,8 @@ import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.events.Location; import com.google.devtools.build.lib.packages.Attribute; import com.google.devtools.build.lib.packages.Info; -import com.google.devtools.build.lib.packages.NativeProvider; import com.google.devtools.build.lib.packages.Rule; +import com.google.devtools.build.lib.packages.StructProvider; import com.google.devtools.build.lib.rules.repository.RepositoryFunction; import com.google.devtools.build.lib.rules.repository.RepositoryFunction.RepositoryFunctionException; import com.google.devtools.build.lib.rules.repository.WorkspaceAttributeMapper; @@ -111,7 +111,7 @@ public class SkylarkRepositoryContext { (com.google.devtools.build.lib.syntax.Environment) null)); } } - attrObject = NativeProvider.STRUCT.create(attrBuilder.build(), "No such attribute '%s'"); + attrObject = StructProvider.STRUCT.create(attrBuilder.build(), "No such attribute '%s'"); } @SkylarkCallable( 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 933790f253..0bc32e4291 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 @@ -1513,7 +1513,7 @@ public final class Attribute implements Comparable<Attribute> { private Object invokeCallback(EventHandler eventHandler, Map<String, Object> attrValues) throws EvalException, InterruptedException { ClassObject attrs = - NativeProvider.STRUCT.create( + StructProvider.STRUCT.create( attrValues, "No such regular (non computed) attribute '%s'."); Object result = callback.call(eventHandler, attrs); try { diff --git a/src/main/java/com/google/devtools/build/lib/packages/ImplicitOutputsFunction.java b/src/main/java/com/google/devtools/build/lib/packages/ImplicitOutputsFunction.java index 33bc2cfa76..96388f297d 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/ImplicitOutputsFunction.java +++ b/src/main/java/com/google/devtools/build/lib/packages/ImplicitOutputsFunction.java @@ -105,7 +105,7 @@ public abstract class ImplicitOutputsFunction { } } ClassObject attrs = - NativeProvider.STRUCT.create( + StructProvider.STRUCT.create( attrValues, "Attribute '%s' either doesn't exist " + "or uses a select() (i.e. could have multiple values)"); diff --git a/src/main/java/com/google/devtools/build/lib/packages/NativeProvider.java b/src/main/java/com/google/devtools/build/lib/packages/NativeProvider.java index 20e649b0e4..c59d81e763 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/NativeProvider.java +++ b/src/main/java/com/google/devtools/build/lib/packages/NativeProvider.java @@ -13,7 +13,6 @@ // limitations under the License. package com.google.devtools.build.lib.packages; -import com.google.common.collect.ImmutableMap; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; import com.google.devtools.build.lib.events.Location; import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; @@ -23,7 +22,6 @@ import com.google.devtools.build.lib.syntax.EvalException; import com.google.devtools.build.lib.syntax.FunctionSignature; import com.google.devtools.build.lib.syntax.SkylarkType; import com.google.devtools.build.lib.util.Pair; -import java.util.Map; import javax.annotation.Nullable; /** @@ -40,8 +38,7 @@ import javax.annotation.Nullable; * </pre> * * To allow construction from Skylark and custom construction logic, override {@link - * Provider#createInstanceFromSkylark(Object[], Environment, Location)} (see {@link #STRUCT} for an - * example. + * ProviderFromFunction#createInstanceFromSkylark(Object[], Environment, Location)}. * * @deprecated use {@link BuiltinProvider} instead. */ @@ -51,9 +48,6 @@ public abstract class NativeProvider<V extends Info> extends ProviderFromFunctio private final NativeKey key; private final String errorMessageFormatForUnknownField; - /** "struct" function. */ - public static final StructProvider STRUCT = new StructProvider(); - private final Class<V> valueClass; public Class<V> getValueClass() { @@ -72,42 +66,6 @@ public abstract class NativeProvider<V extends Info> extends ProviderFromFunctio String getSkylarkName(); } - /** - * The provider for the built-in type {@code struct}. - * - * <p>Its singleton instance is {@link #STRUCT}. - */ - public static final class StructProvider extends NativeProvider<Info> { - private StructProvider() { - super(Info.class, "struct"); - } - - @Override - protected Info createInstanceFromSkylark(Object[] args, Environment env, Location loc) { - @SuppressWarnings("unchecked") - Map<String, Object> kwargs = (Map<String, Object>) args[0]; - return SkylarkInfo.createSchemaless(this, kwargs, loc); - } - - /** - * Creates a struct with the he given field values and message format for unknown fields. - * - * <p>The custom message is useful for objects that have fields but aren't exactly used as - * providers, such as the {@code native} object, and the struct fields of {@code ctx} like - * {@code ctx.attr}. - * */ - public SkylarkInfo create( - Map<String, Object> values, String errorMessageFormatForUnknownField) { - return SkylarkInfo.createSchemalessWithCustomMessage( - this, values, errorMessageFormatForUnknownField); - } - - /** Creates an empty struct with the given location. */ - public SkylarkInfo createEmpty(Location loc) { - return SkylarkInfo.createSchemaless(this, ImmutableMap.of(), loc); - } - } - private static final FunctionSignature.WithValues<Object, SkylarkType> SIGNATURE = FunctionSignature.WithValues.create(FunctionSignature.KWARGS); diff --git a/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java b/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java index ad682b6d33..71bf904666 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java +++ b/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java @@ -1514,7 +1514,7 @@ public final class PackageFactory { builder.put(function.getName(), function); } } - return NativeProvider.STRUCT.create(builder.build(), "no native function or rule '%s'"); + return StructProvider.STRUCT.create(builder.build(), "no native function or rule '%s'"); } private void buildPkgEnv( diff --git a/src/main/java/com/google/devtools/build/lib/packages/StructProvider.java b/src/main/java/com/google/devtools/build/lib/packages/StructProvider.java new file mode 100644 index 0000000000..21f847528b --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/packages/StructProvider.java @@ -0,0 +1,62 @@ +// Copyright 2018 The Bazel Authors. 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.packages; + +import com.google.common.collect.ImmutableMap; +import com.google.devtools.build.lib.events.Location; +import com.google.devtools.build.lib.skylarkbuildapi.StructApi; +import com.google.devtools.build.lib.syntax.EvalException; +import com.google.devtools.build.lib.syntax.SkylarkDict; +import java.util.Map; + +/** + * The provider for the built-in type {@code struct}. + * + * <p>Its singleton instance is {@link StructProvider#STRUCT}. + */ +public final class StructProvider extends BuiltinProvider<Info> + implements StructApi.StructProviderApi { + + /** "struct" function. */ + public static final StructProvider STRUCT = new StructProvider(); + + StructProvider() { + super("struct", Info.class); + } + + @Override + public Info createStruct(SkylarkDict<?, ?> kwargs, Location loc) throws EvalException { + return SkylarkInfo.createSchemaless( + this, kwargs.getContents(String.class, Object.class, "kwargs"), loc); + } + + /** + * Creates a struct with the he given field values and message format for unknown fields. + * + * <p>The custom message is useful for objects that have fields but aren't exactly used as + * providers, such as the {@code native} object, and the struct fields of {@code ctx} like + * {@code ctx.attr}. + * */ + public SkylarkInfo create( + Map<String, Object> values, String errorMessageFormatForUnknownField) { + return SkylarkInfo.createSchemalessWithCustomMessage( + this, values, errorMessageFormatForUnknownField); + } + + /** Creates an empty struct with the given location. */ + public SkylarkInfo createEmpty(Location loc) { + return SkylarkInfo.createSchemaless(this, ImmutableMap.of(), loc); + } +} diff --git a/src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactory.java b/src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactory.java index 5d55d31012..b9d86ad461 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactory.java +++ b/src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactory.java @@ -569,7 +569,7 @@ public class WorkspaceFactory { } builder.put("bazel_version", version); - return NativeProvider.STRUCT.create(builder.build(), "no native function or rule '%s'"); + return StructProvider.STRUCT.create(builder.build(), "no native function or rule '%s'"); } static ClassObject newNativeModule(RuleClassProvider ruleClassProvider, String version) { diff --git a/src/main/java/com/google/devtools/build/lib/rules/core/CoreRules.java b/src/main/java/com/google/devtools/build/lib/rules/core/CoreRules.java index 75fa2d6840..90d44a5bd6 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/core/CoreRules.java +++ b/src/main/java/com/google/devtools/build/lib/rules/core/CoreRules.java @@ -18,7 +18,6 @@ import com.google.devtools.build.lib.analysis.BaseRuleClasses; import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider; import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider.RuleSet; import com.google.devtools.build.lib.analysis.test.TestConfiguration; -import com.google.devtools.build.lib.packages.NativeProvider; /** A set of basic rules - Bazel won't work correctly without these. */ public final class CoreRules implements RuleSet { @@ -38,7 +37,6 @@ public final class CoreRules implements RuleSet { builder.addRuleDefinition(new BaseRuleClasses.BinaryBaseRule()); builder.addRuleDefinition(new BaseRuleClasses.TestBaseRule()); builder.addRuleDefinition(new BaseRuleClasses.ErrorRule()); - builder.addNativeProvider(NativeProvider.STRUCT); } @Override diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProviderSkylarkConverters.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProviderSkylarkConverters.java index c2fe4d631e..f7dc98aeb5 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProviderSkylarkConverters.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProviderSkylarkConverters.java @@ -25,7 +25,7 @@ import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.packages.Info; -import com.google.devtools.build.lib.packages.NativeProvider; +import com.google.devtools.build.lib.packages.StructProvider; import com.google.devtools.build.lib.rules.objc.ObjcProvider.Key; import com.google.devtools.build.lib.syntax.EvalException; import com.google.devtools.build.lib.syntax.EvalUtils; @@ -171,7 +171,7 @@ public class ObjcProviderSkylarkConverters { NestedSetBuilder<Info> result = NestedSetBuilder.stableOrder(); for (BundleableFile bundleableFile : (Iterable<BundleableFile>) javaValue) { result.add( - NativeProvider.STRUCT.create( + StructProvider.STRUCT.create( ImmutableMap.<String, Object>of( BUNDLED_FIELD, bundleableFile.getBundled(), BUNDLE_PATH_FIELD, bundleableFile.getBundlePath()), diff --git a/src/main/java/com/google/devtools/build/lib/rules/python/PyCommon.java b/src/main/java/com/google/devtools/build/lib/rules/python/PyCommon.java index 3a8c068a0e..ede9e0f6ee 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/python/PyCommon.java +++ b/src/main/java/com/google/devtools/build/lib/rules/python/PyCommon.java @@ -43,8 +43,8 @@ import com.google.devtools.build.lib.collect.nestedset.Order; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; import com.google.devtools.build.lib.packages.BuildType; import com.google.devtools.build.lib.packages.Info; -import com.google.devtools.build.lib.packages.NativeProvider; import com.google.devtools.build.lib.packages.Rule; +import com.google.devtools.build.lib.packages.StructProvider; import com.google.devtools.build.lib.rules.cpp.CppFileTypes; import com.google.devtools.build.lib.syntax.EvalException; import com.google.devtools.build.lib.syntax.EvalUtils; @@ -180,7 +180,7 @@ public final class PyCommon { */ public static Info createSourceProvider( NestedSet<Artifact> transitivePythonSources, boolean isUsingSharedLibrary) { - return NativeProvider.STRUCT.create( + return StructProvider.STRUCT.create( ImmutableMap.<String, Object>of( TRANSITIVE_PYTHON_SRCS, SkylarkNestedSet.of(Artifact.class, transitivePythonSources), diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/StructApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/StructApi.java index 5e7b6820ac..debb5bd1f1 100644 --- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/StructApi.java +++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/StructApi.java @@ -15,11 +15,14 @@ package com.google.devtools.build.lib.skylarkbuildapi; import com.google.devtools.build.lib.events.Location; +import com.google.devtools.build.lib.skylarkinterface.Param; import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable; +import com.google.devtools.build.lib.skylarkinterface.SkylarkConstructor; import com.google.devtools.build.lib.skylarkinterface.SkylarkModule; import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory; import com.google.devtools.build.lib.skylarkinterface.SkylarkValue; import com.google.devtools.build.lib.syntax.EvalException; +import com.google.devtools.build.lib.syntax.SkylarkDict; /** Interface for the "struct" object in the build API. */ @SkylarkModule( @@ -72,4 +75,29 @@ public interface StructApi extends SkylarkValue { + "# {\"key\":{\"inner_key\":{\"inner_inner_key\":\"text\"}}}\n</pre>", useLocation = true) public String toJson(Location loc) throws EvalException; + + /** + * Callable Provider for new struct objects. + */ + @SkylarkModule(name = "Provider", documented = false, doc = "") + public interface StructProviderApi { + + @SkylarkCallable( + name = "struct", + doc = + "Creates an immutable struct using the keyword arguments as attributes. It is used to " + + "group multiple values together. Example:<br>" + + "<pre class=\"language-python\">s = struct(x = 2, y = 3)\n" + + "return s.x + getattr(s, \"y\") # returns 5</pre>", + extraKeywords = + @Param( + name = "kwargs", + type = SkylarkDict.class, + defaultValue = "{}", + doc = "Dictionary of arguments."), + useLocation = true, + selfCall = true) + @SkylarkConstructor(objectType = StructApi.class, receiverNameForDoc = "struct") + public StructApi createStruct(SkylarkDict<?, ?> kwargs, Location loc) throws EvalException; + } } diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/TopLevelBootstrap.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/TopLevelBootstrap.java index 910a67a39b..881b5fc2fa 100644 --- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/TopLevelBootstrap.java +++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/TopLevelBootstrap.java @@ -26,18 +26,21 @@ public class TopLevelBootstrap implements Bootstrap { private final Class<? extends SkylarkCommandLineApi> skylarkCommandLineApi; private final Class<? extends SkylarkNativeModuleApi> skylarkNativeModuleApi; private final Class<? extends SkylarkRuleFunctionsApi<?>> skylarkRuleFunctionsApi; + private final StructApi.StructProviderApi structProvider; public TopLevelBootstrap( Class<? extends SkylarkBuildApiGlobals> skylarkBuildApiGlobals, Class<? extends SkylarkAttrApi> skylarkAttrApi, Class<? extends SkylarkCommandLineApi> skylarkCommandLineApi, Class<? extends SkylarkNativeModuleApi> skylarkNativeModuleApi, - Class<? extends SkylarkRuleFunctionsApi<?>> skylarkRuleFunctionsApi) { + Class<? extends SkylarkRuleFunctionsApi<?>> skylarkRuleFunctionsApi, + StructApi.StructProviderApi structProvider) { this.skylarkAttrApi = skylarkAttrApi; this.skylarkBuildApiGlobals = skylarkBuildApiGlobals; this.skylarkCommandLineApi = skylarkCommandLineApi; this.skylarkNativeModuleApi = skylarkNativeModuleApi; this.skylarkRuleFunctionsApi = skylarkRuleFunctionsApi; + this.structProvider = structProvider; } @Override @@ -47,5 +50,6 @@ public class TopLevelBootstrap implements Bootstrap { Runtime.setupModuleGlobals(builder, skylarkCommandLineApi); Runtime.setupModuleGlobals(builder, skylarkNativeModuleApi); Runtime.setupModuleGlobals(builder, skylarkRuleFunctionsApi); + builder.put("struct", structProvider); } } diff --git a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java index debf9f5ab2..13d1997bec 100644 --- a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java +++ b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java @@ -35,7 +35,6 @@ import com.google.devtools.build.lib.packages.Attribute; import com.google.devtools.build.lib.packages.BuildType; import com.google.devtools.build.lib.packages.ImplicitOutputsFunction; import com.google.devtools.build.lib.packages.Info; -import com.google.devtools.build.lib.packages.NativeProvider; import com.google.devtools.build.lib.packages.PredicateWithMessage; import com.google.devtools.build.lib.packages.RequiredProviders; import com.google.devtools.build.lib.packages.RuleClass; @@ -45,6 +44,7 @@ import com.google.devtools.build.lib.packages.SkylarkDefinedAspect; import com.google.devtools.build.lib.packages.SkylarkInfo; import com.google.devtools.build.lib.packages.SkylarkProvider; import com.google.devtools.build.lib.packages.SkylarkProviderIdentifier; +import com.google.devtools.build.lib.packages.StructProvider; import com.google.devtools.build.lib.rules.cpp.transitions.DisableLipoTransition; import com.google.devtools.build.lib.skyframe.SkylarkImportLookupFunction; import com.google.devtools.build.lib.skylark.util.SkylarkTestCase; @@ -1180,17 +1180,17 @@ public class SkylarkRuleClassFunctionsTest extends SkylarkTestCase { } private static Info makeStruct(String field, Object value) { - return NativeProvider.STRUCT.create(ImmutableMap.of(field, value), "no field '%'"); + return StructProvider.STRUCT.create(ImmutableMap.of(field, value), "no field '%'"); } private static Info makeBigStruct(Environment env) { // struct(a=[struct(x={1:1}), ()], b=(), c={2:2}) - return NativeProvider.STRUCT.create( + return StructProvider.STRUCT.create( ImmutableMap.<String, Object>of( "a", MutableList.<Object>of( env, - NativeProvider.STRUCT.create( + StructProvider.STRUCT.create( ImmutableMap.<String, Object>of( "x", SkylarkDict.<Object, Object>of(env, 1, 1)), "no field '%s'"), @@ -1311,9 +1311,9 @@ public class SkylarkRuleClassFunctionsTest extends SkylarkTestCase { "data = struct(x = 1)" ); Info data = (Info) lookup("data"); - assertThat(NativeProvider.STRUCT.isExported()).isTrue(); - assertThat(data.getProvider()).isEqualTo(NativeProvider.STRUCT); - assertThat(data.getProvider().getKey()).isEqualTo(NativeProvider.STRUCT.getKey()); + assertThat(StructProvider.STRUCT.isExported()).isTrue(); + assertThat(data.getProvider()).isEqualTo(StructProvider.STRUCT); + assertThat(data.getProvider().getKey()).isEqualTo(StructProvider.STRUCT.getKey()); } @Test @@ -1656,4 +1656,12 @@ public class SkylarkRuleClassFunctionsTest extends SkylarkTestCase { assertThat(params.get(0)).isEqualTo("NoneType"); assertThat(params.get(1)).isEqualTo("NoneType"); } + + @Test + public void testTypeOfStruct() throws Exception { + eval("p = type(struct)", "s = type(struct())"); + + assertThat(lookup("p")).isEqualTo("Provider"); + assertThat(lookup("s")).isEqualTo("struct"); + } } diff --git a/src/test/java/com/google/devtools/build/lib/syntax/EvalUtilsTest.java b/src/test/java/com/google/devtools/build/lib/syntax/EvalUtilsTest.java index a34eab24ba..4c1810aa16 100644 --- a/src/test/java/com/google/devtools/build/lib/syntax/EvalUtilsTest.java +++ b/src/test/java/com/google/devtools/build/lib/syntax/EvalUtilsTest.java @@ -21,7 +21,7 @@ import static org.junit.Assert.fail; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; -import com.google.devtools.build.lib.packages.NativeProvider; +import com.google.devtools.build.lib.packages.StructProvider; import com.google.devtools.build.lib.skylarkinterface.SkylarkModule; import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter; import com.google.devtools.build.lib.skylarkinterface.SkylarkValue; @@ -129,7 +129,7 @@ public class EvalUtilsTest extends EvaluationTestCase { SkylarkDict.of(env, "key", 123), SkylarkDict.of(env, 123, "value"), NestedSetBuilder.stableOrder().add(1).add(2).add(3).build(), - NativeProvider.STRUCT.create(ImmutableMap.of("key", (Object) "value"), "no field %s"), + StructProvider.STRUCT.create(ImmutableMap.of("key", (Object) "value"), "no field %s"), }; for (int i = 0; i < objects.length; ++i) { diff --git a/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java index 3e0db3dd03..422ac033a5 100644 --- a/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java +++ b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java @@ -24,6 +24,7 @@ import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; import com.google.devtools.build.lib.events.Location; import com.google.devtools.build.lib.packages.NativeInfo; import com.google.devtools.build.lib.packages.NativeProvider; +import com.google.devtools.build.lib.packages.StructProvider; import com.google.devtools.build.lib.skylarkinterface.Param; import com.google.devtools.build.lib.skylarkinterface.ParamType; import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable; @@ -385,7 +386,7 @@ public class SkylarkEvaluationTest extends EvaluationTest { builder.put(nativeFunction, FuncallExpression.getBuiltinCallable(this, nativeFunction)); } - return NativeProvider.STRUCT.create(builder.build(), "no native callable '%s'"); + return StructProvider.STRUCT.create(builder.build(), "no native callable '%s'"); } @SkylarkCallable( |