Search in sources :

Example 1 with SkylarkList

use of com.google.devtools.build.lib.syntax.SkylarkList in project bazel by bazelbuild.

the class SkylarkRuleContextTest method testAccessingRunfiles.

@Test
public void testAccessingRunfiles() throws Exception {
    scratch.file("test/a.py");
    scratch.file("test/b.py");
    scratch.file("test/__init__.py");
    scratch.file("test/rule.bzl", "def _impl(ctx):", "  return", "skylark_rule = rule(", "  implementation = _impl,", "  attrs = {", "    'dep': attr.label(),", "  },", ")");
    scratch.file("test/BUILD", "load('/test/rule', 'skylark_rule')", "py_library(name = 'lib', srcs = ['a.py', 'b.py'])", "skylark_rule(name = 'foo', dep = ':lib')", "py_library(name = 'lib_with_init', srcs = ['a.py', 'b.py', '__init__.py'])", "skylark_rule(name = 'foo_with_init', dep = ':lib_with_init')");
    SkylarkRuleContext ruleContext = createRuleContext("//test:foo");
    Object filenames = evalRuleContextCode(ruleContext, "[f.short_path for f in ruleContext.attr.dep.default_runfiles.files]");
    assertThat(filenames).isInstanceOf(SkylarkList.class);
    SkylarkList filenamesList = (SkylarkList) filenames;
    assertThat(filenamesList).containsExactly("test/a.py", "test/b.py").inOrder();
    Object emptyFilenames = evalRuleContextCode(ruleContext, "list(ruleContext.attr.dep.default_runfiles.empty_filenames)");
    assertThat(emptyFilenames).isInstanceOf(SkylarkList.class);
    SkylarkList emptyFilenamesList = (SkylarkList) emptyFilenames;
    assertThat(emptyFilenamesList).containsExactly("test/__init__.py").inOrder();
    SkylarkRuleContext ruleWithInitContext = createRuleContext("//test:foo_with_init");
    Object noEmptyFilenames = evalRuleContextCode(ruleWithInitContext, "list(ruleContext.attr.dep.default_runfiles.empty_filenames)");
    assertThat(noEmptyFilenames).isInstanceOf(SkylarkList.class);
    SkylarkList noEmptyFilenamesList = (SkylarkList) noEmptyFilenames;
    assertThat(noEmptyFilenamesList).containsExactly().inOrder();
}
Also used : SkylarkList(com.google.devtools.build.lib.syntax.SkylarkList) SkylarkClassObject(com.google.devtools.build.lib.packages.SkylarkClassObject) SkylarkRuleContext(com.google.devtools.build.lib.rules.SkylarkRuleContext) Test(org.junit.Test)

Example 2 with SkylarkList

use of com.google.devtools.build.lib.syntax.SkylarkList in project bazel by bazelbuild.

the class PackageFactory method skylarkifyValue.

/**
   * Converts back to type that will work in BUILD and skylark,
   * such as string instead of label, SkylarkList instead of List,
   * Returns null if we don't want to export the value.
   *
   * <p>All of the types returned are immutable. If we want, we can change this to
   * immutable in the future, but this is the safe choice for now.
   */
