Search in sources :

Example 1 with FuncallExpression

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

the class PackageFactory method newPackageFunction.

/**
   * Returns a function-value implementing "package" in the specified package
   * context.
   */
private static BaseFunction newPackageFunction(final ImmutableMap<String, PackageArgument<?>> packageArguments) {
    // Flatten the map of argument name of PackageArgument specifier in two co-indexed arrays:
    // one for the argument names, to create a FunctionSignature when we create the function,
    // one of the PackageArgument specifiers, over which to iterate at every function invocation
    // at the same time that we iterate over the function arguments.
    final int numArgs = packageArguments.size();
    final String[] argumentNames = new String[numArgs];
    final PackageArgument<?>[] argumentSpecifiers = new PackageArgument<?>[numArgs];
    int i = 0;
    for (Map.Entry<String, PackageArgument<?>> entry : packageArguments.entrySet()) {
        argumentNames[i] = entry.getKey();
        argumentSpecifiers[i++] = entry.getValue();
    }
    return new BaseFunction("package", FunctionSignature.namedOnly(0, argumentNames)) {

        @Override
        public Object call(Object[] arguments, FuncallExpression ast, Environment env) throws EvalException {
            Package.Builder pkgBuilder = getContext(env, ast).pkgBuilder;
            // Validate parameter list
            if (pkgBuilder.isPackageFunctionUsed()) {
                throw new EvalException(ast.getLocation(), "'package' can only be used once per BUILD file");
            }
            pkgBuilder.setPackageFunctionUsed();
            // Parse params
            boolean foundParameter = false;
            for (int i = 0; i < numArgs; i++) {
                Object value = arguments[i];
                if (value != null) {
                    foundParameter = true;
                    argumentSpecifiers[i].convertAndProcess(pkgBuilder, ast.getLocation(), value);
                }
            }
            if (!foundParameter) {
                throw new EvalException(ast.getLocation(), "at least one argument must be given to the 'package' function");
            }
            return Runtime.NONE;
        }
    };
}
Also used : EvalException(com.google.devtools.build.lib.syntax.EvalException) BaseFunction(com.google.devtools.build.lib.syntax.BaseFunction) Environment(com.google.devtools.build.lib.syntax.Environment) ClassObject(com.google.devtools.build.lib.syntax.ClassObject) FuncallExpression(com.google.devtools.build.lib.syntax.FuncallExpression) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) BuildLangTypedAttributeValuesMap(com.google.devtools.build.lib.packages.RuleFactory.BuildLangTypedAttributeValuesMap) TreeMap(java.util.TreeMap)

Example 2 with FuncallExpression

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

the class WorkspaceFactory method newRuleFunction.

/**
   * Returns a function-value implementing the build rule "ruleClass" (e.g. cc_library) in the
   * specified package context.
   */
private static BuiltinFunction newRuleFunction(final RuleFactory ruleFactory, final String ruleClassName, final boolean allowOverride) {
    return new BuiltinFunction(ruleClassName, FunctionSignature.KWARGS, BuiltinFunction.USE_AST_ENV) {

        public Object invoke(Map<String, Object> kwargs, FuncallExpression ast, Environment env) throws EvalException, InterruptedException {
            try {
                Package.Builder builder = PackageFactory.getContext(env, ast).pkgBuilder;
                if (!allowOverride && kwargs.containsKey("name") && builder.targets.containsKey(kwargs.get("name"))) {
                    throw new EvalException(ast.getLocation(), "Cannot redefine repository after any load statement in the WORKSPACE file" + " (for repository '" + kwargs.get("name") + "')");
                }
                RuleClass ruleClass = ruleFactory.getRuleClass(ruleClassName);
                RuleClass bindRuleClass = ruleFactory.getRuleClass("bind");
                Rule rule = builder.externalPackageData().createAndAddRepositoryRule(builder, ruleClass, bindRuleClass, kwargs, ast);
                if (!isLegalWorkspaceName(rule.getName())) {
                    throw new EvalException(ast.getLocation(), rule + "'s name field must be a legal workspace name");
                }
            } catch (RuleFactory.InvalidRuleException | Package.NameConflictException | LabelSyntaxException e) {
                throw new EvalException(ast.getLocation(), e.getMessage());
            }
            return NONE;
        }
    };
}
Also used : LabelSyntaxException(com.google.devtools.build.lib.cmdline.LabelSyntaxException) EvalException(com.google.devtools.build.lib.syntax.EvalException) NameConflictException(com.google.devtools.build.lib.packages.Package.NameConflictException) BuiltinFunction(com.google.devtools.build.lib.syntax.BuiltinFunction) Environment(com.google.devtools.build.lib.syntax.Environment) FuncallExpression(com.google.devtools.build.lib.syntax.FuncallExpression) HashMap(java.util.HashMap) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) InvalidRuleException(com.google.devtools.build.lib.packages.RuleFactory.InvalidRuleException)

