// This is safe because of the type checking @SuppressWarnings("unchecked") private SkylarkNestedSet( Order order, SkylarkType contentType, Object item, Location loc, List<Object> items, List<NestedSet<Object>> transitiveItems) throws EvalException { // Adding the item if (item instanceof SkylarkNestedSet) { SkylarkNestedSet nestedSet = (SkylarkNestedSet) item; if (!nestedSet.isEmpty()) { contentType = checkType(contentType, nestedSet.contentType, loc); transitiveItems.add((NestedSet<Object>) nestedSet.set); } } else if (item instanceof SkylarkList) { // TODO(bazel-team): we should check ImmutableList here but it screws up genrule at line 43 for (Object object : (SkylarkList) item) { contentType = checkType(contentType, SkylarkType.of(object.getClass()), loc); checkImmutable(object, loc); items.add(object); } } else { throw new EvalException( loc, String.format("cannot add value of type '%s' to a set", EvalUtils.getDataTypeName(item))); } this.contentType = Preconditions.checkNotNull(contentType, "type cannot be null"); // Initializing the real nested set NestedSetBuilder<Object> builder = new NestedSetBuilder<>(order); builder.addAll(items); try { for (NestedSet<Object> nestedSet : transitiveItems) { builder.addTransitive(nestedSet); } } catch (IllegalStateException e) { throw new EvalException(loc, e.getMessage()); } this.set = builder.build(); this.items = ImmutableList.copyOf(items); this.transitiveItems = ImmutableList.copyOf(transitiveItems); }
@Override public Object getValue(String name) { switch (name) { case LABEL_FIELD: return getLabel(); case FILES_FIELD: // A shortcut for files to build in Skylark. FileConfiguredTarget and RuleConfiguredTarget // always has FileProvider and Error- and PackageGroupConfiguredTarget-s shouldn't be // accessible in Skylark. return SkylarkNestedSet.of( Artifact.class, getProvider(FileProvider.class).getFilesToBuild()); case DEFAULT_RUNFILES_FIELD: return RunfilesProvider.DEFAULT_RUNFILES.apply(this); case DATA_RUNFILES_FIELD: return RunfilesProvider.DATA_RUNFILES.apply(this); default: return get(name); } }
/** * Print an official representation of object x. For regular data structures, the value should be * parsable back into an equal data structure. * * @param buffer the Appendable to write to. * @param o the string a representation of which to write. * @param quotationMark The quotation mark to be used (' or ") * @return the Appendable, in fluent style. */ public static Appendable write(Appendable buffer, Object o, char quotationMark) { if (o == null) { throw new NullPointerException(); // Java null is not a build language value. } else if (o instanceof String) { writeString(buffer, (String) o, quotationMark); } else if (o instanceof Integer || o instanceof Double) { append(buffer, o.toString()); } else if (o == Runtime.NONE) { append(buffer, "None"); } else if (o == Boolean.TRUE) { append(buffer, "True"); } else if (o == Boolean.FALSE) { append(buffer, "False"); } else if (o instanceof List<?>) { List<?> seq = (List<?>) o; printList(buffer, seq, EvalUtils.isImmutable(seq), quotationMark); } else if (o instanceof SkylarkList) { SkylarkList list = (SkylarkList) o; printList(buffer, list.toList(), list.isTuple(), quotationMark); } else if (o instanceof Map<?, ?>) { Map<?, ?> dict = (Map<?, ?>) o; printList(buffer, getSortedEntrySet(dict), "{", ", ", "}", null, quotationMark); } else if (o instanceof Map.Entry<?, ?>) { Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o; write(buffer, entry.getKey(), quotationMark); append(buffer, ": "); write(buffer, entry.getValue(), quotationMark); } else if (o instanceof SkylarkNestedSet) { SkylarkNestedSet set = (SkylarkNestedSet) o; append(buffer, "set("); printList(buffer, set, "[", ", ", "]", null, quotationMark); Order order = set.getOrder(); if (order != Order.STABLE_ORDER) { append(buffer, ", order = \"" + order.getName() + "\""); } append(buffer, ")"); } else if (o instanceof BaseFunction) { BaseFunction func = (BaseFunction) o; append(buffer, "<function " + func.getName() + ">"); } else if (o instanceof Label) { write(buffer, o.toString(), quotationMark); } else if (o instanceof FilesetEntry) { FilesetEntry entry = (FilesetEntry) o; append(buffer, "FilesetEntry(srcdir = "); write(buffer, entry.getSrcLabel().toString(), quotationMark); append(buffer, ", files = "); write(buffer, makeStringList(entry.getFiles()), quotationMark); append(buffer, ", excludes = "); write(buffer, makeList(entry.getExcludes()), quotationMark); append(buffer, ", destdir = "); write(buffer, entry.getDestDir().getPathString(), quotationMark); append(buffer, ", strip_prefix = "); write(buffer, entry.getStripPrefix(), quotationMark); append(buffer, ", symlinks = "); append(buffer, quotationMark); append(buffer, entry.getSymlinkBehavior().toString()); append(buffer, quotationMark); append(buffer, ")"); } else if (o instanceof PathFragment) { append(buffer, ((PathFragment) o).getPathString()); } else { append(buffer, o.toString()); } return buffer; }