@Nullable
private static Object skylarkifyValue(Object val, Package pkg) throws NotRepresentableException {
    // from Java native types to Skylark types should be part of the Type class hierarchy,
    if (val == null) {
        return null;
    }
    if (val instanceof Boolean) {
        return val;
    }
    if (val instanceof Integer) {
        return val;
    }
    if (val instanceof String) {
        return val;
    }
    if (val instanceof TriState) {
        switch((TriState) val) {
            case AUTO:
                return Integer.valueOf(-1);
            case YES:
                return Integer.valueOf(1);
            case NO:
                return Integer.valueOf(0);
        }
    }
    if (val instanceof Label) {
        Label l = (Label) val;
        if (l.getPackageName().equals(pkg.getName())) {
            return ":" + l.getName();
        }
        return l.getCanonicalForm();
    }
    if (val instanceof List) {
        List<Object> l = new ArrayList<>();
        for (Object o : (List) val) {
            Object elt = skylarkifyValue(o, pkg);
            if (elt == null) {
                continue;
            }
            l.add(elt);
        }
        return SkylarkList.Tuple.copyOf(l);
    }
    if (val instanceof Map) {
        Map<Object, Object> m = new TreeMap<>();
        for (Map.Entry<?, ?> e : ((Map<?, ?>) val).entrySet()) {
            Object key = skylarkifyValue(e.getKey(), pkg);
            Object mapVal = skylarkifyValue(e.getValue(), pkg);
            if (key == null || mapVal == null) {
                continue;
            }
            m.put(key, mapVal);
        }
        return m;
    }
    if (val.getClass().isAnonymousClass()) {
        // Filter them until we invent something more clever.
        return null;
    }
    if (val instanceof SkylarkValue) {
        return val;
    }
    if (val instanceof License) {
        // TODO(bazel-team): convert License.getLicenseTypes() to a list of strings.
        return null;
    }
    if (val instanceof BuildType.SelectorList) {
        return val;
    }
    // if we add more types that we can represent.
    throw new NotRepresentableException(String.format("cannot represent %s (%s) in skylark", val.toString(), val.getClass().toString()));
}
Also used : Label(com.google.devtools.build.lib.cmdline.Label) ArrayList(java.util.ArrayList) TreeMap(java.util.TreeMap) GlobList(com.google.devtools.build.lib.syntax.GlobList) MutableList(com.google.devtools.build.lib.syntax.SkylarkList.MutableList) List(java.util.List) SkylarkList(com.google.devtools.build.lib.syntax.SkylarkList) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) ClassObject(com.google.devtools.build.lib.syntax.ClassObject) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) BuildLangTypedAttributeValuesMap(com.google.devtools.build.lib.packages.RuleFactory.BuildLangTypedAttributeValuesMap) TreeMap(java.util.TreeMap) SkylarkValue(com.google.devtools.build.lib.skylarkinterface.SkylarkValue) Nullable(javax.annotation.Nullable)

Example 3 with SkylarkList

use of com.google.devtools.build.lib.syntax.SkylarkList in project bazel by bazelbuild.

the class SkylarkAspectsTest method aspectOnAspectDiamond.

/**
   * Diamond case.
   * rule r1 depends or r0 with aspect a1.
   * rule r2 depends or r0 with aspect a2.
   * rule rcollect depends on r1, r2 with aspect a3.
   *
   * Aspect a3 should be applied twice to target r0: once in [a1, a3] sequence
   * and once in [a2, a3] sequence.
   */
@Test
public void aspectOnAspectDiamond() throws Exception {
    scratch.file("test/aspect.bzl", "def _a1_impl(target,ctx):", "  return struct(a1p = 'text from a1')", "a1 = aspect(_a1_impl, attr_aspects = ['deps'], provides = ['a1p'])", "", "def _a2_impl(target,ctx):", "  return struct(a2p = 'text from a2')", "a2 = aspect(_a2_impl, attr_aspects = ['deps'], provides = ['a2p'])", "", "def _a3_impl(target,ctx):", "  value = []", "  f = ctx.new_file('a3.out')", "  ctx.file_action(f, 'text')", "  for dep in ctx.rule.attr.deps:", "     if hasattr(dep, 'a3p'):", "         value += dep.a3p", "  s = str(target.label) + str(ctx.aspect_ids) + '='", "  if hasattr(target, 'a1p'):", "     s += 'a1p'", "  if hasattr(target, 'a2p'):", "     s += 'a2p'", "  value.append(s)", "  return struct(a3p = value)", "a3 = aspect(_a3_impl, attr_aspects = ['deps'],", "            required_aspect_providers = [['a1p'], ['a2p']])", "def _r1_impl(ctx):", "  pass", "def _rcollect_impl(ctx):", "  value = []", "  for dep in ctx.attr.deps:", "     if hasattr(dep, 'a3p'):", "         value += dep.a3p", "  return struct(result = value)", "r1 = rule(_r1_impl, attrs = { 'deps' : attr.label_list(aspects = [a1])})", "r2 = rule(_r1_impl, attrs = { 'deps' : attr.label_list(aspects = [a2])})", "rcollect = rule(_rcollect_impl, attrs = { 'deps' : attr.label_list(aspects = [a3])})");
    scratch.file("test/BUILD", "load(':aspect.bzl', 'r1', 'r2', 'rcollect')", "r1(name = 'r0')", "r1(name = 'r1', deps = [':r0'])", "r2(name = 'r2', deps = [':r0'])", "rcollect(name = 'rcollect', deps = [':r1', ':r2'])");
    AnalysisResult analysisResult = update("//test:rcollect");
    ConfiguredTarget target = Iterables.getOnlyElement(analysisResult.getTargetsToBuild());
    SkylarkList result = (SkylarkList) target.get("result");
    assertThat(result).containsExactly("//test:r0[\"//test:aspect.bzl%a1\", \"//test:aspect.bzl%a3\"]=a1p", "//test:r1[\"//test:aspect.bzl%a3\"]=", "//test:r0[\"//test:aspect.bzl%a2\", \"//test:aspect.bzl%a3\"]=a2p", "//test:r2[\"//test:aspect.bzl%a3\"]=");
}
Also used : SkylarkList(com.google.devtools.build.lib.syntax.SkylarkList) ConfiguredTarget(com.google.devtools.build.lib.analysis.ConfiguredTarget) AnalysisResult(com.google.devtools.build.lib.analysis.BuildView.AnalysisResult) Test(org.junit.Test)

