From 7ea23ca78ba04408fada7e90d733ec0ab4e6c062 Mon Sep 17 00:00:00 2001 From: Pranav Gaddamadugu <23022326+d0cd@users.noreply.github.com> Date: Tue, 26 Nov 2024 09:38:16 -0800 Subject: [PATCH] WIP --- Cargo.lock | 1 + Cargo.toml | 3 + compiler/ast/src/program/mod.rs | 2 + compiler/compiler/src/compiler.rs | 18 ------ .../tests/integration/utilities/mod.rs | 1 - leo/cli/commands/build.rs | 46 ++++++++++++++- tests/test-framework/benches/leo_compiler.rs | 1 - utils/disassembler/src/lib.rs | 8 +-- utils/retriever/src/retriever/mod.rs | 56 +++++++++---------- 9 files changed, 79 insertions(+), 57 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f8097591d7..171542092c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1576,6 +1576,7 @@ dependencies = [ "indexmap 2.6.0", "leo-ast", "leo-compiler", + "leo-disassembler", "leo-errors", "leo-package", "leo-retriever", diff --git a/Cargo.toml b/Cargo.toml index 9f5217bedf..e137f321b4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -142,6 +142,9 @@ workspace = true [dependencies.leo-compiler] workspace = true +[dependencies.leo-disassembler] +workspace = true + [dependencies.leo-errors] workspace = true diff --git a/compiler/ast/src/program/mod.rs b/compiler/ast/src/program/mod.rs index 083aa6072a..6cf62d9a9a 100644 --- a/compiler/ast/src/program/mod.rs +++ b/compiler/ast/src/program/mod.rs @@ -38,6 +38,8 @@ pub struct Program { pub stubs: IndexMap, /// A map from program names to program scopes. pub program_scopes: IndexMap, + /// The program tests. + pub tests: Vec, } impl fmt::Display for Program { diff --git a/compiler/compiler/src/compiler.rs b/compiler/compiler/src/compiler.rs index a80bfb2a36..fb21402b3b 100644 --- a/compiler/compiler/src/compiler.rs +++ b/compiler/compiler/src/compiler.rs @@ -44,8 +44,6 @@ pub struct Compiler<'a, N: Network> { output_directory: PathBuf, /// The program name, pub program_name: String, - /// The network name, - pub network: String, /// The AST for the program. pub ast: Ast, /// Options configuring compilation. @@ -66,7 +64,6 @@ impl<'a, N: Network> Compiler<'a, N> { /// Returns a new Leo compiler. pub fn new( program_name: String, - network: String, handler: &'a Handler, main_file_path: PathBuf, output_directory: PathBuf, @@ -81,7 +78,6 @@ impl<'a, N: Network> Compiler<'a, N> { main_file_path, output_directory, program_name, - network, ast: Ast::new(Program::default()), compiler_options: compiler_options.unwrap_or_default(), node_builder, @@ -114,20 +110,6 @@ impl<'a, N: Network> Compiler<'a, N> { // Use the parser to construct the abstract syntax tree (ast). self.ast = leo_parser::parse_ast::(self.handler, &self.node_builder, &prg_sf.src, prg_sf.start_pos)?; - // If the program is imported, then check that the name of its program scope matches the file name. - // Note that parsing enforces that there is exactly one program scope in a file. - // TODO: Clean up check. - let program_scope = self.ast.ast.program_scopes.values().next().unwrap(); - let program_scope_name = format!("{}", program_scope.program_id.name); - if program_scope_name != self.program_name { - return Err(CompilerError::program_scope_name_does_not_match( - program_scope_name, - self.program_name.clone(), - program_scope.program_id.name.span, - ) - .into()); - } - if self.compiler_options.output.initial_ast { self.write_ast_to_json("initial_ast.json")?; } diff --git a/compiler/compiler/tests/integration/utilities/mod.rs b/compiler/compiler/tests/integration/utilities/mod.rs index 449aa0b1bb..f50d8c446f 100644 --- a/compiler/compiler/tests/integration/utilities/mod.rs +++ b/compiler/compiler/tests/integration/utilities/mod.rs @@ -163,7 +163,6 @@ pub fn new_compiler( Compiler::new( program_name, - String::from("aleo"), handler, main_file_path, output_dir, diff --git a/leo/cli/commands/build.rs b/leo/cli/commands/build.rs index aa4d8273f5..9fdd2657d7 100644 --- a/leo/cli/commands/build.rs +++ b/leo/cli/commands/build.rs @@ -35,6 +35,7 @@ use std::{ path::{Path, PathBuf}, str::FromStr, }; +use leo_package::tst::TestDirectory; impl From for CompilerOptions { fn from(options: BuildOptions) -> Self { @@ -142,11 +143,18 @@ fn handle_build(command: &LeoBuild, context: Context) -> Result<(command: &LeoBuild, context: Context) -> Result<::open(&build_directory).map_err(CliError::failed_to_execute_build)?; + let package = Package::::open(&build_directory).map_err(CliError::failed_to_execute_build)?; + + // Add the main program as a stub. + main_stubs.insert(main_sym, leo_disassembler::disassemble(package.program())); + + // If the `build_tests` flag is set, compile the tests. + if command.options.build_tests { + // Compile the tests. + compile_tests( + &package_path, + &program_id, + &handler, + command.options.clone(), + main_stubs.clone(), + )?; + } Ok(()) } @@ -206,7 +229,6 @@ fn compile_leo_file( // Create a new instance of the Leo compiler. let mut compiler = Compiler::::new( program_name.clone(), - program_id.network().to_string(), handler, file_path.clone(), outputs.to_path_buf(), @@ -226,3 +248,23 @@ fn compile_leo_file( tracing::info!("✅ Compiled '{program_name}.aleo' into Aleo instructions"); Ok(()) } + +/// Compiles test files in the `tests/` directory. +#[allow(clippy::too_many_arguments)] +fn compile_tests( + package_path: &Path, + program_id: &ProgramID, + handler: &Handler, + options: BuildOptions, + stubs: IndexMap, +) -> Result<()> { + // Get the files in `/tests` directory. + let test_dir = TestDirectory::files(package_path)?; + + for test_file in test_dir { + // Compile the test file. + + } + Ok(()) +} + diff --git a/tests/test-framework/benches/leo_compiler.rs b/tests/test-framework/benches/leo_compiler.rs index fe1d7a99ee..4334898882 100644 --- a/tests/test-framework/benches/leo_compiler.rs +++ b/tests/test-framework/benches/leo_compiler.rs @@ -86,7 +86,6 @@ struct Sample { fn new_compiler(handler: &Handler) -> Compiler<'_, CurrentNetwork> { Compiler::new( String::from("test"), - String::from("aleo"), handler, PathBuf::from(String::new()), PathBuf::from(String::new()), diff --git a/utils/disassembler/src/lib.rs b/utils/disassembler/src/lib.rs index b97752ddce..10d05c25f8 100644 --- a/utils/disassembler/src/lib.rs +++ b/utils/disassembler/src/lib.rs @@ -26,11 +26,11 @@ use snarkvm::{ use std::str::FromStr; pub fn disassemble, Command: CommandTrait>( - program: ProgramCore, + program: &ProgramCore, ) -> Stub { let program_id = ProgramId::from(program.id()); Stub { - imports: program.imports().into_iter().map(|(id, _)| ProgramId::from(id)).collect(), + imports: program.imports().iter().map(|(id, _)| ProgramId::from(id)).collect(), stub_id: program_id, consts: Vec::new(), structs: [ @@ -48,7 +48,7 @@ pub fn disassemble, Command: Comman .concat(), mappings: program .mappings() - .into_iter() + .iter() .map(|(id, m)| (Identifier::from(id).name, Mapping::from_snarkvm(m))) .collect(), functions: [ @@ -88,7 +88,7 @@ pub fn disassemble, Command: Comman pub fn disassemble_from_str(name: &str, program: &str) -> Result { match Program::::from_str(program) { - Ok(p) => Ok(disassemble(p)), + Ok(p) => Ok(disassemble(&p)), Err(_) => Err(UtilError::snarkvm_parsing_error(name, Default::default())), } } diff --git a/utils/retriever/src/retriever/mod.rs b/utils/retriever/src/retriever/mod.rs index fdd29a1436..67e3d57c7f 100644 --- a/utils/retriever/src/retriever/mod.rs +++ b/utils/retriever/src/retriever/mod.rs @@ -291,40 +291,34 @@ impl Retriever { // Creates the stub of the program, caches it, and writes the local `leo.lock` file pub fn process_local(&mut self, name: Symbol, recursive: bool) -> Result<(), UtilError> { let cur_context = self.contexts.get_mut(&name).unwrap(); - // Don't need to disassemble the main file - if name != self.name { - // Disassemble the program - let compiled_path = cur_context.compiled_file_path(); - if !compiled_path.exists() { - return Err(UtilError::build_file_does_not_exist(compiled_path.to_str().unwrap(), Default::default())); - } - let mut file = File::open(compiled_path).unwrap_or_else(|_| { - panic!("Failed to open file {}", cur_context.compiled_file_path().to_str().unwrap()) - }); - let mut content = String::new(); - file.read_to_string(&mut content).map_err(|err| { - UtilError::util_file_io_error( - format!("Could not read {}", cur_context.compiled_file_path().to_str().unwrap()), - err, - Default::default(), - ) - })?; + // Disassemble the program + let compiled_path = cur_context.compiled_file_path(); + if !compiled_path.exists() { + return Err(UtilError::build_file_does_not_exist(compiled_path.to_str().unwrap(), Default::default())); + } + let mut file = File::open(compiled_path).unwrap_or_else(|_| { + panic!("Failed to open file {}", cur_context.compiled_file_path().to_str().unwrap()) + }); + let mut content = String::new(); + file.read_to_string(&mut content).map_err(|err| { + UtilError::util_file_io_error( + format!("Could not read {}", cur_context.compiled_file_path().to_str().unwrap()), + err, + Default::default(), + ) + })?; - // Cache the disassembled stub - let stub: Stub = disassemble_from_str::(&name.to_string(), &content)?; - if cur_context.add_stub(stub.clone()) { - Err(UtilError::duplicate_dependency_name_error(stub.stub_id.name.name, Default::default()))?; - } + // Cache the disassembled stub + let stub: Stub = disassemble_from_str::(&name.to_string(), &content)?; + if cur_context.add_stub(stub.clone()) { + Err(UtilError::duplicate_dependency_name_error(stub.stub_id.name.name, Default::default()))?; + } - // Cache the hash - cur_context.add_checksum(); + // Cache the hash + cur_context.add_checksum(); - // Only write lock file when recursive building - if recursive { - self.write_lock_file(&name)?; - } - } else { - // Write lock file + // Only write lock file when recursive building or when building the top-level program. + if recursive || name == self.name { self.write_lock_file(&name)?; }