Example 3 with FuncallExpression

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

the class SkylarkRepositoryContextTest method setUpContextForRule.

protected void setUpContextForRule(Map<String, Object> kwargs, Attribute... attributes) throws Exception {
    Package.Builder packageBuilder = Package.newExternalPackageBuilder(Package.Builder.DefaultHelper.INSTANCE, workspaceFile, "runfiles");
    FuncallExpression ast = new FuncallExpression(new Identifier("test"), ImmutableList.<Passed>of());
    ast.setLocation(Location.BUILTIN);
    Rule rule = packageBuilder.externalPackageData().createAndAddRepositoryRule(packageBuilder, buildRuleClass(attributes), null, kwargs, ast);
    HttpDownloader downloader = Mockito.mock(HttpDownloader.class);
    context = new SkylarkRepositoryContext(rule, outputDirectory, Mockito.mock(SkyFunction.Environment.class), ImmutableMap.of("FOO", "BAR"), downloader, new HashMap<String, String>());
}
Also used : Identifier(com.google.devtools.build.lib.syntax.Identifier) SkyFunction(com.google.devtools.build.skyframe.SkyFunction) HttpDownloader(com.google.devtools.build.lib.bazel.repository.downloader.HttpDownloader) HashMap(java.util.HashMap) Package(com.google.devtools.build.lib.packages.Package) Rule(com.google.devtools.build.lib.packages.Rule) FuncallExpression(com.google.devtools.build.lib.syntax.FuncallExpression)

Example 4 with FuncallExpression

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

the class WorkspaceFactory method newBindFunction.

private static BuiltinFunction newBindFunction(final RuleFactory ruleFactory) {
    return new BuiltinFunction("bind", FunctionSignature.namedOnly(1, "name", "actual"), BuiltinFunction.USE_AST_ENV) {

        public Object invoke(String name, String actual, FuncallExpression ast, Environment env) throws EvalException, InterruptedException {
            Label nameLabel;
            try {
                nameLabel = Label.parseAbsolute("//external:" + name);
                try {
                    Package.Builder builder = PackageFactory.getContext(env, ast).pkgBuilder;
                    RuleClass ruleClass = ruleFactory.getRuleClass("bind");
                    builder.externalPackageData().addBindRule(builder, ruleClass, nameLabel, actual == null ? null : Label.parseAbsolute(actual), ast.getLocation(), ruleFactory.getAttributeContainer(ruleClass));
                } catch (RuleFactory.InvalidRuleException | Package.NameConflictException | LabelSyntaxException e) {
                    throw new EvalException(ast.getLocation(), e.getMessage());
                }
            } catch (LabelSyntaxException e) {
                throw new EvalException(ast.getLocation(), e.getMessage());
            }
            return NONE;
        }
    };
}
Also used : LabelSyntaxException(com.google.devtools.build.lib.cmdline.LabelSyntaxException) Label(com.google.devtools.build.lib.cmdline.Label) EvalException(com.google.devtools.build.lib.syntax.EvalException) NameConflictException(com.google.devtools.build.lib.packages.Package.NameConflictException) BuiltinFunction(com.google.devtools.build.lib.syntax.BuiltinFunction) Environment(com.google.devtools.build.lib.syntax.Environment) FuncallExpression(com.google.devtools.build.lib.syntax.FuncallExpression) InvalidRuleException(com.google.devtools.build.lib.packages.RuleFactory.InvalidRuleException)