Example 4 with SkylarkList

use of com.google.devtools.build.lib.syntax.SkylarkList in project bazel by bazelbuild.

the class SkylarkRuleConfiguredTargetBuilder method convertToOutputGroupValue.

public static NestedSet<Artifact> convertToOutputGroupValue(Location loc, String outputGroup, SkylarkValue objects) throws EvalException {
    NestedSet<Artifact> artifacts;
    String typeErrorMessage = "Output group '%s' is of unexpected type. " + "Should be list or set of Files, but got '%s' instead.";
    if (objects instanceof SkylarkList) {
        NestedSetBuilder<Artifact> nestedSetBuilder = NestedSetBuilder.stableOrder();
        for (Object o : (SkylarkList) objects) {
            if (o instanceof Artifact) {
                nestedSetBuilder.add((Artifact) o);
            } else {
                throw new EvalException(loc, String.format(typeErrorMessage, outputGroup, "list with an element of " + EvalUtils.getDataTypeNameFromClass(o.getClass())));
            }
        }
        artifacts = nestedSetBuilder.build();
    } else {
        artifacts = SkylarkType.cast(objects, SkylarkNestedSet.class, Artifact.class, loc, typeErrorMessage, outputGroup, EvalUtils.getDataTypeName(objects, true)).getSet(Artifact.class);
    }
    return artifacts;
}
Also used : SkylarkList(com.google.devtools.build.lib.syntax.SkylarkList) SkylarkClassObject(com.google.devtools.build.lib.packages.SkylarkClassObject) ClassObject(com.google.devtools.build.lib.syntax.ClassObject) EvalException(com.google.devtools.build.lib.syntax.EvalException) Artifact(com.google.devtools.build.lib.actions.Artifact)

Example 5 with SkylarkList

use of com.google.devtools.build.lib.syntax.SkylarkList in project bazel by bazelbuild.

the class SkylarkAttr method createAttribute.

