Search in sources :

Example 1 with Builder

use of com.google.common.collect.ImmutableMap.Builder in project bazel by bazelbuild.

the class SkylarkRuleContext method buildAttributesCollection.

private static SkylarkRuleAttributesCollection buildAttributesCollection(Collection<Attribute> attributes, RuleContext ruleContext, Function<Attribute, Object> attributeValueExtractor) {
    Builder<String, Object> attrBuilder = new Builder<>();
    Builder<String, Object> executableBuilder = new Builder<>();
    Builder<Artifact, FilesToRunProvider> executableRunfilesbuilder = new Builder<>();
    Builder<String, Object> fileBuilder = new Builder<>();
    Builder<String, Object> filesBuilder = new Builder<>();
    HashSet<Artifact> seenExecutables = new HashSet<>();
    for (Attribute a : attributes) {
        Type<?> type = a.getType();
        Object val = attributeValueExtractor.apply(a);
        // Skylark as a Map<String, Label>; this special case preserves that behavior temporarily.
        if (type.getLabelClass() != LabelClass.DEPENDENCY || type == BuildType.LABEL_DICT_UNARY) {
            attrBuilder.put(a.getPublicName(), val == null ? Runtime.NONE : // Attribute values should be type safe
            SkylarkType.convertToSkylark(val, null));
            continue;
        }
        String skyname = a.getPublicName();
        if (a.isExecutable()) {
            // In Skylark only label (not label list) type attributes can have the Executable flag.
            FilesToRunProvider provider = ruleContext.getExecutablePrerequisite(a.getName(), Mode.DONT_CHECK);
            if (provider != null && provider.getExecutable() != null) {
                Artifact executable = provider.getExecutable();
                executableBuilder.put(skyname, executable);
                if (!seenExecutables.contains(executable)) {
                    // todo(dslomov,laurentlb): In general, this is incorrect.
                    // We associate the first encountered FilesToRunProvider with
                    // the executable (this provider is later used to build the spawn).
                    // However ideally we should associate a provider with the attribute name,
                    // and pass the correct FilesToRunProvider to the spawn depending on
                    // what attribute is used to access the executable.
                    executableRunfilesbuilder.put(executable, provider);
                    seenExecutables.add(executable);
                }
            } else {
                executableBuilder.put(skyname, Runtime.NONE);
            }
        }
        if (a.isSingleArtifact()) {
            // In Skylark only label (not label list) type attributes can have the SingleArtifact flag.
            Artifact artifact = ruleContext.getPrerequisiteArtifact(a.getName(), Mode.DONT_CHECK);
            if (artifact != null) {
                fileBuilder.put(skyname, artifact);
            } else {
                fileBuilder.put(skyname, Runtime.NONE);
            }
        }
        filesBuilder.put(skyname, ruleContext.getPrerequisiteArtifacts(a.getName(), Mode.DONT_CHECK).list());
        if (type == BuildType.LABEL && !a.hasSplitConfigurationTransition()) {
            Object prereq = ruleContext.getPrerequisite(a.getName(), Mode.DONT_CHECK);
            if (prereq == null) {
                prereq = Runtime.NONE;
            }
            attrBuilder.put(skyname, prereq);
        } else if (type == BuildType.LABEL_LIST || (type == BuildType.LABEL && a.hasSplitConfigurationTransition())) {
            List<?> allPrereq = ruleContext.getPrerequisites(a.getName(), Mode.DONT_CHECK);
            attrBuilder.put(skyname, SkylarkList.createImmutable(allPrereq));
        } else if (type == BuildType.LABEL_KEYED_STRING_DICT) {
            ImmutableMap.Builder<TransitiveInfoCollection, String> builder = new ImmutableMap.Builder<>();
            Map<Label, String> original = BuildType.LABEL_KEYED_STRING_DICT.cast(val);
            List<? extends TransitiveInfoCollection> allPrereq = ruleContext.getPrerequisites(a.getName(), Mode.DONT_CHECK);
            for (TransitiveInfoCollection prereq : allPrereq) {
                builder.put(prereq, original.get(prereq.getLabel()));
            }
            attrBuilder.put(skyname, SkylarkType.convertToSkylark(builder.build(), null));
        } else if (type == BuildType.LABEL_DICT_UNARY) {
            Map<Label, TransitiveInfoCollection> prereqsByLabel = new LinkedHashMap<>();
            for (TransitiveInfoCollection target : ruleContext.getPrerequisites(a.getName(), Mode.DONT_CHECK)) {
                prereqsByLabel.put(target.getLabel(), target);
            }
            ImmutableMap.Builder<String, TransitiveInfoCollection> attrValue = new ImmutableMap.Builder<>();
            for (Map.Entry<String, Label> entry : ((Map<String, Label>) val).entrySet()) {
                attrValue.put(entry.getKey(), prereqsByLabel.get(entry.getValue()));
            }
            attrBuilder.put(skyname, attrValue.build());
        } else {
            throw new IllegalArgumentException("Can't transform attribute " + a.getName() + " of type " + type + " to a Skylark object");
        }
    }
    return new SkylarkRuleAttributesCollection(ruleContext.getRule().getRuleClass(), attrBuilder.build(), executableBuilder.build(), fileBuilder.build(), filesBuilder.build(), executableRunfilesbuilder.build());
}
Also used : FilesToRunProvider(com.google.devtools.build.lib.analysis.FilesToRunProvider) Attribute(com.google.devtools.build.lib.packages.Attribute) Builder(com.google.common.collect.ImmutableMap.Builder) Label(com.google.devtools.build.lib.cmdline.Label) Artifact(com.google.devtools.build.lib.actions.Artifact) ImmutableMap(com.google.common.collect.ImmutableMap) Entry(java.util.Map.Entry) SkylarkClassObject(com.google.devtools.build.lib.packages.SkylarkClassObject) List(java.util.List) SkylarkList(com.google.devtools.build.lib.syntax.SkylarkList) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) LinkedList(java.util.LinkedList) TransitiveInfoCollection(com.google.devtools.build.lib.analysis.TransitiveInfoCollection) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) HashSet(java.util.HashSet)

Aggregations

ImmutableList (com.google.common.collect.ImmutableList)1 ImmutableMap (com.google.common.collect.ImmutableMap)1 Builder (com.google.common.collect.ImmutableMap.Builder)1 Artifact (com.google.devtools.build.lib.actions.Artifact)1 FilesToRunProvider (com.google.devtools.build.lib.analysis.FilesToRunProvider)1 TransitiveInfoCollection (com.google.devtools.build.lib.analysis.TransitiveInfoCollection)1 Label (com.google.devtools.build.lib.cmdline.Label)1 Attribute (com.google.devtools.build.lib.packages.Attribute)1 SkylarkClassObject (com.google.devtools.build.lib.packages.SkylarkClassObject)1 SkylarkList (com.google.devtools.build.lib.syntax.SkylarkList)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 LinkedHashMap (java.util.LinkedHashMap)1 LinkedList (java.util.LinkedList)1 List (java.util.List)1 Map (java.util.Map)1 Entry (java.util.Map.Entry)1