| // Copyright 2023 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.analysis.starlark; |
| |
| import com.google.common.collect.ImmutableMap; |
| import com.google.devtools.build.lib.analysis.ActionsProvider; |
| import com.google.devtools.build.lib.analysis.DefaultInfo; |
| import com.google.devtools.build.lib.analysis.OutputGroupInfo; |
| import com.google.devtools.build.lib.analysis.RunEnvironmentInfo; |
| import com.google.devtools.build.lib.collect.nestedset.Depset; |
| import com.google.devtools.build.lib.packages.BuildGlobals; |
| import com.google.devtools.build.lib.packages.Proto; |
| import com.google.devtools.build.lib.packages.SelectorList; |
| import com.google.devtools.build.lib.packages.StarlarkGlobals; |
| import com.google.devtools.build.lib.packages.StarlarkNativeModule; |
| import com.google.devtools.build.lib.packages.StructProvider; |
| import net.starlark.java.eval.Starlark; |
| import net.starlark.java.lib.json.Json; |
| |
| /** |
| * Sole implementation of {@link StarlarkGlobals}. |
| * |
| * <p>The reason for the class-interface split is to allow {@link BazelStarlarkEnvironment} to |
| * retrieve symbols defined and aggregated in the lib/analysis/ dir, without creating a dependency |
| * from lib/packages/ to lib/analysis. |
| */ |
| public final class StarlarkGlobalsImpl implements StarlarkGlobals { |
| |
| private StarlarkGlobalsImpl() {} |
| |
| public static final StarlarkGlobalsImpl INSTANCE = new StarlarkGlobalsImpl(); |
| |
| private void addCommonUtilToplevels(ImmutableMap.Builder<String, Object> env) { |
| // Maintainer's note: Changes to this method are relatively high impact since it's sourced for |
| // BUILD, .bzl, and even cquery environments. |
| Starlark.addMethods(env, Depset.DepsetLibrary.INSTANCE); |
| env.put("json", Json.INSTANCE); |
| env.put("proto", Proto.INSTANCE); |
| } |
| |
| @Override |
| public ImmutableMap<String, Object> getUtilToplevels() { |
| // TODO(bazel-team): It's dubious that we include things like depset and select(), but not |
| // struct() here. |
| ImmutableMap.Builder<String, Object> env = ImmutableMap.builder(); |
| addCommonUtilToplevels(env); |
| Starlark.addMethods(env, SelectorList.SelectLibrary.INSTANCE); |
| return env.buildOrThrow(); |
| } |
| |
| @Override |
| public ImmutableMap<String, Object> getUtilToplevelsForCquery() { |
| ImmutableMap.Builder<String, Object> env = ImmutableMap.builder(); |
| addCommonUtilToplevels(env); |
| env.put("struct", StructProvider.STRUCT); |
| return env.buildOrThrow(); |
| } |
| |
| @Override |
| public ImmutableMap<String, Object> getFixedBuildFileToplevelsSharedWithNative() { |
| return StarlarkNativeModule.BINDINGS_FOR_BUILD_FILES; |
| } |
| |
| @Override |
| public ImmutableMap<String, Object> getFixedBuildFileToplevelsNotInNative() { |
| ImmutableMap.Builder<String, Object> env = ImmutableMap.builder(); |
| |
| env.putAll(getUtilToplevels()); |
| Starlark.addMethods(env, BuildGlobals.INSTANCE); |
| |
| return env.buildOrThrow(); |
| } |
| |
| @Override |
| public ImmutableMap<String, Object> getFixedBzlToplevels() { |
| ImmutableMap.Builder<String, Object> env = ImmutableMap.builder(); |
| |
| env.putAll(getUtilToplevels()); |
| |
| Starlark.addMethods(env, new BazelBuildApiGlobals()); // e.g. configuration_field |
| Starlark.addMethods(env, new StarlarkRuleClassFunctions()); // e.g. rule |
| |
| env.put("cmd_helper", new StarlarkCommandLine()); |
| env.put("attr", new StarlarkAttrModule()); |
| env.put("struct", StructProvider.STRUCT); |
| env.put("OutputGroupInfo", OutputGroupInfo.STARLARK_CONSTRUCTOR); |
| env.put("Actions", ActionsProvider.INSTANCE); |
| env.put("DefaultInfo", DefaultInfo.PROVIDER); |
| env.put("RunEnvironmentInfo", RunEnvironmentInfo.PROVIDER); |
| |
| return env.buildOrThrow(); |
| } |
| |
| @Override |
| public ImmutableMap<String, Object> getSclToplevels() { |
| // TODO(bazel-team): We only want the visibility() symbol from BazelBuildApiGlobals, nothing |
| // else, but Starlark#addMethods doesn't allow that kind of granularity, and the Starlark |
| // interpreter doesn't provide any other way to turn a Java method definition into a |
| // callable symbol. So we hack it by building the map of all symbols in that class and |
| // retrieving just the one we want. The alternative of refactoring the class is more churn than |
| // its worth, given the starlarkbuildapi/ split. |
| ImmutableMap.Builder<String, Object> bazelBuildApiGlobalsSymbols = ImmutableMap.builder(); |
| Starlark.addMethods(bazelBuildApiGlobalsSymbols, new BazelBuildApiGlobals()); |
| Object visibilitySymbol = bazelBuildApiGlobalsSymbols.buildOrThrow().get("visibility"); |
| |
| ImmutableMap.Builder<String, Object> env = ImmutableMap.builder(); |
| env.put("visibility", visibilitySymbol); |
| env.put("struct", StructProvider.STRUCT); |
| return env.buildOrThrow(); |
| } |
| } |