/** * Add a Skylark transitive info. The provider value must be safe (i.e. a String, a Boolean, an * Integer, an Artifact, a Label, None, a Java TransitiveInfoProvider or something composed from * these in Skylark using lists, sets, structs or dicts). Otherwise an EvalException is thrown. */ public RuleConfiguredTargetBuilder addSkylarkTransitiveInfo( String name, Object value, Location loc) throws EvalException { try { checkSkylarkObjectSafe(value); } catch (IllegalArgumentException e) { throw new EvalException( loc, String.format("Value of provider '%s' is of an illegal type: %s", name, e.getMessage())); } skylarkProviders.put(name, value); return this; }
private void checkCompositeSkylarkObjectSafe(Object object) { if (object instanceof SkylarkApiProvider) { return; } else if (object instanceof SkylarkList) { SkylarkList list = (SkylarkList) object; if (list == SkylarkList.EMPTY_LIST || isSimpleSkylarkObjectSafe(list.getContentType().getType())) { // Try not to iterate over the list if avoidable. return; } // The list can be a tuple or a list of composite items. for (Object listItem : list) { checkSkylarkObjectSafe(listItem); } return; } else if (object instanceof SkylarkNestedSet) { // SkylarkNestedSets cannot have composite items. Class<?> contentType = ((SkylarkNestedSet) object).getContentType().getType(); if (!contentType.equals(Object.class) && !isSimpleSkylarkObjectSafe(contentType)) { throw new IllegalArgumentException(EvalUtils.getDataTypeName(contentType)); } return; } else if (object instanceof Map<?, ?>) { for (Map.Entry<?, ?> entry : ((Map<?, ?>) object).entrySet()) { checkSkylarkObjectSafe(entry.getKey()); checkSkylarkObjectSafe(entry.getValue()); } return; } else if (object instanceof ClassObject) { ClassObject struct = (ClassObject) object; for (String key : struct.getKeys()) { checkSkylarkObjectSafe(struct.getValue(key)); } return; } throw new IllegalArgumentException(EvalUtils.getDataTypeName(object)); }
/** Add a Skylark transitive info. The provider value must be safe. */ public RuleConfiguredTargetBuilder addSkylarkTransitiveInfo(String name, Object value) { checkSkylarkObjectSafe(value); skylarkProviders.put(name, value); return this; }