private static Attribute.Builder<?> createAttribute(Type<?> type, SkylarkDict<String, Object> arguments, FuncallExpression ast, Environment env) throws EvalException, ConversionException {
    // We use an empty name now so that we can set it later.
    // This trick makes sense only in the context of Skylark (builtin rules should not use it).
    Attribute.Builder<?> builder = Attribute.attr("", type);
    Object defaultValue = arguments.get(DEFAULT_ARG);
    if (!EvalUtils.isNullOrNone(defaultValue)) {
        if (defaultValue instanceof UserDefinedFunction) {
            // Computed attribute. Non label type attributes already caused a type check error.
            SkylarkCallbackFunction callback = new SkylarkCallbackFunction((UserDefinedFunction) defaultValue, ast, env);
            // SkylarkComputedDefaultTemplate needs to know the names of all attributes that it depends
            // on. However, this method does not know anything about other attributes.
            // We solve this problem by asking the SkylarkCallbackFunction for the parameter names used
            // in the function definition, which must be the names of attributes used by the callback.
            builder.value(new SkylarkComputedDefaultTemplate(type, callback.getParameterNames(), callback, ast.getLocation()));
        } else {
            builder.defaultValue(defaultValue, env.getGlobals().label());
        }
    }
    for (String flag : SkylarkList.castSkylarkListOrNoneToList(arguments.get(FLAGS_ARG), String.class, FLAGS_ARG)) {
        builder.setPropertyFlag(flag);
    }
    if (containsNonNoneKey(arguments, MANDATORY_ARG) && (Boolean) arguments.get(MANDATORY_ARG)) {
        builder.setPropertyFlag("MANDATORY");
    }
    // TODO(laurentlb): Deprecated, remove in August 2016 (use allow_empty instead).
    if (containsNonNoneKey(arguments, NON_EMPTY_ARG) && (Boolean) arguments.get(NON_EMPTY_ARG)) {
        builder.setPropertyFlag("NON_EMPTY");
    }
    if (containsNonNoneKey(arguments, ALLOW_EMPTY_ARG) && !(Boolean) arguments.get(ALLOW_EMPTY_ARG)) {
        builder.setPropertyFlag("NON_EMPTY");
    }
    if (containsNonNoneKey(arguments, EXECUTABLE_ARG) && (Boolean) arguments.get(EXECUTABLE_ARG)) {
        builder.setPropertyFlag("EXECUTABLE");
        if (!containsNonNoneKey(arguments, CONFIGURATION_ARG)) {
            throw new EvalException(ast.getLocation(), "cfg parameter is mandatory when executable=True is provided. Please see " + "https://www.bazel.build/versions/master/docs/skylark/rules.html#configurations " + "for more details.");
        }
    }
    // TODO(laurentlb): Deprecated, remove in August 2016 (use allow_single_file).
    if (containsNonNoneKey(arguments, SINGLE_FILE_ARG) && (Boolean) arguments.get(SINGLE_FILE_ARG)) {
        if (containsNonNoneKey(arguments, ALLOW_SINGLE_FILE_ARG)) {
            throw new EvalException(ast.getLocation(), "Cannot specify both single_file (deprecated) and allow_single_file");
        }
        builder.setPropertyFlag("SINGLE_ARTIFACT");
    }
    if (containsNonNoneKey(arguments, ALLOW_FILES_ARG) && containsNonNoneKey(arguments, ALLOW_SINGLE_FILE_ARG)) {
        throw new EvalException(ast.getLocation(), "Cannot specify both allow_files and allow_single_file");
    }
    if (containsNonNoneKey(arguments, ALLOW_FILES_ARG)) {
        Object fileTypesObj = arguments.get(ALLOW_FILES_ARG);
        setAllowedFileTypes(ALLOW_FILES_ARG, fileTypesObj, ast, builder);
    } else if (containsNonNoneKey(arguments, ALLOW_SINGLE_FILE_ARG)) {
        Object fileTypesObj = arguments.get(ALLOW_SINGLE_FILE_ARG);
        setAllowedFileTypes(ALLOW_SINGLE_FILE_ARG, fileTypesObj, ast, builder);
        builder.setPropertyFlag("SINGLE_ARTIFACT");
    } else if (type.getLabelClass() == LabelClass.DEPENDENCY) {
        builder.allowedFileTypes(FileTypeSet.NO_FILE);
    }
    Object ruleClassesObj = arguments.get(ALLOW_RULES_ARG);
    if (ruleClassesObj != null && ruleClassesObj != Runtime.NONE) {
        builder.allowedRuleClasses(SkylarkList.castSkylarkListOrNoneToList(ruleClassesObj, String.class, "allowed rule classes for attribute definition"));
    }
    List<Object> values = SkylarkList.castSkylarkListOrNoneToList(arguments.get(VALUES_ARG), Object.class, VALUES_ARG);
    if (!Iterables.isEmpty(values)) {
        builder.allowedValues(new AllowedValueSet(values));
    }
    if (containsNonNoneKey(arguments, PROVIDERS_ARG)) {
        Object obj = arguments.get(PROVIDERS_ARG);
        SkylarkType.checkType(obj, SkylarkList.class, PROVIDERS_ARG);
        ImmutableList<ImmutableSet<SkylarkProviderIdentifier>> providersList = buildProviderPredicate((SkylarkList<?>) obj, PROVIDERS_ARG, ast.getLocation());
        builder.mandatoryProvidersList(providersList);
    }
    if (containsNonNoneKey(arguments, CONFIGURATION_ARG)) {
        Object trans = arguments.get(CONFIGURATION_ARG);
        if (trans.equals("data")) {
            builder.cfg(ConfigurationTransition.DATA);
        } else if (trans.equals("host")) {
            builder.cfg(ConfigurationTransition.HOST);
        } else if (trans instanceof SplitTransition<?>) {
            builder.cfg((SplitTransition<?>) trans);
        } else if (!trans.equals("target")) {
            throw new EvalException(ast.getLocation(), "cfg must be either 'data', 'host', or 'target'.");
        }
    }
    if (containsNonNoneKey(arguments, ASPECTS_ARG)) {
        Object obj = arguments.get(ASPECTS_ARG);
        SkylarkType.checkType(obj, SkylarkList.class, ASPECTS_ARG);
        List<SkylarkAspect> aspects = ((SkylarkList<?>) obj).getContents(SkylarkAspect.class, "aspects");
        for (SkylarkAspect aspect : aspects) {
            builder.aspect(aspect, ast.getLocation());
        }
    }
    return builder;
}
Also used : SkylarkCallbackFunction(com.google.devtools.build.lib.syntax.SkylarkCallbackFunction) UserDefinedFunction(com.google.devtools.build.lib.syntax.UserDefinedFunction) Attribute(com.google.devtools.build.lib.packages.Attribute) EvalException(com.google.devtools.build.lib.syntax.EvalException) SkylarkList(com.google.devtools.build.lib.syntax.SkylarkList) SplitTransition(com.google.devtools.build.lib.packages.Attribute.SplitTransition) ImmutableSet(com.google.common.collect.ImmutableSet) SkylarkAspect(com.google.devtools.build.lib.packages.SkylarkAspect) SkylarkComputedDefaultTemplate(com.google.devtools.build.lib.packages.Attribute.SkylarkComputedDefaultTemplate) AllowedValueSet(com.google.devtools.build.lib.packages.Attribute.AllowedValueSet)

