blob: 63f1135d2860def1f747ba646303c1309f281bc5 [file] [log] [blame]
// Copyright 2020 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package net.starlark.java.eval;
import com.google.common.collect.ImmutableMap;
import java.io.IOException;
import net.starlark.java.annot.Param;
import net.starlark.java.annot.StarlarkMethod;
import net.starlark.java.syntax.FileOptions;
import net.starlark.java.syntax.ParserInput;
import net.starlark.java.syntax.Program;
import net.starlark.java.syntax.Resolver;
import net.starlark.java.syntax.StarlarkFile;
import net.starlark.java.syntax.SyntaxError;
/**
* Examples of typical API usage of the Starlark interpreter.<br>
* This is not a test, but it is checked by the compiler.
*/
final class Examples {
/**
* This example reads, parses, compiles, and executes a Starlark file. It returns the module,
* which holds the values of global variables.
*/
Module execFile(String filename)
throws IOException, SyntaxError.Exception, EvalException, InterruptedException {
// Read input from the named file.
ParserInput input = ParserInput.readFile(filename);
// Create the module that will be populated by executing the file.
// It holds the global variables, initially empty.
// Its predeclared environment defines only the standard builtins:
// None, True, len, and so on.
Module module = Module.create();
// Resolve, compile, and execute the file.
//
// The Mutability will be associated with all the values created by this thread.
// The try-with-resources statement ensures that all values become frozen
// after execution.
try (Mutability mu = Mutability.create(input.getFile())) {
StarlarkThread thread = new StarlarkThread(mu, StarlarkSemantics.DEFAULT);
Starlark.execFile(input, FileOptions.DEFAULT, module, thread);
}
return module;
}
/**
* This example evaluates a Starlark expression in the specified environment and returns its
* value.
*/
Object evalExpr(String expr, ImmutableMap<String, Object> env)
throws SyntaxError.Exception, EvalException, InterruptedException {
// The apparent file name (for error messages) will be "<expr>".
ParserInput input = ParserInput.fromString(expr, "<expr>");
// Create the module in which the expression is evaluated.
// It may define additional predeclared environment bindings.
Module module = Module.withPredeclared(StarlarkSemantics.DEFAULT, env);
// Resolve, compile, and execute the expression.
try (Mutability mu = Mutability.create(input.getFile())) {
StarlarkThread thread = new StarlarkThread(mu, StarlarkSemantics.DEFAULT);
return Starlark.eval(input, FileOptions.DEFAULT, module, thread);
}
}
/**
* This advanced example reads, parses, and compiles a Starlark file to a Program, then later
* executes it.
*/
Module compileThenExecute()
throws IOException, SyntaxError.Exception, EvalException, InterruptedException {
// Read and parse the named file.
ParserInput input = ParserInput.readFile("my/file.star");
StarlarkFile file = StarlarkFile.parse(input);
// Compile the program, with additional predeclared environment bindings.
// TODO(adonovan): supply Starlark.UNIVERSE somehow.
Program prog = Program.compileFile(file, Resolver.moduleWithPredeclared("zero", "square"));
// . . .
// TODO(adonovan): when supported, show how the compiled program can be
// saved and reloaded, to avoid repeating the cost of parsing and
// compilation.
// Execute the compiled program to populate a module.
// The module's predeclared environment must match the
// names provided during compilation.
Module module = Module.withPredeclared(StarlarkSemantics.DEFAULT, makeEnvironment());
try (Mutability mu = Mutability.create(prog.getFilename())) {
StarlarkThread thread = new StarlarkThread(mu, StarlarkSemantics.DEFAULT);
Starlark.execFileProgram(prog, module, thread);
}
return module;
}
/** This function shows how to construct a callable Starlark value from a Java method. */
ImmutableMap<String, Object> makeEnvironment() {
ImmutableMap.Builder<String, Object> env = ImmutableMap.builder();
env.put("zero", 0);
Starlark.addMethods(env, new MyFunctions(), StarlarkSemantics.DEFAULT); // adds 'square'
return env.buildOrThrow();
}
/**
* The annotated methods of this class are added to the environment by {@link
* Starlark#addMethods}.
*/
static final class MyFunctions {
@StarlarkMethod(
name = "square",
parameters = {@Param(name = "x")},
doc = "Returns the square of its integer argument.")
public StarlarkInt square(StarlarkInt x) {
return StarlarkInt.multiply(x, x);
}
}
}