From 2fd96193280a04c581f0c8feb5bb8b9b8f63d5d0 Mon Sep 17 00:00:00 2001 From: Neil Mitchell Date: Fri, 13 Dec 2024 01:02:13 -0800 Subject: [PATCH] Give the binary a basic file loader Summary: Allows users to write a file `foo.bzl` then do ``` $ starlark $> load("foo.bzl", "a") $> a 42 ``` Assuming `foo.bzl` contains `a = 42`. Reviewed By: JakobDegen Differential Revision: D67107612 fbshipit-source-id: 046be100a4023ca8c249f9b12490566e315fa47b --- starlark_bin/bin/eval.rs | 58 +++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 22 deletions(-) diff --git a/starlark_bin/bin/eval.rs b/starlark_bin/bin/eval.rs index d4a2b54b..16d1497d 100644 --- a/starlark_bin/bin/eval.rs +++ b/starlark_bin/bin/eval.rs @@ -32,6 +32,7 @@ use starlark::environment::Globals; use starlark::environment::Module; use starlark::errors::EvalMessage; use starlark::eval::Evaluator; +use starlark::eval::FileLoader; use starlark::syntax::AstModule; use starlark::syntax::Dialect; use starlark::StarlarkResultExt; @@ -72,6 +73,12 @@ pub(crate) struct Context { pub(crate) suppression_rules: Vec, } +impl FileLoader for Context { + fn load(&self, path: &str) -> starlark::Result { + self.load_path(Path::new(path)) + } +} + /// The outcome of evaluating (checking, parsing or running) given starlark code. pub(crate) struct EvalResult> { /// The diagnostic and error messages from evaluating a given piece of starlark code. @@ -103,24 +110,6 @@ impl Context { globals: Globals, suppression_rules: Vec, ) -> anyhow::Result { - let prelude: Vec<_> = prelude - .iter() - .map(|x| { - let env = Module::new(); - { - let mut eval = Evaluator::new(&env); - let module = AstModule::parse_file(x, &dialect).into_anyhow_result()?; - eval.eval_module(module, &globals).into_anyhow_result()?; - } - Ok(env.freeze()?) - }) - .collect::>()?; - - let module = if module { - Some(Self::new_module(&prelude)) - } else { - None - }; let mut builtin_docs: HashMap = HashMap::new(); let mut builtin_symbols: HashMap = HashMap::new(); for (name, item) in globals.documentation().members { @@ -130,17 +119,41 @@ impl Context { builtin_symbols.insert(name, uri); } - Ok(Self { + let mut ctx = Self { mode, print_non_none, - prelude, - module, + prelude: Vec::new(), + module: None, dialect, globals, builtin_docs, builtin_symbols, suppression_rules, - }) + }; + + ctx.prelude = prelude + .iter() + .map(|x| ctx.load_path(x)) + .collect::>() + .into_anyhow_result()?; + + ctx.module = if module { + Some(Self::new_module(&ctx.prelude)) + } else { + None + }; + + Ok(ctx) + } + + fn load_path(&self, path: &Path) -> starlark::Result { + let env = Module::new(); + let mut eval = Evaluator::new(&env); + eval.set_loader(self); + let module = AstModule::parse_file(path, &self.dialect).into_anyhow_result()?; + eval.eval_module(module, &self.globals)?; + drop(eval); + Ok(env.freeze()?) } fn new_module(prelude: &[FrozenModule]) -> Module { @@ -233,6 +246,7 @@ impl Context { } }; let mut eval = Evaluator::new(module); + eval.set_loader(self); eval.enable_terminal_breakpoint_console(); Self::err( file,