Aggregations

SkylarkList (com.google.devtools.build.lib.syntax.SkylarkList)12 Test (org.junit.Test)8 ConfiguredTarget (com.google.devtools.build.lib.analysis.ConfiguredTarget)6 AnalysisResult (com.google.devtools.build.lib.analysis.BuildView.AnalysisResult)5 SkylarkClassObject (com.google.devtools.build.lib.packages.SkylarkClassObject)3 Artifact (com.google.devtools.build.lib.actions.Artifact)2 SkylarkRuleContext (com.google.devtools.build.lib.rules.SkylarkRuleContext)2 ClassObject (com.google.devtools.build.lib.syntax.ClassObject)2 EvalException (com.google.devtools.build.lib.syntax.EvalException)2 ImmutableList (com.google.common.collect.ImmutableList)1 ImmutableMap (com.google.common.collect.ImmutableMap)1 ImmutableSet (com.google.common.collect.ImmutableSet)1 FileConfiguredTarget (com.google.devtools.build.lib.analysis.FileConfiguredTarget)1 OutputGroupProvider (com.google.devtools.build.lib.analysis.OutputGroupProvider)1 RuleConfiguredTarget (com.google.devtools.build.lib.analysis.RuleConfiguredTarget)1 SkylarkProviders (com.google.devtools.build.lib.analysis.SkylarkProviders)1 Label (com.google.devtools.build.lib.cmdline.Label)1 Attribute (com.google.devtools.build.lib.packages.Attribute)1 AllowedValueSet (com.google.devtools.build.lib.packages.Attribute.AllowedValueSet)1 SkylarkComputedDefaultTemplate (com.google.devtools.build.lib.packages.Attribute.SkylarkComputedDefaultTemplate)1