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;
}
};
}
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;
}
};
}
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>());
}
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;
}
};
}
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);
}
}
Aggregations