blob: 855e06f35a21dcd391669d9c38e63535bdb00e28 [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.
14
15package com.google.devtools.build.lib.rules;
16
Dmitry Lomovfd2bdc32016-10-07 08:52:10 +000017import com.google.common.base.Function;
Dmitry Lomov5a8f1c02015-11-26 10:49:16 +000018import com.google.common.collect.ImmutableList;
Nathan Harmata4ec1e582016-06-10 15:58:30 +000019import com.google.common.collect.ImmutableMap;
Laurent Le Brunebecc552015-06-17 09:12:18 +000020import com.google.common.collect.Iterables;
Lukacs Berki6e91eb92015-09-21 09:12:37 +000021import com.google.devtools.build.lib.cmdline.Label;
Vladimir Moskvadfad9e32016-09-15 18:22:01 +000022import com.google.devtools.build.lib.events.Event;
Dmitry Lomovc5cd8dd2016-07-18 10:42:18 +000023import com.google.devtools.build.lib.events.Location;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010024import com.google.devtools.build.lib.packages.Attribute;
Laurent Le Brunebecc552015-06-17 09:12:18 +000025import com.google.devtools.build.lib.packages.Attribute.AllowedValueSet;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010026import com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition;
Florian Weikertea6c82d2016-09-05 12:15:31 +000027import com.google.devtools.build.lib.packages.Attribute.SkylarkComputedDefaultTemplate;
Lukacs Berkiffa73ad2015-09-18 11:40:12 +000028import com.google.devtools.build.lib.packages.BuildType;
Googler74558fc2016-05-06 21:47:42 +000029import com.google.devtools.build.lib.packages.SkylarkAspect;
Dmitry Lomovfd2bdc32016-10-07 08:52:10 +000030import com.google.devtools.build.lib.packages.SkylarkProviderIdentifier;
Damien Martin-Guillerez2ca9b722016-06-09 17:43:55 +000031import com.google.devtools.build.lib.skylarkinterface.Param;
John Field585d1a02015-12-16 16:03:52 +000032import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
Dmitry Lomov34cdae32016-06-28 16:13:35 +000033import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
John Field585d1a02015-12-16 16:03:52 +000034import com.google.devtools.build.lib.skylarkinterface.SkylarkSignature;
Francois-Rene Rideau537a90b2015-04-22 06:47:31 +000035import com.google.devtools.build.lib.syntax.BuiltinFunction;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010036import com.google.devtools.build.lib.syntax.Environment;
37import com.google.devtools.build.lib.syntax.EvalException;
Francois-Rene Rideau534dca12015-04-21 19:43:19 +000038import com.google.devtools.build.lib.syntax.EvalUtils;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010039import com.google.devtools.build.lib.syntax.FuncallExpression;
Francois-Rene Rideau0f7ba342015-08-31 16:16:21 +000040import com.google.devtools.build.lib.syntax.Runtime;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010041import com.google.devtools.build.lib.syntax.SkylarkCallbackFunction;
Francois-Rene Rideauab049e02016-02-17 16:13:46 +000042import com.google.devtools.build.lib.syntax.SkylarkDict;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010043import com.google.devtools.build.lib.syntax.SkylarkList;
Francois-Rene Rideau537a90b2015-04-22 06:47:31 +000044import com.google.devtools.build.lib.syntax.SkylarkSignatureProcessor;
Yun Peng83fbb91a2016-02-23 18:37:44 +000045import com.google.devtools.build.lib.syntax.SkylarkType;
Lukacs Berkiffa73ad2015-09-18 11:40:12 +000046import com.google.devtools.build.lib.syntax.Type;
47import com.google.devtools.build.lib.syntax.Type.ConversionException;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010048import com.google.devtools.build.lib.syntax.UserDefinedFunction;
Laurent Le Brun2445df12016-05-11 14:36:40 +000049import com.google.devtools.build.lib.util.FileType;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010050import com.google.devtools.build.lib.util.FileTypeSet;
Nathan Harmata4ec1e582016-06-10 15:58:30 +000051import com.google.devtools.build.lib.util.Preconditions;
Yun Peng83fbb91a2016-02-23 18:37:44 +000052import java.util.ArrayList;
Francois-Rene Rideau93ed7f12015-10-20 15:39:33 +000053import java.util.List;
Nathan Harmata4ec1e582016-06-10 15:58:30 +000054import java.util.Map;
Nathan Harmata4ec1e582016-06-10 15:58:30 +000055import javax.annotation.Nullable;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010056
57/**
58 * A helper class to provide Attr module in Skylark.
Laurent Le Brunb20459d2015-07-24 15:41:55 +000059 *
Dmitry Lomov34cdae32016-06-28 16:13:35 +000060 * <p>It exposes functions (e.g. 'attr.string', 'attr.label_list', etc.) to Skylark users. The
61 * functions are executed through reflection. As everywhere in Skylark, arguments are type-checked
62 * with the signature and cannot be null.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010063 */
Laurent Le Brunebecc552015-06-17 09:12:18 +000064@SkylarkModule(
Laurent Le Brune1e31742015-07-24 16:02:14 +000065 name = "attr",
66 namespace = true,
Dmitry Lomov34cdae32016-06-28 16:13:35 +000067 category = SkylarkModuleCategory.BUILTIN,
Laurent Le Brune1e31742015-07-24 16:02:14 +000068 doc =
69 "Module for creating new attributes. "
Laurent Le Brun8f0092d2016-07-06 13:14:38 +000070 + "They are only for use with <a href=\"globals.html#rule\">rule</a> or "
71 + "<a href=\"globals.html#aspect\">aspect</a>."
Laurent Le Brune1e31742015-07-24 16:02:14 +000072)
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010073public final class SkylarkAttr {
74
Laurent Le Brun4deafa82015-07-24 16:51:52 +000075 // Arguments
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010076
Laurent Le Brun4deafa82015-07-24 16:51:52 +000077 private static final String ALLOW_FILES_ARG = "allow_files";
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010078 private static final String ALLOW_FILES_DOC =
Laurent Le Brun2445df12016-05-11 14:36:40 +000079 "whether File targets are allowed. Can be True, False (default), or a list of file "
80 + "extensions that are allowed (e.g. <code>[\".cc\", \".cpp\"]</code>).";
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010081
Laurent Le Brun4deafa82015-07-24 16:51:52 +000082 private static final String ALLOW_RULES_ARG = "allow_rules";
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010083 private static final String ALLOW_RULES_DOC =
Laszlo Csomor52fb6a22015-02-17 09:46:49 +000084 "which rule targets (name of the classes) are allowed. This is deprecated (kept only for "
Laurent Le Brunebecc552015-06-17 09:12:18 +000085 + "compatiblity), use providers instead.";
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010086
Dmitry Lomov5a8f1c02015-11-26 10:49:16 +000087 private static final String ASPECTS_ARG = "aspects";
Jon Brandveind93706d2016-09-15 17:15:24 +000088 private static final String ASPECTS_ARG_DOC =
89 "aspects that should be applied to the dependency or dependencies specified by this "
90 + "attribute";
Dmitry Lomov5a8f1c02015-11-26 10:49:16 +000091
Laurent Le Brun4deafa82015-07-24 16:51:52 +000092 private static final String CONFIGURATION_ARG = "cfg";
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010093 private static final String CONFIGURATION_DOC =
Vladimir Moskva5a510772016-11-23 19:03:38 +000094 "configuration of the attribute. It can be either \"data\", \"host\", or \"target\". "
95 + "This parameter is required if <code>executable</code> is True.";
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010096
Laurent Le Brun4deafa82015-07-24 16:51:52 +000097 private static final String DEFAULT_ARG = "default";
Laurent Le Brunfaf78412015-07-28 16:13:00 +000098 private static final String DEFAULT_DOC = "the default value of the attribute.";
Laurent Le Brun4deafa82015-07-24 16:51:52 +000099
100 private static final String EXECUTABLE_ARG = "executable";
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100101 private static final String EXECUTABLE_DOC =
Laurent Le Brunfaf78412015-07-28 16:13:00 +0000102 "True if the labels have to be executable. This means the label must refer to an "
Laurent Le Brunebecc552015-06-17 09:12:18 +0000103 + "executable file, or to a rule that outputs an executable file. Access the labels "
104 + "with <code>ctx.executable.&lt;attribute_name&gt;</code>.";
105
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000106 private static final String FLAGS_ARG = "flags";
107 private static final String FLAGS_DOC = "deprecated, will be removed";
108
109 private static final String MANDATORY_ARG = "mandatory";
Laurent Le Brunfaf78412015-07-28 16:13:00 +0000110 private static final String MANDATORY_DOC = "True if the value must be explicitly specified";
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000111
112 private static final String NON_EMPTY_ARG = "non_empty";
Laurent Le Brunbc16f722016-07-06 13:40:24 +0000113 private static final String NON_EMPTY_DOC =
114 "True if the attribute must not be empty. Deprecated: Use allow_empty instead.";
115
116 private static final String ALLOW_EMPTY_ARG = "allow_empty";
117 private static final String ALLOW_EMPTY_DOC = "True if the attribute can be empty";
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000118
119 private static final String PROVIDERS_ARG = "providers";
Yun Peng83fbb91a2016-02-23 18:37:44 +0000120 private static final String PROVIDERS_DOC =
Yun Pengda9410c2016-03-18 21:14:51 +0000121 "mandatory providers list. It should be either a list of providers, or a "
122 + "list of lists of providers. Every dependency should provide ALL providers "
123 + "from at least ONE of these lists. A single list of providers will be "
124 + "automatically converted to a list containing one list of providers.";
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000125
126 private static final String SINGLE_FILE_ARG = "single_file";
Laurent Le Brun50681c12016-07-05 10:08:54 +0000127 private static final String ALLOW_SINGLE_FILE_ARG = "allow_single_file";
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000128
129 private static final String VALUES_ARG = "values";
Laurent Le Brunebecc552015-06-17 09:12:18 +0000130 private static final String VALUES_DOC =
Laurent Le Brunfaf78412015-07-28 16:13:00 +0000131 "the list of allowed values for the attribute. An error is raised if any other "
Laurent Le Brunebecc552015-06-17 09:12:18 +0000132 + "value is given.";
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100133
Francois-Rene Rideauab049e02016-02-17 16:13:46 +0000134 private static boolean containsNonNoneKey(SkylarkDict<String, Object> arguments, String key) {
Francois-Rene Rideau0f7ba342015-08-31 16:16:21 +0000135 return arguments.containsKey(key) && arguments.get(key) != Runtime.NONE;
Francois-Rene Rideau534dca12015-04-21 19:43:19 +0000136 }
137
Laurent Le Brun50681c12016-07-05 10:08:54 +0000138 private static void setAllowedFileTypes(
139 String attr, Object fileTypesObj, FuncallExpression ast, Attribute.Builder<?> builder)
140 throws EvalException {
141 if (fileTypesObj == Boolean.TRUE) {
142 builder.allowedFileTypes(FileTypeSet.ANY_FILE);
143 } else if (fileTypesObj == Boolean.FALSE) {
144 builder.allowedFileTypes(FileTypeSet.NO_FILE);
145 } else if (fileTypesObj instanceof SkylarkFileType) {
146 // TODO(laurentlb): deprecated, to be removed
147 builder.allowedFileTypes(((SkylarkFileType) fileTypesObj).getFileTypeSet());
148 } else if (fileTypesObj instanceof SkylarkList) {
149 List<String> arg =
150 SkylarkList.castSkylarkListOrNoneToList(
151 fileTypesObj, String.class, "allow_files argument");
152 builder.allowedFileTypes(FileType.of(arg));
153 } else {
154 throw new EvalException(
155 ast.getLocation(), attr + " should be a boolean or a string list");
156 }
157 }
158
Laurent Le Brune1e31742015-07-24 16:02:14 +0000159 private static Attribute.Builder<?> createAttribute(
Vladimir Moskvadfad9e32016-09-15 18:22:01 +0000160 Type<?> type, SkylarkDict<String, Object> arguments, FuncallExpression ast, Environment env,
161 Location loc) throws EvalException, ConversionException {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100162 // We use an empty name now so that we can set it later.
163 // This trick makes sense only in the context of Skylark (builtin rules should not use it).
164 Attribute.Builder<?> builder = Attribute.attr("", type);
165
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000166 Object defaultValue = arguments.get(DEFAULT_ARG);
Francois-Rene Rideau534dca12015-04-21 19:43:19 +0000167 if (!EvalUtils.isNullOrNone(defaultValue)) {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100168 if (defaultValue instanceof UserDefinedFunction) {
Florian Weikertea6c82d2016-09-05 12:15:31 +0000169 // Computed attribute. Non label type attributes already caused a type check error.
170 SkylarkCallbackFunction callback =
171 new SkylarkCallbackFunction((UserDefinedFunction) defaultValue, ast, env);
172 // SkylarkComputedDefaultTemplate needs to know the names of all attributes that it depends
173 // on. However, this method does not know anything about other attributes.
174 // We solve this problem by asking the SkylarkCallbackFunction for the parameter names used
175 // in the function definition, which must be the names of attributes used by the callback.
Laurent Le Brune1e31742015-07-24 16:02:14 +0000176 builder.value(
Florian Weikertea6c82d2016-09-05 12:15:31 +0000177 new SkylarkComputedDefaultTemplate(
178 type, callback.getParameterNames(), callback, ast.getLocation()));
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100179 } else {
Florian Weikertcb3d7992016-09-06 14:54:22 +0000180 builder.defaultValue(defaultValue, env.getGlobals().label());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100181 }
182 }
183
Francois-Rene Rideau93ed7f12015-10-20 15:39:33 +0000184 for (String flag : SkylarkList.castSkylarkListOrNoneToList(
185 arguments.get(FLAGS_ARG), String.class, FLAGS_ARG)) {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100186 builder.setPropertyFlag(flag);
187 }
188
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000189 if (containsNonNoneKey(arguments, MANDATORY_ARG) && (Boolean) arguments.get(MANDATORY_ARG)) {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100190 builder.setPropertyFlag("MANDATORY");
191 }
192
Laurent Le Brunbc16f722016-07-06 13:40:24 +0000193 // TODO(laurentlb): Deprecated, remove in August 2016 (use allow_empty instead).
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000194 if (containsNonNoneKey(arguments, NON_EMPTY_ARG) && (Boolean) arguments.get(NON_EMPTY_ARG)) {
Laurent Le Brun375b8812015-03-06 18:36:17 +0000195 builder.setPropertyFlag("NON_EMPTY");
196 }
197
Laurent Le Brunbc16f722016-07-06 13:40:24 +0000198 if (containsNonNoneKey(arguments, ALLOW_EMPTY_ARG)
199 && !(Boolean) arguments.get(ALLOW_EMPTY_ARG)) {
200 builder.setPropertyFlag("NON_EMPTY");
201 }
202
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000203 if (containsNonNoneKey(arguments, EXECUTABLE_ARG) && (Boolean) arguments.get(EXECUTABLE_ARG)) {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100204 builder.setPropertyFlag("EXECUTABLE");
Vladimir Moskvadfad9e32016-09-15 18:22:01 +0000205 if (!containsNonNoneKey(arguments, CONFIGURATION_ARG)) {
Vladimir Moskva5a510772016-11-23 19:03:38 +0000206 String message = "Argument `cfg = \"host\"`, `cfg = \"data\"`, or `cfg = \"target\"` "
207 + "is required if `executable = True` is provided for a label. Please see "
Florian Weikertfa437122016-11-04 16:44:29 +0000208 + "https://www.bazel.build/versions/master/docs/skylark/rules.html#configurations "
209 + "for more details.";
Vladimir Moskvadfad9e32016-09-15 18:22:01 +0000210 env.handleEvent(Event.warn(loc, message));
211 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100212 }
213
Laurent Le Brun50681c12016-07-05 10:08:54 +0000214 // TODO(laurentlb): Deprecated, remove in August 2016 (use allow_single_file).
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000215 if (containsNonNoneKey(arguments, SINGLE_FILE_ARG)
216 && (Boolean) arguments.get(SINGLE_FILE_ARG)) {
Laurent Le Brun50681c12016-07-05 10:08:54 +0000217 if (containsNonNoneKey(arguments, ALLOW_SINGLE_FILE_ARG)) {
218 throw new EvalException(
219 ast.getLocation(),
220 "Cannot specify both single_file (deprecated) and allow_single_file");
221 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100222 builder.setPropertyFlag("SINGLE_ARTIFACT");
223 }
224
Laurent Le Brun50681c12016-07-05 10:08:54 +0000225 if (containsNonNoneKey(arguments, ALLOW_FILES_ARG)
226 && containsNonNoneKey(arguments, ALLOW_SINGLE_FILE_ARG)) {
227 throw new EvalException(
228 ast.getLocation(), "Cannot specify both allow_files and allow_single_file");
229 }
230
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000231 if (containsNonNoneKey(arguments, ALLOW_FILES_ARG)) {
232 Object fileTypesObj = arguments.get(ALLOW_FILES_ARG);
Laurent Le Brun50681c12016-07-05 10:08:54 +0000233 setAllowedFileTypes(ALLOW_FILES_ARG, fileTypesObj, ast, builder);
234 } else if (containsNonNoneKey(arguments, ALLOW_SINGLE_FILE_ARG)) {
235 Object fileTypesObj = arguments.get(ALLOW_SINGLE_FILE_ARG);
236 setAllowedFileTypes(ALLOW_SINGLE_FILE_ARG, fileTypesObj, ast, builder);
237 builder.setPropertyFlag("SINGLE_ARTIFACT");
Lukacs Berkiffa73ad2015-09-18 11:40:12 +0000238 } else if (type.equals(BuildType.LABEL) || type.equals(BuildType.LABEL_LIST)) {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100239 builder.allowedFileTypes(FileTypeSet.NO_FILE);
240 }
241
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000242 Object ruleClassesObj = arguments.get(ALLOW_RULES_ARG);
Francois-Rene Rideau0f7ba342015-08-31 16:16:21 +0000243 if (ruleClassesObj != null && ruleClassesObj != Runtime.NONE) {
Laurent Le Brune1e31742015-07-24 16:02:14 +0000244 builder.allowedRuleClasses(
Francois-Rene Rideau93ed7f12015-10-20 15:39:33 +0000245 SkylarkList.castSkylarkListOrNoneToList(
246 ruleClassesObj, String.class, "allowed rule classes for attribute definition"));
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100247 }
248
Francois-Rene Rideau93ed7f12015-10-20 15:39:33 +0000249 List<Object> values = SkylarkList.castSkylarkListOrNoneToList(
250 arguments.get(VALUES_ARG), Object.class, VALUES_ARG);
Laurent Le Brunebecc552015-06-17 09:12:18 +0000251 if (!Iterables.isEmpty(values)) {
252 builder.allowedValues(new AllowedValueSet(values));
253 }
254
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000255 if (containsNonNoneKey(arguments, PROVIDERS_ARG)) {
Yun Peng83fbb91a2016-02-23 18:37:44 +0000256 Object obj = arguments.get(PROVIDERS_ARG);
257 SkylarkType.checkType(obj, SkylarkList.class, PROVIDERS_ARG);
258 boolean isSingleListOfStr = true;
259 for (Object o : (SkylarkList) obj) {
260 isSingleListOfStr = o instanceof String;
261 if (!isSingleListOfStr) {
262 break;
263 }
264 }
265 if (isSingleListOfStr) {
Dmitry Lomovfd2bdc32016-10-07 08:52:10 +0000266 builder.mandatoryProviders(getSkylarkProviderIdentifiers((SkylarkList<?>) obj));
Yun Peng83fbb91a2016-02-23 18:37:44 +0000267 } else {
268 builder.mandatoryProvidersList(getProvidersList((SkylarkList) obj));
269 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100270 }
271
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000272 if (containsNonNoneKey(arguments, CONFIGURATION_ARG)) {
Laurent Le Brunc4ddf6f2016-07-04 13:38:38 +0000273 Object trans = arguments.get(CONFIGURATION_ARG);
Damien Martin-Guillerez6022b7b2016-09-13 15:57:52 +0000274 if (trans instanceof ConfigurationTransition) {
275 // TODO(laurentlb): Deprecated, to be removed in August 2016.
Florian Weikertfa437122016-11-04 16:44:29 +0000276 String message = "Variables HOST_CFG and DATA_CFG are deprecated in favor of strings "
277 + "\"host\" and \"data\" correspondingly";
Vladimir Moskvadfad9e32016-09-15 18:22:01 +0000278 env.handleEvent(Event.warn(loc, message));
Damien Martin-Guillerez6022b7b2016-09-13 15:57:52 +0000279 builder.cfg((ConfigurationTransition) trans);
280 } else if (trans.equals("data")) {
Laurent Le Brunc4ddf6f2016-07-04 13:38:38 +0000281 builder.cfg(ConfigurationTransition.DATA);
282 } else if (trans.equals("host")) {
283 builder.cfg(ConfigurationTransition.HOST);
Vladimir Moskva5a510772016-11-23 19:03:38 +0000284 } else if (!trans.equals("target")) {
285 throw new EvalException(ast.getLocation(),
286 "cfg must be either 'data', 'host', or 'target'.");
Laurent Le Brunc4ddf6f2016-07-04 13:38:38 +0000287 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100288 }
289 return builder;
290 }
291
Dmitry Lomovfd2bdc32016-10-07 08:52:10 +0000292 private static Iterable<SkylarkProviderIdentifier> getSkylarkProviderIdentifiers(
293 SkylarkList<?> obj) throws EvalException {
294 return Iterables.transform(obj.getContents(String.class, PROVIDERS_ARG),
295 new Function<String, SkylarkProviderIdentifier>() {
296 @Override
297 public SkylarkProviderIdentifier apply(String s) {
298 return SkylarkProviderIdentifier.forLegacy(s);
299 }
300 });
301 }
302
303 private static List<Iterable<SkylarkProviderIdentifier>> getProvidersList(
304 SkylarkList<?> skylarkList) throws EvalException {
305 List<Iterable<SkylarkProviderIdentifier>> providersList = new ArrayList<>();
Yun Peng83fbb91a2016-02-23 18:37:44 +0000306 String errorMsg = "Illegal argument: element in '%s' is of unexpected type. "
Yun Pengda9410c2016-03-18 21:14:51 +0000307 + "Should be list of string, but got %s. "
308 + "Notice: one single list of string as 'providers' is still supported.";
Yun Peng83fbb91a2016-02-23 18:37:44 +0000309 for (Object o : skylarkList) {
310 if (!(o instanceof SkylarkList)) {
311 throw new EvalException(null, String.format(errorMsg, PROVIDERS_ARG,
Yun Pengda9410c2016-03-18 21:14:51 +0000312 EvalUtils.getDataTypeName(o, true)));
Yun Peng83fbb91a2016-02-23 18:37:44 +0000313 }
314 for (Object value : (SkylarkList) o) {
315 if (!(value instanceof String)) {
316 throw new EvalException(null, String.format(errorMsg, PROVIDERS_ARG,
317 "list with an element of type "
Yun Pengda9410c2016-03-18 21:14:51 +0000318 + EvalUtils.getDataTypeNameFromClass(value.getClass())));
Yun Peng83fbb91a2016-02-23 18:37:44 +0000319 }
320 }
Dmitry Lomovfd2bdc32016-10-07 08:52:10 +0000321 providersList.add(getSkylarkProviderIdentifiers((SkylarkList<?>) o));
Yun Peng83fbb91a2016-02-23 18:37:44 +0000322 }
323 return providersList;
324 }
325
Dmitry Lomov5a8f1c02015-11-26 10:49:16 +0000326 private static Descriptor createAttrDescriptor(
Francois-Rene Rideauab049e02016-02-17 16:13:46 +0000327 SkylarkDict<String, Object> kwargs, Type<?> type, FuncallExpression ast, Environment env)
Laurent Le Brune1e31742015-07-24 16:02:14 +0000328 throws EvalException {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100329 try {
Vladimir Moskvadfad9e32016-09-15 18:22:01 +0000330 return new Descriptor(createAttribute(type, kwargs, ast, env, ast.getLocation()));
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100331 } catch (ConversionException e) {
332 throw new EvalException(ast.getLocation(), e.getMessage());
333 }
334 }
335
Nathan Harmata4ec1e582016-06-10 15:58:30 +0000336 private static final Map<Type<?>, String> whyNotConfigurable =
337 ImmutableMap.<Type<?>, String>builder()
338 .put(BuildType.LICENSE,
339 "loading phase license checking logic assumes non-configurable values")
340 .put(BuildType.OUTPUT, "output paths are part of the static graph structure")
341 .build();
342
343 /**
344 * If the given attribute type is non-configurable, returns the reason why. Otherwise, returns
345 * {@code null}.
346 */
347 @Nullable
348 public static String maybeGetNonConfigurableReason(Type<?> type) {
349 return whyNotConfigurable.get(type);
350 }
351
Greg Estren223976c2016-02-04 22:40:56 +0000352 private static Descriptor createNonconfigurableAttrDescriptor(
Francois-Rene Rideauab049e02016-02-17 16:13:46 +0000353 SkylarkDict<String, Object> kwargs,
354 Type<?> type,
Francois-Rene Rideauab049e02016-02-17 16:13:46 +0000355 FuncallExpression ast,
Greg Estren223976c2016-02-04 22:40:56 +0000356 Environment env) throws EvalException {
Nathan Harmata4ec1e582016-06-10 15:58:30 +0000357 String whyNotConfigurableReason =
358 Preconditions.checkNotNull(maybeGetNonConfigurableReason(type), type);
Greg Estren223976c2016-02-04 22:40:56 +0000359 try {
360 return new Descriptor(
Vladimir Moskvadfad9e32016-09-15 18:22:01 +0000361 createAttribute(type, kwargs, ast, env, ast.getLocation())
362 .nonconfigurable(whyNotConfigurableReason));
Greg Estren223976c2016-02-04 22:40:56 +0000363 } catch (ConversionException e) {
364 throw new EvalException(ast.getLocation(), e.getMessage());
365 }
366 }
367
Laurent Le Brune1e31742015-07-24 16:02:14 +0000368 @SkylarkSignature(
369 name = "int",
370 doc = "Creates an attribute of type int.",
371 objectType = SkylarkAttr.class,
Dmitry Lomov7b599452015-11-26 10:07:32 +0000372 returnType = Descriptor.class,
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +0000373 parameters = {
Laurent Le Brune1e31742015-07-24 16:02:14 +0000374 @Param(
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000375 name = DEFAULT_ARG,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000376 type = Integer.class,
377 defaultValue = "0",
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +0000378 doc = DEFAULT_DOC,
379 named = true,
380 positional = false
Laurent Le Brune1e31742015-07-24 16:02:14 +0000381 ),
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +0000382 @Param(
383 name = MANDATORY_ARG,
384 type = Boolean.class,
385 defaultValue = "False",
386 doc = MANDATORY_DOC,
387 named = true,
388 positional = false
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000389 ),
Laurent Le Brune1e31742015-07-24 16:02:14 +0000390 @Param(
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000391 name = VALUES_ARG,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000392 type = SkylarkList.class,
393 generic1 = Integer.class,
394 defaultValue = "[]",
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +0000395 doc = VALUES_DOC,
396 named = true,
397 positional = false
Laurent Le Brune1e31742015-07-24 16:02:14 +0000398 )
399 },
400 useAst = true,
401 useEnvironment = true
402 )
403 private static BuiltinFunction integer =
404 new BuiltinFunction("int") {
Dmitry Lomov7b599452015-11-26 10:07:32 +0000405 public Descriptor invoke(
Laurent Le Brune1e31742015-07-24 16:02:14 +0000406 Integer defaultInt,
407 Boolean mandatory,
Francois-Rene Rideauab049e02016-02-17 16:13:46 +0000408 SkylarkList<?> values,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000409 FuncallExpression ast,
410 Environment env)
411 throws EvalException {
412 // TODO(bazel-team): Replace literal strings with constants.
Damien Martin-Guillerez074b9572016-05-23 12:33:07 +0000413 env.checkLoadingOrWorkspacePhase("attr.int", ast.getLocation());
Dmitry Lomov5a8f1c02015-11-26 10:49:16 +0000414 return createAttrDescriptor(
Francois-Rene Rideauab049e02016-02-17 16:13:46 +0000415 EvalUtils.<String, Object>optionMap(
416 env, DEFAULT_ARG, defaultInt, MANDATORY_ARG, mandatory, VALUES_ARG, values),
Laurent Le Brune1e31742015-07-24 16:02:14 +0000417 Type.INTEGER,
418 ast,
419 env);
420 }
421 };
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100422
Laurent Le Brune1e31742015-07-24 16:02:14 +0000423 @SkylarkSignature(
424 name = "string",
Dave MacLachlanf2d560a2016-03-02 01:24:44 +0000425 doc = "Creates an attribute of type <a href=\"string.html\">string</a>.",
Laurent Le Brune1e31742015-07-24 16:02:14 +0000426 objectType = SkylarkAttr.class,
Dmitry Lomov7b599452015-11-26 10:07:32 +0000427 returnType = Descriptor.class,
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +0000428 parameters = {
Laurent Le Brune1e31742015-07-24 16:02:14 +0000429 @Param(
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000430 name = DEFAULT_ARG,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000431 type = String.class,
432 defaultValue = "''",
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +0000433 doc = DEFAULT_DOC,
434 named = true,
435 positional = false
Laurent Le Brune1e31742015-07-24 16:02:14 +0000436 ),
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +0000437 @Param(
438 name = MANDATORY_ARG,
439 type = Boolean.class,
440 defaultValue = "False",
441 doc = MANDATORY_DOC,
442 named = true,
443 positional = false
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000444 ),
Laurent Le Brune1e31742015-07-24 16:02:14 +0000445 @Param(
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000446 name = VALUES_ARG,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000447 type = SkylarkList.class,
448 generic1 = String.class,
449 defaultValue = "[]",
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +0000450 doc = VALUES_DOC,
451 named = true,
452 positional = false
Laurent Le Brune1e31742015-07-24 16:02:14 +0000453 )
454 },
455 useAst = true,
456 useEnvironment = true
457 )
458 private static BuiltinFunction string =
459 new BuiltinFunction("string") {
Dmitry Lomov7b599452015-11-26 10:07:32 +0000460 public Descriptor invoke(
Laurent Le Brune1e31742015-07-24 16:02:14 +0000461 String defaultString,
462 Boolean mandatory,
Francois-Rene Rideauab049e02016-02-17 16:13:46 +0000463 SkylarkList<?> values,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000464 FuncallExpression ast,
465 Environment env)
466 throws EvalException {
Damien Martin-Guillerez074b9572016-05-23 12:33:07 +0000467 env.checkLoadingOrWorkspacePhase("attr.string", ast.getLocation());
Dmitry Lomov5a8f1c02015-11-26 10:49:16 +0000468 return createAttrDescriptor(
Francois-Rene Rideauab049e02016-02-17 16:13:46 +0000469 EvalUtils.<String, Object>optionMap(
470 env, DEFAULT_ARG, defaultString, MANDATORY_ARG, mandatory, VALUES_ARG, values),
Laurent Le Brune1e31742015-07-24 16:02:14 +0000471 Type.STRING,
472 ast,
473 env);
474 }
475 };
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100476
Laurent Le Brune1e31742015-07-24 16:02:14 +0000477 @SkylarkSignature(
478 name = "label",
479 doc =
Dave MacLachlanf2d560a2016-03-02 01:24:44 +0000480 "Creates an attribute of type <a href=\"Target.html\">Target</a> which is the target "
481 + "referred to by the label. "
Laurent Le Brune1e31742015-07-24 16:02:14 +0000482 + "It is the only way to specify a dependency to another target. "
Dave MacLachlanf2d560a2016-03-02 01:24:44 +0000483 + "If you need a dependency that the user cannot overwrite, "
484 + "<a href=\"../rules.html#private-attributes\">make the attribute private</a>.",
Laurent Le Brune1e31742015-07-24 16:02:14 +0000485 objectType = SkylarkAttr.class,
Dmitry Lomov7b599452015-11-26 10:07:32 +0000486 returnType = Descriptor.class,
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +0000487 parameters = {
Laurent Le Brune1e31742015-07-24 16:02:14 +0000488 @Param(
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000489 name = DEFAULT_ARG,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000490 type = Label.class,
491 callbackEnabled = true,
492 noneable = true,
493 defaultValue = "None",
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +0000494 named = true,
495 positional = false,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000496 doc =
497 DEFAULT_DOC
Dave MacLachlanf2d560a2016-03-02 01:24:44 +0000498 + " Use the <a href=\"globals.html#Label\"><code>Label</code></a> function to "
499 + "specify a default value ex:</p>"
500 + "<code>attr.label(default = Label(\"//a:b\"))</code>"
Laurent Le Brune1e31742015-07-24 16:02:14 +0000501 ),
Laurent Le Brune1e31742015-07-24 16:02:14 +0000502 @Param(
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000503 name = EXECUTABLE_ARG,
504 type = Boolean.class,
505 defaultValue = "False",
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +0000506 named = true,
507 positional = false,
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000508 doc = EXECUTABLE_DOC
509 ),
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +0000510 @Param(
511 name = ALLOW_FILES_ARG,
Laurent Le Brun50681c12016-07-05 10:08:54 +0000512 defaultValue = "None",
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +0000513 named = true,
514 positional = false,
515 doc = ALLOW_FILES_DOC
516 ),
517 @Param(
Laurent Le Brun50681c12016-07-05 10:08:54 +0000518 name = ALLOW_SINGLE_FILE_ARG,
519 defaultValue = "None",
520 named = true,
521 positional = false,
522 doc =
523 "This is similar to <code>allow_files</code>, with the restriction that the label must "
Googler01395612016-11-16 20:28:51 +0000524 + "correspond to a single <a href=\"File.html\">File</a>. "
Laurent Le Brun50681c12016-07-05 10:08:54 +0000525 + "Access it through <code>ctx.file.&lt;attribute_name&gt;</code>."
526 ),
527 @Param(
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +0000528 name = MANDATORY_ARG,
529 type = Boolean.class,
530 defaultValue = "False",
531 named = true,
532 positional = false,
533 doc = MANDATORY_DOC
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000534 ),
535 @Param(
536 name = PROVIDERS_ARG,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000537 type = SkylarkList.class,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000538 defaultValue = "[]",
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +0000539 named = true,
540 positional = false,
Yun Peng83fbb91a2016-02-23 18:37:44 +0000541 doc = PROVIDERS_DOC
Laurent Le Brune1e31742015-07-24 16:02:14 +0000542 ),
543 @Param(
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000544 name = ALLOW_RULES_ARG,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000545 type = SkylarkList.class,
546 generic1 = String.class,
547 noneable = true,
548 defaultValue = "None",
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +0000549 named = true,
550 positional = false,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000551 doc = ALLOW_RULES_DOC
552 ),
553 @Param(
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000554 name = SINGLE_FILE_ARG,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000555 type = Boolean.class,
556 defaultValue = "False",
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +0000557 named = true,
558 positional = false,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000559 doc =
Laurent Le Brun50681c12016-07-05 10:08:54 +0000560 "Deprecated: Use <code>allow_single_file</code> instead. "
Googler01395612016-11-16 20:28:51 +0000561 + "If True, the label must correspond to a single <a href=\"File.html\">File</a>. "
Laurent Le Brune1e31742015-07-24 16:02:14 +0000562 + "Access it through <code>ctx.file.&lt;attribute_name&gt;</code>."
563 ),
564 @Param(
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000565 name = CONFIGURATION_ARG,
Laurent Le Brunc4ddf6f2016-07-04 13:38:38 +0000566 type = Object.class,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000567 noneable = true,
568 defaultValue = "None",
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +0000569 named = true,
570 positional = false,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000571 doc = CONFIGURATION_DOC
Jon Brandveind93706d2016-09-15 17:15:24 +0000572 ),
573 @Param(
574 name = ASPECTS_ARG,
575 type = SkylarkList.class,
576 generic1 = SkylarkAspect.class,
577 defaultValue = "[]",
578 named = true,
579 positional = false,
580 doc = ASPECTS_ARG_DOC
Laurent Le Brune1e31742015-07-24 16:02:14 +0000581 )
582 },
583 useAst = true,
584 useEnvironment = true
585 )
586 private static BuiltinFunction label =
587 new BuiltinFunction("label") {
Dmitry Lomov7b599452015-11-26 10:07:32 +0000588 public Descriptor invoke(
Laurent Le Brune1e31742015-07-24 16:02:14 +0000589 Object defaultO,
590 Boolean executable,
591 Object allowFiles,
Laurent Le Brun50681c12016-07-05 10:08:54 +0000592 Object allowSingleFile,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000593 Boolean mandatory,
Francois-Rene Rideauab049e02016-02-17 16:13:46 +0000594 SkylarkList<?> providers,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000595 Object allowRules,
596 Boolean singleFile,
597 Object cfg,
Jon Brandveind93706d2016-09-15 17:15:24 +0000598 SkylarkList<?> aspects,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000599 FuncallExpression ast,
600 Environment env)
601 throws EvalException {
Damien Martin-Guillerez074b9572016-05-23 12:33:07 +0000602 env.checkLoadingOrWorkspacePhase("attr.label", ast.getLocation());
Jon Brandveind93706d2016-09-15 17:15:24 +0000603 try {
604 Attribute.Builder<?> attribute = createAttribute(
605 BuildType.LABEL,
606 EvalUtils.<String, Object>optionMap(
607 env,
608 DEFAULT_ARG,
609 defaultO,
610 EXECUTABLE_ARG,
611 executable,
612 ALLOW_FILES_ARG,
613 allowFiles,
614 ALLOW_SINGLE_FILE_ARG,
615 allowSingleFile,
616 MANDATORY_ARG,
617 mandatory,
618 PROVIDERS_ARG,
619 providers,
620 ALLOW_RULES_ARG,
621 allowRules,
622 SINGLE_FILE_ARG,
623 singleFile,
624 CONFIGURATION_ARG,
625 cfg),
626 ast,
Vladimir Moskvadfad9e32016-09-15 18:22:01 +0000627 env,
628 ast.getLocation());
Jon Brandveind93706d2016-09-15 17:15:24 +0000629 ImmutableList<SkylarkAspect> skylarkAspects =
630 ImmutableList.copyOf(aspects.getContents(SkylarkAspect.class, "aspects"));
631 return new Descriptor(attribute, skylarkAspects);
632 } catch (EvalException e) {
633 throw new EvalException(ast.getLocation(), e.getMessage(), e);
634 }
Laurent Le Brune1e31742015-07-24 16:02:14 +0000635 }
636 };
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100637
Laurent Le Brune1e31742015-07-24 16:02:14 +0000638 @SkylarkSignature(
639 name = "string_list",
Laurent Le Brunbc16f722016-07-06 13:40:24 +0000640 doc =
641 "Creates an attribute which is a <a href=\"list.html\">list</a> of "
642 + "<a href=\"string.html\">strings</a>.",
Laurent Le Brune1e31742015-07-24 16:02:14 +0000643 objectType = SkylarkAttr.class,
Dmitry Lomov7b599452015-11-26 10:07:32 +0000644 returnType = Descriptor.class,
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +0000645 parameters = {
Laurent Le Brune1e31742015-07-24 16:02:14 +0000646 @Param(
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000647 name = DEFAULT_ARG,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000648 type = SkylarkList.class,
649 generic1 = String.class,
650 defaultValue = "[]",
Dave MacLachlanf2d560a2016-03-02 01:24:44 +0000651 doc = DEFAULT_DOC
Laurent Le Brune1e31742015-07-24 16:02:14 +0000652 ),
Laurent Le Brunbc16f722016-07-06 13:40:24 +0000653 @Param(
654 name = MANDATORY_ARG,
655 type = Boolean.class,
656 defaultValue = "False",
657 doc = MANDATORY_DOC
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000658 ),
Laurent Le Brunbc16f722016-07-06 13:40:24 +0000659 @Param(
660 name = NON_EMPTY_ARG,
661 type = Boolean.class,
662 defaultValue = "False",
663 doc = NON_EMPTY_DOC
664 ),
665 @Param(
666 name = ALLOW_EMPTY_ARG,
667 type = Boolean.class,
668 defaultValue = "True",
Dmitry Shevchenko43731852016-07-29 17:42:34 +0000669 doc = ALLOW_EMPTY_DOC
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000670 )
Laurent Le Brune1e31742015-07-24 16:02:14 +0000671 },
672 useAst = true,
673 useEnvironment = true
674 )
675 private static BuiltinFunction stringList =
676 new BuiltinFunction("string_list") {
Dmitry Lomov7b599452015-11-26 10:07:32 +0000677 public Descriptor invoke(
Francois-Rene Rideauab049e02016-02-17 16:13:46 +0000678 SkylarkList<?> defaultList,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000679 Boolean mandatory,
680 Boolean nonEmpty,
Laurent Le Brunbc16f722016-07-06 13:40:24 +0000681 Boolean allowEmpty,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000682 FuncallExpression ast,
683 Environment env)
684 throws EvalException {
Damien Martin-Guillerez074b9572016-05-23 12:33:07 +0000685 env.checkLoadingOrWorkspacePhase("attr.string_list", ast.getLocation());
Dmitry Lomov5a8f1c02015-11-26 10:49:16 +0000686 return createAttrDescriptor(
Francois-Rene Rideauab049e02016-02-17 16:13:46 +0000687 EvalUtils.<String, Object>optionMap(
688 env,
689 DEFAULT_ARG,
690 defaultList,
691 MANDATORY_ARG,
692 mandatory,
693 NON_EMPTY_ARG,
Laurent Le Brunbc16f722016-07-06 13:40:24 +0000694 nonEmpty,
695 ALLOW_EMPTY_ARG,
696 allowEmpty),
Laurent Le Brune1e31742015-07-24 16:02:14 +0000697 Type.STRING_LIST,
698 ast,
699 env);
700 }
701 };
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100702
Laurent Le Brune1e31742015-07-24 16:02:14 +0000703 @SkylarkSignature(
704 name = "int_list",
Dave MacLachlanf2d560a2016-03-02 01:24:44 +0000705 doc = "Creates an attribute which is a <a href=\"list.html\">list</a> of ints",
Laurent Le Brune1e31742015-07-24 16:02:14 +0000706 objectType = SkylarkAttr.class,
Dmitry Lomov7b599452015-11-26 10:07:32 +0000707 returnType = Descriptor.class,
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +0000708 parameters = {
Laurent Le Brune1e31742015-07-24 16:02:14 +0000709 @Param(
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000710 name = DEFAULT_ARG,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000711 type = SkylarkList.class,
712 generic1 = Integer.class,
713 defaultValue = "[]",
Dave MacLachlanf2d560a2016-03-02 01:24:44 +0000714 doc = DEFAULT_DOC
Laurent Le Brune1e31742015-07-24 16:02:14 +0000715 ),
Laurent Le Brunbc16f722016-07-06 13:40:24 +0000716 @Param(
717 name = MANDATORY_ARG,
718 type = Boolean.class,
719 defaultValue = "False",
720 doc = MANDATORY_DOC
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000721 ),
Laurent Le Brunbc16f722016-07-06 13:40:24 +0000722 @Param(
723 name = NON_EMPTY_ARG,
724 type = Boolean.class,
725 defaultValue = "False",
726 doc = NON_EMPTY_DOC
727 ),
728 @Param(
729 name = ALLOW_EMPTY_ARG,
730 type = Boolean.class,
731 defaultValue = "True",
732 doc = ALLOW_EMPTY_DOC
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000733 )
Laurent Le Brune1e31742015-07-24 16:02:14 +0000734 },
735 useAst = true,
736 useEnvironment = true
737 )
738 private static BuiltinFunction intList =
739 new BuiltinFunction("int_list") {
Dmitry Lomov7b599452015-11-26 10:07:32 +0000740 public Descriptor invoke(
Francois-Rene Rideauab049e02016-02-17 16:13:46 +0000741 SkylarkList<?> defaultList,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000742 Boolean mandatory,
743 Boolean nonEmpty,
Laurent Le Brunbc16f722016-07-06 13:40:24 +0000744 Boolean allowEmpty,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000745 FuncallExpression ast,
746 Environment env)
747 throws EvalException {
Damien Martin-Guillerez074b9572016-05-23 12:33:07 +0000748 env.checkLoadingOrWorkspacePhase("attr.int_list", ast.getLocation());
Dmitry Lomov5a8f1c02015-11-26 10:49:16 +0000749 return createAttrDescriptor(
Francois-Rene Rideauab049e02016-02-17 16:13:46 +0000750 EvalUtils.<String, Object>optionMap(
751 env,
752 DEFAULT_ARG,
753 defaultList,
754 MANDATORY_ARG,
755 mandatory,
756 NON_EMPTY_ARG,
Laurent Le Brunbc16f722016-07-06 13:40:24 +0000757 nonEmpty,
758 ALLOW_EMPTY_ARG,
759 allowEmpty),
Laurent Le Brune1e31742015-07-24 16:02:14 +0000760 Type.INTEGER_LIST,
761 ast,
762 env);
763 }
764 };
Laurent Le Brunb20459d2015-07-24 15:41:55 +0000765
Laurent Le Brune1e31742015-07-24 16:02:14 +0000766 @SkylarkSignature(
767 name = "label_list",
768 doc =
Dave MacLachlanf2d560a2016-03-02 01:24:44 +0000769 "Creates an attribute which is a <a href=\"list.html\">list</a> of type "
770 + "<a href=\"Target.html\">Target</a> which are specified by the labels in the list. "
David Chen24f2d992015-08-17 17:25:46 +0000771 + "See <a href=\"attr.html#label\">label</a> for more information.",
Laurent Le Brune1e31742015-07-24 16:02:14 +0000772 objectType = SkylarkAttr.class,
Dmitry Lomov7b599452015-11-26 10:07:32 +0000773 returnType = Descriptor.class,
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +0000774 parameters = {
Laurent Le Brune1e31742015-07-24 16:02:14 +0000775 @Param(
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000776 name = DEFAULT_ARG,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000777 type = SkylarkList.class,
778 generic1 = Label.class,
779 callbackEnabled = true,
780 defaultValue = "[]",
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +0000781 named = true,
782 positional = false,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000783 doc =
784 DEFAULT_DOC
Dave MacLachlanf2d560a2016-03-02 01:24:44 +0000785 + " Use the <a href=\"globals.html#Label\"><code>Label</code></a> function to "
786 + "specify default values ex:</p>"
787 + "<code>attr.label_list(default = [ Label(\"//a:b\"), Label(\"//a:c\") ])</code>"
Laurent Le Brune1e31742015-07-24 16:02:14 +0000788 ),
789 @Param(
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000790 name = ALLOW_FILES_ARG, // bool or FileType filter
Laurent Le Brun50681c12016-07-05 10:08:54 +0000791 defaultValue = "None",
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +0000792 named = true,
793 positional = false,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000794 doc = ALLOW_FILES_DOC
795 ),
796 @Param(
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000797 name = ALLOW_RULES_ARG,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000798 type = SkylarkList.class,
799 generic1 = String.class,
800 noneable = true,
801 defaultValue = "None",
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +0000802 named = true,
803 positional = false,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000804 doc = ALLOW_RULES_DOC
805 ),
806 @Param(
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000807 name = PROVIDERS_ARG,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000808 type = SkylarkList.class,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000809 defaultValue = "[]",
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +0000810 named = true,
811 positional = false,
Yun Peng83fbb91a2016-02-23 18:37:44 +0000812 doc = PROVIDERS_DOC
Laurent Le Brune1e31742015-07-24 16:02:14 +0000813 ),
814 @Param(
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000815 name = FLAGS_ARG,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000816 type = SkylarkList.class,
817 generic1 = String.class,
818 defaultValue = "[]",
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +0000819 named = true,
820 positional = false,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000821 doc = FLAGS_DOC
822 ),
Laurent Le Brunbc16f722016-07-06 13:40:24 +0000823 @Param(
824 name = MANDATORY_ARG,
825 type = Boolean.class,
826 defaultValue = "False",
827 named = true,
828 positional = false,
829 doc = MANDATORY_DOC
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000830 ),
Laurent Le Brunbc16f722016-07-06 13:40:24 +0000831 @Param(
832 name = NON_EMPTY_ARG,
833 type = Boolean.class,
834 defaultValue = "False",
835 named = true,
836 positional = false,
837 doc = NON_EMPTY_DOC
838 ),
839 @Param(
840 name = ALLOW_EMPTY_ARG,
841 type = Boolean.class,
842 defaultValue = "True",
843 doc = ALLOW_EMPTY_DOC
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000844 ),
Laurent Le Brune1e31742015-07-24 16:02:14 +0000845 @Param(
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000846 name = CONFIGURATION_ARG,
Laurent Le Brunc4ddf6f2016-07-04 13:38:38 +0000847 type = Object.class,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000848 noneable = true,
849 defaultValue = "None",
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +0000850 named = true,
851 positional = false,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000852 doc = CONFIGURATION_DOC
Dmitry Lomov5a8f1c02015-11-26 10:49:16 +0000853 ),
854 @Param(
855 name = ASPECTS_ARG,
856 type = SkylarkList.class,
857 generic1 = SkylarkAspect.class,
858 defaultValue = "[]",
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +0000859 named = true,
860 positional = false,
Jon Brandveind93706d2016-09-15 17:15:24 +0000861 doc = ASPECTS_ARG_DOC
Laurent Le Brune1e31742015-07-24 16:02:14 +0000862 )
863 },
864 useAst = true,
865 useEnvironment = true
866 )
867 private static BuiltinFunction labelList =
868 new BuiltinFunction("label_list") {
Dmitry Lomov7b599452015-11-26 10:07:32 +0000869 public Descriptor invoke(
Laurent Le Brune1e31742015-07-24 16:02:14 +0000870 Object defaultList,
871 Object allowFiles,
872 Object allowRules,
Francois-Rene Rideauab049e02016-02-17 16:13:46 +0000873 SkylarkList<?> providers,
874 SkylarkList<?> flags,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000875 Boolean mandatory,
876 Boolean nonEmpty,
Laurent Le Brunbc16f722016-07-06 13:40:24 +0000877 Boolean allowEmpty,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000878 Object cfg,
Francois-Rene Rideauab049e02016-02-17 16:13:46 +0000879 SkylarkList<?> aspects,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000880 FuncallExpression ast,
881 Environment env)
882 throws EvalException {
Damien Martin-Guillerez074b9572016-05-23 12:33:07 +0000883 env.checkLoadingOrWorkspacePhase("attr.label_list", ast.getLocation());
Laurent Le Brunbc16f722016-07-06 13:40:24 +0000884 SkylarkDict<String, Object> kwargs =
885 EvalUtils.<String, Object>optionMap(
886 env,
887 DEFAULT_ARG,
888 defaultList,
889 ALLOW_FILES_ARG,
890 allowFiles,
891 ALLOW_RULES_ARG,
892 allowRules,
893 PROVIDERS_ARG,
894 providers,
895 FLAGS_ARG,
896 flags,
897 MANDATORY_ARG,
898 mandatory,
899 NON_EMPTY_ARG,
900 nonEmpty,
901 ALLOW_EMPTY_ARG,
902 allowEmpty,
903 CONFIGURATION_ARG,
904 cfg);
Dmitry Lomov5a8f1c02015-11-26 10:49:16 +0000905 try {
Laurent Le Brunbc16f722016-07-06 13:40:24 +0000906 Attribute.Builder<?> attribute =
Vladimir Moskvadfad9e32016-09-15 18:22:01 +0000907 createAttribute(BuildType.LABEL_LIST, kwargs, ast, env, ast.getLocation());
Francois-Rene Rideauab049e02016-02-17 16:13:46 +0000908 ImmutableList<SkylarkAspect> skylarkAspects =
909 ImmutableList.copyOf(aspects.getContents(SkylarkAspect.class, "aspects"));
Dmitry Lomov5a8f1c02015-11-26 10:49:16 +0000910 return new Descriptor(attribute, skylarkAspects);
Francois-Rene Rideauab049e02016-02-17 16:13:46 +0000911 } catch (EvalException e) {
912 throw new EvalException(ast.getLocation(), e.getMessage(), e);
Dmitry Lomov5a8f1c02015-11-26 10:49:16 +0000913 }
914 }
Laurent Le Brune1e31742015-07-24 16:02:14 +0000915 };
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100916
Laurent Le Brune1e31742015-07-24 16:02:14 +0000917 @SkylarkSignature(
918 name = "bool",
Dave MacLachlanf2d560a2016-03-02 01:24:44 +0000919 doc = "Creates an attribute of type bool.",
Laurent Le Brune1e31742015-07-24 16:02:14 +0000920 objectType = SkylarkAttr.class,
Dmitry Lomov7b599452015-11-26 10:07:32 +0000921 returnType = Descriptor.class,
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +0000922 parameters = {
923 @Param(
924 name = DEFAULT_ARG,
925 type = Boolean.class,
926 defaultValue = "False",
927 named = true,
928 positional = false,
929 doc = DEFAULT_DOC
930 ),
931 @Param(
932 name = MANDATORY_ARG,
933 type = Boolean.class,
934 defaultValue = "False",
935 named = true,
936 positional = false,
937 doc = MANDATORY_DOC
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000938 )
Laurent Le Brune1e31742015-07-24 16:02:14 +0000939 },
940 useAst = true,
941 useEnvironment = true
942 )
943 private static BuiltinFunction bool =
944 new BuiltinFunction("bool") {
Dmitry Lomov7b599452015-11-26 10:07:32 +0000945 public Descriptor invoke(
Laurent Le Brune1e31742015-07-24 16:02:14 +0000946 Boolean defaultO, Boolean mandatory, FuncallExpression ast, Environment env)
947 throws EvalException {
Damien Martin-Guillerez074b9572016-05-23 12:33:07 +0000948 env.checkLoadingOrWorkspacePhase("attr.bool", ast.getLocation());
Dmitry Lomov5a8f1c02015-11-26 10:49:16 +0000949 return createAttrDescriptor(
Francois-Rene Rideauab049e02016-02-17 16:13:46 +0000950 EvalUtils.<String, Object>optionMap(
951 env, DEFAULT_ARG, defaultO, MANDATORY_ARG, mandatory),
Laurent Le Brune1e31742015-07-24 16:02:14 +0000952 Type.BOOLEAN,
953 ast,
954 env);
955 }
956 };
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100957
Laurent Le Brune1e31742015-07-24 16:02:14 +0000958 @SkylarkSignature(
959 name = "output",
960 doc =
Dave MacLachlanf2d560a2016-03-02 01:24:44 +0000961 "Creates an attribute of type output. "
Laurent Le Brune1e31742015-07-24 16:02:14 +0000962 + "The user provides a file name (string) and the rule must create an action that "
963 + "generates the file.",
964 objectType = SkylarkAttr.class,
Dmitry Lomov7b599452015-11-26 10:07:32 +0000965 returnType = Descriptor.class,
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +0000966 parameters = {
Laurent Le Brune1e31742015-07-24 16:02:14 +0000967 @Param(
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000968 name = DEFAULT_ARG,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000969 type = Label.class,
970 noneable = true,
971 defaultValue = "None",
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +0000972 named = true,
973 positional = false,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000974 doc = DEFAULT_DOC
975 ),
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +0000976 @Param(
977 name = MANDATORY_ARG,
978 type = Boolean.class,
979 defaultValue = "False",
980 named = true,
981 positional = false,
982 doc = MANDATORY_DOC
Laurent Le Brun4deafa82015-07-24 16:51:52 +0000983 )
Laurent Le Brune1e31742015-07-24 16:02:14 +0000984 },
985 useAst = true,
986 useEnvironment = true
987 )
988 private static BuiltinFunction output =
989 new BuiltinFunction("output") {
Dmitry Lomov7b599452015-11-26 10:07:32 +0000990 public Descriptor invoke(
Laurent Le Brune1e31742015-07-24 16:02:14 +0000991 Object defaultO, Boolean mandatory, FuncallExpression ast, Environment env)
992 throws EvalException {
Damien Martin-Guillerez074b9572016-05-23 12:33:07 +0000993 env.checkLoadingOrWorkspacePhase("attr.output", ast.getLocation());
Greg Estren223976c2016-02-04 22:40:56 +0000994 return createNonconfigurableAttrDescriptor(
Francois-Rene Rideauab049e02016-02-17 16:13:46 +0000995 EvalUtils.<String, Object>optionMap(
996 env, DEFAULT_ARG, defaultO, MANDATORY_ARG, mandatory),
Lukacs Berkiffa73ad2015-09-18 11:40:12 +0000997 BuildType.OUTPUT,
Laurent Le Brune1e31742015-07-24 16:02:14 +0000998 ast,
999 env);
1000 }
1001 };
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +01001002
Laurent Le Brune1e31742015-07-24 16:02:14 +00001003 @SkylarkSignature(
1004 name = "output_list",
1005 doc =
Dave MacLachlanf2d560a2016-03-02 01:24:44 +00001006 "Creates an attribute which is a <a href=\"list.html\">list</a> of outputs. "
1007 + "See <a href=\"attr.html#output\">output</a> for more information.",
Laurent Le Brune1e31742015-07-24 16:02:14 +00001008 objectType = SkylarkAttr.class,
Dmitry Lomov7b599452015-11-26 10:07:32 +00001009 returnType = Descriptor.class,
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +00001010 parameters = {
Laurent Le Brune1e31742015-07-24 16:02:14 +00001011 @Param(
Laurent Le Brun4deafa82015-07-24 16:51:52 +00001012 name = DEFAULT_ARG,
Laurent Le Brune1e31742015-07-24 16:02:14 +00001013 type = SkylarkList.class,
1014 generic1 = Label.class,
1015 defaultValue = "[]",
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +00001016 named = true,
1017 positional = false,
Laurent Le Brune1e31742015-07-24 16:02:14 +00001018 doc = DEFAULT_DOC
1019 ),
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +00001020 @Param(
1021 name = MANDATORY_ARG,
1022 type = Boolean.class,
1023 defaultValue = "False",
1024 named = true,
1025 positional = false,
1026 doc = MANDATORY_DOC
Laurent Le Brun4deafa82015-07-24 16:51:52 +00001027 ),
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +00001028 @Param(
1029 name = NON_EMPTY_ARG,
1030 type = Boolean.class,
1031 defaultValue = "False",
1032 named = true,
1033 positional = false,
1034 doc = NON_EMPTY_DOC
Laurent Le Brunbc16f722016-07-06 13:40:24 +00001035 ),
1036 @Param(
1037 name = ALLOW_EMPTY_ARG,
1038 type = Boolean.class,
1039 defaultValue = "True",
1040 doc = ALLOW_EMPTY_DOC
Laurent Le Brun4deafa82015-07-24 16:51:52 +00001041 )
Laurent Le Brune1e31742015-07-24 16:02:14 +00001042 },
1043 useAst = true,
1044 useEnvironment = true
1045 )
1046 private static BuiltinFunction outputList =
1047 new BuiltinFunction("output_list") {
Dmitry Lomov7b599452015-11-26 10:07:32 +00001048 public Descriptor invoke(
Laurent Le Brune1e31742015-07-24 16:02:14 +00001049 SkylarkList defaultList,
1050 Boolean mandatory,
1051 Boolean nonEmpty,
Laurent Le Brunbc16f722016-07-06 13:40:24 +00001052 Boolean allowEmpty,
Laurent Le Brune1e31742015-07-24 16:02:14 +00001053 FuncallExpression ast,
1054 Environment env)
1055 throws EvalException {
Damien Martin-Guillerez074b9572016-05-23 12:33:07 +00001056 env.checkLoadingOrWorkspacePhase("attr.output_list", ast.getLocation());
Dmitry Lomov5a8f1c02015-11-26 10:49:16 +00001057 return createAttrDescriptor(
Francois-Rene Rideauab049e02016-02-17 16:13:46 +00001058 EvalUtils.<String, Object>optionMap(
1059 env,
1060 DEFAULT_ARG,
1061 defaultList,
1062 MANDATORY_ARG,
1063 mandatory,
1064 NON_EMPTY_ARG,
Laurent Le Brunbc16f722016-07-06 13:40:24 +00001065 nonEmpty,
1066 ALLOW_EMPTY_ARG,
1067 allowEmpty),
Lukacs Berkiffa73ad2015-09-18 11:40:12 +00001068 BuildType.OUTPUT_LIST,
Laurent Le Brune1e31742015-07-24 16:02:14 +00001069 ast,
1070 env);
1071 }
1072 };
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +01001073
Laurent Le Brune1e31742015-07-24 16:02:14 +00001074 @SkylarkSignature(
1075 name = "string_dict",
Laurent Le Brunbc16f722016-07-06 13:40:24 +00001076 doc =
1077 "Creates an attribute of type <a href=\"dict.html\">dict</a>, mapping from "
1078 + "<a href=\"string.html\">string</a> to <a href=\"string.html\">string</a>.",
Laurent Le Brune1e31742015-07-24 16:02:14 +00001079 objectType = SkylarkAttr.class,
Dmitry Lomov7b599452015-11-26 10:07:32 +00001080 returnType = Descriptor.class,
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +00001081 parameters = {
1082 @Param(
1083 name = DEFAULT_ARG,
1084 type = SkylarkDict.class,
1085 named = true,
1086 positional = false,
1087 defaultValue = "{}",
1088 doc = DEFAULT_DOC
Laurent Le Brun4deafa82015-07-24 16:51:52 +00001089 ),
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +00001090 @Param(
1091 name = MANDATORY_ARG,
1092 type = Boolean.class,
1093 named = true,
1094 positional = false,
1095 defaultValue = "False",
1096 doc = MANDATORY_DOC
1097 ),
1098 @Param(
1099 name = NON_EMPTY_ARG,
1100 type = Boolean.class,
1101 defaultValue = "False",
1102 named = true,
1103 positional = false,
1104 doc = NON_EMPTY_DOC
Laurent Le Brunbc16f722016-07-06 13:40:24 +00001105 ),
1106 @Param(
1107 name = ALLOW_EMPTY_ARG,
1108 type = Boolean.class,
1109 defaultValue = "True",
1110 doc = ALLOW_EMPTY_DOC
Laurent Le Brun4deafa82015-07-24 16:51:52 +00001111 )
Laurent Le Brune1e31742015-07-24 16:02:14 +00001112 },
1113 useAst = true,
1114 useEnvironment = true
1115 )
1116 private static BuiltinFunction stringDict =
1117 new BuiltinFunction("string_dict") {
Dmitry Lomov7b599452015-11-26 10:07:32 +00001118 public Descriptor invoke(
Francois-Rene Rideauab049e02016-02-17 16:13:46 +00001119 SkylarkDict<?, ?> defaultO,
Laurent Le Brune1e31742015-07-24 16:02:14 +00001120 Boolean mandatory,
1121 Boolean nonEmpty,
Laurent Le Brunbc16f722016-07-06 13:40:24 +00001122 Boolean allowEmpty,
Laurent Le Brune1e31742015-07-24 16:02:14 +00001123 FuncallExpression ast,
1124 Environment env)
1125 throws EvalException {
Damien Martin-Guillerez074b9572016-05-23 12:33:07 +00001126 env.checkLoadingOrWorkspacePhase("attr.string_dict", ast.getLocation());
Dmitry Lomov5a8f1c02015-11-26 10:49:16 +00001127 return createAttrDescriptor(
Francois-Rene Rideauab049e02016-02-17 16:13:46 +00001128 EvalUtils.<String, Object>optionMap(
Laurent Le Brunbc16f722016-07-06 13:40:24 +00001129 env,
1130 DEFAULT_ARG,
1131 defaultO,
1132 MANDATORY_ARG,
1133 mandatory,
1134 NON_EMPTY_ARG,
1135 nonEmpty,
1136 ALLOW_EMPTY_ARG,
1137 allowEmpty),
Laurent Le Brune1e31742015-07-24 16:02:14 +00001138 Type.STRING_DICT,
1139 ast,
1140 env);
1141 }
1142 };
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +01001143
Laurent Le Brune1e31742015-07-24 16:02:14 +00001144 @SkylarkSignature(
Francois-Rene Rideau028e3192015-10-29 14:26:59 +00001145 name = "string_list_dict",
Laurent Le Brunbc16f722016-07-06 13:40:24 +00001146 doc =
1147 "Creates an attribute of type <a href=\"dict.html\">dict</a>, mapping from "
1148 + "<a href=\"string.html\">string</a> to <a href=\"list.html\">list</a> of "
1149 + "<a href=\"string.html\">string</a>.",
Francois-Rene Rideau028e3192015-10-29 14:26:59 +00001150 objectType = SkylarkAttr.class,
Dmitry Lomov7b599452015-11-26 10:07:32 +00001151 returnType = Descriptor.class,
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +00001152 parameters = {
1153 @Param(
1154 name = DEFAULT_ARG,
1155 type = SkylarkDict.class,
1156 defaultValue = "{}",
1157 named = true,
1158 positional = false,
1159 doc = DEFAULT_DOC
Francois-Rene Rideau028e3192015-10-29 14:26:59 +00001160 ),
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +00001161 @Param(
1162 name = MANDATORY_ARG,
1163 type = Boolean.class,
1164 defaultValue = "False",
1165 named = true,
1166 positional = false,
1167 doc = MANDATORY_DOC
1168 ),
1169 @Param(
1170 name = NON_EMPTY_ARG,
1171 type = Boolean.class,
1172 defaultValue = "False",
1173 named = true,
1174 positional = false,
1175 doc = NON_EMPTY_DOC
Laurent Le Brunbc16f722016-07-06 13:40:24 +00001176 ),
1177 @Param(
1178 name = ALLOW_EMPTY_ARG,
1179 type = Boolean.class,
1180 defaultValue = "True",
1181 doc = ALLOW_EMPTY_DOC
Francois-Rene Rideau028e3192015-10-29 14:26:59 +00001182 )
1183 },
1184 useAst = true,
1185 useEnvironment = true
1186 )
1187 private static BuiltinFunction stringListDict =
1188 new BuiltinFunction("string_list_dict") {
Dmitry Lomov7b599452015-11-26 10:07:32 +00001189 public Descriptor invoke(
Francois-Rene Rideauab049e02016-02-17 16:13:46 +00001190 SkylarkDict<?, ?> defaultO,
Francois-Rene Rideau028e3192015-10-29 14:26:59 +00001191 Boolean mandatory,
1192 Boolean nonEmpty,
Laurent Le Brunbc16f722016-07-06 13:40:24 +00001193 Boolean allowEmpty,
Francois-Rene Rideau028e3192015-10-29 14:26:59 +00001194 FuncallExpression ast,
1195 Environment env)
1196 throws EvalException {
Damien Martin-Guillerez074b9572016-05-23 12:33:07 +00001197 env.checkLoadingOrWorkspacePhase("attr.string_list_dict", ast.getLocation());
Dmitry Lomov5a8f1c02015-11-26 10:49:16 +00001198 return createAttrDescriptor(
Francois-Rene Rideauab049e02016-02-17 16:13:46 +00001199 EvalUtils.<String, Object>optionMap(
Laurent Le Brunbc16f722016-07-06 13:40:24 +00001200 env,
1201 DEFAULT_ARG,
1202 defaultO,
1203 MANDATORY_ARG,
1204 mandatory,
1205 NON_EMPTY_ARG,
1206 nonEmpty,
1207 ALLOW_EMPTY_ARG,
1208 allowEmpty),
Francois-Rene Rideau028e3192015-10-29 14:26:59 +00001209 Type.STRING_LIST_DICT,
1210 ast,
1211 env);
1212 }
1213 };
1214
1215 @SkylarkSignature(
Laurent Le Brune1e31742015-07-24 16:02:14 +00001216 name = "license",
Dave MacLachlanf2d560a2016-03-02 01:24:44 +00001217 doc = "Creates an attribute of type license.",
Laurent Le Brune1e31742015-07-24 16:02:14 +00001218 // TODO(bazel-team): Implement proper license support for Skylark.
1219 objectType = SkylarkAttr.class,
Dmitry Lomov7b599452015-11-26 10:07:32 +00001220 returnType = Descriptor.class,
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +00001221 parameters = {
Laurent Le Brune1e31742015-07-24 16:02:14 +00001222 // TODO(bazel-team): ensure this is the correct default value
Damien Martin-Guillerez014388c2016-06-14 10:28:31 +00001223 @Param(
1224 name = DEFAULT_ARG,
1225 defaultValue = "None",
1226 noneable = true,
1227 named = true,
1228 positional = false,
1229 doc = DEFAULT_DOC),
1230 @Param(
1231 name = MANDATORY_ARG,
1232 type = Boolean.class,
1233 defaultValue = "False",
1234 named = true,
1235 positional = false,
1236 doc = MANDATORY_DOC
Laurent Le Brun4deafa82015-07-24 16:51:52 +00001237 )
Laurent Le Brune1e31742015-07-24 16:02:14 +00001238 },
1239 useAst = true,
1240 useEnvironment = true
1241 )
1242 private static BuiltinFunction license =
1243 new BuiltinFunction("license") {
Dmitry Lomov7b599452015-11-26 10:07:32 +00001244 public Descriptor invoke(
Laurent Le Brune1e31742015-07-24 16:02:14 +00001245 Object defaultO, Boolean mandatory, FuncallExpression ast, Environment env)
1246 throws EvalException {
Damien Martin-Guillerez074b9572016-05-23 12:33:07 +00001247 env.checkLoadingOrWorkspacePhase("attr.license", ast.getLocation());
Greg Estren223976c2016-02-04 22:40:56 +00001248 return createNonconfigurableAttrDescriptor(
Francois-Rene Rideauab049e02016-02-17 16:13:46 +00001249 EvalUtils.<String, Object>optionMap(
1250 env, DEFAULT_ARG, defaultO, MANDATORY_ARG, mandatory),
Lukacs Berkiffa73ad2015-09-18 11:40:12 +00001251 BuildType.LICENSE,
Laurent Le Brune1e31742015-07-24 16:02:14 +00001252 ast,
1253 env);
1254 }
1255 };
Francois-Rene Rideau537a90b2015-04-22 06:47:31 +00001256
Dmitry Lomov34cdae32016-06-28 16:13:35 +00001257 /** A descriptor of an attribute defined in Skylark. */
1258 @SkylarkModule(
1259 name = "attr_defintion",
1260 category = SkylarkModuleCategory.NONE,
1261 doc =
Florian Weikertfa437122016-11-04 16:44:29 +00001262 "Representation of a definition of an attribute; constructed by <code>attr.*</code> "
1263 + "functions. They are only for use with <a href=\"globals.html#rule\">rule</a> or "
Laurent Le Brun8f0092d2016-07-06 13:14:38 +00001264 + "<a href=\"globals.html#aspect\">aspect</a>."
1265
Dmitry Lomov34cdae32016-06-28 16:13:35 +00001266 )
Dmitry Lomov7b599452015-11-26 10:07:32 +00001267 public static final class Descriptor {
1268 private final Attribute.Builder<?> attributeBuilder;
Dmitry Lomov5a8f1c02015-11-26 10:49:16 +00001269 private final ImmutableList<SkylarkAspect> aspects;
Dmitry Lomovc5cd8dd2016-07-18 10:42:18 +00001270 boolean exported;
Dmitry Lomov7b599452015-11-26 10:07:32 +00001271
1272 public Descriptor(Attribute.Builder<?> attributeBuilder) {
Dmitry Lomov5a8f1c02015-11-26 10:49:16 +00001273 this(attributeBuilder, ImmutableList.<SkylarkAspect>of());
1274 }
1275
1276 public Descriptor(Attribute.Builder<?> attributeBuilder, ImmutableList<SkylarkAspect> aspects) {
Dmitry Lomov7b599452015-11-26 10:07:32 +00001277 this.attributeBuilder = attributeBuilder;
Dmitry Lomov5a8f1c02015-11-26 10:49:16 +00001278 this.aspects = aspects;
Dmitry Lomovc5cd8dd2016-07-18 10:42:18 +00001279 exported = false;
Dmitry Lomov7b599452015-11-26 10:07:32 +00001280 }
1281
1282 public Attribute.Builder<?> getAttributeBuilder() {
1283 return attributeBuilder;
1284 }
Dmitry Lomov5a8f1c02015-11-26 10:49:16 +00001285
1286 public ImmutableList<SkylarkAspect> getAspects() {
1287 return aspects;
1288 }
Dmitry Lomovc5cd8dd2016-07-18 10:42:18 +00001289
1290 public void exportAspects(Location definitionLocation) throws EvalException {
1291 if (exported) {
1292 // Only export an attribute definiton once.
1293 return;
1294 }
1295 Attribute.Builder<?> attributeBuilder = getAttributeBuilder();
1296 for (SkylarkAspect skylarkAspect : getAspects()) {
1297 if (!skylarkAspect.isExported()) {
1298 throw new EvalException(definitionLocation,
1299 "All aspects applied to rule dependencies must be top-level values");
1300 }
Dmitry Lomovf188dc22016-07-19 09:00:55 +00001301 attributeBuilder.aspect(skylarkAspect, definitionLocation);
Dmitry Lomovc5cd8dd2016-07-18 10:42:18 +00001302 }
1303 exported = true;
1304 }
Dmitry Lomov7b599452015-11-26 10:07:32 +00001305 }
1306
Francois-Rene Rideau537a90b2015-04-22 06:47:31 +00001307 static {
1308 SkylarkSignatureProcessor.configureSkylarkFunctions(SkylarkAttr.class);
1309 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +01001310}