public class BuckSkylarkTypes extends Object
Modifier and Type | Method and Description |
---|---|
static Object |
asDeepImmutable(Object arg)
Attempt to get a deeply immutable instance of a value passed in from Skylark
|
static boolean |
isImmutable(Object o)
Checks if a given value is 'Immutable'.
|
static Object |
skylarkValueFromNullable(Object object) |
static <NonWildcardType,DestType extends NonWildcardType> |
toJavaList(com.google.devtools.build.lib.syntax.SkylarkList<?> list,
Class<NonWildcardType> elementClass,
String description)
Validate that all objects are of a given type and return an
ImmutableList containing
those objects. |
static void |
validateKwargName(com.google.devtools.build.lib.events.Location location,
String kwarg)
Ensure that a name is a valid kwarg/field identifier
|
static Object |
validateNoneOrType(com.google.devtools.build.lib.events.Location location,
Class<?> clazz,
Object object)
Check that a value is either
Runtime.NONE or an instance of clazz |
public static <NonWildcardType,DestType extends NonWildcardType> com.google.common.collect.ImmutableList<DestType> toJavaList(com.google.devtools.build.lib.syntax.SkylarkList<?> list, Class<NonWildcardType> elementClass, @Nullable String description) throws com.google.devtools.build.lib.syntax.EvalException
ImmutableList
containing
those objects.
This is a workaround for SkylarkList.getContents(Class, String)
being unable to
handle generic types correctly. e.g. it is currently impossible to do:
SkylarkList<?> skyList = // Provided by user
// Works, but compiler complains because Provider is not specialized
ImmutableList<Provider> providers = skyList.getContents(Provider.class, null));
// Does not work because Provider.class != the class of Provider<?>
ImmutableList<Provider<?>> providers = skyList.getContents(Provider.class, null));
This function makes the following usage possible
SkylarkList<?> skyList = // Provided by user
ImmutableList<Provider<?>> providers = BuckSkylarkTypes.toJavaList(skyList, Provider.class, null));
This function wraps a dirty type cast up and tries to apply some basic type boundaries to
reduce the likelihood of creating a foot gun.NonWildcardType
- The non-wildcard type. e.g. Provider.class
DestType
- The type of the elements in the resulting container. This can be either the
same as NonWildcardType
, or a generic type like Provider<?>
list
- The list of objects to validateelementClass
- The non-wildcard version of the desired final classdescription
- a description of the argument being converted, or null, for debuggingDestType
. This is immutable because we do some type casting under the
hood, and do not want any assumptions to be made about the backing store of the container,
nor do we want users to assume they can safely insert into that list.com.google.devtools.build.lib.syntax.EvalException
- If one of the elements was not of the type specified in elementClass
public static Object asDeepImmutable(Object arg) throws MutableObjectException
Note that if mutable objects are passed in (namely SkylarkList
or SkylarkDict
, a copy may be made to get an immutable instance. This may happen in very deeply
nested structures, so the runtime is variable based on how mutable the objects are. For the
best performance, only immutable structures should be passed in, as that turns into a simple
identity function.
arg
- A value from the skylark interpreter. This should only be primitive objects, or
SkylarkValue
instancesSkylarkValue
or a primitive value
SkylarkList
if the original object is a SkylarkList
and
all values were immutable or could be made immutable. As above, this may be a copy, or
inner elements may have had to be copied if they were mutable
SkylarkDict
if the original object is a SkylarkDict
and
all keys and values were immutable, or could be made so. Again, note that copies may be
made in order to make mutable objects immutableMutableObjectException
- If a nested or top level object was mutable, and could not be
made immutable. This generally only applies to incorrectly implemented native data types
that are exported to Skylark.public static void validateKwargName(com.google.devtools.build.lib.events.Location location, String kwarg) throws com.google.devtools.build.lib.syntax.EvalException
This is useful as Skylark does not validate these by default when creating a signature
location
- location of the kwarg currently being evaluatedkwarg
- the name of a kwarg / fieldcom.google.devtools.build.lib.syntax.EvalException
public static Object skylarkValueFromNullable(@Nullable Object object)
None
if object
is null
, else return object
. This is
just a central place ot make sure things we return from internal implementations into
Skylark are properly turned into Nonepublic static Object validateNoneOrType(com.google.devtools.build.lib.events.Location location, Class<?> clazz, Object object) throws com.google.devtools.build.lib.syntax.EvalException
Runtime.NONE
or an instance of clazz
location
- location of evaluationclazz
- the class that the object should be an instance of if not Runtime.NONE
object
- the object to checkcom.google.devtools.build.lib.syntax.EvalException
- if the object is not of the correct typepublic static boolean isImmutable(Object o)
EvalUtils.isImmutable(java.lang.Object)
, but it can also
handle ImmutableCollection
and ImmutableMap