Example 5 with FuncallExpression

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

the class RuleFactory method generatorAttributesForMacros.

/**
   * If the rule was created by a macro, this method sets the appropriate values for the
   * attributes generator_{name, function, location} and returns all attributes.
   *
   * <p>Otherwise, it returns the given attributes without any changes.
   */
private static AttributesAndLocation generatorAttributesForMacros(BuildLangTypedAttributeValuesMap args, @Nullable Environment env, Location location, Label label) {
    // trace (=> no macro) or b) the attributes have already been set by Python pre-processing.
    if (env == null) {
        return new AttributesAndLocation(args, location);
    }
    boolean hasName = args.containsAttributeNamed("generator_name");
    boolean hasFunc = args.containsAttributeNamed("generator_function");
    // TODO(bazel-team): resolve cases in our code where hasName && !hasFunc, or hasFunc && !hasName
    if (hasName || hasFunc) {
        return new AttributesAndLocation(args, location);
    }
    Pair<FuncallExpression, BaseFunction> topCall = env.getTopCall();
    if (topCall == null || !(topCall.second instanceof UserDefinedFunction)) {
        return new AttributesAndLocation(args, location);
    }
    FuncallExpression generator = topCall.first;
    BaseFunction function = topCall.second;
    String name = generator.getNameArg();
    ImmutableMap.Builder<String, Object> builder = ImmutableMap.builder();
    for (String attributeName : args.getAttributeNames()) {
        builder.put(attributeName, args.getAttributeValue(attributeName));
    }
    builder.put("generator_name", (name == null) ? args.getAttributeValue("name") : name);
    builder.put("generator_function", function.getName());
    if (generator.getLocation() != null) {
        location = generator.getLocation();
    }
    String relativePath = maybeGetRelativeLocation(location, label);
    if (relativePath != null) {
        builder.put("generator_location", relativePath);
    }
    try {
        return new AttributesAndLocation(new BuildLangTypedAttributeValuesMap(builder.build()), location);
    } catch (IllegalArgumentException ex) {
        // We just fall back to the default case and swallow any messages.
        return new AttributesAndLocation(args, location);
    }
}
Also used : BaseFunction(com.google.devtools.build.lib.syntax.BaseFunction) UserDefinedFunction(com.google.devtools.build.lib.syntax.UserDefinedFunction) FuncallExpression(com.google.devtools.build.lib.syntax.FuncallExpression) ImmutableMap(com.google.common.collect.ImmutableMap)

Aggregations

FuncallExpression (com.google.devtools.build.lib.syntax.FuncallExpression)5 ImmutableMap (com.google.common.collect.ImmutableMap)3 Environment (com.google.devtools.build.lib.syntax.Environment)3 EvalException (com.google.devtools.build.lib.syntax.EvalException)3 LabelSyntaxException (com.google.devtools.build.lib.cmdline.LabelSyntaxException)2 NameConflictException (com.google.devtools.build.lib.packages.Package.NameConflictException)2 InvalidRuleException (com.google.devtools.build.lib.packages.RuleFactory.InvalidRuleException)2 BaseFunction (com.google.devtools.build.lib.syntax.BaseFunction)2 BuiltinFunction (com.google.devtools.build.lib.syntax.BuiltinFunction)2 HashMap (java.util.HashMap)2 Map (java.util.Map)2 HttpDownloader (com.google.devtools.build.lib.bazel.repository.downloader.HttpDownloader)1 Label (com.google.devtools.build.lib.cmdline.Label)1 Package (com.google.devtools.build.lib.packages.Package)1 Rule (com.google.devtools.build.lib.packages.Rule)1 BuildLangTypedAttributeValuesMap (com.google.devtools.build.lib.packages.RuleFactory.BuildLangTypedAttributeValuesMap)1 ClassObject (com.google.devtools.build.lib.syntax.ClassObject)1 Identifier (com.google.devtools.build.lib.syntax.Identifier)1 UserDefinedFunction (com.google.devtools.build.lib.syntax.UserDefinedFunction)1 SkyFunction (com.google.devtools.build.skyframe.SkyFunction)1