// Copyright 2016 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.syntax; import com.google.common.collect.ImmutableList; import com.google.devtools.build.lib.collect.nestedset.Order; import com.google.devtools.build.lib.events.Location; import com.google.devtools.build.lib.skylarkinterface.Param; import com.google.devtools.build.lib.skylarkinterface.SkylarkSignature; import com.google.devtools.build.lib.syntax.SkylarkList.MutableList; import java.util.List; /** * A helper class containing additional built in functions for Bazel (BUILD files and .bzl files). */ public class BazelLibrary { @SkylarkSignature( name = "type", returnType = String.class, doc = "Returns the type name of its argument. This is useful for debugging and " + "type-checking. Examples:" + "
" + "type(2) == \"int\"\n" + "type([1]) == \"list\"\n" + "type(struct(a = 2)) == \"struct\"" + "" + "This function might change in the future. To write Python-compatible code and " + "be future-proof, use it only to compare return values: " + "
" + "if type(x) == type([]): # if x is a list" + "", parameters = {@Param(name = "x", doc = "The object to check type of.")} ) private static final BuiltinFunction type = new BuiltinFunction("type") { public String invoke(Object object) { // There is no 'type' type in Skylark, so we return a string with the type name. return EvalUtils.getDataTypeName(object, false); } }; @SkylarkSignature( name = "depset", returnType = SkylarkNestedSet.class, doc = "Creates a depset. The
direct
parameter is a list "
+ "of direct elements of the depset, and transitive
parameter is "
+ "a list of depsets whose elements become indirect elements of the created depset. "
+ "The order in which elements are returned when the depset is converted to a list "
+ "is specified by the order
parameter. "
+ "See the Depsets overview for more information. "
+ "All elements (direct and indirect) of a depset must be of the same type. " + "
The order of the created depset should be compatible with the order of "
+ "its transitive
depsets. \"default\"
order is compatible "
+ "with any other order, all other orders are only compatible with themselves."
+ "
Note on backward/forward compatibility. This function currently accepts a "
+ "positional items
parameter. It is deprecated and will be removed "
+ "in the future, and after its removal direct
will become a sole "
+ "positional parameter of the depset
function. Thus, both of the "
+ "following calls are equivalent and future-proof:
"
+ "
" + "depset(['a', 'b'], transitive = [...])\n" + "depset(direct = ['a', 'b'], transitive = [...])\n" + "", parameters = { @Param( name = "items", type = Object.class, defaultValue = "[]", doc = "Deprecated: Either an iterable whose items become the direct elements of " + "the new depset, in left-to-right order, or else a depset that becomes " + "a transitive element of the new depset. In the latter case, " + "
transitive
cannot be specified."
),
@Param(
name = "order",
type = String.class,
defaultValue = "\"default\"",
doc =
"The traversal strategy for the new depset. See here for "
+ "the possible values."
),
@Param(
name = "direct",
type = SkylarkList.class,
defaultValue = "None",
positional = false,
named = true,
noneable = true,
doc = "A list of direct elements of a depset."
),
@Param(
name = "transitive",
named = true,
positional = false,
type = SkylarkList.class,
generic1 = SkylarkNestedSet.class,
noneable = true,
doc = "A list of depsets whose elements will become indirect elements of the depset.",
defaultValue = "None"
)
},
useLocation = true
)
private static final BuiltinFunction depset =
new BuiltinFunction("depset") {
public SkylarkNestedSet invoke(
Object items, String orderString, Object direct, Object transitive, Location loc)
throws EvalException {
Order order;
try {
order = Order.parse(orderString);
} catch (IllegalArgumentException ex) {
throw new EvalException(loc, ex);
}
if (transitive == Runtime.NONE && direct == Runtime.NONE) {
// Legacy behavior.
return SkylarkNestedSet.of(order, items, loc);
}
if (direct != Runtime.NONE && !isEmptySkylarkList(items)) {
throw new EvalException(
loc, "Do not pass both 'direct' and 'items' argument to depset constructor.");
}
// Non-legacy behavior: either 'transitive' or 'direct' were specified.
Iterable