From ccf813d1c4bcdeae25dcc8ecb3d4fb16dfbbf1ca Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Mon, 11 Sep 2023 19:10:36 +0000 Subject: [PATCH 01/42] first attempt --- Cargo.lock | 36 +++ Cargo.toml | 1 + crates/nargo_fmt/Cargo.toml | 12 + crates/nargo_fmt/src/config.rs | 15 + crates/nargo_fmt/src/lib.rs | 73 +++++ crates/nargo_fmt/src/visitor.rs | 264 ++++++++++++++++++ crates/nargo_fmt/tests/source/call.nr | 3 + crates/nargo_fmt/tests/source/comment.nr | 30 ++ crates/nargo_fmt/tests/source/empty.nr | 0 crates/nargo_fmt/tests/source/expr.nr | 41 +++ crates/nargo_fmt/tests/source/infix.nr | 5 + .../nargo_fmt/tests/source/nested-if-else.nr | 4 + crates/nargo_fmt/tests/source/print.nr | 3 + crates/nargo_fmt/tests/source/print2.nr | 5 + .../nargo_fmt/tests/source/unary_operators.nr | 3 + .../src/hir/def_collector/dc_mod.rs | 4 +- crates/noirc_frontend/src/hir/def_map/mod.rs | 4 +- .../src/hir/resolution/resolver.rs | 3 +- .../noirc_frontend/src/hir/type_check/mod.rs | 3 +- .../src/monomorphization/mod.rs | 3 +- crates/noirc_frontend/src/parser/mod.rs | 128 +++++++-- crates/noirc_frontend/src/parser/parser.rs | 87 +++--- 22 files changed, 659 insertions(+), 68 deletions(-) create mode 100644 crates/nargo_fmt/Cargo.toml create mode 100644 crates/nargo_fmt/src/config.rs create mode 100644 crates/nargo_fmt/src/lib.rs create mode 100644 crates/nargo_fmt/src/visitor.rs create mode 100644 crates/nargo_fmt/tests/source/call.nr create mode 100644 crates/nargo_fmt/tests/source/comment.nr create mode 100644 crates/nargo_fmt/tests/source/empty.nr create mode 100644 crates/nargo_fmt/tests/source/expr.nr create mode 100644 crates/nargo_fmt/tests/source/infix.nr create mode 100644 crates/nargo_fmt/tests/source/nested-if-else.nr create mode 100644 crates/nargo_fmt/tests/source/print.nr create mode 100644 crates/nargo_fmt/tests/source/print2.nr create mode 100644 crates/nargo_fmt/tests/source/unary_operators.nr diff --git a/Cargo.lock b/Cargo.lock index 76a9d98e23c..89f0a0511f1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1196,6 +1196,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "dissimilar" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86e3bdc80eee6e16b2b6b0f87fbc98c04bee3455e35174c0de1a125d0688c632" + [[package]] name = "doc-comment" version = "0.3.3" @@ -1323,6 +1329,16 @@ dependencies = [ "libc", ] +[[package]] +name = "expect-test" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d9eafeadd538e68fb28016364c9732d78e420b9ff8853fa5e4058861e9f8d3" +dependencies = [ + "dissimilar", + "once_cell", +] + [[package]] name = "eyre" version = "0.6.8" @@ -2206,6 +2222,15 @@ dependencies = [ "tower", ] +[[package]] +name = "nargo_fmt" +version = "0.10.5" +dependencies = [ + "expect-test", + "noirc_frontend", + "readonly", +] + [[package]] name = "nargo_toml" version = "0.10.5" @@ -2815,6 +2840,17 @@ dependencies = [ "rand_core 0.3.1", ] +[[package]] +name = "readonly" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8f439da1766942fe069954da6058b2e6c1760eb878bae76f5be9fc29f56f574" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.26", +] + [[package]] name = "redox_syscall" version = "0.2.16" diff --git a/Cargo.toml b/Cargo.toml index 63fe20ad72d..8b7e1f60910 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ members = [ "crates/noirc_driver", "crates/noirc_printable_type", "crates/nargo", + "crates/nargo_fmt", "crates/nargo_cli", "crates/nargo_toml", "crates/fm", diff --git a/crates/nargo_fmt/Cargo.toml b/crates/nargo_fmt/Cargo.toml new file mode 100644 index 00000000000..76b14b835a7 --- /dev/null +++ b/crates/nargo_fmt/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "nargo_fmt" +version.workspace = true +authors.workspace = true +edition.workspace = true + +[dependencies] +noirc_frontend.workspace = true +readonly = "0.2" + +[dev-dependencies] +expect-test = "1.4.1" diff --git a/crates/nargo_fmt/src/config.rs b/crates/nargo_fmt/src/config.rs new file mode 100644 index 00000000000..f5927c9ddb8 --- /dev/null +++ b/crates/nargo_fmt/src/config.rs @@ -0,0 +1,15 @@ +#[readonly::make] +pub struct Config { + /// Maximum width of each line. + #[readonly] + pub max_width: usize, + /// Number of spaces per tab. + #[readonly] + pub tab_spaces: usize, +} + +impl Default for Config { + fn default() -> Self { + Self { max_width: 100, tab_spaces: 4 } + } +} diff --git a/crates/nargo_fmt/src/lib.rs b/crates/nargo_fmt/src/lib.rs new file mode 100644 index 00000000000..7d3264343f0 --- /dev/null +++ b/crates/nargo_fmt/src/lib.rs @@ -0,0 +1,73 @@ +#![deny(unused_qualifications, clippy::use_self)] + +mod config; +mod visitor; + +use noirc_frontend::parser::Fmt; +use visitor::FmtVisitor; + +pub fn format(source: &str) -> String { + let (module, errors) = noirc_frontend::parse_program::(source); + + // TODO: error handling + if !errors.is_empty() { + panic!("{errors:?}"); + } + + let mut fmt = FmtVisitor::new(source); + fmt.visit_module(module); + fmt.finish() +} + +#[cfg(test)] +mod tests { + use std::{ffi::OsStr, path::PathBuf}; + + #[test] + fn it_works() { + println!( + "{}", + super::format( + "fn main() { + { + // hello + } + }" + ) + ); + } + + #[test] + fn test() { + let files = std::fs::read_dir("tests/source").unwrap(); + for file in files { + let file = file.unwrap(); + + let source_path = file.path(); + let source = std::fs::read_to_string(&source_path).unwrap(); + let fmt_text = crate::format(&source); + + let target_path: PathBuf = source_path + .components() + .map(|component| { + if component.as_os_str() == "source" { + OsStr::new("target") + } else { + component.as_os_str() + } + }) + .collect(); + + let target = match std::fs::read_to_string(&target_path) { + Ok(t) => t, + Err(err) if err.kind() == std::io::ErrorKind::NotFound => { + std::fs::write(target_path, fmt_text.clone()).unwrap(); + fmt_text.clone() + } + Err(err) => unreachable!("{err}"), + }; + + assert_eq!(fmt_text, target); + } + } +} diff --git a/crates/nargo_fmt/src/visitor.rs b/crates/nargo_fmt/src/visitor.rs new file mode 100644 index 00000000000..0a581d303a3 --- /dev/null +++ b/crates/nargo_fmt/src/visitor.rs @@ -0,0 +1,264 @@ +use noirc_frontend::{ + hir::resolution::errors::Span, + parser::{ItemKind, ParsedModuleFmt}, + BlockExpression, Expression, ExpressionKind, NoirFunction, Statement, +}; + +use crate::config::Config; + +/// A macro to create a slice from a given data source, helping to avoid borrow checker errors. +macro_rules! slice { + ($this:ident, $start:expr, $end:expr) => { + &$this.source[$start as usize..$end as usize] + }; +} + +pub struct FmtVisitor<'a> { + config: Config, + buffer: String, + source: &'a str, + block_indent: Indent, + last_position: u32, +} + +impl<'a> FmtVisitor<'a> { + pub fn new(source: &'a str) -> Self { + Self { + config: Config::default(), + buffer: String::new(), + source, + last_position: 0, + block_indent: Indent { block_indent: 0 }, + } + } + + pub fn at_start(&self) -> bool { + self.buffer.is_empty() + } + + pub fn finish(self) -> String { + self.buffer + } + + fn push_str(&mut self, s: &str) { + self.buffer.push_str(s); + } + + #[track_caller] + fn push_rewrite(&mut self, s: String, span: Span) { + self.format_missing_indent(span.start(), true); + self.push_str(&s); + } + + pub fn visit_module(&mut self, module: ParsedModuleFmt) { + for item in module.items { + match item.kind { + ItemKind::Function(func) => { + let fn_before_block = self.rewrite_fn_before_block(func.clone()); + + self.format_missing_indent(item.span.start(), false); + self.push_str(&fn_before_block); + + self.push_str(" "); + + self.visit_block(func.def.body, func.def.span, false); + } + } + } + + self.format_missing_indent(self.source.len() as u32, false); + } + + fn visit_block(&mut self, block: BlockExpression, block_span: Span, should_indent: bool) { + if block.is_empty() { + let slice = slice!(self, block_span.start(), block_span.end()); + let comment_str = slice[1..slice.len() - 1].trim(); + + let comment_str = if comment_str.is_empty() { + "{}".to_string() + } else { + let indent = self.block_indent.to_string(); + format!("{{\n{indent}{comment_str}\n{indent}}}",) + }; + + self.last_position = block_span.end(); + self.push_str(&comment_str); + return; + } + + self.last_position = block_span.start() + 1; // `{` + self.block_indent.block_indent(&self.config); + self.push_str("{"); + + // TODO: Implement setting the last position for statements. + for stmt in block.0 { + match stmt { + Statement::Let(_) => todo!(), + Statement::Constrain(_) => todo!(), + Statement::Expression(expr) => self.visit_expr(expr), + Statement::Assign(_) => todo!(), + Statement::Semi(expr) => { + self.visit_expr(expr); + self.push_str(";"); + self.last_position += 1; // `;` + } + Statement::Error => unreachable!(), + } + } + + self.last_position = block_span.end(); + self.block_indent.block_unindent(&self.config); + + self.push_str("\n"); + if should_indent { + self.push_str(&self.block_indent.to_string()); + } + self.push_str("}"); + } + + fn visit_expr(&mut self, expr: Expression) { + let span = expr.span; + + let rewrite = self.format_expr(expr); + self.push_rewrite(rewrite, span); + + self.last_position = span.end(); + } + + fn format_expr(&self, Expression { kind, span }: Expression) -> String { + match kind { + // TODO: literals can contain comments + ExpressionKind::Literal(literal) => literal.to_string(), + ExpressionKind::Block(block) => { + let mut visitor = FmtVisitor::new(self.source); + + visitor.block_indent = self.block_indent; + visitor.visit_block(block, span, true); + + visitor.buffer + } + ExpressionKind::Prefix(prefix) => { + format!("{}{}", prefix.operator, self.format_expr(prefix.rhs)) + } + ExpressionKind::Index(_) => todo!(), + ExpressionKind::Call(call) => { + let callee = self.format_expr(*call.func); + let args = call + .arguments + .into_iter() + .map(|arg| self.format_expr(arg)) + .collect::>() + .join(", "); + + format!("{callee}({args})") + } + ExpressionKind::Infix(infix) => { + let lhs = self.format_expr(infix.lhs); + let op = infix.operator.contents; + let rhs = self.format_expr(infix.rhs); + + format!("{lhs} {op} {rhs}") + } + ExpressionKind::If(if_expr) => { + let condition = self.format_expr(if_expr.condition); + let consequence = self.format_expr(if_expr.consequence); + let alternative = if_expr + .alternative + .map_or(String::new(), |alternative| self.format_expr(alternative)); + + format!("{condition} {consequence} {alternative}") + } + ExpressionKind::Variable(_) => slice!(self, span.start(), span.end()).to_string(), + ExpressionKind::Tuple(_) => todo!(), + ExpressionKind::Lambda(_) => todo!(), + ExpressionKind::Error => unreachable!(), + // TODO: + expr => expr.to_string(), + } + } + + #[track_caller] + fn format_missing_indent(&mut self, end: u32, should_indent: bool) { + self.format_missing_inner(end, |this, last_slice, slice| { + this.push_str(last_slice.trim_end()); + + if last_slice == slice && !this.at_start() { + this.push_str("\n"); + } + + if should_indent { + let indent = this.block_indent.to_string(); + this.push_str(&indent); + } + }); + } + + #[track_caller] + fn format_missing_inner( + &mut self, + end: u32, + process_last_slice: impl Fn(&mut Self, &str, &str), + ) { + let start = self.last_position; + + if start == end { + if !self.at_start() { + process_last_slice(self, "", "") + } + return; + } + + let slice = slice!(self, start, end); + self.last_position = end; + + if slice.trim().is_empty() && !self.buffer.is_empty() { + self.push_str("\n"); + process_last_slice(self, "", slice); + } else { + self.buffer.push_str(slice); + let indent = self.block_indent.to_string(); + self.push_str(&indent); + } + } + + fn rewrite_fn_before_block(&self, func: NoirFunction) -> String { + let mut result = String::with_capacity(1024); + + result.push_str("fn "); + result.push_str(func.name()); + + if !func.def.generics.is_empty() { + todo!("emit generics") + } + + result.push('('); + if func.parameters().is_empty() { + // TODO: Inside the parameters, there can be a comment, for example `fn hello(/**/) {}`. + } else { + todo!("emit parameters") + } + + result.push(')'); + result + } +} + +#[derive(Clone, Copy)] +struct Indent { + block_indent: usize, +} + +impl Indent { + fn block_indent(&mut self, config: &Config) { + self.block_indent += config.tab_spaces; + } + + fn block_unindent(&mut self, config: &Config) { + self.block_indent -= config.tab_spaces; + } + + #[allow(clippy::inherent_to_string)] + fn to_string(self) -> String { + " ".repeat(self.block_indent) + } +} diff --git a/crates/nargo_fmt/tests/source/call.nr b/crates/nargo_fmt/tests/source/call.nr new file mode 100644 index 00000000000..8927ebc85db --- /dev/null +++ b/crates/nargo_fmt/tests/source/call.nr @@ -0,0 +1,3 @@ +fn main() { + main(4, 3); +} \ No newline at end of file diff --git a/crates/nargo_fmt/tests/source/comment.nr b/crates/nargo_fmt/tests/source/comment.nr new file mode 100644 index 00000000000..8101677b255 --- /dev/null +++ b/crates/nargo_fmt/tests/source/comment.nr @@ -0,0 +1,30 @@ +fn comment1() { + // +} + +// random comment + +fn comment2() { // Test +} + +fn comment3() // some comment +{ +} + +fn comment4() +// some comment +{ +} + +fn comment5() // some comment +{ +} + +fn comment6() // some comment some comment some comment some comment some comment some comment so +{ +} + +fn comment7() +// some comment some comment some comment some comment some comment some comment some comment +{ +} \ No newline at end of file diff --git a/crates/nargo_fmt/tests/source/empty.nr b/crates/nargo_fmt/tests/source/empty.nr new file mode 100644 index 00000000000..e69de29bb2d diff --git a/crates/nargo_fmt/tests/source/expr.nr b/crates/nargo_fmt/tests/source/expr.nr new file mode 100644 index 00000000000..3e86be5a418 --- /dev/null +++ b/crates/nargo_fmt/tests/source/expr.nr @@ -0,0 +1,41 @@ +// Test some empty blocks. +fn qux() { + {} + + { /* a block with a comment */ } + { + + } + { + // A block with a comment. + } +} + +fn foo_return() { + "yay" +} + +fn fooblock() { + { + "inner-block" + } +} + +fn fooblock() { + { + { + { + "inner-block" + } + } + } +} + +fn comment() { + // this is a test comment + 1 +} + +fn only_comment() { + // Keep this here +} diff --git a/crates/nargo_fmt/tests/source/infix.nr b/crates/nargo_fmt/tests/source/infix.nr new file mode 100644 index 00000000000..13b53170da6 --- /dev/null +++ b/crates/nargo_fmt/tests/source/infix.nr @@ -0,0 +1,5 @@ +fn foo() { + 40 + 2; + !40 + 2; + 40 + 2 == 42; +} diff --git a/crates/nargo_fmt/tests/source/nested-if-else.nr b/crates/nargo_fmt/tests/source/nested-if-else.nr new file mode 100644 index 00000000000..6e94daf1efe --- /dev/null +++ b/crates/nargo_fmt/tests/source/nested-if-else.nr @@ -0,0 +1,4 @@ +// FIXME: +// fn nested_if_else() { +// if false { 1 } else if false { 2 } else { 3 } +// } diff --git a/crates/nargo_fmt/tests/source/print.nr b/crates/nargo_fmt/tests/source/print.nr new file mode 100644 index 00000000000..8afa562dada --- /dev/null +++ b/crates/nargo_fmt/tests/source/print.nr @@ -0,0 +1,3 @@ +use dep::std; + +fn main() { std::println("Hello world"); } diff --git a/crates/nargo_fmt/tests/source/print2.nr b/crates/nargo_fmt/tests/source/print2.nr new file mode 100644 index 00000000000..07ef9dd0386 --- /dev/null +++ b/crates/nargo_fmt/tests/source/print2.nr @@ -0,0 +1,5 @@ +use dep::std; + +fn main( ) { +std::println("Hello world"); +} diff --git a/crates/nargo_fmt/tests/source/unary_operators.nr b/crates/nargo_fmt/tests/source/unary_operators.nr new file mode 100644 index 00000000000..5805c7081f5 --- /dev/null +++ b/crates/nargo_fmt/tests/source/unary_operators.nr @@ -0,0 +1,3 @@ +fn main() { + -1 +} \ No newline at end of file diff --git a/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs b/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs index 809623623ee..17a16e2ff5a 100644 --- a/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs +++ b/crates/noirc_frontend/src/hir/def_collector/dc_mod.rs @@ -5,7 +5,7 @@ use crate::{ graph::CrateId, hir::def_collector::dc_crate::{UnresolvedStruct, UnresolvedTrait}, node_interner::TraitId, - parser::SubModule, + parser::{Compiler, SubModule}, FunctionDefinition, FunctionReturnType, Ident, LetStatement, NoirFunction, NoirStruct, NoirTrait, NoirTypeAlias, ParsedModule, TraitImpl, TraitImplItem, TraitItem, TypeImpl, UnresolvedType, @@ -496,7 +496,7 @@ impl<'a> ModCollector<'a> { &mut self, context: &mut Context, crate_id: CrateId, - submodules: Vec, + submodules: Vec>, file_id: FileId, errors: &mut Vec, ) { diff --git a/crates/noirc_frontend/src/hir/def_map/mod.rs b/crates/noirc_frontend/src/hir/def_map/mod.rs index c7cc02b8dac..ca923c7520d 100644 --- a/crates/noirc_frontend/src/hir/def_map/mod.rs +++ b/crates/noirc_frontend/src/hir/def_map/mod.rs @@ -2,7 +2,7 @@ use crate::graph::CrateId; use crate::hir::def_collector::dc_crate::DefCollector; use crate::hir::Context; use crate::node_interner::{FuncId, NodeInterner}; -use crate::parser::{parse_program, ParsedModule}; +use crate::parser::{parse_program, Compiler, ParsedModule}; use crate::token::{Attribute, TestScope}; use arena::{Arena, Index}; use fm::{FileId, FileManager}; @@ -217,7 +217,7 @@ pub fn parse_file( all_errors: &mut Vec, ) -> ParsedModule { let file = fm.fetch_file(file_id); - let (program, errors) = parse_program(file.source()); + let (program, errors) = parse_program::(file.source()); all_errors.extend(errors.into_iter().map(|error| error.in_file(file_id))); program } diff --git a/crates/noirc_frontend/src/hir/resolution/resolver.rs b/crates/noirc_frontend/src/hir/resolution/resolver.rs index cf0f8f80751..f9a880ad091 100644 --- a/crates/noirc_frontend/src/hir/resolution/resolver.rs +++ b/crates/noirc_frontend/src/hir/resolution/resolver.rs @@ -1524,6 +1524,7 @@ mod test { use crate::hir_def::function::HirFunction; use crate::hir_def::stmt::HirStatement; use crate::node_interner::{FuncId, NodeInterner}; + use crate::parser::Compiler; use crate::ParsedModule; use crate::{ hir::def_map::{CrateDefMap, LocalModuleId, ModuleDefId}, @@ -1537,7 +1538,7 @@ mod test { fn init_src_code_resolution( src: &str, ) -> (ParsedModule, NodeInterner, HashMap, FileId, TestPathResolver) { - let (program, errors) = parse_program(src); + let (program, errors) = parse_program::(src); if errors.iter().any(|e| e.is_error()) { panic!("Unexpected parse errors in test code: {:?}", errors); } diff --git a/crates/noirc_frontend/src/hir/type_check/mod.rs b/crates/noirc_frontend/src/hir/type_check/mod.rs index 8596a9cc28c..5783867e84b 100644 --- a/crates/noirc_frontend/src/hir/type_check/mod.rs +++ b/crates/noirc_frontend/src/hir/type_check/mod.rs @@ -187,6 +187,7 @@ mod test { stmt::HirStatement, }; use crate::node_interner::{DefinitionKind, FuncId, NodeInterner}; + use crate::parser::Compiler; use crate::{ hir::{ def_map::{CrateDefMap, LocalModuleId, ModuleDefId}, @@ -394,7 +395,7 @@ mod test { // This function assumes that there is only one function and this is the // func id that is returned fn type_check_src_code(src: &str, func_namespace: Vec) { - let (program, errors) = parse_program(src); + let (program, errors) = parse_program::(src); let mut interner = NodeInterner::default(); // Using assert_eq here instead of assert(errors.is_empty()) displays diff --git a/crates/noirc_frontend/src/monomorphization/mod.rs b/crates/noirc_frontend/src/monomorphization/mod.rs index 7a25c5e6b77..bbcefce8eb5 100644 --- a/crates/noirc_frontend/src/monomorphization/mod.rs +++ b/crates/noirc_frontend/src/monomorphization/mod.rs @@ -1344,6 +1344,7 @@ mod tests { hir_def::function::HirFunction, node_interner::{FuncId, NodeInterner}, parse_program, + parser::Compiler, }; use super::monomorphize; @@ -1351,7 +1352,7 @@ mod tests { // TODO: refactor into a more general test utility? // mostly copied from hir / type_check / mod.rs and adapted a bit fn type_check_src_code(src: &str, func_namespace: Vec) -> (FuncId, NodeInterner) { - let (program, errors) = parse_program(src); + let (program, errors) = parse_program::(src); let mut interner = NodeInterner::default(); // Using assert_eq here instead of assert(errors.is_empty()) displays diff --git a/crates/noirc_frontend/src/parser/mod.rs b/crates/noirc_frontend/src/parser/mod.rs index 64f8c077648..55d8ba44da4 100644 --- a/crates/noirc_frontend/src/parser/mod.rs +++ b/crates/noirc_frontend/src/parser/mod.rs @@ -35,7 +35,7 @@ pub use parser::parse_program; static UNIQUE_NAME_COUNTER: AtomicU32 = AtomicU32::new(0); #[derive(Debug, Clone)] -pub(crate) enum TopLevelStatement { +pub(crate) enum TopLevelStatement { Function(NoirFunction), Module(Ident), Import(UseTree), @@ -44,7 +44,7 @@ pub(crate) enum TopLevelStatement { TraitImpl(TraitImpl), Impl(TypeImpl), TypeAlias(NoirTypeAlias), - SubModule(SubModule), + SubModule(SubModule), Global(LetStatement), Error, } @@ -205,7 +205,7 @@ fn parameter_name_recovery() -> impl NoirParser { try_skip_until([Colon, RightParen, Comma], [RightParen, Comma]) } -fn top_level_statement_recovery() -> impl NoirParser { +fn top_level_statement_recovery() -> impl NoirParser> { none_of([Token::Semicolon, Token::RightBrace, Token::EOF]) .repeated() .ignore_then(one_of([Token::Semicolon])) @@ -217,6 +217,85 @@ fn force<'a, T: 'a>(parser: impl NoirParser + 'a) -> impl NoirParser; +} + +pub trait ParsedModuleBuilder { + fn push_function(&mut self, func: NoirFunction, span: Span); + fn push_type(&mut self, typ: NoirStruct, span: Span); + fn push_trait(&mut self, noir_trait: NoirTrait, span: Span); + fn push_trait_impl(&mut self, trait_impl: TraitImpl, span: Span); + fn push_impl(&mut self, r#impl: TypeImpl, span: Span); + fn push_type_alias(&mut self, type_alias: NoirTypeAlias, span: Span); + fn push_import(&mut self, import_stmt: UseTree, span: Span); + fn push_module_decl(&mut self, mod_name: Ident, span: Span); + fn push_submodule(&mut self, submodule: SubModule, span: Span); + fn push_global(&mut self, global: LetStatement, span: Span); +} + +#[derive(Debug, Clone, Copy)] +pub struct Compiler; + +impl Mode for Compiler { + type ParsedModule = ParsedModule; +} + +#[derive(Debug, Clone, Copy)] +pub struct Fmt; + +impl Mode for Fmt { + type ParsedModule = ParsedModuleFmt; +} + +#[derive(Clone, Debug, Default)] +pub struct ParsedModuleFmt { + pub items: Vec, +} + +#[allow(unused_variables)] +impl ParsedModuleBuilder for ParsedModuleFmt { + fn push_function(&mut self, func: NoirFunction, span: Span) { + self.items.push(Item { kind: ItemKind::Function(func), span }); + } + + fn push_type(&mut self, typ: NoirStruct, span: Span) { + todo!() + } + + fn push_trait(&mut self, noir_trait: NoirTrait, span: Span) { + todo!() + } + + fn push_trait_impl(&mut self, trait_impl: TraitImpl, span: Span) { + todo!() + } + + fn push_impl(&mut self, r#impl: TypeImpl, span: Span) { + todo!() + } + + fn push_type_alias(&mut self, type_alias: NoirTypeAlias, span: Span) { + todo!() + } + + fn push_import(&mut self, import_stmt: UseTree, span: Span) { + todo!() + } + + fn push_module_decl(&mut self, mod_name: Ident, span: Span) { + todo!() + } + + fn push_submodule(&mut self, submodule: SubModule, span: Span) { + todo!() + } + + fn push_global(&mut self, global: LetStatement, span: Span) { + todo!() + } +} + /// A ParsedModule contains an entire Ast for one file. #[derive(Clone, Debug, Default)] pub struct ParsedModule { @@ -233,56 +312,67 @@ pub struct ParsedModule { pub module_decls: Vec, /// Full submodules as in `mod foo { ... definitions ... }` - pub submodules: Vec, + pub submodules: Vec>, +} + +#[derive(Clone, Debug)] +pub enum ItemKind { + Function(NoirFunction), +} + +#[derive(Clone, Debug)] +pub struct Item { + pub kind: ItemKind, + pub span: Span, } /// A submodule defined via `mod name { contents }` in some larger file. /// These submodules always share the same file as some larger ParsedModule #[derive(Clone, Debug)] -pub struct SubModule { +pub struct SubModule { pub name: Ident, - pub contents: ParsedModule, + pub contents: M::ParsedModule, pub is_contract: bool, } -impl ParsedModule { - fn push_function(&mut self, func: NoirFunction) { +impl ParsedModuleBuilder for ParsedModule { + fn push_function(&mut self, func: NoirFunction, _span: Span) { self.functions.push(func); } - fn push_type(&mut self, typ: NoirStruct) { + fn push_type(&mut self, typ: NoirStruct, _span: Span) { self.types.push(typ); } - fn push_trait(&mut self, noir_trait: NoirTrait) { + fn push_trait(&mut self, noir_trait: NoirTrait, _span: Span) { self.traits.push(noir_trait); } - fn push_trait_impl(&mut self, trait_impl: TraitImpl) { + fn push_trait_impl(&mut self, trait_impl: TraitImpl, _span: Span) { self.trait_impls.push(trait_impl); } - fn push_impl(&mut self, r#impl: TypeImpl) { + fn push_impl(&mut self, r#impl: TypeImpl, _span: Span) { self.impls.push(r#impl); } - fn push_type_alias(&mut self, type_alias: NoirTypeAlias) { + fn push_type_alias(&mut self, type_alias: NoirTypeAlias, _span: Span) { self.type_aliases.push(type_alias); } - fn push_import(&mut self, import_stmt: UseTree) { + fn push_import(&mut self, import_stmt: UseTree, _span: Span) { self.imports.extend(import_stmt.desugar(None)); } - fn push_module_decl(&mut self, mod_name: Ident) { + fn push_module_decl(&mut self, mod_name: Ident, _span: Span) { self.module_decls.push(mod_name); } - fn push_submodule(&mut self, submodule: SubModule) { + fn push_submodule(&mut self, submodule: SubModule, _span: Span) { self.submodules.push(submodule); } - fn push_global(&mut self, global: LetStatement) { + fn push_global(&mut self, global: LetStatement, _span: Span) { self.globals.push(global); } } @@ -459,7 +549,7 @@ impl ForRange { } } -impl std::fmt::Display for TopLevelStatement { +impl std::fmt::Display for TopLevelStatement { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { TopLevelStatement::Function(fun) => fun.fmt(f), @@ -515,7 +605,7 @@ impl std::fmt::Display for ParsedModule { } } -impl std::fmt::Display for SubModule { +impl std::fmt::Display for SubModule { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "mod {} {{", self.name)?; diff --git a/crates/noirc_frontend/src/parser/parser.rs b/crates/noirc_frontend/src/parser/parser.rs index 00eba5de3f3..2b97ff62272 100644 --- a/crates/noirc_frontend/src/parser/parser.rs +++ b/crates/noirc_frontend/src/parser/parser.rs @@ -23,13 +23,12 @@ //! prevent other parsers from being tried afterward since there is no longer an error. Thus, they should //! be limited to cases like the above `fn` example where it is clear we shouldn't back out of the //! current parser to try alternative parsers in a `choice` expression. -use super::spanned; use super::{ foldl_with_span, labels::ParsingRuleLabel, parameter_name_recovery, parameter_recovery, parenthesized, then_commit, then_commit_ignore, top_level_statement_recovery, ExprParser, - ForRange, NoirParser, ParsedModule, ParserError, ParserErrorReason, Precedence, SubModule, - TopLevelStatement, + ForRange, NoirParser, ParserError, ParserErrorReason, Precedence, SubModule, TopLevelStatement, }; +use super::{spanned, Mode, ParsedModuleBuilder}; use crate::ast::{ Expression, ExpressionKind, LetStatement, Statement, UnresolvedType, UnresolvedTypeData, }; @@ -54,40 +53,40 @@ use noirc_errors::{CustomDiagnostic, Span, Spanned}; /// of the program along with any parsing errors encountered. If the parsing errors /// Vec is non-empty, there may be Error nodes in the Ast to fill in the gaps that /// failed to parse. Otherwise the Ast is guaranteed to have 0 Error nodes. -pub fn parse_program(source_program: &str) -> (ParsedModule, Vec) { +pub fn parse_program(source_program: &str) -> (M::ParsedModule, Vec) { let (tokens, lexing_errors) = Lexer::lex(source_program); let mut errors = vecmap(lexing_errors, Into::into); - let (module, parsing_errors) = program().parse_recovery_verbose(tokens); + let (module, parsing_errors) = program::().parse_recovery_verbose(tokens); errors.extend(parsing_errors.into_iter().map(Into::into)); (module.unwrap(), errors) } /// program: module EOF -fn program() -> impl NoirParser { - module().then_ignore(force(just(Token::EOF))) +fn program() -> impl NoirParser { + module::().then_ignore(force(just(Token::EOF))) } /// module: top_level_statement module /// | %empty -fn module() -> impl NoirParser { +fn module() -> impl NoirParser { recursive(|module_parser| { empty() - .map(|_| ParsedModule::default()) - .then(top_level_statement(module_parser).repeated()) - .foldl(|mut program, statement| { + .map(|_| M::ParsedModule::default()) + .then(spanned(top_level_statement::(module_parser)).repeated()) + .foldl(|mut program, (statement, span)| { match statement { - TopLevelStatement::Function(f) => program.push_function(f), - TopLevelStatement::Module(m) => program.push_module_decl(m), - TopLevelStatement::Import(i) => program.push_import(i), - TopLevelStatement::Struct(s) => program.push_type(s), - TopLevelStatement::Trait(t) => program.push_trait(t), - TopLevelStatement::TraitImpl(t) => program.push_trait_impl(t), - TopLevelStatement::Impl(i) => program.push_impl(i), - TopLevelStatement::TypeAlias(t) => program.push_type_alias(t), - TopLevelStatement::SubModule(s) => program.push_submodule(s), - TopLevelStatement::Global(c) => program.push_global(c), + TopLevelStatement::Function(f) => program.push_function(f, span), + TopLevelStatement::Module(m) => program.push_module_decl(m, span), + TopLevelStatement::Import(i) => program.push_import(i, span), + TopLevelStatement::Struct(s) => program.push_type(s, span), + TopLevelStatement::Trait(t) => program.push_trait(t, span), + TopLevelStatement::TraitImpl(t) => program.push_trait_impl(t, span), + TopLevelStatement::Impl(i) => program.push_impl(i, span), + TopLevelStatement::TypeAlias(t) => program.push_type_alias(t, span), + TopLevelStatement::SubModule(s) => program.push_submodule(s, span), + TopLevelStatement::Global(c) => program.push_global(c, span), TopLevelStatement::Error => (), } program @@ -103,9 +102,9 @@ fn module() -> impl NoirParser { /// | module_declaration /// | use_statement /// | global_declaration -fn top_level_statement( - module_parser: impl NoirParser, -) -> impl NoirParser { +fn top_level_statement( + module_parser: impl NoirParser, +) -> impl NoirParser> { choice(( function_definition(false).map(TopLevelStatement::Function), struct_definition(), @@ -119,11 +118,11 @@ fn top_level_statement( use_statement().then_ignore(force(just(Token::Semicolon))), global_declaration().then_ignore(force(just(Token::Semicolon))), )) - .recover_via(top_level_statement_recovery()) + .recover_via(top_level_statement_recovery::()) } /// global_declaration: 'global' ident global_type_annotation '=' literal -fn global_declaration() -> impl NoirParser { +fn global_declaration() -> impl NoirParser> { let p = ignore_then_commit( keyword(Keyword::Global).labelled(ParsingRuleLabel::Global), ident().map(Pattern::Identifier), @@ -135,7 +134,9 @@ fn global_declaration() -> impl NoirParser { } /// submodule: 'mod' ident '{' module '}' -fn submodule(module_parser: impl NoirParser) -> impl NoirParser { +fn submodule( + module_parser: impl NoirParser, +) -> impl NoirParser> { keyword(Keyword::Mod) .ignore_then(ident()) .then_ignore(just(Token::LeftBrace)) @@ -147,7 +148,9 @@ fn submodule(module_parser: impl NoirParser) -> impl NoirParser) -> impl NoirParser { +fn contract( + module_parser: impl NoirParser, +) -> impl NoirParser> { keyword(Keyword::Contract) .ignore_then(ident()) .then_ignore(just(Token::LeftBrace)) @@ -221,7 +224,7 @@ fn generics() -> impl NoirParser> { .map(|opt| opt.unwrap_or_default()) } -fn struct_definition() -> impl NoirParser { +fn struct_definition() -> impl NoirParser> { use self::Keyword::Struct; use Token::*; @@ -241,7 +244,7 @@ fn struct_definition() -> impl NoirParser { ) } -fn type_alias_definition() -> impl NoirParser { +fn type_alias_definition() -> impl NoirParser> { use self::Keyword::Type; let p = ignore_then_commit(keyword(Type), ident()); @@ -365,7 +368,7 @@ fn self_parameter() -> impl NoirParser<(Pattern, UnresolvedType, Visibility)> { }) } -fn trait_definition() -> impl NoirParser { +fn trait_definition() -> impl NoirParser> { keyword(Keyword::Trait) .ignore_then(ident()) .then(generics()) @@ -467,7 +470,7 @@ fn trait_type_declaration() -> impl NoirParser { /// Parses a non-trait implementation, adding a set of methods to a type. /// /// implementation: 'impl' generics type '{' function_definition ... '}' -fn implementation() -> impl NoirParser { +fn implementation() -> impl NoirParser> { keyword(Keyword::Impl) .ignore_then(generics()) .then(parse_type().map_with_span(|typ, span| (typ, span))) @@ -484,7 +487,7 @@ fn implementation() -> impl NoirParser { /// and an optional `where` clause is also useable. /// /// trait_implementation: 'impl' generics ident generic_args for type '{' trait_implementation_body '}' -fn trait_implementation() -> impl NoirParser { +fn trait_implementation() -> impl NoirParser> { keyword(Keyword::Impl) .ignore_then(generics()) .then(ident()) @@ -611,11 +614,11 @@ fn optional_type_annotation<'a>() -> impl NoirParser + 'a { .map(|r#type| r#type.unwrap_or_else(UnresolvedType::unspecified)) } -fn module_declaration() -> impl NoirParser { +fn module_declaration() -> impl NoirParser> { keyword(Keyword::Mod).ignore_then(ident()).map(TopLevelStatement::Module) } -fn use_statement() -> impl NoirParser { +fn use_statement() -> impl NoirParser> { keyword(Keyword::Use).ignore_then(use_tree()).map(TopLevelStatement::Import) } @@ -1530,7 +1533,7 @@ mod test { use noirc_errors::CustomDiagnostic; use super::*; - use crate::{ArrayLiteral, Literal}; + use crate::{parser::Compiler, ArrayLiteral, Literal}; fn parse_with(parser: P, program: &str) -> Result> where @@ -1986,7 +1989,7 @@ mod test { #[test] fn parse_trait() { parse_all( - trait_definition(), + trait_definition::(), vec![ // Empty traits are legal in Rust and sometimes used as a way to whitelist certain types // for a particular operation. Also known as `tag` or `marker` traits: @@ -2087,8 +2090,8 @@ mod test { #[test] fn parse_module_declaration() { - parse_with(module_declaration(), "mod foo").unwrap(); - parse_with(module_declaration(), "mod 1").unwrap_err(); + parse_with(module_declaration::(), "mod foo").unwrap(); + parse_with(module_declaration::(), "mod 1").unwrap_err(); } #[test] @@ -2145,7 +2148,7 @@ mod test { #[test] fn parse_use() { parse_all( - use_statement(), + use_statement::(), vec![ "use std::hash", "use std", @@ -2180,7 +2183,7 @@ mod test { "struct Bar { ident: Field, }", "struct Baz { ident: Field, other: Field }", ]; - parse_all(struct_definition(), cases); + parse_all(struct_definition::(), cases); let failing = vec!["struct { }", "struct Foo { bar: pub Field }"]; parse_all_failing(struct_definition(), failing); @@ -2189,7 +2192,7 @@ mod test { #[test] fn parse_type_aliases() { let cases = vec!["type foo = u8", "type bar = String", "type baz = Vec"]; - parse_all(type_alias_definition(), cases); + parse_all(type_alias_definition::(), cases); let failing = vec!["type = u8", "type foo", "type foo = 1"]; parse_all_failing(type_alias_definition(), failing); From 88336fcbc8a231fc03bb93119200d1a2f5622f27 Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Fri, 15 Sep 2023 09:50:14 +0000 Subject: [PATCH 02/42] move to tooling and minor fixes --- Cargo.lock | 527 ++++++++++-------- Cargo.toml | 1 + .../src/hir/def_collector/dc_crate.rs | 7 +- .../src/hir/def_collector/dc_mod.rs | 10 +- .../noirc_frontend/src/hir/def_map/mod.rs | 2 +- .../src/hir/resolution/resolver.rs | 4 +- .../noirc_frontend/src/hir/type_check/mod.rs | 2 +- .../src/monomorphization/mod.rs | 5 +- compiler/noirc_frontend/src/parser/mod.rs | 191 +++---- compiler/noirc_frontend/src/parser/parser.rs | 65 ++- .../regression_mem_op_predicate/Nargo.toml | 7 - .../regression_mem_op_predicate/Prover.toml | 2 - .../regression_mem_op_predicate/src/main.nr | 8 - {crates => tooling}/nargo_fmt/Cargo.toml | 0 {crates => tooling}/nargo_fmt/src/config.rs | 0 {crates => tooling}/nargo_fmt/src/lib.rs | 4 +- {crates => tooling}/nargo_fmt/src/visitor.rs | 7 +- .../nargo_fmt/tests/source/call.nr | 0 .../nargo_fmt/tests/source/comment.nr | 0 .../nargo_fmt/tests/source/empty.nr | 0 .../nargo_fmt/tests/source/expr.nr | 0 .../nargo_fmt/tests/source/infix.nr | 0 .../nargo_fmt/tests/source/nested-if-else.nr | 0 .../nargo_fmt/tests/source/print.nr | 0 .../nargo_fmt/tests/source/print2.nr | 0 .../nargo_fmt/tests/source/unary_operators.nr | 0 26 files changed, 431 insertions(+), 411 deletions(-) delete mode 100644 crates/nargo_cli/tests/execution_success/regression_mem_op_predicate/Nargo.toml delete mode 100644 crates/nargo_cli/tests/execution_success/regression_mem_op_predicate/Prover.toml delete mode 100644 crates/nargo_cli/tests/execution_success/regression_mem_op_predicate/src/main.nr rename {crates => tooling}/nargo_fmt/Cargo.toml (100%) rename {crates => tooling}/nargo_fmt/src/config.rs (100%) rename {crates => tooling}/nargo_fmt/src/lib.rs (94%) rename {crates => tooling}/nargo_fmt/src/visitor.rs (97%) rename {crates => tooling}/nargo_fmt/tests/source/call.nr (100%) rename {crates => tooling}/nargo_fmt/tests/source/comment.nr (100%) rename {crates => tooling}/nargo_fmt/tests/source/empty.nr (100%) rename {crates => tooling}/nargo_fmt/tests/source/expr.nr (100%) rename {crates => tooling}/nargo_fmt/tests/source/infix.nr (100%) rename {crates => tooling}/nargo_fmt/tests/source/nested-if-else.nr (100%) rename {crates => tooling}/nargo_fmt/tests/source/print.nr (100%) rename {crates => tooling}/nargo_fmt/tests/source/print2.nr (100%) rename {crates => tooling}/nargo_fmt/tests/source/unary_operators.nr (100%) diff --git a/Cargo.lock b/Cargo.lock index c039794f936..daee8c17e76 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -101,11 +101,11 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.21.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" dependencies = [ - "gimli 0.28.0", + "gimli 0.27.3", ] [[package]] @@ -139,9 +139,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.5" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783" +checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" dependencies = [ "memchr", ] @@ -169,23 +169,24 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstream" -version = "0.5.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c" +checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is-terminal", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.3" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b84bf0a05bbb2a83e5eb6fa36bb6e87baa08193c35ff52bbf6b38d8af2890e46" +checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" [[package]] name = "anstyle-parse" @@ -207,9 +208,9 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "2.1.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd" +checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" dependencies = [ "anstyle", "windows-sys 0.48.0", @@ -382,9 +383,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72bd600f2652d2cccb0a33ab4f92d163ab3930844c8b0ad3713a5ae3285eeb4e" dependencies = [ "futures", - "lsp-types 0.94.1", + "lsp-types 0.94.0", "pin-project-lite", - "rustix", + "rustix 0.38.4", "serde", "serde_json", "thiserror", @@ -403,9 +404,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" dependencies = [ "addr2line", "cc", @@ -424,9 +425,9 @@ checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" [[package]] name = "base64" -version = "0.21.4" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" +checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" [[package]] name = "base64ct" @@ -451,9 +452,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.0" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" [[package]] name = "bitmaps" @@ -518,9 +519,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.6.2" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c2f7349907b712260e64b0afe2f84692af14a454be26187d9df565c7f69266a" +checksum = "6798148dccfbff0fae41c7574d2fa8f1ef3492fba0face179de5d8d447d67b05" dependencies = [ "memchr", "regex-automata", @@ -574,9 +575,9 @@ dependencies = [ [[package]] name = "bytemuck" -version = "1.14.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" +checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" [[package]] name = "byteorder" @@ -586,9 +587,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.5.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" [[package]] name = "camino" @@ -630,12 +631,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.0.83" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" -dependencies = [ - "libc", -] +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" [[package]] name = "cfg-if" @@ -695,19 +693,20 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.3" +version = "4.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84ed82781cea27b43c9b106a979fe450a13a31aab0500595fb3fc06616de08e6" +checksum = "5fd304a20bff958a57f04c4e96a2e7594cc4490a0e809cbd48bb6437edaa452d" dependencies = [ "clap_builder", "clap_derive", + "once_cell", ] [[package]] name = "clap_builder" -version = "4.4.2" +version = "4.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bb9faaa7c2ef94b2743a21f5a29e6f0010dff4caa69ac8e9d6cf8b6fa74da08" +checksum = "01c6a3f08f1fe5662a35cfe393aec09c4df95f60ee93b7556505260f75eee9e1" dependencies = [ "anstream", "anstyle", @@ -717,21 +716,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.4.2" +version = "4.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" +checksum = "54a9bb5758fc5dfe728d1019941681eccaf0cf8a4189b692a0ee2f2ecf90a050" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.26", ] [[package]] name = "clap_lex" -version = "0.5.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" +checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" [[package]] name = "codespan" @@ -810,9 +809,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.9.5" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" +checksum = "795bc6e66a8e340f075fcf6227e417a2dc976b92b91f3cdc778bb858778b6747" [[package]] name = "const_format" @@ -842,9 +841,9 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "corosensei" -version = "0.1.4" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80128832c58ea9cbd041d2a759ec449224487b2c1e400453d99d244eead87a8e" +checksum = "9847f90f32a50b0dcbd68bc23ff242798b13080b97b0569f6ed96a45ce4cf2cd" dependencies = [ "autocfg", "cfg-if", @@ -855,9 +854,9 @@ dependencies = [ [[package]] name = "cpp_demangle" -version = "0.4.3" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8227005286ec39567949b33df9896bcadfa6051bccca2488129f108ca23119" +checksum = "ee34052ee3d93d6d8f3e6f81d85c47921f6653a19a7b70e939e3e602d893a674" dependencies = [ "cfg-if", ] @@ -1106,7 +1105,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.33", + "syn 2.0.26", ] [[package]] @@ -1117,14 +1116,14 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn 2.0.33", + "syn 2.0.26", ] [[package]] name = "dashmap" -version = "5.5.3" +version = "5.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +checksum = "6943ae99c34386c84a470c499d3414f66502a41340aa895406e0d2e4a207b91d" dependencies = [ "cfg-if", "hashbrown 0.14.0", @@ -1154,9 +1153,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.8" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" +checksum = "7684a49fb1af197853ef7b2ee694bc1f5b4179556f1e5710e1760c5db6f5e929" dependencies = [ "serde", ] @@ -1230,6 +1229,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "dissimilar" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86e3bdc80eee6e16b2b6b0f87fbc98c04bee3455e35174c0de1a125d0688c632" + [[package]] name = "doc-comment" version = "0.3.3" @@ -1250,9 +1255,9 @@ dependencies = [ [[package]] name = "either" -version = "1.9.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" [[package]] name = "elliptic-curve" @@ -1282,9 +1287,9 @@ checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" dependencies = [ "cfg-if", ] @@ -1327,7 +1332,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.26", ] [[package]] @@ -1338,9 +1343,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.3" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" dependencies = [ "errno-dragonfly", "libc", @@ -1357,6 +1362,16 @@ dependencies = [ "libc", ] +[[package]] +name = "expect-test" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d9eafeadd538e68fb28016364c9732d78e420b9ff8853fa5e4058861e9f8d3" +dependencies = [ + "dissimilar", + "once_cell", +] + [[package]] name = "eyre" version = "0.6.8" @@ -1375,9 +1390,12 @@ checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" [[package]] name = "fastrand" -version = "2.0.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] [[package]] name = "ff" @@ -1415,9 +1433,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.27" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010" +checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" dependencies = [ "crc32fast", "miniz_oxide", @@ -1510,7 +1528,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.26", ] [[package]] @@ -1597,15 +1615,15 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.0" +version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" [[package]] name = "globset" -version = "0.4.13" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "759c97c1e17c55525b57192c06a267cda0ac5210b222d6b82189a2338fa1c13d" +checksum = "1391ab1f92ffcc08911957149833e682aa3fe252b9f45f966d2ef972274c97df" dependencies = [ "aho-corasick", "bstr", @@ -1651,9 +1669,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.21" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" dependencies = [ "bytes", "fnv", @@ -1764,9 +1782,9 @@ checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" -version = "1.0.3" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "hyper" @@ -1785,7 +1803,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.4.9", + "socket2", "tokio", "tower-service", "tracing", @@ -1912,12 +1930,12 @@ dependencies = [ [[package]] name = "inferno" -version = "0.11.16" +version = "0.11.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73c0fefcb6d409a6587c07515951495d482006f89a21daa0f2f783aa4fd5e027" +checksum = "2fb7c1b80a1dfa604bb4a649a5c5aeef3d913f7c520cb42b40e534e8a61bcdfc" dependencies = [ "ahash 0.8.3", - "indexmap 2.0.0", + "indexmap 1.9.3", "is-terminal", "itoa", "log", @@ -1928,6 +1946,26 @@ dependencies = [ "str_stack", ] +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "ipnet" version = "2.8.0" @@ -1941,7 +1979,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi", - "rustix", + "rustix 0.38.4", "windows-sys 0.48.0", ] @@ -2008,15 +2046,21 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.148" +version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "linux-raw-sys" -version = "0.4.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" + +[[package]] +name = "linux-raw-sys" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" [[package]] name = "lock_api" @@ -2030,9 +2074,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" [[package]] name = "lsp-types" @@ -2049,9 +2093,9 @@ dependencies = [ [[package]] name = "lsp-types" -version = "0.94.1" +version = "0.94.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c66bfd44a06ae10647fe3f8214762e9369fd4248df1350924b4ef9e770a85ea1" +checksum = "0b63735a13a1f9cd4f4835223d828ed9c2e35c8c5e61837774399f558b6a1237" dependencies = [ "bitflags 1.3.2", "serde", @@ -2071,9 +2115,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.6.3" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memmap2" @@ -2197,6 +2241,15 @@ dependencies = [ "tower", ] +[[package]] +name = "nargo_fmt" +version = "0.11.1" +dependencies = [ + "expect-test", + "noirc_frontend", + "readonly", +] + [[package]] name = "nargo_toml" version = "0.11.1" @@ -2213,13 +2266,14 @@ dependencies = [ [[package]] name = "nix" -version = "0.26.4" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" dependencies = [ "bitflags 1.3.2", "cfg-if", "libc", + "static_assertions", ] [[package]] @@ -2231,7 +2285,7 @@ dependencies = [ "codespan-lsp", "codespan-reporting", "fm", - "lsp-types 0.94.1", + "lsp-types 0.94.0", "nargo", "nargo_toml", "noirc_driver", @@ -2381,9 +2435,9 @@ checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" [[package]] name = "num-bigint" -version = "0.4.4" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" dependencies = [ "autocfg", "num-integer", @@ -2412,9 +2466,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.16" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" dependencies = [ "autocfg", ] @@ -2431,9 +2485,9 @@ dependencies = [ [[package]] name = "object" -version = "0.32.1" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" dependencies = [ "memchr", ] @@ -2504,9 +2558,9 @@ checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57" [[package]] name = "pin-utils" @@ -2668,9 +2722,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.67" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" dependencies = [ "unicode-ident", ] @@ -2706,9 +2760,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "5fe8a65d69dd0808184ebb5f836ab526bb259db23c657efa38711b1072ee47f0" dependencies = [ "proc-macro2", ] @@ -2779,6 +2833,17 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "readonly" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8f439da1766942fe069954da6058b2e6c1760eb878bae76f5be9fc29f56f574" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.26", +] + [[package]] name = "redox_syscall" version = "0.2.16" @@ -2822,9 +2887,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.9.5" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" +checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" dependencies = [ "aho-corasick", "memchr", @@ -2834,9 +2899,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.8" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" +checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310" dependencies = [ "aho-corasick", "memchr", @@ -2845,9 +2910,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.7.5" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" +checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" [[package]] name = "region" @@ -2872,9 +2937,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.20" +version = "0.11.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1" +checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" dependencies = [ "base64", "bytes", @@ -2994,7 +3059,7 @@ dependencies = [ "quote", "rust-embed-utils", "shellexpand", - "syn 2.0.33", + "syn 2.0.26", "walkdir", ] @@ -3032,22 +3097,36 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.13" +version = "0.37.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" +dependencies = [ + "bitflags 1.3.2", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys 0.3.8", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustix" +version = "0.38.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7db8590df6dfcd144d22afd1b83b36c21a18d7cbc1dc4bb5295a8712e9eb662" +checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.3.3", "errno", "libc", - "linux-raw-sys", + "linux-raw-sys 0.4.3", "windows-sys 0.48.0", ] [[package]] name = "rustls" -version = "0.21.7" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" +checksum = "79ea77c539259495ce8ca47f53e66ae0330a8819f67e23ac96ca02f50e7b7d36" dependencies = [ "log", "ring", @@ -3066,9 +3145,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.101.5" +version = "0.101.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45a27e3b59326c16e23d30aeb7a36a24cc0d29e71d68ff611cdfb4a01d013bed" +checksum = "7d93931baf2d282fff8d3a532bbfd7653f734643161b87e3e01e59a04439bf0d" dependencies = [ "ring", "untrusted", @@ -3201,9 +3280,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.188" +version = "1.0.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9" dependencies = [ "serde_derive", ] @@ -3221,20 +3300,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.188" +version = "1.0.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.26", ] [[package]] name = "serde_json" -version = "1.0.107" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +checksum = "d03b412469450d4404fe8499a268edd7f8b79fecb074b0d812ad64ca21f4031b" dependencies = [ "itoa", "ryu", @@ -3243,13 +3322,13 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.16" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" +checksum = "1d89a8107374290037607734c0b73a85db7ed80cae314b3c5791f192a496e731" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.26", ] [[package]] @@ -3275,9 +3354,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.3.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ca3b16a3d82c4088f343b7480a93550b3eabe1a358569c2dfe38bbcead07237" +checksum = "1402f54f9a3b9e2efe71c1cea24e648acce55887983553eeb858cf3115acfd49" dependencies = [ "base64", "chrono", @@ -3292,14 +3371,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.3.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e6be15c453eb305019bfa438b1593c731f36a289a7853f7707ee29e870b3b3c" +checksum = "9197f1ad0e3c173a0222d3c4404fb04c3afe87e962bcb327af73e8301fa203c7" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.26", ] [[package]] @@ -3369,9 +3448,9 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.9" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" dependencies = [ "autocfg", ] @@ -3416,16 +3495,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "socket2" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" -dependencies = [ - "libc", - "windows-sys 0.48.0", -] - [[package]] name = "spin" version = "0.5.2" @@ -3448,6 +3517,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "str_stack" version = "0.1.0" @@ -3487,9 +3562,9 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "symbolic-common" -version = "12.4.0" +version = "12.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e0e9bc48b3852f36a84f8d0da275d50cb3c2b88b59b9ec35fdd8b7fa239e37d" +checksum = "167a4ffd7c35c143fd1030aa3c2caf76ba42220bd5a6b5f4781896434723b8c3" dependencies = [ "debugid", "memmap2", @@ -3499,9 +3574,9 @@ dependencies = [ [[package]] name = "symbolic-demangle" -version = "12.4.0" +version = "12.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "691e53bdc0702aba3a5abc2cffff89346fcbd4050748883c7e2f714b33a69045" +checksum = "e378c50e80686c1c5c205674e1f86a2858bec3d2a7dfdd690331a8a19330f293" dependencies = [ "cpp_demangle", "rustc-demangle", @@ -3521,9 +3596,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.33" +version = "2.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9caece70c63bfba29ec2fed841a09851b14a235c60010fa4de58089b6c025668" +checksum = "45c3457aacde3c65315de5031ec191ce46604304d2446e803d71ade03308d970" dependencies = [ "proc-macro2", "quote", @@ -3549,20 +3624,21 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.12.11" +version = "0.12.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d0e916b1148c8e263850e1ebcbd046f333e0683c724876bb0da63ea4373dc8a" +checksum = "1d2faeef5759ab89935255b1a4cd98e0baf99d1085e37d36599c625dac49ae8e" [[package]] name = "tempfile" -version = "3.8.0" +version = "3.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" +checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" dependencies = [ + "autocfg", "cfg-if", "fastrand", "redox_syscall 0.3.5", - "rustix", + "rustix 0.37.23", "windows-sys 0.48.0", ] @@ -3607,22 +3683,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.48" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" +checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.48" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" +checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.26", ] [[package]] @@ -3637,9 +3713,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.28" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17f6bb557fd245c28e6411aa56b6403c689ad95061f50e4be16c274e70a17e48" +checksum = "b0fdd63d58b18d663fbdf70e049f00a22c8e42be082203be7f26589213cd75ea" dependencies = [ "deranged", "itoa", @@ -3656,9 +3732,9 @@ checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" -version = "0.2.14" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a942f44339478ef67935ab2bbaec2fb0322496cf3cbe84b261e06ac3814c572" +checksum = "eb71511c991639bb078fd5bf97757e03914361c48100d52878b8e52b46fb92cd" dependencies = [ "time-core", ] @@ -3690,17 +3766,18 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.32.0" +version = "1.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" +checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da" dependencies = [ + "autocfg", "backtrace", "bytes", "libc", "mio", "num_cpus", "pin-project-lite", - "socket2 0.5.4", + "socket2", "tokio-macros", "windows-sys 0.48.0", ] @@ -3713,7 +3790,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.26", ] [[package]] @@ -3743,9 +3820,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.7.8" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" +checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542" dependencies = [ "serde", "serde_spanned", @@ -3764,9 +3841,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.19.15" +version = "0.19.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" dependencies = [ "indexmap 2.0.0", "serde", @@ -3819,7 +3896,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.26", ] [[package]] @@ -3873,9 +3950,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" [[package]] name = "unicode-normalization" @@ -3906,9 +3983,9 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "url" -version = "2.4.1" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" dependencies = [ "form_urlencoded", "idna", @@ -3955,15 +4032,15 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "54f8c3c56044fc359f905b72879576a15d49c46d085ed6266a98826716f14033" dependencies = [ - "rustix", + "rustix 0.38.4", "windows-sys 0.48.0", ] [[package]] name = "walkdir" -version = "2.4.0" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" dependencies = [ "same-file", "winapi-util", @@ -4007,7 +4084,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.26", "wasm-bindgen-shared", ] @@ -4064,7 +4141,7 @@ checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.26", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4101,9 +4178,9 @@ dependencies = [ [[package]] name = "wasm-encoder" -version = "0.32.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ba64e81215916eaeb48fee292f29401d69235d62d8b8fd92a7b2844ec5ae5f7" +checksum = "06a3d1b4a575ffb873679402b2aedb3117555eb65c27b1b86c8a91e574bc2a2a" dependencies = [ "leb128", ] @@ -4264,9 +4341,9 @@ dependencies = [ [[package]] name = "wast" -version = "64.0.0" +version = "62.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a259b226fd6910225aa7baeba82f9d9933b6d00f2ce1b49b80fa4214328237cc" +checksum = "c7f7ee878019d69436895f019b65f62c33da63595d8e857cbdc87c13ecb29a32" dependencies = [ "leb128", "memchr", @@ -4276,9 +4353,9 @@ dependencies = [ [[package]] name = "wat" -version = "1.0.71" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53253d920ab413fca1c7dc2161d601c79b4fdf631d0ba51dd4343bf9b556c3f6" +checksum = "295572bf24aa5b685a971a83ad3e8b6e684aaad8a9be24bc7bf59bed84cc1c08" dependencies = [ "wast", ] @@ -4293,11 +4370,24 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0e74f82d49d545ad128049b7e88f6576df2da6b02e9ce565c6f533be576957e" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "webpki-roots" -version = "0.25.2" +version = "0.22.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" +checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" +dependencies = [ + "webpki", +] [[package]] name = "winapi" @@ -4363,24 +4453,24 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.5" +version = "0.48.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" dependencies = [ "windows_aarch64_gnullvm", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", "windows_x86_64_gnullvm", - "windows_x86_64_msvc 0.48.5", + "windows_x86_64_msvc 0.48.0", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.5" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" [[package]] name = "windows_aarch64_msvc" @@ -4390,9 +4480,9 @@ checksum = "cd761fd3eb9ab8cc1ed81e56e567f02dd82c4c837e48ac3b2181b9ffc5060807" [[package]] name = "windows_aarch64_msvc" -version = "0.48.5" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" [[package]] name = "windows_i686_gnu" @@ -4402,9 +4492,9 @@ checksum = "cab0cf703a96bab2dc0c02c0fa748491294bf9b7feb27e1f4f96340f208ada0e" [[package]] name = "windows_i686_gnu" -version = "0.48.5" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" [[package]] name = "windows_i686_msvc" @@ -4414,9 +4504,9 @@ checksum = "8cfdbe89cc9ad7ce618ba34abc34bbb6c36d99e96cae2245b7943cd75ee773d0" [[package]] name = "windows_i686_msvc" -version = "0.48.5" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" [[package]] name = "windows_x86_64_gnu" @@ -4426,15 +4516,15 @@ checksum = "b4dd9b0c0e9ece7bb22e84d70d01b71c6d6248b81a3c60d11869451b4cb24784" [[package]] name = "windows_x86_64_gnu" -version = "0.48.5" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.5" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" [[package]] name = "windows_x86_64_msvc" @@ -4444,27 +4534,26 @@ checksum = "ff1e4aa646495048ec7f3ffddc411e1d829c026a2ec62b39da15c1055e406eaa" [[package]] name = "windows_x86_64_msvc" -version = "0.48.5" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "winnow" -version = "0.5.15" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc" +checksum = "81fac9742fd1ad1bd9643b991319f72dd031016d44b77039a26977eb667141e7" dependencies = [ "memchr", ] [[package]] name = "winreg" -version = "0.50.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" dependencies = [ - "cfg-if", - "windows-sys 0.48.0", + "winapi", ] [[package]] @@ -4502,5 +4591,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.26", ] diff --git a/Cargo.toml b/Cargo.toml index 0120cb3cb8a..3d28fb6ab87 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ members = [ # Crates related to tooling built ontop of the Noir compiler "tooling/acvm_backend_barretenberg", "tooling/nargo", + "tooling/nargo_fmt", "tooling/nargo_cli", "tooling/nargo_toml", "tooling/noirc_abi", diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs index c55335e4443..28029cf0b40 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -12,10 +12,11 @@ use crate::hir::resolution::{ use crate::hir::type_check::{type_check_func, TypeChecker}; use crate::hir::Context; use crate::node_interner::{FuncId, NodeInterner, StmtId, StructId, TraitId, TypeAliasId}; +use crate::parser::LegacyParsedModule; use crate::{ ExpressionKind, FunctionReturnType, Generics, Ident, LetStatement, Literal, NoirFunction, - NoirStruct, NoirTrait, NoirTypeAlias, ParsedModule, Shared, StructType, TraitItem, - TraitItemType, Type, TypeBinding, UnresolvedGenerics, UnresolvedType, + NoirStruct, NoirTrait, NoirTypeAlias, Shared, StructType, TraitItem, TraitItemType, Type, + TypeBinding, UnresolvedGenerics, UnresolvedType, }; use fm::FileId; use iter_extended::vecmap; @@ -120,7 +121,7 @@ impl DefCollector { pub fn collect( mut def_map: CrateDefMap, context: &mut Context, - ast: ParsedModule, + ast: LegacyParsedModule, root_file_id: FileId, errors: &mut Vec, ) { diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs index 2679059cebd..5bcc7167ae8 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs @@ -5,9 +5,9 @@ use crate::{ graph::CrateId, hir::def_collector::dc_crate::{UnresolvedStruct, UnresolvedTrait}, node_interner::TraitId, - parser::SubModule, + parser::{LegacyParsedModule, SubModule}, FunctionDefinition, Ident, LetStatement, NoirFunction, NoirStruct, NoirTrait, NoirTypeAlias, - ParsedModule, TraitImpl, TraitImplItem, TraitItem, TypeImpl, + TraitImpl, TraitImplItem, TraitItem, TypeImpl, }; use super::{ @@ -33,7 +33,7 @@ struct ModCollector<'a> { /// This performs the entirety of the definition collection phase of the name resolution pass. pub fn collect_defs( def_collector: &mut DefCollector, - ast: ParsedModule, + ast: LegacyParsedModule, file_id: FileId, module_id: LocalModuleId, crate_id: CrateId, @@ -437,7 +437,7 @@ impl<'a> ModCollector<'a> { ) { collect_defs( self.def_collector, - submodule.contents, + submodule.contents.into_legacy(), file_id, child, crate_id, @@ -470,7 +470,7 @@ impl<'a> ModCollector<'a> { }; // Parse the AST for the module we just found and then recursively look for it's defs - let ast = parse_file(&mut context.file_manager, child_file_id, errors); + let ast = parse_file(&mut context.file_manager, child_file_id, errors).into_legacy(); // Add module into def collector and get a ModuleId if let Some(child_mod_id) = diff --git a/compiler/noirc_frontend/src/hir/def_map/mod.rs b/compiler/noirc_frontend/src/hir/def_map/mod.rs index 1a7c6674e01..9396f6c4d62 100644 --- a/compiler/noirc_frontend/src/hir/def_map/mod.rs +++ b/compiler/noirc_frontend/src/hir/def_map/mod.rs @@ -86,7 +86,7 @@ impl CrateDefMap { // First parse the root file. let root_file_id = context.crate_graph[crate_id].root_file_id; - let ast = parse_file(&mut context.file_manager, root_file_id, errors); + let ast = parse_file(&mut context.file_manager, root_file_id, errors).into_legacy(); #[cfg(feature = "aztec")] let ast = aztec_library::transform(ast, &crate_id, context, errors); diff --git a/compiler/noirc_frontend/src/hir/resolution/resolver.rs b/compiler/noirc_frontend/src/hir/resolution/resolver.rs index 411e91f2cf4..7994c2ac7fd 100644 --- a/compiler/noirc_frontend/src/hir/resolution/resolver.rs +++ b/compiler/noirc_frontend/src/hir/resolution/resolver.rs @@ -1598,7 +1598,7 @@ mod test { } let mut errors = Vec::new(); - for func in program.functions { + for func in program.into_legacy().functions { let id = interner.push_fn(HirFunction::empty()); interner.push_function_definition(func.name().to_string(), id); @@ -1615,7 +1615,7 @@ mod test { init_src_code_resolution(src); let mut all_captures: Vec> = Vec::new(); - for func in program.functions { + for func in program.into_legacy().functions { let id = interner.push_fn(HirFunction::empty()); interner.push_function_definition(func.name().to_string(), id); path_resolver.insert_func(func.name().to_owned(), id); diff --git a/compiler/noirc_frontend/src/hir/type_check/mod.rs b/compiler/noirc_frontend/src/hir/type_check/mod.rs index ea1793b7e76..09de74c18f5 100644 --- a/compiler/noirc_frontend/src/hir/type_check/mod.rs +++ b/compiler/noirc_frontend/src/hir/type_check/mod.rs @@ -433,7 +433,7 @@ mod test { }, ); - let func_meta = vecmap(program.functions, |nf| { + let func_meta = vecmap(program.into_legacy().functions, |nf| { let resolver = Resolver::new(&mut interner, &path_resolver, &def_maps, file); let (hir_func, func_meta, resolver_errors) = resolver.resolve_function(nf, main_id, ModuleId::dummy_id()); diff --git a/compiler/noirc_frontend/src/monomorphization/mod.rs b/compiler/noirc_frontend/src/monomorphization/mod.rs index eaaca98c6f0..2773cc0f2a7 100644 --- a/compiler/noirc_frontend/src/monomorphization/mod.rs +++ b/compiler/noirc_frontend/src/monomorphization/mod.rs @@ -1347,7 +1347,6 @@ mod tests { hir_def::function::HirFunction, node_interner::{FuncId, NodeInterner}, parse_program, - parser::Compiler, }; use super::monomorphize; @@ -1355,7 +1354,7 @@ mod tests { // TODO: refactor into a more general test utility? // mostly copied from hir / type_check / mod.rs and adapted a bit fn type_check_src_code(src: &str, func_namespace: Vec) -> (FuncId, NodeInterner) { - let (program, errors) = parse_program::(src); + let (program, errors) = parse_program(src); let mut interner = NodeInterner::default(); // Using assert_eq here instead of assert(errors.is_empty()) displays @@ -1393,7 +1392,7 @@ mod tests { }, ); - let func_meta = vecmap(program.functions, |nf| { + let func_meta = vecmap(program.into_legacy().functions, |nf| { let resolver = Resolver::new(&mut interner, &path_resolver, &def_maps, file); let (hir_func, func_meta, _resolver_errors) = resolver.resolve_function(nf, main_id, ModuleId::dummy_id()); diff --git a/compiler/noirc_frontend/src/parser/mod.rs b/compiler/noirc_frontend/src/parser/mod.rs index 55d8ba44da4..32e4fce8f24 100644 --- a/compiler/noirc_frontend/src/parser/mod.rs +++ b/compiler/noirc_frontend/src/parser/mod.rs @@ -35,7 +35,7 @@ pub use parser::parse_program; static UNIQUE_NAME_COUNTER: AtomicU32 = AtomicU32::new(0); #[derive(Debug, Clone)] -pub(crate) enum TopLevelStatement { +pub(crate) enum TopLevelStatement { Function(NoirFunction), Module(Ident), Import(UseTree), @@ -44,7 +44,7 @@ pub(crate) enum TopLevelStatement { TraitImpl(TraitImpl), Impl(TypeImpl), TypeAlias(NoirTypeAlias), - SubModule(SubModule), + SubModule(SubModule), Global(LetStatement), Error, } @@ -205,7 +205,7 @@ fn parameter_name_recovery() -> impl NoirParser { try_skip_until([Colon, RightParen, Comma], [RightParen, Comma]) } -fn top_level_statement_recovery() -> impl NoirParser> { +fn top_level_statement_recovery() -> impl NoirParser { none_of([Token::Semicolon, Token::RightBrace, Token::EOF]) .repeated() .ignore_then(one_of([Token::Semicolon])) @@ -217,88 +217,7 @@ fn force<'a, T: 'a>(parser: impl NoirParser + 'a) -> impl NoirParser; -} - -pub trait ParsedModuleBuilder { - fn push_function(&mut self, func: NoirFunction, span: Span); - fn push_type(&mut self, typ: NoirStruct, span: Span); - fn push_trait(&mut self, noir_trait: NoirTrait, span: Span); - fn push_trait_impl(&mut self, trait_impl: TraitImpl, span: Span); - fn push_impl(&mut self, r#impl: TypeImpl, span: Span); - fn push_type_alias(&mut self, type_alias: NoirTypeAlias, span: Span); - fn push_import(&mut self, import_stmt: UseTree, span: Span); - fn push_module_decl(&mut self, mod_name: Ident, span: Span); - fn push_submodule(&mut self, submodule: SubModule, span: Span); - fn push_global(&mut self, global: LetStatement, span: Span); -} - -#[derive(Debug, Clone, Copy)] -pub struct Compiler; - -impl Mode for Compiler { - type ParsedModule = ParsedModule; -} - -#[derive(Debug, Clone, Copy)] -pub struct Fmt; - -impl Mode for Fmt { - type ParsedModule = ParsedModuleFmt; -} - -#[derive(Clone, Debug, Default)] -pub struct ParsedModuleFmt { - pub items: Vec, -} - -#[allow(unused_variables)] -impl ParsedModuleBuilder for ParsedModuleFmt { - fn push_function(&mut self, func: NoirFunction, span: Span) { - self.items.push(Item { kind: ItemKind::Function(func), span }); - } - - fn push_type(&mut self, typ: NoirStruct, span: Span) { - todo!() - } - - fn push_trait(&mut self, noir_trait: NoirTrait, span: Span) { - todo!() - } - - fn push_trait_impl(&mut self, trait_impl: TraitImpl, span: Span) { - todo!() - } - - fn push_impl(&mut self, r#impl: TypeImpl, span: Span) { - todo!() - } - - fn push_type_alias(&mut self, type_alias: NoirTypeAlias, span: Span) { - todo!() - } - - fn push_import(&mut self, import_stmt: UseTree, span: Span) { - todo!() - } - - fn push_module_decl(&mut self, mod_name: Ident, span: Span) { - todo!() - } - - fn push_submodule(&mut self, submodule: SubModule, span: Span) { - todo!() - } - - fn push_global(&mut self, global: LetStatement, span: Span) { - todo!() - } -} - -/// A ParsedModule contains an entire Ast for one file. -#[derive(Clone, Debug, Default)] -pub struct ParsedModule { +pub struct LegacyParsedModule { pub imports: Vec, pub functions: Vec, pub types: Vec, @@ -312,12 +231,19 @@ pub struct ParsedModule { pub module_decls: Vec, /// Full submodules as in `mod foo { ... definitions ... }` - pub submodules: Vec>, + pub submodules: Vec, } -#[derive(Clone, Debug)] -pub enum ItemKind { - Function(NoirFunction), +/// A ParsedModule contains an entire Ast for one file. +#[derive(Clone, Debug, Default)] +pub struct ParsedModule { + pub items: Vec, +} + +impl ParsedModule { + pub fn into_legacy(self) -> LegacyParsedModule { + todo!() + } } #[derive(Clone, Debug)] @@ -326,54 +252,73 @@ pub struct Item { pub span: Span, } +#[derive(Clone, Debug)] +pub enum ItemKind { + Import(ImportStatement), + Function(NoirFunction), + Struct(NoirStruct), + Trait(NoirTrait), + TraitImpl(TraitImpl), + Impl(TypeImpl), + TypeAlias(NoirTypeAlias), + Global(LetStatement), + ModuleDecl(Ident), + Submodules(SubModule), +} + /// A submodule defined via `mod name { contents }` in some larger file. /// These submodules always share the same file as some larger ParsedModule #[derive(Clone, Debug)] -pub struct SubModule { +pub struct SubModule { pub name: Ident, - pub contents: M::ParsedModule, + pub contents: ParsedModule, pub is_contract: bool, } -impl ParsedModuleBuilder for ParsedModule { - fn push_function(&mut self, func: NoirFunction, _span: Span) { - self.functions.push(func); +impl ParsedModule { + fn push_function(&mut self, func: NoirFunction, span: Span) { + self.items.push(Item { kind: ItemKind::Function(func), span }); } - fn push_type(&mut self, typ: NoirStruct, _span: Span) { - self.types.push(typ); + fn push_type(&mut self, typ: NoirStruct, span: Span) { + self.items.push(Item { kind: ItemKind::Struct(typ), span }); } - fn push_trait(&mut self, noir_trait: NoirTrait, _span: Span) { - self.traits.push(noir_trait); + fn push_trait(&mut self, noir_trait: NoirTrait, span: Span) { + self.items.push(Item { kind: ItemKind::Trait(noir_trait), span }); } - fn push_trait_impl(&mut self, trait_impl: TraitImpl, _span: Span) { - self.trait_impls.push(trait_impl); + fn push_trait_impl(&mut self, trait_impl: TraitImpl, span: Span) { + self.items.push(Item { kind: ItemKind::TraitImpl(trait_impl), span }); } - fn push_impl(&mut self, r#impl: TypeImpl, _span: Span) { - self.impls.push(r#impl); + fn push_impl(&mut self, r#impl: TypeImpl, span: Span) { + self.items.push(Item { kind: ItemKind::Impl(r#impl), span }); } - fn push_type_alias(&mut self, type_alias: NoirTypeAlias, _span: Span) { - self.type_aliases.push(type_alias); + fn push_type_alias(&mut self, type_alias: NoirTypeAlias, span: Span) { + self.items.push(Item { kind: ItemKind::TypeAlias(type_alias), span }); } - fn push_import(&mut self, import_stmt: UseTree, _span: Span) { - self.imports.extend(import_stmt.desugar(None)); + fn push_import(&mut self, import_stmt: UseTree, span: Span) { + self.items.extend( + import_stmt + .desugar(None) + .into_iter() + .map(|kind| Item { kind: ItemKind::Import(kind), span }), + ); } - fn push_module_decl(&mut self, mod_name: Ident, _span: Span) { - self.module_decls.push(mod_name); + fn push_module_decl(&mut self, mod_name: Ident, span: Span) { + self.items.push(Item { kind: ItemKind::ModuleDecl(mod_name), span }); } - fn push_submodule(&mut self, submodule: SubModule, _span: Span) { - self.submodules.push(submodule); + fn push_submodule(&mut self, submodule: SubModule, span: Span) { + self.items.push(Item { kind: ItemKind::Submodules(submodule), span }); } - fn push_global(&mut self, global: LetStatement, _span: Span) { - self.globals.push(global); + fn push_global(&mut self, global: LetStatement, span: Span) { + self.items.push(Item { kind: ItemKind::Global(global), span }); } } @@ -549,7 +494,7 @@ impl ForRange { } } -impl std::fmt::Display for TopLevelStatement { +impl std::fmt::Display for TopLevelStatement { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { TopLevelStatement::Function(fun) => fun.fmt(f), @@ -569,35 +514,37 @@ impl std::fmt::Display for TopLevelStatement { impl std::fmt::Display for ParsedModule { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - for decl in &self.module_decls { + let legacy = self.clone().into_legacy(); + + for decl in &legacy.module_decls { writeln!(f, "mod {decl};")?; } - for import in &self.imports { + for import in &legacy.imports { write!(f, "{import}")?; } - for global_const in &self.globals { + for global_const in &legacy.globals { write!(f, "{global_const}")?; } - for type_ in &self.types { + for type_ in &legacy.types { write!(f, "{type_}")?; } - for function in &self.functions { + for function in &legacy.functions { write!(f, "{function}")?; } - for impl_ in &self.impls { + for impl_ in &legacy.impls { write!(f, "{impl_}")?; } - for type_alias in &self.type_aliases { + for type_alias in &legacy.type_aliases { write!(f, "{type_alias}")?; } - for submodule in &self.submodules { + for submodule in &legacy.submodules { write!(f, "{submodule}")?; } @@ -605,7 +552,7 @@ impl std::fmt::Display for ParsedModule { } } -impl std::fmt::Display for SubModule { +impl std::fmt::Display for SubModule { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "mod {} {{", self.name)?; diff --git a/compiler/noirc_frontend/src/parser/parser.rs b/compiler/noirc_frontend/src/parser/parser.rs index 0efad9ead47..b90e5be4a54 100644 --- a/compiler/noirc_frontend/src/parser/parser.rs +++ b/compiler/noirc_frontend/src/parser/parser.rs @@ -23,12 +23,13 @@ //! prevent other parsers from being tried afterward since there is no longer an error. Thus, they should //! be limited to cases like the above `fn` example where it is clear we shouldn't back out of the //! current parser to try alternative parsers in a `choice` expression. +use super::spanned; use super::{ foldl_with_span, labels::ParsingRuleLabel, parameter_name_recovery, parameter_recovery, parenthesized, then_commit, then_commit_ignore, top_level_statement_recovery, ExprParser, - ForRange, NoirParser, ParserError, ParserErrorReason, Precedence, SubModule, TopLevelStatement, + ForRange, NoirParser, ParsedModule, ParserError, ParserErrorReason, Precedence, SubModule, + TopLevelStatement, }; -use super::{spanned, Mode, ParsedModuleBuilder}; use crate::ast::{ Expression, ExpressionKind, LetStatement, Statement, UnresolvedType, UnresolvedTypeData, }; @@ -53,28 +54,28 @@ use noirc_errors::{CustomDiagnostic, Span, Spanned}; /// of the program along with any parsing errors encountered. If the parsing errors /// Vec is non-empty, there may be Error nodes in the Ast to fill in the gaps that /// failed to parse. Otherwise the Ast is guaranteed to have 0 Error nodes. -pub fn parse_program(source_program: &str) -> (M::ParsedModule, Vec) { +pub fn parse_program(source_program: &str) -> (ParsedModule, Vec) { let (tokens, lexing_errors) = Lexer::lex(source_program); let mut errors = vecmap(lexing_errors, Into::into); - let (module, parsing_errors) = program::().parse_recovery_verbose(tokens); + let (module, parsing_errors) = program().parse_recovery_verbose(tokens); errors.extend(parsing_errors.into_iter().map(Into::into)); (module.unwrap(), errors) } /// program: module EOF -fn program() -> impl NoirParser { - module::().then_ignore(force(just(Token::EOF))) +fn program() -> impl NoirParser { + module().then_ignore(force(just(Token::EOF))) } /// module: top_level_statement module /// | %empty -fn module() -> impl NoirParser { +fn module() -> impl NoirParser { recursive(|module_parser| { empty() - .map(|_| M::ParsedModule::default()) - .then(spanned(top_level_statement::(module_parser)).repeated()) + .map(|_| ParsedModule::default()) + .then(spanned(top_level_statement(module_parser)).repeated()) .foldl(|mut program, (statement, span)| { match statement { TopLevelStatement::Function(f) => program.push_function(f, span), @@ -102,9 +103,9 @@ fn module() -> impl NoirParser { /// | module_declaration /// | use_statement /// | global_declaration -fn top_level_statement( - module_parser: impl NoirParser, -) -> impl NoirParser> { +fn top_level_statement( + module_parser: impl NoirParser, +) -> impl NoirParser { choice(( function_definition(false).map(TopLevelStatement::Function), struct_definition(), @@ -118,11 +119,11 @@ fn top_level_statement( use_statement().then_ignore(force(just(Token::Semicolon))), global_declaration().then_ignore(force(just(Token::Semicolon))), )) - .recover_via(top_level_statement_recovery::()) + .recover_via(top_level_statement_recovery()) } /// global_declaration: 'global' ident global_type_annotation '=' literal -fn global_declaration() -> impl NoirParser> { +fn global_declaration() -> impl NoirParser { let p = ignore_then_commit( keyword(Keyword::Global).labelled(ParsingRuleLabel::Global), ident().map(Pattern::Identifier), @@ -134,9 +135,7 @@ fn global_declaration() -> impl NoirParser> { } /// submodule: 'mod' ident '{' module '}' -fn submodule( - module_parser: impl NoirParser, -) -> impl NoirParser> { +fn submodule(module_parser: impl NoirParser) -> impl NoirParser { keyword(Keyword::Mod) .ignore_then(ident()) .then_ignore(just(Token::LeftBrace)) @@ -148,9 +147,7 @@ fn submodule( } /// contract: 'contract' ident '{' module '}' -fn contract( - module_parser: impl NoirParser, -) -> impl NoirParser> { +fn contract(module_parser: impl NoirParser) -> impl NoirParser { keyword(Keyword::Contract) .ignore_then(ident()) .then_ignore(just(Token::LeftBrace)) @@ -227,7 +224,7 @@ fn generics() -> impl NoirParser> { .map(|opt| opt.unwrap_or_default()) } -fn struct_definition() -> impl NoirParser> { +fn struct_definition() -> impl NoirParser { use self::Keyword::Struct; use Token::*; @@ -247,7 +244,7 @@ fn struct_definition() -> impl NoirParser> { ) } -fn type_alias_definition() -> impl NoirParser> { +fn type_alias_definition() -> impl NoirParser { use self::Keyword::Type; let p = ignore_then_commit(keyword(Type), ident()); @@ -375,7 +372,7 @@ fn self_parameter() -> impl NoirParser<(Pattern, UnresolvedType, Visibility)> { }) } -fn trait_definition() -> impl NoirParser> { +fn trait_definition() -> impl NoirParser { keyword(Keyword::Trait) .ignore_then(ident()) .then(generics()) @@ -509,7 +506,7 @@ fn trait_type_declaration() -> impl NoirParser { /// Parses a non-trait implementation, adding a set of methods to a type. /// /// implementation: 'impl' generics type '{' function_definition ... '}' -fn implementation() -> impl NoirParser> { +fn implementation() -> impl NoirParser { keyword(Keyword::Impl) .ignore_then(generics()) .then(parse_type().map_with_span(|typ, span| (typ, span))) @@ -526,7 +523,7 @@ fn implementation() -> impl NoirParser> { /// and an optional `where` clause is also useable. /// /// trait_implementation: 'impl' generics ident generic_args for type '{' trait_implementation_body '}' -fn trait_implementation() -> impl NoirParser> { +fn trait_implementation() -> impl NoirParser { keyword(Keyword::Impl) .ignore_then(generics()) .then(ident()) @@ -653,11 +650,11 @@ fn optional_type_annotation<'a>() -> impl NoirParser + 'a { .map(|r#type| r#type.unwrap_or_else(UnresolvedType::unspecified)) } -fn module_declaration() -> impl NoirParser> { +fn module_declaration() -> impl NoirParser { keyword(Keyword::Mod).ignore_then(ident()).map(TopLevelStatement::Module) } -fn use_statement() -> impl NoirParser> { +fn use_statement() -> impl NoirParser { keyword(Keyword::Use).ignore_then(use_tree()).map(TopLevelStatement::Import) } @@ -1572,7 +1569,7 @@ mod test { use noirc_errors::CustomDiagnostic; use super::*; - use crate::{parser::Compiler, ArrayLiteral, Literal}; + use crate::{ArrayLiteral, Literal}; fn parse_with(parser: P, program: &str) -> Result> where @@ -2028,7 +2025,7 @@ mod test { #[test] fn parse_trait() { parse_all( - trait_definition::(), + trait_definition(), vec![ // Empty traits are legal in Rust and sometimes used as a way to whitelist certain types // for a particular operation. Also known as `tag` or `marker` traits: @@ -2129,8 +2126,8 @@ mod test { #[test] fn parse_module_declaration() { - parse_with(module_declaration::(), "mod foo").unwrap(); - parse_with(module_declaration::(), "mod 1").unwrap_err(); + parse_with(module_declaration(), "mod foo").unwrap(); + parse_with(module_declaration(), "mod 1").unwrap_err(); } #[test] @@ -2187,7 +2184,7 @@ mod test { #[test] fn parse_use() { parse_all( - use_statement::(), + use_statement(), vec![ "use std::hash", "use std", @@ -2222,7 +2219,7 @@ mod test { "struct Bar { ident: Field, }", "struct Baz { ident: Field, other: Field }", ]; - parse_all(struct_definition::(), cases); + parse_all(struct_definition(), cases); let failing = vec!["struct { }", "struct Foo { bar: pub Field }"]; parse_all_failing(struct_definition(), failing); @@ -2231,7 +2228,7 @@ mod test { #[test] fn parse_type_aliases() { let cases = vec!["type foo = u8", "type bar = String", "type baz = Vec"]; - parse_all(type_alias_definition::(), cases); + parse_all(type_alias_definition(), cases); let failing = vec!["type = u8", "type foo", "type foo = 1"]; parse_all_failing(type_alias_definition(), failing); diff --git a/crates/nargo_cli/tests/execution_success/regression_mem_op_predicate/Nargo.toml b/crates/nargo_cli/tests/execution_success/regression_mem_op_predicate/Nargo.toml deleted file mode 100644 index 0361b28fd1e..00000000000 --- a/crates/nargo_cli/tests/execution_success/regression_mem_op_predicate/Nargo.toml +++ /dev/null @@ -1,7 +0,0 @@ -[package] -name = "regression_mem_op_predicate" -type = "bin" -authors = [""] -compiler_version = "0.1" - -[dependencies] diff --git a/crates/nargo_cli/tests/execution_success/regression_mem_op_predicate/Prover.toml b/crates/nargo_cli/tests/execution_success/regression_mem_op_predicate/Prover.toml deleted file mode 100644 index 3621f24082c..00000000000 --- a/crates/nargo_cli/tests/execution_success/regression_mem_op_predicate/Prover.toml +++ /dev/null @@ -1,2 +0,0 @@ -x = [4,3,1,5,111] -idx = 12 \ No newline at end of file diff --git a/crates/nargo_cli/tests/execution_success/regression_mem_op_predicate/src/main.nr b/crates/nargo_cli/tests/execution_success/regression_mem_op_predicate/src/main.nr deleted file mode 100644 index a592e2b62b4..00000000000 --- a/crates/nargo_cli/tests/execution_success/regression_mem_op_predicate/src/main.nr +++ /dev/null @@ -1,8 +0,0 @@ -fn main(mut x: [u32; 5], idx: Field) { - // We should not hit out of bounds here as we have a predicate - // that should not be hit - if idx as u32 < 3 { - x[idx] = 10; - } - assert(x[4] == 111); -} \ No newline at end of file diff --git a/crates/nargo_fmt/Cargo.toml b/tooling/nargo_fmt/Cargo.toml similarity index 100% rename from crates/nargo_fmt/Cargo.toml rename to tooling/nargo_fmt/Cargo.toml diff --git a/crates/nargo_fmt/src/config.rs b/tooling/nargo_fmt/src/config.rs similarity index 100% rename from crates/nargo_fmt/src/config.rs rename to tooling/nargo_fmt/src/config.rs diff --git a/crates/nargo_fmt/src/lib.rs b/tooling/nargo_fmt/src/lib.rs similarity index 94% rename from crates/nargo_fmt/src/lib.rs rename to tooling/nargo_fmt/src/lib.rs index 7d3264343f0..bf8f4f39d2f 100644 --- a/crates/nargo_fmt/src/lib.rs +++ b/tooling/nargo_fmt/src/lib.rs @@ -3,11 +3,10 @@ mod config; mod visitor; -use noirc_frontend::parser::Fmt; use visitor::FmtVisitor; pub fn format(source: &str) -> String { - let (module, errors) = noirc_frontend::parse_program::(source); + let (module, errors) = noirc_frontend::parse_program(source); // TODO: error handling if !errors.is_empty() { @@ -67,6 +66,7 @@ mod tests { Err(err) => unreachable!("{err}"), }; + // TODO: better diff assert_eq!(fmt_text, target); } } diff --git a/crates/nargo_fmt/src/visitor.rs b/tooling/nargo_fmt/src/visitor.rs similarity index 97% rename from crates/nargo_fmt/src/visitor.rs rename to tooling/nargo_fmt/src/visitor.rs index 0a581d303a3..e5d7f12f0f4 100644 --- a/crates/nargo_fmt/src/visitor.rs +++ b/tooling/nargo_fmt/src/visitor.rs @@ -1,6 +1,6 @@ use noirc_frontend::{ hir::resolution::errors::Span, - parser::{ItemKind, ParsedModuleFmt}, + parser::{ItemKind, ParsedModule}, BlockExpression, Expression, ExpressionKind, NoirFunction, Statement, }; @@ -50,7 +50,7 @@ impl<'a> FmtVisitor<'a> { self.push_str(&s); } - pub fn visit_module(&mut self, module: ParsedModuleFmt) { + pub fn visit_module(&mut self, module: ParsedModule) { for item in module.items { match item.kind { ItemKind::Function(func) => { @@ -63,6 +63,9 @@ impl<'a> FmtVisitor<'a> { self.visit_block(func.def.body, func.def.span, false); } + _ => { + self.format_missing_indent(item.span.end(), false); + } } } diff --git a/crates/nargo_fmt/tests/source/call.nr b/tooling/nargo_fmt/tests/source/call.nr similarity index 100% rename from crates/nargo_fmt/tests/source/call.nr rename to tooling/nargo_fmt/tests/source/call.nr diff --git a/crates/nargo_fmt/tests/source/comment.nr b/tooling/nargo_fmt/tests/source/comment.nr similarity index 100% rename from crates/nargo_fmt/tests/source/comment.nr rename to tooling/nargo_fmt/tests/source/comment.nr diff --git a/crates/nargo_fmt/tests/source/empty.nr b/tooling/nargo_fmt/tests/source/empty.nr similarity index 100% rename from crates/nargo_fmt/tests/source/empty.nr rename to tooling/nargo_fmt/tests/source/empty.nr diff --git a/crates/nargo_fmt/tests/source/expr.nr b/tooling/nargo_fmt/tests/source/expr.nr similarity index 100% rename from crates/nargo_fmt/tests/source/expr.nr rename to tooling/nargo_fmt/tests/source/expr.nr diff --git a/crates/nargo_fmt/tests/source/infix.nr b/tooling/nargo_fmt/tests/source/infix.nr similarity index 100% rename from crates/nargo_fmt/tests/source/infix.nr rename to tooling/nargo_fmt/tests/source/infix.nr diff --git a/crates/nargo_fmt/tests/source/nested-if-else.nr b/tooling/nargo_fmt/tests/source/nested-if-else.nr similarity index 100% rename from crates/nargo_fmt/tests/source/nested-if-else.nr rename to tooling/nargo_fmt/tests/source/nested-if-else.nr diff --git a/crates/nargo_fmt/tests/source/print.nr b/tooling/nargo_fmt/tests/source/print.nr similarity index 100% rename from crates/nargo_fmt/tests/source/print.nr rename to tooling/nargo_fmt/tests/source/print.nr diff --git a/crates/nargo_fmt/tests/source/print2.nr b/tooling/nargo_fmt/tests/source/print2.nr similarity index 100% rename from crates/nargo_fmt/tests/source/print2.nr rename to tooling/nargo_fmt/tests/source/print2.nr diff --git a/crates/nargo_fmt/tests/source/unary_operators.nr b/tooling/nargo_fmt/tests/source/unary_operators.nr similarity index 100% rename from crates/nargo_fmt/tests/source/unary_operators.nr rename to tooling/nargo_fmt/tests/source/unary_operators.nr From e26baa4ed9ac5ce67591bbd3eb873b275c9a0e38 Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Fri, 15 Sep 2023 09:59:45 +0000 Subject: [PATCH 03/42] set `license.workspace = true` --- Cargo.lock | 17 ----------------- tooling/nargo_fmt/Cargo.toml | 4 +--- 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index daee8c17e76..20f01a46a80 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1229,12 +1229,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "dissimilar" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86e3bdc80eee6e16b2b6b0f87fbc98c04bee3455e35174c0de1a125d0688c632" - [[package]] name = "doc-comment" version = "0.3.3" @@ -1362,16 +1356,6 @@ dependencies = [ "libc", ] -[[package]] -name = "expect-test" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d9eafeadd538e68fb28016364c9732d78e420b9ff8853fa5e4058861e9f8d3" -dependencies = [ - "dissimilar", - "once_cell", -] - [[package]] name = "eyre" version = "0.6.8" @@ -2245,7 +2229,6 @@ dependencies = [ name = "nargo_fmt" version = "0.11.1" dependencies = [ - "expect-test", "noirc_frontend", "readonly", ] diff --git a/tooling/nargo_fmt/Cargo.toml b/tooling/nargo_fmt/Cargo.toml index 76b14b835a7..da77216c0ad 100644 --- a/tooling/nargo_fmt/Cargo.toml +++ b/tooling/nargo_fmt/Cargo.toml @@ -3,10 +3,8 @@ name = "nargo_fmt" version.workspace = true authors.workspace = true edition.workspace = true +license.workspace = true [dependencies] noirc_frontend.workspace = true readonly = "0.2" - -[dev-dependencies] -expect-test = "1.4.1" From 86fc87cfeab86f2444809202a6bdf0f5a1ec2b1d Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Fri, 15 Sep 2023 10:05:57 +0000 Subject: [PATCH 04/42] fix confusion with .gitignore --- tooling/nargo_fmt/src/lib.rs | 4 +-- tooling/nargo_fmt/tests/expected/call.nr | 3 ++ tooling/nargo_fmt/tests/expected/comment.nr | 14 ++++++++ .../tests/{source => expected}/empty.nr | 0 tooling/nargo_fmt/tests/expected/expr.nr | 35 +++++++++++++++++++ .../tests/{source => expected}/infix.nr | 0 .../{source => expected}/nested-if-else.nr | 0 tooling/nargo_fmt/tests/expected/print.nr | 4 +++ tooling/nargo_fmt/tests/expected/print2.nr | 4 +++ .../tests/expected/unary_operators.nr | 3 ++ .../nargo_fmt/tests/{source => input}/call.nr | 0 .../tests/{source => input}/comment.nr | 0 tooling/nargo_fmt/tests/input/empty.nr | 0 .../nargo_fmt/tests/{source => input}/expr.nr | 0 tooling/nargo_fmt/tests/input/infix.nr | 5 +++ .../nargo_fmt/tests/input/nested-if-else.nr | 4 +++ .../tests/{source => input}/print.nr | 0 .../tests/{source => input}/print2.nr | 0 .../{source => input}/unary_operators.nr | 0 19 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 tooling/nargo_fmt/tests/expected/call.nr create mode 100644 tooling/nargo_fmt/tests/expected/comment.nr rename tooling/nargo_fmt/tests/{source => expected}/empty.nr (100%) create mode 100644 tooling/nargo_fmt/tests/expected/expr.nr rename tooling/nargo_fmt/tests/{source => expected}/infix.nr (100%) rename tooling/nargo_fmt/tests/{source => expected}/nested-if-else.nr (100%) create mode 100644 tooling/nargo_fmt/tests/expected/print.nr create mode 100644 tooling/nargo_fmt/tests/expected/print2.nr create mode 100644 tooling/nargo_fmt/tests/expected/unary_operators.nr rename tooling/nargo_fmt/tests/{source => input}/call.nr (100%) rename tooling/nargo_fmt/tests/{source => input}/comment.nr (100%) create mode 100644 tooling/nargo_fmt/tests/input/empty.nr rename tooling/nargo_fmt/tests/{source => input}/expr.nr (100%) create mode 100644 tooling/nargo_fmt/tests/input/infix.nr create mode 100644 tooling/nargo_fmt/tests/input/nested-if-else.nr rename tooling/nargo_fmt/tests/{source => input}/print.nr (100%) rename tooling/nargo_fmt/tests/{source => input}/print2.nr (100%) rename tooling/nargo_fmt/tests/{source => input}/unary_operators.nr (100%) diff --git a/tooling/nargo_fmt/src/lib.rs b/tooling/nargo_fmt/src/lib.rs index bf8f4f39d2f..3d31b9ed865 100644 --- a/tooling/nargo_fmt/src/lib.rs +++ b/tooling/nargo_fmt/src/lib.rs @@ -49,8 +49,8 @@ mod tests { let target_path: PathBuf = source_path .components() .map(|component| { - if component.as_os_str() == "source" { - OsStr::new("target") + if component.as_os_str() == "input" { + OsStr::new("expected") } else { component.as_os_str() } diff --git a/tooling/nargo_fmt/tests/expected/call.nr b/tooling/nargo_fmt/tests/expected/call.nr new file mode 100644 index 00000000000..ca4d5b82683 --- /dev/null +++ b/tooling/nargo_fmt/tests/expected/call.nr @@ -0,0 +1,3 @@ +fn main() { + main(4, 3); +} diff --git a/tooling/nargo_fmt/tests/expected/comment.nr b/tooling/nargo_fmt/tests/expected/comment.nr new file mode 100644 index 00000000000..930a500062d --- /dev/null +++ b/tooling/nargo_fmt/tests/expected/comment.nr @@ -0,0 +1,14 @@ +fn comment1() { +// +} + +// random comment + +fn comment2() { +// Test +} +fn comment3() {} +fn comment4() {} +fn comment5() {} +fn comment6() {} +fn comment7() {} diff --git a/tooling/nargo_fmt/tests/source/empty.nr b/tooling/nargo_fmt/tests/expected/empty.nr similarity index 100% rename from tooling/nargo_fmt/tests/source/empty.nr rename to tooling/nargo_fmt/tests/expected/empty.nr diff --git a/tooling/nargo_fmt/tests/expected/expr.nr b/tooling/nargo_fmt/tests/expected/expr.nr new file mode 100644 index 00000000000..8e54eb336b4 --- /dev/null +++ b/tooling/nargo_fmt/tests/expected/expr.nr @@ -0,0 +1,35 @@ +// Test some empty blocks. +fn qux() { + {} + { + /* a block with a comment */ + } + {} + { + // A block with a comment. + } +} +fn foo_return() { + "yay" +} +fn fooblock() { + { + "inner-block" + } +} +fn fooblock() { + { + { + { + "inner-block" + } + } + } +} +fn comment() { + // this is a test comment + 1 +} +fn only_comment() { +// Keep this here +} diff --git a/tooling/nargo_fmt/tests/source/infix.nr b/tooling/nargo_fmt/tests/expected/infix.nr similarity index 100% rename from tooling/nargo_fmt/tests/source/infix.nr rename to tooling/nargo_fmt/tests/expected/infix.nr diff --git a/tooling/nargo_fmt/tests/source/nested-if-else.nr b/tooling/nargo_fmt/tests/expected/nested-if-else.nr similarity index 100% rename from tooling/nargo_fmt/tests/source/nested-if-else.nr rename to tooling/nargo_fmt/tests/expected/nested-if-else.nr diff --git a/tooling/nargo_fmt/tests/expected/print.nr b/tooling/nargo_fmt/tests/expected/print.nr new file mode 100644 index 00000000000..3fbd305306d --- /dev/null +++ b/tooling/nargo_fmt/tests/expected/print.nr @@ -0,0 +1,4 @@ +use dep::std; +fn main() { + std::println("Hello world"); +} diff --git a/tooling/nargo_fmt/tests/expected/print2.nr b/tooling/nargo_fmt/tests/expected/print2.nr new file mode 100644 index 00000000000..3fbd305306d --- /dev/null +++ b/tooling/nargo_fmt/tests/expected/print2.nr @@ -0,0 +1,4 @@ +use dep::std; +fn main() { + std::println("Hello world"); +} diff --git a/tooling/nargo_fmt/tests/expected/unary_operators.nr b/tooling/nargo_fmt/tests/expected/unary_operators.nr new file mode 100644 index 00000000000..88140ac9a6e --- /dev/null +++ b/tooling/nargo_fmt/tests/expected/unary_operators.nr @@ -0,0 +1,3 @@ +fn main() { + -1 +} diff --git a/tooling/nargo_fmt/tests/source/call.nr b/tooling/nargo_fmt/tests/input/call.nr similarity index 100% rename from tooling/nargo_fmt/tests/source/call.nr rename to tooling/nargo_fmt/tests/input/call.nr diff --git a/tooling/nargo_fmt/tests/source/comment.nr b/tooling/nargo_fmt/tests/input/comment.nr similarity index 100% rename from tooling/nargo_fmt/tests/source/comment.nr rename to tooling/nargo_fmt/tests/input/comment.nr diff --git a/tooling/nargo_fmt/tests/input/empty.nr b/tooling/nargo_fmt/tests/input/empty.nr new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tooling/nargo_fmt/tests/source/expr.nr b/tooling/nargo_fmt/tests/input/expr.nr similarity index 100% rename from tooling/nargo_fmt/tests/source/expr.nr rename to tooling/nargo_fmt/tests/input/expr.nr diff --git a/tooling/nargo_fmt/tests/input/infix.nr b/tooling/nargo_fmt/tests/input/infix.nr new file mode 100644 index 00000000000..13b53170da6 --- /dev/null +++ b/tooling/nargo_fmt/tests/input/infix.nr @@ -0,0 +1,5 @@ +fn foo() { + 40 + 2; + !40 + 2; + 40 + 2 == 42; +} diff --git a/tooling/nargo_fmt/tests/input/nested-if-else.nr b/tooling/nargo_fmt/tests/input/nested-if-else.nr new file mode 100644 index 00000000000..6e94daf1efe --- /dev/null +++ b/tooling/nargo_fmt/tests/input/nested-if-else.nr @@ -0,0 +1,4 @@ +// FIXME: +// fn nested_if_else() { +// if false { 1 } else if false { 2 } else { 3 } +// } diff --git a/tooling/nargo_fmt/tests/source/print.nr b/tooling/nargo_fmt/tests/input/print.nr similarity index 100% rename from tooling/nargo_fmt/tests/source/print.nr rename to tooling/nargo_fmt/tests/input/print.nr diff --git a/tooling/nargo_fmt/tests/source/print2.nr b/tooling/nargo_fmt/tests/input/print2.nr similarity index 100% rename from tooling/nargo_fmt/tests/source/print2.nr rename to tooling/nargo_fmt/tests/input/print2.nr diff --git a/tooling/nargo_fmt/tests/source/unary_operators.nr b/tooling/nargo_fmt/tests/input/unary_operators.nr similarity index 100% rename from tooling/nargo_fmt/tests/source/unary_operators.nr rename to tooling/nargo_fmt/tests/input/unary_operators.nr From bffe2ebf480d9c2ca8520ef6b0c7340c3229b82b Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Fri, 15 Sep 2023 10:45:57 +0000 Subject: [PATCH 05/42] impl `ParsedModule::into_legacy` --- compiler/noirc_frontend/src/parser/mod.rs | 69 +++++++++++-------- compiler/noirc_frontend/src/parser/parser.rs | 24 ++++--- tooling/nargo_fmt/src/lib.rs | 2 +- tooling/nargo_fmt/src/visitor.rs | 12 ---- .../tests/expected/nested-if-else.nr | 15 ++-- .../nargo_fmt/tests/input/nested-if-else.nr | 7 +- 6 files changed, 69 insertions(+), 60 deletions(-) diff --git a/compiler/noirc_frontend/src/parser/mod.rs b/compiler/noirc_frontend/src/parser/mod.rs index 32e4fce8f24..693580b1d37 100644 --- a/compiler/noirc_frontend/src/parser/mod.rs +++ b/compiler/noirc_frontend/src/parser/mod.rs @@ -217,6 +217,7 @@ fn force<'a, T: 'a>(parser: impl NoirParser + 'a) -> impl NoirParser, pub functions: Vec, @@ -242,7 +243,24 @@ pub struct ParsedModule { impl ParsedModule { pub fn into_legacy(self) -> LegacyParsedModule { - todo!() + let mut module = LegacyParsedModule::default(); + + for item in self.items { + match item.kind { + ItemKind::Import(import) => module.push_import(import), + ItemKind::Function(func) => module.push_function(func), + ItemKind::Struct(typ) => module.push_type(typ), + ItemKind::Trait(noir_trait) => module.push_trait(noir_trait), + ItemKind::TraitImpl(trait_impl) => module.push_trait_impl(trait_impl), + ItemKind::Impl(r#impl) => module.push_impl(r#impl), + ItemKind::TypeAlias(type_alias) => module.push_type_alias(type_alias), + ItemKind::Global(global) => module.push_global(global), + ItemKind::ModuleDecl(mod_name) => module.push_module_decl(mod_name), + ItemKind::Submodules(submodule) => module.push_submodule(submodule), + } + } + + module } } @@ -254,7 +272,7 @@ pub struct Item { #[derive(Clone, Debug)] pub enum ItemKind { - Import(ImportStatement), + Import(UseTree), Function(NoirFunction), Struct(NoirStruct), Trait(NoirTrait), @@ -275,50 +293,45 @@ pub struct SubModule { pub is_contract: bool, } -impl ParsedModule { - fn push_function(&mut self, func: NoirFunction, span: Span) { - self.items.push(Item { kind: ItemKind::Function(func), span }); +impl LegacyParsedModule { + fn push_function(&mut self, func: NoirFunction) { + self.functions.push(func); } - fn push_type(&mut self, typ: NoirStruct, span: Span) { - self.items.push(Item { kind: ItemKind::Struct(typ), span }); + fn push_type(&mut self, typ: NoirStruct) { + self.types.push(typ); } - fn push_trait(&mut self, noir_trait: NoirTrait, span: Span) { - self.items.push(Item { kind: ItemKind::Trait(noir_trait), span }); + fn push_trait(&mut self, noir_trait: NoirTrait) { + self.traits.push(noir_trait); } - fn push_trait_impl(&mut self, trait_impl: TraitImpl, span: Span) { - self.items.push(Item { kind: ItemKind::TraitImpl(trait_impl), span }); + fn push_trait_impl(&mut self, trait_impl: TraitImpl) { + self.trait_impls.push(trait_impl); } - fn push_impl(&mut self, r#impl: TypeImpl, span: Span) { - self.items.push(Item { kind: ItemKind::Impl(r#impl), span }); + fn push_impl(&mut self, r#impl: TypeImpl) { + self.impls.push(r#impl); } - fn push_type_alias(&mut self, type_alias: NoirTypeAlias, span: Span) { - self.items.push(Item { kind: ItemKind::TypeAlias(type_alias), span }); + fn push_type_alias(&mut self, type_alias: NoirTypeAlias) { + self.type_aliases.push(type_alias); } - fn push_import(&mut self, import_stmt: UseTree, span: Span) { - self.items.extend( - import_stmt - .desugar(None) - .into_iter() - .map(|kind| Item { kind: ItemKind::Import(kind), span }), - ); + fn push_import(&mut self, import_stmt: UseTree) { + self.imports.extend(import_stmt.desugar(None)); } - fn push_module_decl(&mut self, mod_name: Ident, span: Span) { - self.items.push(Item { kind: ItemKind::ModuleDecl(mod_name), span }); + fn push_module_decl(&mut self, mod_name: Ident) { + self.module_decls.push(mod_name); } - fn push_submodule(&mut self, submodule: SubModule, span: Span) { - self.items.push(Item { kind: ItemKind::Submodules(submodule), span }); + fn push_submodule(&mut self, submodule: SubModule) { + self.submodules.push(submodule); } - fn push_global(&mut self, global: LetStatement, span: Span) { - self.items.push(Item { kind: ItemKind::Global(global), span }); + fn push_global(&mut self, global: LetStatement) { + self.globals.push(global); } } diff --git a/compiler/noirc_frontend/src/parser/parser.rs b/compiler/noirc_frontend/src/parser/parser.rs index b90e5be4a54..6f95db2404b 100644 --- a/compiler/noirc_frontend/src/parser/parser.rs +++ b/compiler/noirc_frontend/src/parser/parser.rs @@ -23,13 +23,13 @@ //! prevent other parsers from being tried afterward since there is no longer an error. Thus, they should //! be limited to cases like the above `fn` example where it is clear we shouldn't back out of the //! current parser to try alternative parsers in a `choice` expression. -use super::spanned; use super::{ foldl_with_span, labels::ParsingRuleLabel, parameter_name_recovery, parameter_recovery, parenthesized, then_commit, then_commit_ignore, top_level_statement_recovery, ExprParser, ForRange, NoirParser, ParsedModule, ParserError, ParserErrorReason, Precedence, SubModule, TopLevelStatement, }; +use super::{spanned, Item, ItemKind}; use crate::ast::{ Expression, ExpressionKind, LetStatement, Statement, UnresolvedType, UnresolvedTypeData, }; @@ -77,17 +77,19 @@ fn module() -> impl NoirParser { .map(|_| ParsedModule::default()) .then(spanned(top_level_statement(module_parser)).repeated()) .foldl(|mut program, (statement, span)| { + let mut push_item = |kind| program.items.push(Item { kind, span }); + match statement { - TopLevelStatement::Function(f) => program.push_function(f, span), - TopLevelStatement::Module(m) => program.push_module_decl(m, span), - TopLevelStatement::Import(i) => program.push_import(i, span), - TopLevelStatement::Struct(s) => program.push_type(s, span), - TopLevelStatement::Trait(t) => program.push_trait(t, span), - TopLevelStatement::TraitImpl(t) => program.push_trait_impl(t, span), - TopLevelStatement::Impl(i) => program.push_impl(i, span), - TopLevelStatement::TypeAlias(t) => program.push_type_alias(t, span), - TopLevelStatement::SubModule(s) => program.push_submodule(s, span), - TopLevelStatement::Global(c) => program.push_global(c, span), + TopLevelStatement::Function(f) => push_item(ItemKind::Function(f)), + TopLevelStatement::Module(m) => push_item(ItemKind::ModuleDecl(m)), + TopLevelStatement::Import(i) => push_item(ItemKind::Import(i)), + TopLevelStatement::Struct(s) => push_item(ItemKind::Struct(s)), + TopLevelStatement::Trait(t) => push_item(ItemKind::Trait(t)), + TopLevelStatement::TraitImpl(t) => push_item(ItemKind::TraitImpl(t)), + TopLevelStatement::Impl(i) => push_item(ItemKind::Impl(i)), + TopLevelStatement::TypeAlias(t) => push_item(ItemKind::TypeAlias(t)), + TopLevelStatement::SubModule(s) => push_item(ItemKind::Submodules(s)), + TopLevelStatement::Global(c) => push_item(ItemKind::Global(c)), TopLevelStatement::Error => (), } program diff --git a/tooling/nargo_fmt/src/lib.rs b/tooling/nargo_fmt/src/lib.rs index 3d31b9ed865..536a563c1c3 100644 --- a/tooling/nargo_fmt/src/lib.rs +++ b/tooling/nargo_fmt/src/lib.rs @@ -38,7 +38,7 @@ mod tests { #[test] fn test() { - let files = std::fs::read_dir("tests/source").unwrap(); + let files = std::fs::read_dir("tests/input").unwrap(); for file in files { let file = file.unwrap(); diff --git a/tooling/nargo_fmt/src/visitor.rs b/tooling/nargo_fmt/src/visitor.rs index e5d7f12f0f4..a9c462fee4f 100644 --- a/tooling/nargo_fmt/src/visitor.rs +++ b/tooling/nargo_fmt/src/visitor.rs @@ -143,7 +143,6 @@ impl<'a> FmtVisitor<'a> { ExpressionKind::Prefix(prefix) => { format!("{}{}", prefix.operator, self.format_expr(prefix.rhs)) } - ExpressionKind::Index(_) => todo!(), ExpressionKind::Call(call) => { let callee = self.format_expr(*call.func); let args = call @@ -162,18 +161,7 @@ impl<'a> FmtVisitor<'a> { format!("{lhs} {op} {rhs}") } - ExpressionKind::If(if_expr) => { - let condition = self.format_expr(if_expr.condition); - let consequence = self.format_expr(if_expr.consequence); - let alternative = if_expr - .alternative - .map_or(String::new(), |alternative| self.format_expr(alternative)); - - format!("{condition} {consequence} {alternative}") - } ExpressionKind::Variable(_) => slice!(self, span.start(), span.end()).to_string(), - ExpressionKind::Tuple(_) => todo!(), - ExpressionKind::Lambda(_) => todo!(), ExpressionKind::Error => unreachable!(), // TODO: expr => expr.to_string(), diff --git a/tooling/nargo_fmt/tests/expected/nested-if-else.nr b/tooling/nargo_fmt/tests/expected/nested-if-else.nr index 6e94daf1efe..756540e1bd8 100644 --- a/tooling/nargo_fmt/tests/expected/nested-if-else.nr +++ b/tooling/nargo_fmt/tests/expected/nested-if-else.nr @@ -1,4 +1,11 @@ -// FIXME: -// fn nested_if_else() { -// if false { 1 } else if false { 2 } else { 3 } -// } +fn nested_if_else() { + if false { + 1 +} else { + if false { + 2 + } else { + 3 + } +} +} diff --git a/tooling/nargo_fmt/tests/input/nested-if-else.nr b/tooling/nargo_fmt/tests/input/nested-if-else.nr index 6e94daf1efe..8aa120e3b18 100644 --- a/tooling/nargo_fmt/tests/input/nested-if-else.nr +++ b/tooling/nargo_fmt/tests/input/nested-if-else.nr @@ -1,4 +1,3 @@ -// FIXME: -// fn nested_if_else() { -// if false { 1 } else if false { 2 } else { 3 } -// } +fn nested_if_else() { + if false { 1 } else if false { 2 } else { 3 } +} From bde580d6ce3cb4e42be44699c06c89a65f61fd2d Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Fri, 15 Sep 2023 12:46:50 +0000 Subject: [PATCH 06/42] add `nargo fmt` command --- Cargo.lock | 1 + Cargo.toml | 1 + tooling/nargo_cli/Cargo.toml | 1 + tooling/nargo_cli/src/cli/fmt_cmd.rs | 48 ++++++++++++++++++++++++++++ tooling/nargo_cli/src/cli/mod.rs | 3 ++ 5 files changed, 54 insertions(+) create mode 100644 tooling/nargo_cli/src/cli/fmt_cmd.rs diff --git a/Cargo.lock b/Cargo.lock index 20f01a46a80..ae2ce7cb554 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2201,6 +2201,7 @@ dependencies = [ "iai", "iter-extended", "nargo", + "nargo_fmt", "nargo_toml", "noir_lsp", "noirc_abi", diff --git a/Cargo.toml b/Cargo.toml index 3d28fb6ab87..cf0d6789a3e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,6 +38,7 @@ arena = { path = "compiler/utils/arena" } fm = { path = "compiler/fm" } iter-extended = { path = "compiler/utils/iter-extended" } nargo = { path = "tooling/nargo" } +nargo_fmt = { path = "tooling/nargo_fmt" } nargo_cli = { path = "tooling/nargo_cli" } nargo_toml = { path = "tooling/nargo_toml" } noir_lsp = { path = "tooling/lsp" } diff --git a/tooling/nargo_cli/Cargo.toml b/tooling/nargo_cli/Cargo.toml index 0b85c66b6fa..e8df5e7f8bf 100644 --- a/tooling/nargo_cli/Cargo.toml +++ b/tooling/nargo_cli/Cargo.toml @@ -23,6 +23,7 @@ clap.workspace = true fm.workspace = true iter-extended.workspace = true nargo.workspace = true +nargo_fmt.workspace = true nargo_toml.workspace = true noir_lsp.workspace = true noirc_driver.workspace = true diff --git a/tooling/nargo_cli/src/cli/fmt_cmd.rs b/tooling/nargo_cli/src/cli/fmt_cmd.rs new file mode 100644 index 00000000000..8a507921677 --- /dev/null +++ b/tooling/nargo_cli/src/cli/fmt_cmd.rs @@ -0,0 +1,48 @@ +use std::path::{Path, PathBuf}; + +use clap::Args; +use nargo_toml::find_package_root; + +use crate::errors::CliError; + +use super::NargoConfig; + +#[derive(Debug, Clone, Args)] +pub(crate) struct FormatCommand {} + +pub(crate) fn run(_args: FormatCommand, config: NargoConfig) -> Result<(), CliError> { + let files = { + let package = find_package_root(&config.program_dir)?; + read_files(&package.join("src")).map_err(|error| CliError::Generic(error.to_string()))? + }; + + for file in files { + let source = + std::fs::read_to_string(&file).map_err(|error| CliError::Generic(error.to_string()))?; + + let source = nargo_fmt::format(&source); + std::fs::write(file, source).map_err(|error| CliError::Generic(error.to_string()))?; + } + + Ok(()) +} + +fn read_files(path: &Path) -> color_eyre::Result> { + let mut files = vec![]; + + if path.is_dir() { + let entries = std::fs::read_dir(path)?; + + for entry in entries { + let path = entry?.path(); + + if path.is_dir() { + files.append(&mut read_files(&path)?); + } else if path.extension().map_or(false, |extension| extension == "nr") { + files.push(path); + } + } + } + + Ok(files) +} diff --git a/tooling/nargo_cli/src/cli/mod.rs b/tooling/nargo_cli/src/cli/mod.rs index 56d36095518..54e60a505a3 100644 --- a/tooling/nargo_cli/src/cli/mod.rs +++ b/tooling/nargo_cli/src/cli/mod.rs @@ -14,6 +14,7 @@ mod check_cmd; mod codegen_verifier_cmd; mod compile_cmd; mod execute_cmd; +mod fmt_cmd; mod info_cmd; mod init_cmd; mod lsp_cmd; @@ -52,6 +53,7 @@ pub(crate) struct NargoConfig { enum NargoCommand { Backend(backend_cmd::BackendCommand), Check(check_cmd::CheckCommand), + Fmt(fmt_cmd::FormatCommand), CodegenVerifier(codegen_verifier_cmd::CodegenVerifierCommand), #[command(alias = "build")] Compile(compile_cmd::CompileCommand), @@ -100,6 +102,7 @@ pub(crate) fn start_cli() -> eyre::Result<()> { NargoCommand::CodegenVerifier(args) => codegen_verifier_cmd::run(&backend, args, config), NargoCommand::Backend(args) => backend_cmd::run(args), NargoCommand::Lsp(args) => lsp_cmd::run(&backend, args, config), + NargoCommand::Fmt(args) => fmt_cmd::run(args, config), }?; Ok(()) From 61f158d3408e6192ff24de066337edf29864dbfc Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Fri, 15 Sep 2023 16:41:53 +0000 Subject: [PATCH 07/42] simple emit fn parameters --- Cargo.lock | 1 + tooling/nargo_cli/src/cli/fmt_cmd.rs | 9 ++++++++- tooling/nargo_fmt/Cargo.toml | 1 + tooling/nargo_fmt/src/lib.rs | 24 +++++------------------- tooling/nargo_fmt/src/visitor.rs | 22 ++++++++++++++++++---- tooling/nargo_fmt/tests/expected/fn.nr | 1 + tooling/nargo_fmt/tests/input/fn.nr | 1 + 7 files changed, 35 insertions(+), 24 deletions(-) create mode 100644 tooling/nargo_fmt/tests/expected/fn.nr create mode 100644 tooling/nargo_fmt/tests/input/fn.nr diff --git a/Cargo.lock b/Cargo.lock index ae2ce7cb554..61465440ac6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2230,6 +2230,7 @@ dependencies = [ name = "nargo_fmt" version = "0.11.1" dependencies = [ + "noirc_errors", "noirc_frontend", "readonly", ] diff --git a/tooling/nargo_cli/src/cli/fmt_cmd.rs b/tooling/nargo_cli/src/cli/fmt_cmd.rs index 8a507921677..6bb91047afd 100644 --- a/tooling/nargo_cli/src/cli/fmt_cmd.rs +++ b/tooling/nargo_cli/src/cli/fmt_cmd.rs @@ -20,7 +20,14 @@ pub(crate) fn run(_args: FormatCommand, config: NargoConfig) -> Result<(), CliEr let source = std::fs::read_to_string(&file).map_err(|error| CliError::Generic(error.to_string()))?; - let source = nargo_fmt::format(&source); + let source = match nargo_fmt::format(&source) { + Ok(t) => t, + Err(errors) => { + println!("{errors:?}"); + continue; + } + }; + std::fs::write(file, source).map_err(|error| CliError::Generic(error.to_string()))?; } diff --git a/tooling/nargo_fmt/Cargo.toml b/tooling/nargo_fmt/Cargo.toml index da77216c0ad..53479b1d9a1 100644 --- a/tooling/nargo_fmt/Cargo.toml +++ b/tooling/nargo_fmt/Cargo.toml @@ -7,4 +7,5 @@ license.workspace = true [dependencies] noirc_frontend.workspace = true +noirc_errors.workspace = true readonly = "0.2" diff --git a/tooling/nargo_fmt/src/lib.rs b/tooling/nargo_fmt/src/lib.rs index 536a563c1c3..9e868b62c62 100644 --- a/tooling/nargo_fmt/src/lib.rs +++ b/tooling/nargo_fmt/src/lib.rs @@ -5,37 +5,23 @@ mod visitor; use visitor::FmtVisitor; -pub fn format(source: &str) -> String { +pub fn format(source: &str) -> Result> { let (module, errors) = noirc_frontend::parse_program(source); - // TODO: error handling if !errors.is_empty() { - panic!("{errors:?}"); + return Err(errors); } let mut fmt = FmtVisitor::new(source); fmt.visit_module(module); - fmt.finish() + + Ok(fmt.finish()) } #[cfg(test)] mod tests { use std::{ffi::OsStr, path::PathBuf}; - #[test] - fn it_works() { - println!( - "{}", - super::format( - "fn main() { - { - // hello - } - }" - ) - ); - } - #[test] fn test() { let files = std::fs::read_dir("tests/input").unwrap(); @@ -44,7 +30,7 @@ mod tests { let source_path = file.path(); let source = std::fs::read_to_string(&source_path).unwrap(); - let fmt_text = crate::format(&source); + let fmt_text = crate::format(&source).unwrap(); let target_path: PathBuf = source_path .components() diff --git a/tooling/nargo_fmt/src/visitor.rs b/tooling/nargo_fmt/src/visitor.rs index a9c462fee4f..1516fa1e528 100644 --- a/tooling/nargo_fmt/src/visitor.rs +++ b/tooling/nargo_fmt/src/visitor.rs @@ -1,7 +1,7 @@ use noirc_frontend::{ hir::resolution::errors::Span, parser::{ItemKind, ParsedModule}, - BlockExpression, Expression, ExpressionKind, NoirFunction, Statement, + BlockExpression, Expression, ExpressionKind, NoirFunction, Statement, Visibility, }; use crate::config::Config; @@ -77,7 +77,7 @@ impl<'a> FmtVisitor<'a> { let slice = slice!(self, block_span.start(), block_span.end()); let comment_str = slice[1..slice.len() - 1].trim(); - let comment_str = if comment_str.is_empty() { + let block_str = if comment_str.is_empty() { "{}".to_string() } else { let indent = self.block_indent.to_string(); @@ -85,7 +85,7 @@ impl<'a> FmtVisitor<'a> { }; self.last_position = block_span.end(); - self.push_str(&comment_str); + self.push_str(&block_str); return; } @@ -226,7 +226,21 @@ impl<'a> FmtVisitor<'a> { if func.parameters().is_empty() { // TODO: Inside the parameters, there can be a comment, for example `fn hello(/**/) {}`. } else { - todo!("emit parameters") + let parameters = func.parameters(); + + for (index, (pattern, ty, vis)) in parameters.iter().enumerate() { + result.push_str(&pattern.to_string()); + result.push_str(": "); + if let Visibility::Public = vis { + result.push_str("pub "); + } + let ty_span = ty.span.unwrap(); + result.push_str(slice!(self, ty_span.start(), ty_span.end())); + + if index < parameters.len() - 1 { + result.push_str(", "); + } + } } result.push(')'); diff --git a/tooling/nargo_fmt/tests/expected/fn.nr b/tooling/nargo_fmt/tests/expected/fn.nr new file mode 100644 index 00000000000..89484dc83c2 --- /dev/null +++ b/tooling/nargo_fmt/tests/expected/fn.nr @@ -0,0 +1 @@ +fn main(x: pub u8, y: u8) {} diff --git a/tooling/nargo_fmt/tests/input/fn.nr b/tooling/nargo_fmt/tests/input/fn.nr new file mode 100644 index 00000000000..89484dc83c2 --- /dev/null +++ b/tooling/nargo_fmt/tests/input/fn.nr @@ -0,0 +1 @@ +fn main(x: pub u8, y: u8) {} From d5ac3a6eab113844df2fa36c50c2422dfdfab737 Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Fri, 15 Sep 2023 18:33:18 +0000 Subject: [PATCH 08/42] basic rewrite stmt --- compiler/noirc_frontend/src/ast/expression.rs | 20 +++-- compiler/noirc_frontend/src/ast/statement.rs | 85 +++++++++++-------- .../src/hir/resolution/resolver.rs | 22 ++--- compiler/noirc_frontend/src/parser/mod.rs | 39 ++++++--- compiler/noirc_frontend/src/parser/parser.rs | 54 ++++++------ tooling/nargo_fmt/src/visitor.rs | 20 ++--- .../nargo_fmt/tests/expected/read_array.nr | 6 ++ tooling/nargo_fmt/tests/input/read_array.nr | 6 ++ 8 files changed, 149 insertions(+), 103 deletions(-) create mode 100644 tooling/nargo_fmt/tests/expected/read_array.nr create mode 100644 tooling/nargo_fmt/tests/input/read_array.nr diff --git a/compiler/noirc_frontend/src/ast/expression.rs b/compiler/noirc_frontend/src/ast/expression.rs index 9b695eb3e59..46748e916f5 100644 --- a/compiler/noirc_frontend/src/ast/expression.rs +++ b/compiler/noirc_frontend/src/ast/expression.rs @@ -2,8 +2,8 @@ use std::fmt::Display; use crate::token::{Attributes, Token}; use crate::{ - Distinctness, Ident, Path, Pattern, Recoverable, Statement, TraitConstraint, UnresolvedType, - UnresolvedTypeData, Visibility, + Distinctness, Ident, Path, Pattern, Recoverable, Statement, StatementKind, TraitConstraint, + UnresolvedType, UnresolvedTypeData, Visibility, }; use acvm::FieldElement; use iter_extended::vecmap; @@ -170,8 +170,14 @@ impl Expression { // as a sequence of { if, tuple } rather than a function call. This behavior matches rust. let kind = if matches!(&lhs.kind, ExpressionKind::If(..)) { ExpressionKind::Block(BlockExpression(vec![ - Statement::Expression(lhs), - Statement::Expression(Expression::new(ExpressionKind::Tuple(arguments), span)), + Statement { kind: StatementKind::Expression(lhs), span }, + Statement { + kind: StatementKind::Expression(Expression::new( + ExpressionKind::Tuple(arguments), + span, + )), + span, + }, ])) } else { ExpressionKind::Call(Box::new(CallExpression { func: Box::new(lhs), arguments })) @@ -434,8 +440,8 @@ pub struct IndexExpression { pub struct BlockExpression(pub Vec); impl BlockExpression { - pub fn pop(&mut self) -> Option { - self.0.pop() + pub fn pop(&mut self) -> Option { + self.0.pop().map(|stmt| stmt.kind) } pub fn len(&self) -> usize { @@ -503,7 +509,7 @@ impl Display for BlockExpression { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { writeln!(f, "{{")?; for statement in &self.0 { - let statement = statement.to_string(); + let statement = statement.kind.to_string(); for line in statement.lines() { writeln!(f, " {line}")?; } diff --git a/compiler/noirc_frontend/src/ast/statement.rs b/compiler/noirc_frontend/src/ast/statement.rs index 3d9ab1e6ec4..52b78f1d857 100644 --- a/compiler/noirc_frontend/src/ast/statement.rs +++ b/compiler/noirc_frontend/src/ast/statement.rs @@ -14,11 +14,17 @@ use noirc_errors::{Span, Spanned}; /// for an identifier that already failed to parse. pub const ERROR_IDENT: &str = "$error"; +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct Statement { + pub kind: StatementKind, + pub span: Span, +} + /// Ast node for statements in noir. Statements are always within a block { } /// of some kind and are terminated via a Semicolon, except if the statement /// ends in a block, such as a Statement::Expression containing an if expression. #[derive(Debug, PartialEq, Eq, Clone)] -pub enum Statement { +pub enum StatementKind { Let(LetStatement), Constrain(ConstrainStatement), Expression(Expression), @@ -31,62 +37,67 @@ pub enum Statement { Error, } -impl Recoverable for Statement { - fn error(_: Span) -> Self { - Statement::Error - } -} - impl Statement { - pub fn new_let( - ((pattern, r#type), expression): ((Pattern, UnresolvedType), Expression), - ) -> Statement { - Statement::Let(LetStatement { pattern, r#type, expression }) - } - pub fn add_semicolon( self, semi: Option, span: Span, last_statement_in_block: bool, emit_error: &mut dyn FnMut(ParserError), - ) -> Statement { + ) -> Self { let missing_semicolon = ParserError::with_reason(ParserErrorReason::MissingSeparatingSemi, span); - match self { - Statement::Let(_) - | Statement::Constrain(_) - | Statement::Assign(_) - | Statement::Semi(_) - | Statement::Error => { + + let kind = match self.kind { + StatementKind::Let(_) + | StatementKind::Constrain(_) + | StatementKind::Assign(_) + | StatementKind::Semi(_) + | StatementKind::Error => { // To match rust, statements always require a semicolon, even at the end of a block if semi.is_none() { emit_error(missing_semicolon); } - self + self.kind } - Statement::Expression(expr) => { + StatementKind::Expression(expr) => { match (&expr.kind, semi, last_statement_in_block) { // Semicolons are optional for these expressions (ExpressionKind::Block(_), semi, _) | (ExpressionKind::For(_), semi, _) | (ExpressionKind::If(_), semi, _) => { if semi.is_some() { - Statement::Semi(expr) + StatementKind::Semi(expr) } else { - Statement::Expression(expr) + StatementKind::Expression(expr) } } (_, None, false) => { emit_error(missing_semicolon); - Statement::Expression(expr) + StatementKind::Expression(expr) } - (_, Some(_), _) => Statement::Semi(expr), - (_, None, true) => Statement::Expression(expr), + (_, Some(_), _) => StatementKind::Semi(expr), + (_, None, true) => StatementKind::Expression(expr), } } - } + }; + + Statement { kind, span: self.span } + } +} + +impl Recoverable for StatementKind { + fn error(_: Span) -> Self { + StatementKind::Error + } +} + +impl StatementKind { + pub fn new_let( + ((pattern, r#type), expression): ((Pattern, UnresolvedType), Expression), + ) -> StatementKind { + StatementKind::Let(LetStatement { pattern, r#type, expression }) } /// Create a Statement::Assign value, desugaring any combined operators like += if needed. @@ -95,7 +106,7 @@ impl Statement { operator: Token, mut expression: Expression, span: Span, - ) -> Statement { + ) -> StatementKind { // Desugar `a = b` to `a = a b`. This relies on the evaluation of `a` having no side effects, // which is currently enforced by the restricted syntax of LValues. if operator != Token::Assign { @@ -110,7 +121,7 @@ impl Statement { expression = Expression::new(ExpressionKind::Infix(Box::new(infix)), span); } - Statement::Assign(AssignStatement { lvalue, expression }) + StatementKind::Assign(AssignStatement { lvalue, expression }) } } @@ -459,15 +470,15 @@ impl LValue { } } -impl Display for Statement { +impl Display for StatementKind { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - Statement::Let(let_statement) => let_statement.fmt(f), - Statement::Constrain(constrain) => constrain.fmt(f), - Statement::Expression(expression) => expression.fmt(f), - Statement::Assign(assign) => assign.fmt(f), - Statement::Semi(semi) => write!(f, "{semi};"), - Statement::Error => write!(f, "Error"), + StatementKind::Let(let_statement) => let_statement.fmt(f), + StatementKind::Constrain(constrain) => constrain.fmt(f), + StatementKind::Expression(expression) => expression.fmt(f), + StatementKind::Assign(assign) => assign.fmt(f), + StatementKind::Semi(semi) => write!(f, "{semi};"), + StatementKind::Error => write!(f, "Error"), } } } diff --git a/compiler/noirc_frontend/src/hir/resolution/resolver.rs b/compiler/noirc_frontend/src/hir/resolution/resolver.rs index 7994c2ac7fd..f20576f6418 100644 --- a/compiler/noirc_frontend/src/hir/resolution/resolver.rs +++ b/compiler/noirc_frontend/src/hir/resolution/resolver.rs @@ -31,7 +31,7 @@ use crate::node_interner::{ use crate::{ hir::{def_map::CrateDefMap, resolution::path_resolver::PathResolver}, BlockExpression, Expression, ExpressionKind, FunctionKind, Ident, Literal, NoirFunction, - Statement, + StatementKind, }; use crate::{ ArrayLiteral, ContractFunctionType, Distinctness, Generics, LValue, NoirStruct, NoirTypeAlias, @@ -920,9 +920,9 @@ impl<'a> Resolver<'a> { }) } - pub fn resolve_stmt(&mut self, stmt: Statement) -> HirStatement { + pub fn resolve_stmt(&mut self, stmt: StatementKind) -> HirStatement { match stmt { - Statement::Let(let_stmt) => { + StatementKind::Let(let_stmt) => { let expression = self.resolve_expression(let_stmt.expression); let definition = DefinitionKind::Local(Some(expression)); HirStatement::Let(HirLetStatement { @@ -931,24 +931,26 @@ impl<'a> Resolver<'a> { expression, }) } - Statement::Constrain(constrain_stmt) => { + StatementKind::Constrain(constrain_stmt) => { let expr_id = self.resolve_expression(constrain_stmt.0); let assert_message = constrain_stmt.1; HirStatement::Constrain(HirConstrainStatement(expr_id, self.file, assert_message)) } - Statement::Expression(expr) => HirStatement::Expression(self.resolve_expression(expr)), - Statement::Semi(expr) => HirStatement::Semi(self.resolve_expression(expr)), - Statement::Assign(assign_stmt) => { + StatementKind::Expression(expr) => { + HirStatement::Expression(self.resolve_expression(expr)) + } + StatementKind::Semi(expr) => HirStatement::Semi(self.resolve_expression(expr)), + StatementKind::Assign(assign_stmt) => { let identifier = self.resolve_lvalue(assign_stmt.lvalue); let expression = self.resolve_expression(assign_stmt.expression); let stmt = HirAssignStatement { lvalue: identifier, expression }; HirStatement::Assign(stmt) } - Statement::Error => HirStatement::Error, + StatementKind::Error => HirStatement::Error, } } - pub fn intern_stmt(&mut self, stmt: Statement) -> StmtId { + pub fn intern_stmt(&mut self, stmt: StatementKind) -> StmtId { let hir_stmt = self.resolve_stmt(stmt); self.interner.push_stmt(hir_stmt) } @@ -1409,7 +1411,7 @@ impl<'a> Resolver<'a> { fn resolve_block(&mut self, block_expr: BlockExpression) -> HirExpression { let statements = - self.in_new_scope(|this| vecmap(block_expr.0, |stmt| this.intern_stmt(stmt))); + self.in_new_scope(|this| vecmap(block_expr.0, |stmt| this.intern_stmt(stmt.kind))); HirExpression::Block(HirBlockExpression(statements)) } diff --git a/compiler/noirc_frontend/src/parser/mod.rs b/compiler/noirc_frontend/src/parser/mod.rs index 693580b1d37..f7c6ede54ee 100644 --- a/compiler/noirc_frontend/src/parser/mod.rs +++ b/compiler/noirc_frontend/src/parser/mod.rs @@ -18,7 +18,7 @@ use crate::{ast::ImportStatement, Expression, NoirStruct}; use crate::{ BlockExpression, ExpressionKind, ForExpression, Ident, IndexExpression, LetStatement, MethodCallExpression, NoirFunction, NoirTrait, NoirTypeAlias, Path, PathKind, Pattern, - Recoverable, Statement, TraitImpl, TypeImpl, UnresolvedType, UseTree, + Recoverable, Statement, StatementKind, TraitImpl, TypeImpl, UnresolvedType, UseTree, }; use acvm::FieldElement; @@ -190,7 +190,7 @@ where /// Recovery strategy for statements: If a statement fails to parse skip until the next ';' or fail /// if we find a '}' first. -fn statement_recovery() -> impl NoirParser { +fn statement_recovery() -> impl NoirParser { use Token::*; try_skip_until([Semicolon, RightBrace], RightBrace) } @@ -449,11 +449,14 @@ impl ForRange { let array_ident = Ident::new(array_name, array_span); // let fresh1 = array; - let let_array = Statement::Let(LetStatement { - pattern: Pattern::Identifier(array_ident.clone()), - r#type: UnresolvedType::unspecified(), - expression: array, - }); + let let_array = Statement { + kind: StatementKind::Let(LetStatement { + pattern: Pattern::Identifier(array_ident.clone()), + r#type: UnresolvedType::unspecified(), + expression: array, + }), + span: array_span, + }; // array.len() let segments = vec![array_ident]; @@ -482,14 +485,19 @@ impl ForRange { })); // let elem = array[i]; - let let_elem = Statement::Let(LetStatement { - pattern: Pattern::Identifier(identifier), - r#type: UnresolvedType::unspecified(), - expression: Expression::new(loop_element, array_span), - }); + let let_elem = Statement { + kind: StatementKind::Let(LetStatement { + pattern: Pattern::Identifier(identifier), + r#type: UnresolvedType::unspecified(), + expression: Expression::new(loop_element, array_span), + }), + span: array_span, + }; + + let block = Statement { kind: StatementKind::Expression(block), span: array_span }; let block_span = block.span; - let new_block = BlockExpression(vec![let_elem, Statement::Expression(block)]); + let new_block = BlockExpression(vec![let_elem]); let new_block = Expression::new(ExpressionKind::Block(new_block), block_span); let for_loop = ExpressionKind::For(Box::new(ForExpression { identifier: fresh_identifier, @@ -500,7 +508,10 @@ impl ForRange { ExpressionKind::Block(BlockExpression(vec![ let_array, - Statement::Expression(Expression::new(for_loop, for_loop_span)), + Statement { + kind: StatementKind::Expression(Expression::new(for_loop, for_loop_span)), + span: for_loop_span, + }, ])) } } diff --git a/compiler/noirc_frontend/src/parser/parser.rs b/compiler/noirc_frontend/src/parser/parser.rs index 913afb0b536..2d8611e09c1 100644 --- a/compiler/noirc_frontend/src/parser/parser.rs +++ b/compiler/noirc_frontend/src/parser/parser.rs @@ -31,7 +31,7 @@ use super::{ }; use super::{spanned, Item, ItemKind}; use crate::ast::{ - Expression, ExpressionKind, LetStatement, Statement, UnresolvedType, UnresolvedTypeData, + Expression, ExpressionKind, LetStatement, StatementKind, UnresolvedType, UnresolvedTypeData, }; use crate::lexer::Lexer; use crate::parser::{force, ignore_then_commit, statement_recovery}; @@ -40,7 +40,7 @@ use crate::{ BinaryOp, BinaryOpKind, BlockExpression, ConstrainStatement, Distinctness, FunctionDefinition, FunctionReturnType, Ident, IfExpression, InfixExpression, LValue, Lambda, Literal, NoirFunction, NoirStruct, NoirTrait, NoirTypeAlias, Path, PathKind, Pattern, Recoverable, - TraitBound, TraitConstraint, TraitImpl, TraitImplItem, TraitItem, TypeImpl, UnaryOp, + Statement, TraitBound, TraitConstraint, TraitImpl, TraitImplItem, TraitItem, TypeImpl, UnaryOp, UnresolvedTypeExpression, UseTree, UseTreeKind, Visibility, }; @@ -621,6 +621,7 @@ where statement(expr_parser) .recover_via(statement_recovery()) .then(just(Semicolon).or_not().map_with_span(|s, span| (s, span))) + .map_with_span(|(kind, rest), span| (Statement { kind, span }, rest)) .repeated() .validate(check_statements_require_semicolon) .delimited_by(just(LeftBrace), just(RightBrace)) @@ -628,7 +629,7 @@ where LeftBrace, RightBrace, [(LeftParen, RightParen), (LeftBracket, RightBracket)], - |_| vec![Statement::Error], + |span| vec![Statement { kind: StatementKind::Error, span }], )) .map(BlockExpression) } @@ -729,7 +730,7 @@ fn ident() -> impl NoirParser { token_kind(TokenKind::Ident).map_with_span(Ident::from_token) } -fn statement<'a, P>(expr_parser: P) -> impl NoirParser + 'a +fn statement<'a, P>(expr_parser: P) -> impl NoirParser + 'a where P: ExprParser + 'a, { @@ -740,11 +741,11 @@ where declaration(expr_parser.clone()), assignment(expr_parser.clone()), return_statement(expr_parser.clone()), - expr_parser.map(Statement::Expression), + expr_parser.map(StatementKind::Expression), )) } -fn constrain<'a, P>(expr_parser: P) -> impl NoirParser + 'a +fn constrain<'a, P>(expr_parser: P) -> impl NoirParser + 'a where P: ExprParser + 'a, { @@ -752,14 +753,14 @@ where keyword(Keyword::Constrain).labelled(ParsingRuleLabel::Statement), expr_parser, ) - .map(|expr| Statement::Constrain(ConstrainStatement(expr, None))) + .map(|expr| StatementKind::Constrain(ConstrainStatement(expr, None))) .validate(|expr, span, emit| { emit(ParserError::with_reason(ParserErrorReason::ConstrainDeprecated, span)); expr }) } -fn assertion<'a, P>(expr_parser: P) -> impl NoirParser + 'a +fn assertion<'a, P>(expr_parser: P) -> impl NoirParser + 'a where P: ExprParser + 'a, { @@ -780,11 +781,11 @@ where } } - Statement::Constrain(ConstrainStatement(condition, message_str)) + StatementKind::Constrain(ConstrainStatement(condition, message_str)) }) } -fn assertion_eq<'a, P>(expr_parser: P) -> impl NoirParser + 'a +fn assertion_eq<'a, P>(expr_parser: P) -> impl NoirParser + 'a where P: ExprParser + 'a, { @@ -811,11 +812,11 @@ where emit(ParserError::with_reason(ParserErrorReason::AssertMessageNotString, span)); } } - Statement::Constrain(ConstrainStatement(predicate, message_str)) + StatementKind::Constrain(ConstrainStatement(predicate, message_str)) }) } -fn declaration<'a, P>(expr_parser: P) -> impl NoirParser + 'a +fn declaration<'a, P>(expr_parser: P) -> impl NoirParser + 'a where P: ExprParser + 'a, { @@ -824,7 +825,7 @@ where let p = p.then(optional_type_annotation()); let p = then_commit_ignore(p, just(Token::Assign)); let p = then_commit(p, expr_parser); - p.map(Statement::new_let) + p.map(StatementKind::new_let) } fn pattern() -> impl NoirParser { @@ -866,7 +867,7 @@ fn pattern() -> impl NoirParser { .labelled(ParsingRuleLabel::Pattern) } -fn assignment<'a, P>(expr_parser: P) -> impl NoirParser + 'a +fn assignment<'a, P>(expr_parser: P) -> impl NoirParser + 'a where P: ExprParser + 'a, { @@ -875,7 +876,7 @@ where then_commit(fallible, expr_parser).map_with_span( |((identifier, operator), expression), span| { - Statement::assign(identifier, operator, expression, span) + StatementKind::assign(identifier, operator, expression, span) }, ) } @@ -1143,14 +1144,14 @@ fn expression_no_constructors() -> impl ExprParser { .labelled(ParsingRuleLabel::Expression) } -fn return_statement<'a, P>(expr_parser: P) -> impl NoirParser + 'a +fn return_statement<'a, P>(expr_parser: P) -> impl NoirParser + 'a where P: ExprParser + 'a, { ignore_then_commit(keyword(Keyword::Return), expr_parser.or_not()) .validate(|_, span, emit| { emit(ParserError::with_reason(ParserErrorReason::EarlyReturn, span)); - Statement::Error + StatementKind::Error }) .labelled(ParsingRuleLabel::Statement) } @@ -1333,7 +1334,10 @@ where // Wrap the inner `if` expression in a block expression. // i.e. rewrite the sugared form `if cond1 {} else if cond2 {}` as `if cond1 {} else { if cond2 {} }`. let if_expression = Expression::new(kind, span); - let desugared_else = BlockExpression(vec![Statement::Expression(if_expression)]); + let desugared_else = BlockExpression(vec![Statement { + kind: StatementKind::Expression(if_expression), + span, + }]); Expression::new(ExpressionKind::Block(desugared_else), span) })); @@ -1787,13 +1791,13 @@ mod test { // Regression for #1310: this should be parsed as a block and not a function call let res = parse_with(block(expression()), "{ if true { 1 } else { 2 } (3, 4) }").unwrap(); - match unwrap_expr(res.0.last().unwrap()) { + match unwrap_expr(&res.0.last().unwrap().kind) { // The `if` followed by a tuple is currently creates a block around both in case // there was none to start with, so there is an extra block here. ExpressionKind::Block(block) => { assert_eq!(block.0.len(), 2); - assert!(matches!(unwrap_expr(&block.0[0]), ExpressionKind::If(_))); - assert!(matches!(unwrap_expr(&block.0[1]), ExpressionKind::Tuple(_))); + assert!(matches!(unwrap_expr(&block.0[0].kind), ExpressionKind::If(_))); + assert!(matches!(unwrap_expr(&block.0[1].kind), ExpressionKind::Tuple(_))); } _ => unreachable!(), } @@ -1812,9 +1816,9 @@ mod test { } /// Extract an Statement::Expression from a statement or panic - fn unwrap_expr(stmt: &Statement) -> &ExpressionKind { + fn unwrap_expr(stmt: &StatementKind) -> &ExpressionKind { match stmt { - Statement::Expression(expr) => &expr.kind, + StatementKind::Expression(expr) => &expr.kind, _ => unreachable!(), } } @@ -1912,7 +1916,7 @@ mod test { match parse_with(assertion(expression()), "assert(x == y, \"assertion message\")").unwrap() { - Statement::Constrain(ConstrainStatement(_, message)) => { + StatementKind::Constrain(ConstrainStatement(_, message)) => { assert_eq!(message, Some("assertion message".to_owned())); } _ => unreachable!(), @@ -1936,7 +1940,7 @@ mod test { match parse_with(assertion_eq(expression()), "assert_eq(x, y, \"assertion message\")") .unwrap() { - Statement::Constrain(ConstrainStatement(_, message)) => { + StatementKind::Constrain(ConstrainStatement(_, message)) => { assert_eq!(message, Some("assertion message".to_owned())); } _ => unreachable!(), diff --git a/tooling/nargo_fmt/src/visitor.rs b/tooling/nargo_fmt/src/visitor.rs index 1516fa1e528..397bf4ddf18 100644 --- a/tooling/nargo_fmt/src/visitor.rs +++ b/tooling/nargo_fmt/src/visitor.rs @@ -1,7 +1,7 @@ use noirc_frontend::{ hir::resolution::errors::Span, parser::{ItemKind, ParsedModule}, - BlockExpression, Expression, ExpressionKind, NoirFunction, Statement, Visibility, + BlockExpression, Expression, ExpressionKind, NoirFunction, StatementKind, Visibility, }; use crate::config::Config; @@ -93,20 +93,20 @@ impl<'a> FmtVisitor<'a> { self.block_indent.block_indent(&self.config); self.push_str("{"); - // TODO: Implement setting the last position for statements. for stmt in block.0 { - match stmt { - Statement::Let(_) => todo!(), - Statement::Constrain(_) => todo!(), - Statement::Expression(expr) => self.visit_expr(expr), - Statement::Assign(_) => todo!(), - Statement::Semi(expr) => { + match stmt.kind { + StatementKind::Expression(expr) => self.visit_expr(expr), + StatementKind::Semi(expr) => { self.visit_expr(expr); self.push_str(";"); - self.last_position += 1; // `;` } - Statement::Error => unreachable!(), + StatementKind::Error => unreachable!(), + _ => { + self.format_missing_indent(stmt.span.end(), false); + } } + + self.last_position = stmt.span.end(); } self.last_position = block_span.end(); diff --git a/tooling/nargo_fmt/tests/expected/read_array.nr b/tooling/nargo_fmt/tests/expected/read_array.nr new file mode 100644 index 00000000000..4e0a21d8b19 --- /dev/null +++ b/tooling/nargo_fmt/tests/expected/read_array.nr @@ -0,0 +1,6 @@ +fn read_array(x: [Field; 3]) { + assert(x[0] == 1); + let y = [1, 5, 27]; + + assert(y[x[0]] == 5); +} diff --git a/tooling/nargo_fmt/tests/input/read_array.nr b/tooling/nargo_fmt/tests/input/read_array.nr new file mode 100644 index 00000000000..d2619884b5d --- /dev/null +++ b/tooling/nargo_fmt/tests/input/read_array.nr @@ -0,0 +1,6 @@ +fn read_array(x: [Field; 3]) { + assert(x[0] == 1); + let y = [1, 5, 27]; + + assert(y[x[0]] == 5); +} From 945bc1cfbd3581d5a4b4f8412619b6a23c60743c Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Fri, 15 Sep 2023 18:42:51 +0000 Subject: [PATCH 09/42] fix clippy --- compiler/noirc_frontend/src/hir/def_map/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/noirc_frontend/src/hir/def_map/mod.rs b/compiler/noirc_frontend/src/hir/def_map/mod.rs index dc6c0d85b67..0d39514c8d3 100644 --- a/compiler/noirc_frontend/src/hir/def_map/mod.rs +++ b/compiler/noirc_frontend/src/hir/def_map/mod.rs @@ -86,7 +86,7 @@ impl CrateDefMap { // First parse the root file. let root_file_id = context.crate_graph[crate_id].root_file_id; - let ast = parse_file(&mut context.file_manager, root_file_id, errors).into_legacy(); + let ast = parse_file(&context.file_manager, root_file_id, errors).into_legacy(); #[cfg(feature = "aztec")] let ast = aztec_library::transform(ast, &crate_id, context, errors); From 44ef7ea288b82b61f32f50dbbdf67ecba5ab418a Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Fri, 15 Sep 2023 19:09:54 +0000 Subject: [PATCH 10/42] update Cargo.lock --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index af73c1559c2..a2bd4a4514a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2228,7 +2228,7 @@ dependencies = [ [[package]] name = "nargo_fmt" -version = "0.11.1" +version = "0.12.0" dependencies = [ "noirc_errors", "noirc_frontend", From 77607d34e147feeed0c476a84a45bde9af310a6d Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Fri, 15 Sep 2023 21:09:08 +0000 Subject: [PATCH 11/42] ops.. --- .../regression_mem_op_predicate/Nargo.toml | 7 +++++++ .../regression_mem_op_predicate/Prover.toml | 2 ++ .../regression_mem_op_predicate/src/main.nr | 8 ++++++++ 3 files changed, 17 insertions(+) create mode 100644 tooling/nargo_cli/tests/execution_success/regression_mem_op_predicate/Nargo.toml create mode 100644 tooling/nargo_cli/tests/execution_success/regression_mem_op_predicate/Prover.toml create mode 100644 tooling/nargo_cli/tests/execution_success/regression_mem_op_predicate/src/main.nr diff --git a/tooling/nargo_cli/tests/execution_success/regression_mem_op_predicate/Nargo.toml b/tooling/nargo_cli/tests/execution_success/regression_mem_op_predicate/Nargo.toml new file mode 100644 index 00000000000..0361b28fd1e --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/regression_mem_op_predicate/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "regression_mem_op_predicate" +type = "bin" +authors = [""] +compiler_version = "0.1" + +[dependencies] diff --git a/tooling/nargo_cli/tests/execution_success/regression_mem_op_predicate/Prover.toml b/tooling/nargo_cli/tests/execution_success/regression_mem_op_predicate/Prover.toml new file mode 100644 index 00000000000..3621f24082c --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/regression_mem_op_predicate/Prover.toml @@ -0,0 +1,2 @@ +x = [4,3,1,5,111] +idx = 12 \ No newline at end of file diff --git a/tooling/nargo_cli/tests/execution_success/regression_mem_op_predicate/src/main.nr b/tooling/nargo_cli/tests/execution_success/regression_mem_op_predicate/src/main.nr new file mode 100644 index 00000000000..a592e2b62b4 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/regression_mem_op_predicate/src/main.nr @@ -0,0 +1,8 @@ +fn main(mut x: [u32; 5], idx: Field) { + // We should not hit out of bounds here as we have a predicate + // that should not be hit + if idx as u32 < 3 { + x[idx] = 10; + } + assert(x[4] == 111); +} \ No newline at end of file From 31461d7da0641ec5705cf772ff192eb4eb7db4ed Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Sat, 16 Sep 2023 14:32:37 +0000 Subject: [PATCH 12/42] fix --- compiler/noirc_frontend/src/parser/mod.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/compiler/noirc_frontend/src/parser/mod.rs b/compiler/noirc_frontend/src/parser/mod.rs index f7c6ede54ee..fae41015d63 100644 --- a/compiler/noirc_frontend/src/parser/mod.rs +++ b/compiler/noirc_frontend/src/parser/mod.rs @@ -494,10 +494,11 @@ impl ForRange { span: array_span, }; - let block = Statement { kind: StatementKind::Expression(block), span: array_span }; - let block_span = block.span; - let new_block = BlockExpression(vec![let_elem]); + let new_block = BlockExpression(vec![ + let_elem, + Statement { kind: StatementKind::Expression(block), span: block_span }, + ]); let new_block = Expression::new(ExpressionKind::Block(new_block), block_span); let for_loop = ExpressionKind::For(Box::new(ForExpression { identifier: fresh_identifier, From 6df3d0a631233da05169560509f0f5cb05f4d72d Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Thu, 21 Sep 2023 10:11:59 +0000 Subject: [PATCH 13/42] specifically for handling comments within empty function parameters --- tooling/nargo_fmt/src/visitor.rs | 54 +++++++++++++------ tooling/nargo_fmt/tests/expected/comment.nr | 2 +- tooling/nargo_fmt/tests/expected/expr.nr | 2 +- tooling/nargo_fmt/tests/expected/print.nr | 1 + tooling/nargo_fmt/tests/expected/print2.nr | 1 + .../nargo_fmt/tests/expected/read_array.nr | 9 ++-- tooling/nargo_fmt/tests/input/comment.nr | 4 +- 7 files changed, 51 insertions(+), 22 deletions(-) diff --git a/tooling/nargo_fmt/src/visitor.rs b/tooling/nargo_fmt/src/visitor.rs index 397bf4ddf18..fa5e4121a9e 100644 --- a/tooling/nargo_fmt/src/visitor.rs +++ b/tooling/nargo_fmt/src/visitor.rs @@ -1,7 +1,8 @@ use noirc_frontend::{ hir::resolution::errors::Span, parser::{ItemKind, ParsedModule}, - BlockExpression, Expression, ExpressionKind, NoirFunction, StatementKind, Visibility, + BlockExpression, Expression, ExpressionKind, NoirFunction, Statement, StatementKind, + Visibility, }; use crate::config::Config; @@ -93,7 +94,20 @@ impl<'a> FmtVisitor<'a> { self.block_indent.block_indent(&self.config); self.push_str("{"); - for stmt in block.0 { + self.visit_stmts(block.0); + + self.last_position = block_span.end(); + self.block_indent.block_unindent(&self.config); + + self.push_str("\n"); + if should_indent { + self.push_str(&self.block_indent.to_string()); + } + self.push_str("}"); + } + + fn visit_stmts(&mut self, stmts: Vec) { + for stmt in stmts { match stmt.kind { StatementKind::Expression(expr) => self.visit_expr(expr), StatementKind::Semi(expr) => { @@ -108,15 +122,6 @@ impl<'a> FmtVisitor<'a> { self.last_position = stmt.span.end(); } - - self.last_position = block_span.end(); - self.block_indent.block_unindent(&self.config); - - self.push_str("\n"); - if should_indent { - self.push_str(&self.block_indent.to_string()); - } - self.push_str("}"); } fn visit_expr(&mut self, expr: Expression) { @@ -202,29 +207,46 @@ impl<'a> FmtVisitor<'a> { let slice = slice!(self, start, end); self.last_position = end; - if slice.trim().is_empty() && !self.buffer.is_empty() { + if slice.trim().is_empty() && !self.at_start() { self.push_str("\n"); process_last_slice(self, "", slice); } else { - self.buffer.push_str(slice); - let indent = self.block_indent.to_string(); - self.push_str(&indent); + process_last_slice(self, slice, slice) } } fn rewrite_fn_before_block(&self, func: NoirFunction) -> String { + let ident_end = func.name_ident().span().end(); + let mut result = String::with_capacity(1024); result.push_str("fn "); result.push_str(func.name()); + let slice = slice!(self, ident_end, func.span().end()); + + let (params_start, params_end) = if func.parameters().is_empty() { + let params_start = slice.find('(').unwrap() as u32; + let params_end = slice.find(')').unwrap() as u32 + 1; + + (ident_end + params_start, ident_end + params_end) + } else { + (0, 0) + }; + + let slice = slice!(self, params_start, params_end); + dbg!(slice); + if !func.def.generics.is_empty() { todo!("emit generics") } result.push('('); if func.parameters().is_empty() { - // TODO: Inside the parameters, there can be a comment, for example `fn hello(/**/) {}`. + let slice = slice!(self, params_start + 1, params_end - 1); + if !slice.trim().is_empty() { + result.push_str(slice); + } } else { let parameters = func.parameters(); diff --git a/tooling/nargo_fmt/tests/expected/comment.nr b/tooling/nargo_fmt/tests/expected/comment.nr index 930a500062d..ebb00acfc5f 100644 --- a/tooling/nargo_fmt/tests/expected/comment.nr +++ b/tooling/nargo_fmt/tests/expected/comment.nr @@ -3,7 +3,6 @@ fn comment1() { } // random comment - fn comment2() { // Test } @@ -12,3 +11,4 @@ fn comment4() {} fn comment5() {} fn comment6() {} fn comment7() {} +fn comment8(/*test*/) {} diff --git a/tooling/nargo_fmt/tests/expected/expr.nr b/tooling/nargo_fmt/tests/expected/expr.nr index 8e54eb336b4..d8920940e8f 100644 --- a/tooling/nargo_fmt/tests/expected/expr.nr +++ b/tooling/nargo_fmt/tests/expected/expr.nr @@ -28,7 +28,7 @@ fn fooblock() { } fn comment() { // this is a test comment - 1 + 1 } fn only_comment() { // Keep this here diff --git a/tooling/nargo_fmt/tests/expected/print.nr b/tooling/nargo_fmt/tests/expected/print.nr index 3fbd305306d..e169f565455 100644 --- a/tooling/nargo_fmt/tests/expected/print.nr +++ b/tooling/nargo_fmt/tests/expected/print.nr @@ -1,4 +1,5 @@ use dep::std; + fn main() { std::println("Hello world"); } diff --git a/tooling/nargo_fmt/tests/expected/print2.nr b/tooling/nargo_fmt/tests/expected/print2.nr index 3fbd305306d..e169f565455 100644 --- a/tooling/nargo_fmt/tests/expected/print2.nr +++ b/tooling/nargo_fmt/tests/expected/print2.nr @@ -1,4 +1,5 @@ use dep::std; + fn main() { std::println("Hello world"); } diff --git a/tooling/nargo_fmt/tests/expected/read_array.nr b/tooling/nargo_fmt/tests/expected/read_array.nr index 4e0a21d8b19..d95ca0bfb4e 100644 --- a/tooling/nargo_fmt/tests/expected/read_array.nr +++ b/tooling/nargo_fmt/tests/expected/read_array.nr @@ -1,6 +1,9 @@ fn read_array(x: [Field; 3]) { - assert(x[0] == 1); - let y = [1, 5, 27]; + assert(x[0] == 1); + + let y = [1, 5, 27]; + + + assert(y[x[0]] == 5); - assert(y[x[0]] == 5); } diff --git a/tooling/nargo_fmt/tests/input/comment.nr b/tooling/nargo_fmt/tests/input/comment.nr index 8101677b255..0e203a82d66 100644 --- a/tooling/nargo_fmt/tests/input/comment.nr +++ b/tooling/nargo_fmt/tests/input/comment.nr @@ -27,4 +27,6 @@ fn comment6() // some comment some comment some comment some comment some commen fn comment7() // some comment some comment some comment some comment some comment some comment some comment { -} \ No newline at end of file +} + +fn comment8(/*test*/) {} From ea90042454664c5a02e1acd8d7682739ef80a9f2 Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Mon, 25 Sep 2023 12:23:11 +0000 Subject: [PATCH 14/42] fixed errors after the merge --- .../noirc_frontend/src/hir/def_collector/dc_crate.rs | 8 ++++---- .../noirc_frontend/src/hir/def_collector/dc_mod.rs | 8 ++++---- compiler/noirc_frontend/src/hir/def_map/mod.rs | 2 +- .../noirc_frontend/src/hir/resolution/resolver.rs | 4 ++-- compiler/noirc_frontend/src/hir/type_check/mod.rs | 2 +- compiler/noirc_frontend/src/parser/mod.rs | 12 ++++++------ 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs index 2f347b44654..f774a045670 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -15,11 +15,11 @@ use crate::hir_def::traits::{TraitConstant, TraitFunction, TraitImpl, TraitType} use crate::node_interner::{ FuncId, NodeInterner, StmtId, StructId, TraitId, TraitImplKey, TypeAliasId, }; -use crate::parser::LegacyParsedModule; +use crate::parser::UnorderParsedModule; use crate::{ ExpressionKind, Generics, Ident, LetStatement, Literal, NoirFunction, NoirStruct, NoirTrait, - NoirTypeAlias, ParsedModule, Shared, StructType, TraitItem, Type, TypeBinding, - TypeVariableKind, UnresolvedGenerics, UnresolvedType, + NoirTypeAlias, Shared, StructType, TraitItem, Type, TypeBinding, TypeVariableKind, + UnresolvedGenerics, UnresolvedType, }; use fm::FileId; use iter_extended::vecmap; @@ -124,7 +124,7 @@ impl DefCollector { pub fn collect( mut def_map: CrateDefMap, context: &mut Context, - ast: LegacyParsedModule, + ast: UnorderParsedModule, root_file_id: FileId, errors: &mut Vec, ) { diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs index c19e089000b..fec598008e6 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs @@ -10,7 +10,7 @@ use crate::{ def_map::ScopeResolveError, }, node_interner::{FunctionModifiers, TraitId}, - parser::{LegacyParsedModule, SubModule}, + parser::{UnorderParsedModule, SubModule}, token::Attributes, FunctionDefinition, Ident, LetStatement, NoirFunction, NoirStruct, NoirTrait, NoirTraitImpl, NoirTypeAlias, TraitImplItem, TraitItem, TypeImpl, @@ -39,7 +39,7 @@ struct ModCollector<'a> { /// This performs the entirety of the definition collection phase of the name resolution pass. pub fn collect_defs( def_collector: &mut DefCollector, - ast: LegacyParsedModule, + ast: UnorderParsedModule, file_id: FileId, module_id: LocalModuleId, crate_id: CrateId, @@ -505,7 +505,7 @@ impl<'a> ModCollector<'a> { ) { collect_defs( self.def_collector, - submodule.contents.into_legacy(), + submodule.contents.into_unorder(), file_id, child, crate_id, @@ -556,7 +556,7 @@ impl<'a> ModCollector<'a> { context.visited_files.insert(child_file_id, location); // Parse the AST for the module we just found and then recursively look for it's defs - let ast = parse_file(&context.file_manager, child_file_id, errors).into_legacy(); + let ast = parse_file(&context.file_manager, child_file_id, errors).into_unorder(); // Add module into def collector and get a ModuleId if let Some(child_mod_id) = diff --git a/compiler/noirc_frontend/src/hir/def_map/mod.rs b/compiler/noirc_frontend/src/hir/def_map/mod.rs index ec86339ad58..69e377c03f2 100644 --- a/compiler/noirc_frontend/src/hir/def_map/mod.rs +++ b/compiler/noirc_frontend/src/hir/def_map/mod.rs @@ -86,7 +86,7 @@ impl CrateDefMap { // First parse the root file. let root_file_id = context.crate_graph[crate_id].root_file_id; - let ast = parse_file(&context.file_manager, root_file_id, errors).into_legacy(); + let ast = parse_file(&context.file_manager, root_file_id, errors).into_unorder(); #[cfg(feature = "aztec")] let ast = aztec_library::transform(ast, &crate_id, context, errors); diff --git a/compiler/noirc_frontend/src/hir/resolution/resolver.rs b/compiler/noirc_frontend/src/hir/resolution/resolver.rs index f128d55806c..dd350afa4d9 100644 --- a/compiler/noirc_frontend/src/hir/resolution/resolver.rs +++ b/compiler/noirc_frontend/src/hir/resolution/resolver.rs @@ -1634,7 +1634,7 @@ mod test { } let mut errors = Vec::new(); - for func in program.into_legacy().functions { + for func in program.into_unorder().functions { let id = interner.push_test_function_definition(func.name().to_string()); let resolver = Resolver::new(&mut interner, &path_resolver, &def_maps, file); @@ -1650,7 +1650,7 @@ mod test { init_src_code_resolution(src); let mut all_captures: Vec> = Vec::new(); - for func in program.into_legacy().functions { + for func in program.into_unorder().functions { let name = func.name().to_string(); let id = interner.push_test_function_definition(name); path_resolver.insert_func(func.name().to_owned(), id); diff --git a/compiler/noirc_frontend/src/hir/type_check/mod.rs b/compiler/noirc_frontend/src/hir/type_check/mod.rs index 3d1c3f10789..e32ed740c83 100644 --- a/compiler/noirc_frontend/src/hir/type_check/mod.rs +++ b/compiler/noirc_frontend/src/hir/type_check/mod.rs @@ -439,7 +439,7 @@ mod test { }, ); - let func_meta = vecmap(program.into_legacy().functions, |nf| { + let func_meta = vecmap(program.into_unorder().functions, |nf| { let resolver = Resolver::new(&mut interner, &path_resolver, &def_maps, file); let (hir_func, func_meta, resolver_errors) = resolver.resolve_function(nf, main_id); assert_eq!(resolver_errors, vec![]); diff --git a/compiler/noirc_frontend/src/parser/mod.rs b/compiler/noirc_frontend/src/parser/mod.rs index c366a7d60f0..2b9b7eefb84 100644 --- a/compiler/noirc_frontend/src/parser/mod.rs +++ b/compiler/noirc_frontend/src/parser/mod.rs @@ -218,7 +218,7 @@ fn force<'a, T: 'a>(parser: impl NoirParser + 'a) -> impl NoirParser, pub functions: Vec, pub types: Vec, @@ -242,8 +242,8 @@ pub struct ParsedModule { } impl ParsedModule { - pub fn into_legacy(self) -> LegacyParsedModule { - let mut module = LegacyParsedModule::default(); + pub fn into_unorder(self) -> UnorderParsedModule { + let mut module = UnorderParsedModule::default(); for item in self.items { match item.kind { @@ -276,7 +276,7 @@ pub enum ItemKind { Function(NoirFunction), Struct(NoirStruct), Trait(NoirTrait), - TraitImpl(TraitImpl), + TraitImpl(NoirTraitImpl), Impl(TypeImpl), TypeAlias(NoirTypeAlias), Global(LetStatement), @@ -293,7 +293,7 @@ pub struct SubModule { pub is_contract: bool, } -impl LegacyParsedModule { +impl UnorderParsedModule { fn push_function(&mut self, func: NoirFunction) { self.functions.push(func); } @@ -539,7 +539,7 @@ impl std::fmt::Display for TopLevelStatement { impl std::fmt::Display for ParsedModule { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let legacy = self.clone().into_legacy(); + let legacy = self.clone().into_unorder(); for decl in &legacy.module_decls { writeln!(f, "mod {decl};")?; From 787f56aa3e7735e72414ebfd46680fca41cbc2e5 Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Mon, 25 Sep 2023 12:28:13 +0000 Subject: [PATCH 15/42] cargo fmt --- compiler/noirc_frontend/src/ast/expression.rs | 4 ++-- compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/noirc_frontend/src/ast/expression.rs b/compiler/noirc_frontend/src/ast/expression.rs index d9b9cd261bd..b9048002457 100644 --- a/compiler/noirc_frontend/src/ast/expression.rs +++ b/compiler/noirc_frontend/src/ast/expression.rs @@ -3,8 +3,8 @@ use std::fmt::Display; use crate::token::{Attributes, Token}; use crate::{ - Distinctness, Ident, Path, Pattern, Recoverable, Statement, StatementKind, UnresolvedTraitConstraint, - UnresolvedType, UnresolvedTypeData, Visibility, + Distinctness, Ident, Path, Pattern, Recoverable, Statement, StatementKind, + UnresolvedTraitConstraint, UnresolvedType, UnresolvedTypeData, Visibility, }; use acvm::FieldElement; use iter_extended::vecmap; diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs index fec598008e6..45c9bd5f3c5 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs @@ -10,7 +10,7 @@ use crate::{ def_map::ScopeResolveError, }, node_interner::{FunctionModifiers, TraitId}, - parser::{UnorderParsedModule, SubModule}, + parser::{SubModule, UnorderParsedModule}, token::Attributes, FunctionDefinition, Ident, LetStatement, NoirFunction, NoirStruct, NoirTrait, NoirTraitImpl, NoirTypeAlias, TraitImplItem, TraitItem, TypeImpl, From 7de95ce761aa0eb2e72d44fbe33d4de8547052ba Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Mon, 25 Sep 2023 13:18:04 +0000 Subject: [PATCH 16/42] a naive attempt not to lose comments --- tooling/nargo_fmt/src/visitor.rs | 32 ++++++++++++++------- tooling/nargo_fmt/tests/expected/comment.nr | 15 ++++++---- 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/tooling/nargo_fmt/src/visitor.rs b/tooling/nargo_fmt/src/visitor.rs index fa5e4121a9e..ff2b52567ba 100644 --- a/tooling/nargo_fmt/src/visitor.rs +++ b/tooling/nargo_fmt/src/visitor.rs @@ -1,8 +1,8 @@ use noirc_frontend::{ hir::resolution::errors::Span, parser::{ItemKind, ParsedModule}, - BlockExpression, Expression, ExpressionKind, NoirFunction, Statement, StatementKind, - Visibility, + BlockExpression, Expression, ExpressionKind, FunctionReturnType, NoirFunction, Statement, + StatementKind, Visibility, }; use crate::config::Config; @@ -55,12 +55,13 @@ impl<'a> FmtVisitor<'a> { for item in module.items { match item.kind { ItemKind::Function(func) => { - let fn_before_block = self.rewrite_fn_before_block(func.clone()); + let (fn_before_block, force_brace_newline) = + self.rewrite_fn_before_block(func.clone()); self.format_missing_indent(item.span.start(), false); - self.push_str(&fn_before_block); - self.push_str(" "); + self.push_str(&fn_before_block); + self.push_str(if force_brace_newline { "\n" } else { " " }); self.visit_block(func.def.body, func.def.span, false); } @@ -215,8 +216,9 @@ impl<'a> FmtVisitor<'a> { } } - fn rewrite_fn_before_block(&self, func: NoirFunction) -> String { + fn rewrite_fn_before_block(&self, func: NoirFunction) -> (String, bool) { let ident_end = func.name_ident().span().end(); + let mut force_brace_newline = false; let mut result = String::with_capacity(1024); @@ -231,12 +233,11 @@ impl<'a> FmtVisitor<'a> { (ident_end + params_start, ident_end + params_end) } else { - (0, 0) + let (pattern, ty, _y) = func.parameters().last().unwrap(); + // FIXME: + (pattern.name_ident().span().start(), ty.span.unwrap().end()) }; - let slice = slice!(self, params_start, params_end); - dbg!(slice); - if !func.def.generics.is_empty() { todo!("emit generics") } @@ -266,7 +267,16 @@ impl<'a> FmtVisitor<'a> { } result.push(')'); - result + + if let FunctionReturnType::Default(span) = func.def.return_type { + let slice = slice!(self, params_end + 1, span.end() - 1); + if !slice.trim().is_empty() { + result.push_str(slice.trim_end()); + force_brace_newline = true; + } + } + + (result, force_brace_newline) } } diff --git a/tooling/nargo_fmt/tests/expected/comment.nr b/tooling/nargo_fmt/tests/expected/comment.nr index ebb00acfc5f..27d82a04a90 100644 --- a/tooling/nargo_fmt/tests/expected/comment.nr +++ b/tooling/nargo_fmt/tests/expected/comment.nr @@ -6,9 +6,14 @@ fn comment1() { fn comment2() { // Test } -fn comment3() {} -fn comment4() {} -fn comment5() {} -fn comment6() {} -fn comment7() {} +fn comment3()// some comment +{} +fn comment4()// some comment +{} +fn comment5()// some comment +{} +fn comment6()// some comment some comment some comment some comment some comment some comment so +{} +fn comment7()// some comment some comment some comment some comment some comment some comment some comment +{} fn comment8(/*test*/) {} From 69181bec20fa089cf1ec82a81e28b7df5249b641 Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Mon, 25 Sep 2023 13:51:28 +0000 Subject: [PATCH 17/42] write as is --- tooling/nargo_fmt/src/visitor.rs | 40 ++++++++++--------- .../tests/expected/nested-if-else.nr | 10 +---- 2 files changed, 23 insertions(+), 27 deletions(-) diff --git a/tooling/nargo_fmt/src/visitor.rs b/tooling/nargo_fmt/src/visitor.rs index ff2b52567ba..1812536c5d1 100644 --- a/tooling/nargo_fmt/src/visitor.rs +++ b/tooling/nargo_fmt/src/visitor.rs @@ -136,8 +136,7 @@ impl<'a> FmtVisitor<'a> { fn format_expr(&self, Expression { kind, span }: Expression) -> String { match kind { - // TODO: literals can contain comments - ExpressionKind::Literal(literal) => literal.to_string(), + ExpressionKind::Literal(_literal) => slice!(self, span.start(), span.end()).to_string(), ExpressionKind::Block(block) => { let mut visitor = FmtVisitor::new(self.source); @@ -149,28 +148,33 @@ impl<'a> FmtVisitor<'a> { ExpressionKind::Prefix(prefix) => { format!("{}{}", prefix.operator, self.format_expr(prefix.rhs)) } - ExpressionKind::Call(call) => { - let callee = self.format_expr(*call.func); - let args = call - .arguments - .into_iter() - .map(|arg| self.format_expr(arg)) - .collect::>() - .join(", "); - - format!("{callee}({args})") + ExpressionKind::Call(_call) => { + // FIXME: + // let callee = self.format_expr(*call.func); + // let args = call + // .arguments + // .into_iter() + // .map(|arg| self.format_expr(arg)) + // .collect::>() + // .join(", "); + + // format!("{callee}({args})") + + slice!(self, span.start(), span.end()).to_string() } - ExpressionKind::Infix(infix) => { - let lhs = self.format_expr(infix.lhs); - let op = infix.operator.contents; - let rhs = self.format_expr(infix.rhs); + ExpressionKind::Infix(_infix) => { + // let lhs = self.format_expr(infix.lhs); + // let op = infix.operator.contents; + // let rhs = self.format_expr(infix.rhs); - format!("{lhs} {op} {rhs}") + // format!("{lhs} {op} {rhs}") + + slice!(self, span.start(), span.end()).to_string() } ExpressionKind::Variable(_) => slice!(self, span.start(), span.end()).to_string(), ExpressionKind::Error => unreachable!(), // TODO: - expr => expr.to_string(), + _expr => slice!(self, span.start(), span.end()).to_string(), } } diff --git a/tooling/nargo_fmt/tests/expected/nested-if-else.nr b/tooling/nargo_fmt/tests/expected/nested-if-else.nr index 756540e1bd8..8aa120e3b18 100644 --- a/tooling/nargo_fmt/tests/expected/nested-if-else.nr +++ b/tooling/nargo_fmt/tests/expected/nested-if-else.nr @@ -1,11 +1,3 @@ fn nested_if_else() { - if false { - 1 -} else { - if false { - 2 - } else { - 3 - } -} + if false { 1 } else if false { 2 } else { 3 } } From 0eef49a541eb1094cc0f6957a6470e8e0bcf82a9 Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Wed, 27 Sep 2023 09:38:09 +0000 Subject: [PATCH 18/42] fixed errors after the merge --- compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs | 1 + compiler/noirc_frontend/src/hir/def_map/mod.rs | 3 ++- tooling/nargo_fmt/src/lib.rs | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs index f26c3a5b98f..0f214b1813c 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs @@ -568,6 +568,7 @@ impl<'a> ModCollector<'a> { // Parse the AST for the module we just found and then recursively look for it's defs //let ast = parse_file(&context.file_manager, child_file_id, errors).into_unorder(); let (ast, parsing_errors) = parse_file(&context.file_manager, child_file_id); + let ast = ast.into_unorder(); errors.extend( parsing_errors.iter().map(|e| (e.clone().into(), child_file_id)).collect::>(), diff --git a/compiler/noirc_frontend/src/hir/def_map/mod.rs b/compiler/noirc_frontend/src/hir/def_map/mod.rs index 70e618e73f8..b6c3a9eb8dc 100644 --- a/compiler/noirc_frontend/src/hir/def_map/mod.rs +++ b/compiler/noirc_frontend/src/hir/def_map/mod.rs @@ -85,7 +85,8 @@ impl CrateDefMap { // First parse the root file. let root_file_id = context.crate_graph[crate_id].root_file_id; - let (ast, parsing_errors) = parse_file(&context.file_manager, root_file_id).into_unorder(); + let (ast, parsing_errors) = parse_file(&context.file_manager, root_file_id); + let ast = ast.into_unorder(); #[cfg(feature = "aztec")] let ast = match aztec_library::transform(ast, &crate_id, context) { diff --git a/tooling/nargo_fmt/src/lib.rs b/tooling/nargo_fmt/src/lib.rs index 9e868b62c62..3dfe29707f1 100644 --- a/tooling/nargo_fmt/src/lib.rs +++ b/tooling/nargo_fmt/src/lib.rs @@ -3,9 +3,10 @@ mod config; mod visitor; +use noirc_frontend::parser::ParserError; use visitor::FmtVisitor; -pub fn format(source: &str) -> Result> { +pub fn format(source: &str) -> Result> { let (module, errors) = noirc_frontend::parse_program(source); if !errors.is_empty() { From fa298b8e0a880f0b810cf2ea975841bd9510d0f5 Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Wed, 27 Sep 2023 12:49:14 +0000 Subject: [PATCH 19/42] make clippy happy --- Cargo.lock | 1 - tooling/nargo_fmt/Cargo.toml | 1 - tooling/nargo_fmt/src/config.rs | 3 ++- tooling/nargo_fmt/src/lib.rs | 8 ++++-- tooling/nargo_fmt/src/visitor.rs | 44 +++++++------------------------- 5 files changed, 17 insertions(+), 40 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 89454afe0ef..350ea516278 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2305,7 +2305,6 @@ dependencies = [ name = "nargo_fmt" version = "0.14.0" dependencies = [ - "noirc_errors", "noirc_frontend", "readonly", ] diff --git a/tooling/nargo_fmt/Cargo.toml b/tooling/nargo_fmt/Cargo.toml index 53479b1d9a1..da77216c0ad 100644 --- a/tooling/nargo_fmt/Cargo.toml +++ b/tooling/nargo_fmt/Cargo.toml @@ -7,5 +7,4 @@ license.workspace = true [dependencies] noirc_frontend.workspace = true -noirc_errors.workspace = true readonly = "0.2" diff --git a/tooling/nargo_fmt/src/config.rs b/tooling/nargo_fmt/src/config.rs index f5927c9ddb8..eb9b2915d26 100644 --- a/tooling/nargo_fmt/src/config.rs +++ b/tooling/nargo_fmt/src/config.rs @@ -1,5 +1,6 @@ +#[allow(unreachable_pub)] #[readonly::make] -pub struct Config { +pub(crate) struct Config { /// Maximum width of each line. #[readonly] pub max_width: usize, diff --git a/tooling/nargo_fmt/src/lib.rs b/tooling/nargo_fmt/src/lib.rs index 3dfe29707f1..c12428e4d1d 100644 --- a/tooling/nargo_fmt/src/lib.rs +++ b/tooling/nargo_fmt/src/lib.rs @@ -1,4 +1,8 @@ -#![deny(unused_qualifications, clippy::use_self)] +#![forbid(unsafe_code)] +#![warn(unused_crate_dependencies, unused_extern_crates)] +#![warn(unreachable_pub)] +#![warn(clippy::semicolon_if_nothing_returned)] +#![warn(unused_qualifications, clippy::use_self)] mod config; mod visitor; @@ -53,7 +57,7 @@ mod tests { Err(err) => unreachable!("{err}"), }; - // TODO: better diff + // FIXME: better diff assert_eq!(fmt_text, target); } } diff --git a/tooling/nargo_fmt/src/visitor.rs b/tooling/nargo_fmt/src/visitor.rs index 1812536c5d1..be85a2b91de 100644 --- a/tooling/nargo_fmt/src/visitor.rs +++ b/tooling/nargo_fmt/src/visitor.rs @@ -14,7 +14,7 @@ macro_rules! slice { }; } -pub struct FmtVisitor<'a> { +pub(crate) struct FmtVisitor<'a> { config: Config, buffer: String, source: &'a str, @@ -23,7 +23,7 @@ pub struct FmtVisitor<'a> { } impl<'a> FmtVisitor<'a> { - pub fn new(source: &'a str) -> Self { + pub(crate) fn new(source: &'a str) -> Self { Self { config: Config::default(), buffer: String::new(), @@ -33,12 +33,12 @@ impl<'a> FmtVisitor<'a> { } } - pub fn at_start(&self) -> bool { - self.buffer.is_empty() + pub(crate) fn finish(self) -> String { + self.buffer } - pub fn finish(self) -> String { - self.buffer + fn at_start(&self) -> bool { + self.buffer.is_empty() } fn push_str(&mut self, s: &str) { @@ -51,7 +51,7 @@ impl<'a> FmtVisitor<'a> { self.push_str(&s); } - pub fn visit_module(&mut self, module: ParsedModule) { + pub(crate) fn visit_module(&mut self, module: ParsedModule) { for item in module.items { match item.kind { ItemKind::Function(func) => { @@ -136,7 +136,6 @@ impl<'a> FmtVisitor<'a> { fn format_expr(&self, Expression { kind, span }: Expression) -> String { match kind { - ExpressionKind::Literal(_literal) => slice!(self, span.start(), span.end()).to_string(), ExpressionKind::Block(block) => { let mut visitor = FmtVisitor::new(self.source); @@ -148,31 +147,6 @@ impl<'a> FmtVisitor<'a> { ExpressionKind::Prefix(prefix) => { format!("{}{}", prefix.operator, self.format_expr(prefix.rhs)) } - ExpressionKind::Call(_call) => { - // FIXME: - // let callee = self.format_expr(*call.func); - // let args = call - // .arguments - // .into_iter() - // .map(|arg| self.format_expr(arg)) - // .collect::>() - // .join(", "); - - // format!("{callee}({args})") - - slice!(self, span.start(), span.end()).to_string() - } - ExpressionKind::Infix(_infix) => { - // let lhs = self.format_expr(infix.lhs); - // let op = infix.operator.contents; - // let rhs = self.format_expr(infix.rhs); - - // format!("{lhs} {op} {rhs}") - - slice!(self, span.start(), span.end()).to_string() - } - ExpressionKind::Variable(_) => slice!(self, span.start(), span.end()).to_string(), - ExpressionKind::Error => unreachable!(), // TODO: _expr => slice!(self, span.start(), span.end()).to_string(), } @@ -204,7 +178,7 @@ impl<'a> FmtVisitor<'a> { if start == end { if !self.at_start() { - process_last_slice(self, "", "") + process_last_slice(self, "", ""); } return; } @@ -216,7 +190,7 @@ impl<'a> FmtVisitor<'a> { self.push_str("\n"); process_last_slice(self, "", slice); } else { - process_last_slice(self, slice, slice) + process_last_slice(self, slice, slice); } } From b83925bcb4cb9692418c2d78961afd585e4c6497 Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Wed, 27 Sep 2023 14:18:26 +0000 Subject: [PATCH 20/42] for simplicity MVP abandon the complex --- tooling/nargo_fmt/src/visitor.rs | 70 ++------------------- tooling/nargo_fmt/tests/expected/comment.nr | 12 ++-- tooling/nargo_fmt/tests/expected/print2.nr | 2 +- 3 files changed, 14 insertions(+), 70 deletions(-) diff --git a/tooling/nargo_fmt/src/visitor.rs b/tooling/nargo_fmt/src/visitor.rs index be85a2b91de..745a9922759 100644 --- a/tooling/nargo_fmt/src/visitor.rs +++ b/tooling/nargo_fmt/src/visitor.rs @@ -1,8 +1,7 @@ use noirc_frontend::{ hir::resolution::errors::Span, parser::{ItemKind, ParsedModule}, - BlockExpression, Expression, ExpressionKind, FunctionReturnType, NoirFunction, Statement, - StatementKind, Visibility, + BlockExpression, Expression, ExpressionKind, NoirFunction, Statement, StatementKind, }; use crate::config::Config; @@ -56,7 +55,7 @@ impl<'a> FmtVisitor<'a> { match item.kind { ItemKind::Function(func) => { let (fn_before_block, force_brace_newline) = - self.rewrite_fn_before_block(func.clone()); + self.rewrite_fn_before_block(func.clone(), item.span.start()); self.format_missing_indent(item.span.start(), false); @@ -194,67 +193,10 @@ impl<'a> FmtVisitor<'a> { } } - fn rewrite_fn_before_block(&self, func: NoirFunction) -> (String, bool) { - let ident_end = func.name_ident().span().end(); - let mut force_brace_newline = false; - - let mut result = String::with_capacity(1024); - - result.push_str("fn "); - result.push_str(func.name()); - - let slice = slice!(self, ident_end, func.span().end()); - - let (params_start, params_end) = if func.parameters().is_empty() { - let params_start = slice.find('(').unwrap() as u32; - let params_end = slice.find(')').unwrap() as u32 + 1; - - (ident_end + params_start, ident_end + params_end) - } else { - let (pattern, ty, _y) = func.parameters().last().unwrap(); - // FIXME: - (pattern.name_ident().span().start(), ty.span.unwrap().end()) - }; - - if !func.def.generics.is_empty() { - todo!("emit generics") - } - - result.push('('); - if func.parameters().is_empty() { - let slice = slice!(self, params_start + 1, params_end - 1); - if !slice.trim().is_empty() { - result.push_str(slice); - } - } else { - let parameters = func.parameters(); - - for (index, (pattern, ty, vis)) in parameters.iter().enumerate() { - result.push_str(&pattern.to_string()); - result.push_str(": "); - if let Visibility::Public = vis { - result.push_str("pub "); - } - let ty_span = ty.span.unwrap(); - result.push_str(slice!(self, ty_span.start(), ty_span.end())); - - if index < parameters.len() - 1 { - result.push_str(", "); - } - } - } - - result.push(')'); - - if let FunctionReturnType::Default(span) = func.def.return_type { - let slice = slice!(self, params_end + 1, span.end() - 1); - if !slice.trim().is_empty() { - result.push_str(slice.trim_end()); - force_brace_newline = true; - } - } - - (result, force_brace_newline) + fn rewrite_fn_before_block(&self, func: NoirFunction, start: u32) -> (String, bool) { + let slice = slice!(self, start, func.span().start()); + let force_brace_newline = slice.contains("//"); + (slice.trim_end().to_string(), force_brace_newline) } } diff --git a/tooling/nargo_fmt/tests/expected/comment.nr b/tooling/nargo_fmt/tests/expected/comment.nr index 27d82a04a90..9acc56b1f3e 100644 --- a/tooling/nargo_fmt/tests/expected/comment.nr +++ b/tooling/nargo_fmt/tests/expected/comment.nr @@ -6,14 +6,16 @@ fn comment1() { fn comment2() { // Test } -fn comment3()// some comment +fn comment3() // some comment {} -fn comment4()// some comment +fn comment4() +// some comment {} -fn comment5()// some comment +fn comment5() // some comment {} -fn comment6()// some comment some comment some comment some comment some comment some comment so +fn comment6() // some comment some comment some comment some comment some comment some comment so {} -fn comment7()// some comment some comment some comment some comment some comment some comment some comment +fn comment7() +// some comment some comment some comment some comment some comment some comment some comment {} fn comment8(/*test*/) {} diff --git a/tooling/nargo_fmt/tests/expected/print2.nr b/tooling/nargo_fmt/tests/expected/print2.nr index e169f565455..80284444af8 100644 --- a/tooling/nargo_fmt/tests/expected/print2.nr +++ b/tooling/nargo_fmt/tests/expected/print2.nr @@ -1,5 +1,5 @@ use dep::std; -fn main() { +fn main( ) { std::println("Hello world"); } From a1108bc6a5a98c8712022dd124897bef9c51dcb0 Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Wed, 27 Sep 2023 15:43:32 +0000 Subject: [PATCH 21/42] fix `read_array` --- tooling/nargo_fmt/src/visitor.rs | 7 +++++-- tooling/nargo_fmt/tests/expected/read_array.nr | 3 --- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tooling/nargo_fmt/src/visitor.rs b/tooling/nargo_fmt/src/visitor.rs index 745a9922759..ef16079723d 100644 --- a/tooling/nargo_fmt/src/visitor.rs +++ b/tooling/nargo_fmt/src/visitor.rs @@ -108,7 +108,7 @@ impl<'a> FmtVisitor<'a> { fn visit_stmts(&mut self, stmts: Vec) { for stmt in stmts { - match stmt.kind { + match dbg!(stmt.kind) { StatementKind::Expression(expr) => self.visit_expr(expr), StatementKind::Semi(expr) => { self.visit_expr(expr); @@ -116,7 +116,9 @@ impl<'a> FmtVisitor<'a> { } StatementKind::Error => unreachable!(), _ => { - self.format_missing_indent(stmt.span.end(), false); + self.format_missing_inner(stmt.span.end(), |this, slice, _| { + this.push_str(slice); + }); } } @@ -128,6 +130,7 @@ impl<'a> FmtVisitor<'a> { let span = expr.span; let rewrite = self.format_expr(expr); + dbg!(&rewrite); self.push_rewrite(rewrite, span); self.last_position = span.end(); diff --git a/tooling/nargo_fmt/tests/expected/read_array.nr b/tooling/nargo_fmt/tests/expected/read_array.nr index d95ca0bfb4e..d2619884b5d 100644 --- a/tooling/nargo_fmt/tests/expected/read_array.nr +++ b/tooling/nargo_fmt/tests/expected/read_array.nr @@ -1,9 +1,6 @@ fn read_array(x: [Field; 3]) { assert(x[0] == 1); - let y = [1, 5, 27]; - assert(y[x[0]] == 5); - } From c7b58fae91eb2a278fcba0e4f94c246b33564390 Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Wed, 27 Sep 2023 18:37:21 +0000 Subject: [PATCH 22/42] add `format_missing` --- tooling/nargo_fmt/src/visitor.rs | 31 ++++++++++------------ tooling/nargo_fmt/tests/expected/print.nr | 1 - tooling/nargo_fmt/tests/expected/print2.nr | 1 - 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/tooling/nargo_fmt/src/visitor.rs b/tooling/nargo_fmt/src/visitor.rs index ef16079723d..0babaaf0c21 100644 --- a/tooling/nargo_fmt/src/visitor.rs +++ b/tooling/nargo_fmt/src/visitor.rs @@ -1,6 +1,6 @@ use noirc_frontend::{ hir::resolution::errors::Span, - parser::{ItemKind, ParsedModule}, + parser::{Item, ItemKind, ParsedModule}, BlockExpression, Expression, ExpressionKind, NoirFunction, Statement, StatementKind, }; @@ -51,22 +51,20 @@ impl<'a> FmtVisitor<'a> { } pub(crate) fn visit_module(&mut self, module: ParsedModule) { - for item in module.items { - match item.kind { + for Item { kind, span } in module.items { + match kind { ItemKind::Function(func) => { let (fn_before_block, force_brace_newline) = - self.rewrite_fn_before_block(func.clone(), item.span.start()); + self.rewrite_fn_before_block(func.clone(), span.start()); - self.format_missing_indent(item.span.start(), false); + self.format_missing_indent(span.start(), false); self.push_str(&fn_before_block); self.push_str(if force_brace_newline { "\n" } else { " " }); self.visit_block(func.def.body, func.def.span, false); } - _ => { - self.format_missing_indent(item.span.end(), false); - } + _ => self.format_missing(span.end()), } } @@ -107,22 +105,18 @@ impl<'a> FmtVisitor<'a> { } fn visit_stmts(&mut self, stmts: Vec) { - for stmt in stmts { - match dbg!(stmt.kind) { + for Statement { kind, span } in stmts { + match kind { StatementKind::Expression(expr) => self.visit_expr(expr), StatementKind::Semi(expr) => { self.visit_expr(expr); self.push_str(";"); } StatementKind::Error => unreachable!(), - _ => { - self.format_missing_inner(stmt.span.end(), |this, slice, _| { - this.push_str(slice); - }); - } + _ => self.format_missing(span.end()), } - self.last_position = stmt.span.end(); + self.last_position = span.end(); } } @@ -130,7 +124,6 @@ impl<'a> FmtVisitor<'a> { let span = expr.span; let rewrite = self.format_expr(expr); - dbg!(&rewrite); self.push_rewrite(rewrite, span); self.last_position = span.end(); @@ -154,6 +147,10 @@ impl<'a> FmtVisitor<'a> { } } + fn format_missing(&mut self, end: u32) { + self.format_missing_inner(end, |this, slice, _| this.push_str(slice)); + } + #[track_caller] fn format_missing_indent(&mut self, end: u32, should_indent: bool) { self.format_missing_inner(end, |this, last_slice, slice| { diff --git a/tooling/nargo_fmt/tests/expected/print.nr b/tooling/nargo_fmt/tests/expected/print.nr index e169f565455..3fbd305306d 100644 --- a/tooling/nargo_fmt/tests/expected/print.nr +++ b/tooling/nargo_fmt/tests/expected/print.nr @@ -1,5 +1,4 @@ use dep::std; - fn main() { std::println("Hello world"); } diff --git a/tooling/nargo_fmt/tests/expected/print2.nr b/tooling/nargo_fmt/tests/expected/print2.nr index 80284444af8..adeed82d5e9 100644 --- a/tooling/nargo_fmt/tests/expected/print2.nr +++ b/tooling/nargo_fmt/tests/expected/print2.nr @@ -1,5 +1,4 @@ use dep::std; - fn main( ) { std::println("Hello world"); } From 240ce40f0aac7b8d09193c4a1e588f3d23a69125 Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Wed, 27 Sep 2023 18:41:02 +0000 Subject: [PATCH 23/42] add tests --- tooling/nargo_fmt/tests/expected/struct.nr | 75 +++++++++++++++++++++ tooling/nargo_fmt/tests/expected/vec.nr | 60 +++++++++++++++++ tooling/nargo_fmt/tests/input/struct.nr | 77 ++++++++++++++++++++++ tooling/nargo_fmt/tests/input/vec.nr | 60 +++++++++++++++++ 4 files changed, 272 insertions(+) create mode 100644 tooling/nargo_fmt/tests/expected/struct.nr create mode 100644 tooling/nargo_fmt/tests/expected/vec.nr create mode 100644 tooling/nargo_fmt/tests/input/struct.nr create mode 100644 tooling/nargo_fmt/tests/input/vec.nr diff --git a/tooling/nargo_fmt/tests/expected/struct.nr b/tooling/nargo_fmt/tests/expected/struct.nr new file mode 100644 index 00000000000..c2b50ded890 --- /dev/null +++ b/tooling/nargo_fmt/tests/expected/struct.nr @@ -0,0 +1,75 @@ +struct Foo { + bar: Field, + array: [Field; 2], +} + +struct Pair { + first: Foo, + second: Field, +} + +impl Foo { + fn default(x: Field,y: Field) -> Self { + Self { bar: 0, array: [x,y] } + } +} + +impl Pair { + fn foo(p: Self) -> Foo { + p.first + } + + fn bar(self) -> Field { + self.foo().bar + } +} + +struct Nested { + a: Field, + b: Field +} +struct MyStruct { + my_bool: bool, + my_int: u32, + my_nest: Nested, +} +fn test_struct_in_tuple(a_bool : bool,x:Field, y:Field) -> (MyStruct, bool) { + let my_struct = MyStruct { + my_bool: a_bool, + my_int: 5, + my_nest: Nested{a:x,b:y}, + }; + (my_struct, a_bool) +} + +struct Animal { + legs: Field, + eyes: u8, +} +fn get_dog() -> Animal { + let dog = Animal { legs: 4, eyes: 2 }; + dog +} +fn main(x: Field, y: Field) { + let first = Foo::default(x,y); + let p = Pair { first, second: 1 }; + + assert(p.bar() == x); + assert(p.second == y); + assert(p.first.array[0] != p.first.array[1]); + + // Nested structs + let (struct_from_tuple, a_bool) = test_struct_in_tuple(true,x,y); + assert(struct_from_tuple.my_bool == true); + assert(a_bool == true); + assert(struct_from_tuple.my_int == 5); + assert(struct_from_tuple.my_nest.a == 0); + + // Regression test for issue #670 + let Animal { legs, eyes } = get_dog(); + let six = legs + eyes as Field; + + assert(six == 6); + + let Animal { legs: _, eyes: _ } = get_dog(); +} diff --git a/tooling/nargo_fmt/tests/expected/vec.nr b/tooling/nargo_fmt/tests/expected/vec.nr new file mode 100644 index 00000000000..1c9a791961e --- /dev/null +++ b/tooling/nargo_fmt/tests/expected/vec.nr @@ -0,0 +1,60 @@ +struct Vec { + slice: [T] +} + +// A mutable vector type implemented as a wrapper around immutable slices. +// A separate type is technically not needed but helps differentiate which operations are mutable. +impl Vec { + pub fn new() -> Self { + Self { slice: [] } + } + + // Create a Vec containing each element from the given slice. + // Mutations to the resulting Vec will not affect the original slice. + pub fn from_slice(slice: [T]) -> Self { + Self { slice } + } + + /// Get an element from the vector at the given index. + /// Panics if the given index + /// points beyond the end of the vector. + pub fn get(self, index: Field) -> T { + self.slice[index] + } + + /// Push a new element to the end of the vector, returning a + /// new vector with a length one greater than the + /// original unmodified vector. + pub fn push(&mut self, elem: T) { + self.slice = self.slice.push_back(elem); + } + + /// Pop an element from the end of the given vector, returning + /// a new vector with a length of one less than the given vector, + /// as well as the popped element. + /// Panics if the given vector's length is zero. + pub fn pop(&mut self) -> T { + let (popped_slice, last_elem) = self.slice.pop_back(); + self.slice = popped_slice; + last_elem + } + + /// Insert an element at a specified index, shifting all elements + /// after it to the right + pub fn insert(&mut self, index: Field, elem: T) { + self.slice = self.slice.insert(index, elem); + } + + /// Remove an element at a specified index, shifting all elements + /// after it to the left, returning the removed element + pub fn remove(&mut self, index: Field) -> T { + let (new_slice, elem) = self.slice.remove(index); + self.slice = new_slice; + elem + } + + /// Returns the number of elements in the vector + pub fn len(self) -> Field { + self.slice.len() + } +} diff --git a/tooling/nargo_fmt/tests/input/struct.nr b/tooling/nargo_fmt/tests/input/struct.nr new file mode 100644 index 00000000000..5e3530e8364 --- /dev/null +++ b/tooling/nargo_fmt/tests/input/struct.nr @@ -0,0 +1,77 @@ +struct Foo { + bar: Field, + array: [Field; 2], +} + +struct Pair { + first: Foo, + second: Field, +} + +impl Foo { + fn default(x: Field,y: Field) -> Self { + Self { bar: 0, array: [x,y] } + } +} + +impl Pair { + fn foo(p: Self) -> Foo { + p.first + } + + fn bar(self) -> Field { + self.foo().bar + } +} + +struct Nested { + a: Field, + b: Field +} +struct MyStruct { + my_bool: bool, + my_int: u32, + my_nest: Nested, +} +fn test_struct_in_tuple(a_bool : bool,x:Field, y:Field) -> (MyStruct, bool) { + let my_struct = MyStruct { + my_bool: a_bool, + my_int: 5, + my_nest: Nested{a:x,b:y}, + }; + (my_struct, a_bool) +} + +struct Animal { + legs: Field, + eyes: u8, +} + +fn get_dog() -> Animal { + let dog = Animal { legs: 4, eyes: 2 }; + dog +} + +fn main(x: Field, y: Field) { + let first = Foo::default(x,y); + let p = Pair { first, second: 1 }; + + assert(p.bar() == x); + assert(p.second == y); + assert(p.first.array[0] != p.first.array[1]); + + // Nested structs + let (struct_from_tuple, a_bool) = test_struct_in_tuple(true,x,y); + assert(struct_from_tuple.my_bool == true); + assert(a_bool == true); + assert(struct_from_tuple.my_int == 5); + assert(struct_from_tuple.my_nest.a == 0); + + // Regression test for issue #670 + let Animal { legs, eyes } = get_dog(); + let six = legs + eyes as Field; + + assert(six == 6); + + let Animal { legs: _, eyes: _ } = get_dog(); +} diff --git a/tooling/nargo_fmt/tests/input/vec.nr b/tooling/nargo_fmt/tests/input/vec.nr new file mode 100644 index 00000000000..1c9a791961e --- /dev/null +++ b/tooling/nargo_fmt/tests/input/vec.nr @@ -0,0 +1,60 @@ +struct Vec { + slice: [T] +} + +// A mutable vector type implemented as a wrapper around immutable slices. +// A separate type is technically not needed but helps differentiate which operations are mutable. +impl Vec { + pub fn new() -> Self { + Self { slice: [] } + } + + // Create a Vec containing each element from the given slice. + // Mutations to the resulting Vec will not affect the original slice. + pub fn from_slice(slice: [T]) -> Self { + Self { slice } + } + + /// Get an element from the vector at the given index. + /// Panics if the given index + /// points beyond the end of the vector. + pub fn get(self, index: Field) -> T { + self.slice[index] + } + + /// Push a new element to the end of the vector, returning a + /// new vector with a length one greater than the + /// original unmodified vector. + pub fn push(&mut self, elem: T) { + self.slice = self.slice.push_back(elem); + } + + /// Pop an element from the end of the given vector, returning + /// a new vector with a length of one less than the given vector, + /// as well as the popped element. + /// Panics if the given vector's length is zero. + pub fn pop(&mut self) -> T { + let (popped_slice, last_elem) = self.slice.pop_back(); + self.slice = popped_slice; + last_elem + } + + /// Insert an element at a specified index, shifting all elements + /// after it to the right + pub fn insert(&mut self, index: Field, elem: T) { + self.slice = self.slice.insert(index, elem); + } + + /// Remove an element at a specified index, shifting all elements + /// after it to the left, returning the removed element + pub fn remove(&mut self, index: Field) -> T { + let (new_slice, elem) = self.slice.remove(index); + self.slice = new_slice; + elem + } + + /// Returns the number of elements in the vector + pub fn len(self) -> Field { + self.slice.len() + } +} From b2655d02e2a9848077ae1fa9f7411aee9b3d28bf Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Wed, 27 Sep 2023 18:56:07 +0000 Subject: [PATCH 24/42] add `with_indent` --- tooling/nargo_fmt/src/visitor.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/tooling/nargo_fmt/src/visitor.rs b/tooling/nargo_fmt/src/visitor.rs index 0babaaf0c21..4c9c12f3fae 100644 --- a/tooling/nargo_fmt/src/visitor.rs +++ b/tooling/nargo_fmt/src/visitor.rs @@ -36,6 +36,12 @@ impl<'a> FmtVisitor<'a> { self.buffer } + fn with_indent(&mut self, f: impl FnOnce(&mut Self)) { + self.block_indent.block_indent(&self.config); + f(self); + self.block_indent.block_unindent(&self.config); + } + fn at_start(&self) -> bool { self.buffer.is_empty() } @@ -89,18 +95,20 @@ impl<'a> FmtVisitor<'a> { } self.last_position = block_span.start() + 1; // `{` - self.block_indent.block_indent(&self.config); + self.push_str("{"); - self.visit_stmts(block.0); + self.with_indent(|this| { + this.visit_stmts(block.0); + }); + self.push_str("\n"); self.last_position = block_span.end(); - self.block_indent.block_unindent(&self.config); - self.push_str("\n"); if should_indent { self.push_str(&self.block_indent.to_string()); } + self.push_str("}"); } From b8d6ffd426427e96349480d9b8c0326fa7f13f2b Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Thu, 28 Sep 2023 12:24:41 +0000 Subject: [PATCH 25/42] smol refactoring --- tooling/nargo_fmt/src/visitor.rs | 123 +++----------------- tooling/nargo_fmt/src/visitor/expr.rs | 77 ++++++++++++ tooling/nargo_fmt/src/visitor/item.rs | 27 +++++ tooling/nargo_fmt/src/visitor/stmt.rs | 19 +++ tooling/nargo_fmt/tests/expected/add.nr | 7 ++ tooling/nargo_fmt/tests/expected/comment.nr | 4 +- tooling/nargo_fmt/tests/expected/expr.nr | 19 ++- tooling/nargo_fmt/tests/expected/module.nr | 23 ++++ tooling/nargo_fmt/tests/input/add.nr | 7 ++ tooling/nargo_fmt/tests/input/expr.nr | 18 +++ tooling/nargo_fmt/tests/input/module.nr | 23 ++++ 11 files changed, 233 insertions(+), 114 deletions(-) create mode 100644 tooling/nargo_fmt/src/visitor/expr.rs create mode 100644 tooling/nargo_fmt/src/visitor/item.rs create mode 100644 tooling/nargo_fmt/src/visitor/stmt.rs create mode 100644 tooling/nargo_fmt/tests/expected/add.nr create mode 100644 tooling/nargo_fmt/tests/expected/module.nr create mode 100644 tooling/nargo_fmt/tests/input/add.nr create mode 100644 tooling/nargo_fmt/tests/input/module.nr diff --git a/tooling/nargo_fmt/src/visitor.rs b/tooling/nargo_fmt/src/visitor.rs index 4c9c12f3fae..9cd8e6a6329 100644 --- a/tooling/nargo_fmt/src/visitor.rs +++ b/tooling/nargo_fmt/src/visitor.rs @@ -1,18 +1,19 @@ -use noirc_frontend::{ - hir::resolution::errors::Span, - parser::{Item, ItemKind, ParsedModule}, - BlockExpression, Expression, ExpressionKind, NoirFunction, Statement, StatementKind, -}; - -use crate::config::Config; - /// A macro to create a slice from a given data source, helping to avoid borrow checker errors. +#[macro_export] macro_rules! slice { ($this:ident, $start:expr, $end:expr) => { &$this.source[$start as usize..$end as usize] }; } +mod expr; +mod item; +mod stmt; + +use noirc_frontend::{hir::resolution::errors::Span, NoirFunction}; + +use crate::config::Config; + pub(crate) struct FmtVisitor<'a> { config: Config, buffer: String, @@ -36,10 +37,11 @@ impl<'a> FmtVisitor<'a> { self.buffer } - fn with_indent(&mut self, f: impl FnOnce(&mut Self)) { + fn with_indent(&mut self, f: impl FnOnce(&mut Self) -> T) -> T { self.block_indent.block_indent(&self.config); - f(self); + let ret = f(self); self.block_indent.block_unindent(&self.config); + ret } fn at_start(&self) -> bool { @@ -56,105 +58,6 @@ impl<'a> FmtVisitor<'a> { self.push_str(&s); } - pub(crate) fn visit_module(&mut self, module: ParsedModule) { - for Item { kind, span } in module.items { - match kind { - ItemKind::Function(func) => { - let (fn_before_block, force_brace_newline) = - self.rewrite_fn_before_block(func.clone(), span.start()); - - self.format_missing_indent(span.start(), false); - - self.push_str(&fn_before_block); - self.push_str(if force_brace_newline { "\n" } else { " " }); - - self.visit_block(func.def.body, func.def.span, false); - } - _ => self.format_missing(span.end()), - } - } - - self.format_missing_indent(self.source.len() as u32, false); - } - - fn visit_block(&mut self, block: BlockExpression, block_span: Span, should_indent: bool) { - if block.is_empty() { - let slice = slice!(self, block_span.start(), block_span.end()); - let comment_str = slice[1..slice.len() - 1].trim(); - - let block_str = if comment_str.is_empty() { - "{}".to_string() - } else { - let indent = self.block_indent.to_string(); - format!("{{\n{indent}{comment_str}\n{indent}}}",) - }; - - self.last_position = block_span.end(); - self.push_str(&block_str); - return; - } - - self.last_position = block_span.start() + 1; // `{` - - self.push_str("{"); - - self.with_indent(|this| { - this.visit_stmts(block.0); - }); - - self.push_str("\n"); - self.last_position = block_span.end(); - - if should_indent { - self.push_str(&self.block_indent.to_string()); - } - - self.push_str("}"); - } - - fn visit_stmts(&mut self, stmts: Vec) { - for Statement { kind, span } in stmts { - match kind { - StatementKind::Expression(expr) => self.visit_expr(expr), - StatementKind::Semi(expr) => { - self.visit_expr(expr); - self.push_str(";"); - } - StatementKind::Error => unreachable!(), - _ => self.format_missing(span.end()), - } - - self.last_position = span.end(); - } - } - - fn visit_expr(&mut self, expr: Expression) { - let span = expr.span; - - let rewrite = self.format_expr(expr); - self.push_rewrite(rewrite, span); - - self.last_position = span.end(); - } - - fn format_expr(&self, Expression { kind, span }: Expression) -> String { - match kind { - ExpressionKind::Block(block) => { - let mut visitor = FmtVisitor::new(self.source); - - visitor.block_indent = self.block_indent; - visitor.visit_block(block, span, true); - - visitor.buffer - } - ExpressionKind::Prefix(prefix) => { - format!("{}{}", prefix.operator, self.format_expr(prefix.rhs)) - } - // TODO: - _expr => slice!(self, span.start(), span.end()).to_string(), - } - } - fn format_missing(&mut self, end: u32) { self.format_missing_inner(end, |this, slice, _| this.push_str(slice)); } @@ -201,7 +104,7 @@ impl<'a> FmtVisitor<'a> { } } - fn rewrite_fn_before_block(&self, func: NoirFunction, start: u32) -> (String, bool) { + fn format_fn_before_block(&self, func: NoirFunction, start: u32) -> (String, bool) { let slice = slice!(self, start, func.span().start()); let force_brace_newline = slice.contains("//"); (slice.trim_end().to_string(), force_brace_newline) diff --git a/tooling/nargo_fmt/src/visitor/expr.rs b/tooling/nargo_fmt/src/visitor/expr.rs new file mode 100644 index 00000000000..f7ed4dd538f --- /dev/null +++ b/tooling/nargo_fmt/src/visitor/expr.rs @@ -0,0 +1,77 @@ +use noirc_frontend::{hir::resolution::errors::Span, BlockExpression, Expression, ExpressionKind}; + +use super::FmtVisitor; + +impl FmtVisitor<'_> { + pub(crate) fn visit_expr(&mut self, expr: Expression) { + let span = expr.span; + + let rewrite = self.format_expr(expr); + self.push_rewrite(rewrite, span); + + self.last_position = span.end(); + } + + fn format_expr(&self, Expression { kind, span }: Expression) -> String { + match kind { + ExpressionKind::Block(block) => { + let mut visitor = FmtVisitor::new(self.source); + + visitor.block_indent = self.block_indent; + visitor.visit_block(block, span, true); + + visitor.buffer + } + ExpressionKind::Prefix(prefix) => { + format!("{}{}", prefix.operator, self.format_expr(prefix.rhs)) + } + // TODO: + _expr => slice!(self, span.start(), span.end()).to_string(), + } + } + + pub(crate) fn visit_block( + &mut self, + block: BlockExpression, + block_span: Span, + should_indent: bool, + ) { + if block.is_empty() { + self.visit_empty_block(block_span, should_indent); + return; + } + + self.last_position = block_span.start() + 1; // `{` + self.push_str("{"); + + self.with_indent(|this| { + this.visit_stmts(block.0); + }); + self.last_position = block_span.end(); + + self.push_str("\n"); + if should_indent { + self.push_str(&self.block_indent.to_string()); + } + self.push_str("}"); + } + + fn visit_empty_block(&mut self, block_span: Span, should_indent: bool) { + let slice = slice!(self, block_span.start(), block_span.end()); + let comment_str = slice[1..slice.len() - 1].trim(); + let block_str = if comment_str.is_empty() { + "{}".to_string() + } else { + self.block_indent.block_indent(&self.config); + let open_indent = self.block_indent.to_string(); + self.block_indent.block_unindent(&self.config); + let close_indent = + if should_indent { self.block_indent.to_string() } else { String::new() }; + + let ret = format!("{{\n{open_indent}{comment_str}\n{close_indent}}}"); + ret + }; + self.last_position = block_span.end(); + self.push_str(&block_str); + } +} diff --git a/tooling/nargo_fmt/src/visitor/item.rs b/tooling/nargo_fmt/src/visitor/item.rs new file mode 100644 index 00000000000..f9d2c76cdee --- /dev/null +++ b/tooling/nargo_fmt/src/visitor/item.rs @@ -0,0 +1,27 @@ +use noirc_frontend::{ + parser::{Item, ItemKind}, + ParsedModule, +}; + +impl super::FmtVisitor<'_> { + pub(crate) fn visit_module(&mut self, module: ParsedModule) { + for Item { kind, span } in module.items { + match kind { + ItemKind::Function(func) => { + let (fn_before_block, force_brace_newline) = + self.format_fn_before_block(func.clone(), span.start()); + + self.format_missing_indent(span.start(), false); + + self.push_str(&fn_before_block); + self.push_str(if force_brace_newline { "\n" } else { " " }); + + self.visit_block(func.def.body, func.def.span, false); + } + _ => self.format_missing(span.end()), + } + } + + self.format_missing_indent(self.source.len() as u32, false); + } +} diff --git a/tooling/nargo_fmt/src/visitor/stmt.rs b/tooling/nargo_fmt/src/visitor/stmt.rs new file mode 100644 index 00000000000..973167fd19a --- /dev/null +++ b/tooling/nargo_fmt/src/visitor/stmt.rs @@ -0,0 +1,19 @@ +use noirc_frontend::{Statement, StatementKind}; + +impl super::FmtVisitor<'_> { + pub(crate) fn visit_stmts(&mut self, stmts: Vec) { + for Statement { kind, span } in stmts { + match kind { + StatementKind::Expression(expr) => self.visit_expr(expr), + StatementKind::Semi(expr) => { + self.visit_expr(expr); + self.push_str(";"); + } + StatementKind::Error => unreachable!(), + _ => self.format_missing(span.end()), + } + + self.last_position = span.end(); + } + } +} diff --git a/tooling/nargo_fmt/tests/expected/add.nr b/tooling/nargo_fmt/tests/expected/add.nr new file mode 100644 index 00000000000..6f2892942c1 --- /dev/null +++ b/tooling/nargo_fmt/tests/expected/add.nr @@ -0,0 +1,7 @@ +fn main(mut x: u32, y: u32, z: u32) { + x += y; + assert(x == z); + + x *= 8; + assert(x>9); +} diff --git a/tooling/nargo_fmt/tests/expected/comment.nr b/tooling/nargo_fmt/tests/expected/comment.nr index 9acc56b1f3e..1a7c41b0b0c 100644 --- a/tooling/nargo_fmt/tests/expected/comment.nr +++ b/tooling/nargo_fmt/tests/expected/comment.nr @@ -1,10 +1,10 @@ fn comment1() { -// + // } // random comment fn comment2() { -// Test + // Test } fn comment3() // some comment {} diff --git a/tooling/nargo_fmt/tests/expected/expr.nr b/tooling/nargo_fmt/tests/expected/expr.nr index d8920940e8f..8435ba4ace7 100644 --- a/tooling/nargo_fmt/tests/expected/expr.nr +++ b/tooling/nargo_fmt/tests/expected/expr.nr @@ -2,11 +2,18 @@ fn qux() { {} { - /* a block with a comment */ + /* a block with a comment */ } {} { - // A block with a comment. + // A block with a comment. + } + { + { + { + // A block with a comment. + } + } } } fn foo_return() { @@ -31,5 +38,13 @@ fn comment() { 1 } fn only_comment() { + // Keep this here +} +fn only_comments() { + // Keep this here // Keep this here } +fn only_comments() { + // Keep this here + // Keep this here +} diff --git a/tooling/nargo_fmt/tests/expected/module.nr b/tooling/nargo_fmt/tests/expected/module.nr new file mode 100644 index 00000000000..e419543dbc4 --- /dev/null +++ b/tooling/nargo_fmt/tests/expected/module.nr @@ -0,0 +1,23 @@ +mod a { + mod b { + struct Data { + a: Field + } + } + + fn data(a: Field) -> Data { + Data { a } + } + + fn data2(a: Field) -> Data2 { + Data2 { a } + } + + mod tests { + #[test] + fn test() { + data(1); + data2(1); + } + } +} diff --git a/tooling/nargo_fmt/tests/input/add.nr b/tooling/nargo_fmt/tests/input/add.nr new file mode 100644 index 00000000000..6f2892942c1 --- /dev/null +++ b/tooling/nargo_fmt/tests/input/add.nr @@ -0,0 +1,7 @@ +fn main(mut x: u32, y: u32, z: u32) { + x += y; + assert(x == z); + + x *= 8; + assert(x>9); +} diff --git a/tooling/nargo_fmt/tests/input/expr.nr b/tooling/nargo_fmt/tests/input/expr.nr index 3e86be5a418..6417264dfcd 100644 --- a/tooling/nargo_fmt/tests/input/expr.nr +++ b/tooling/nargo_fmt/tests/input/expr.nr @@ -9,6 +9,14 @@ fn qux() { { // A block with a comment. } + + { + { + { + // A block with a comment. + } + } + } } fn foo_return() { @@ -39,3 +47,13 @@ fn comment() { fn only_comment() { // Keep this here } + +fn only_comments() { +// Keep this here +// Keep this here +} + +fn only_comments() { + // Keep this here + // Keep this here +} diff --git a/tooling/nargo_fmt/tests/input/module.nr b/tooling/nargo_fmt/tests/input/module.nr new file mode 100644 index 00000000000..e419543dbc4 --- /dev/null +++ b/tooling/nargo_fmt/tests/input/module.nr @@ -0,0 +1,23 @@ +mod a { + mod b { + struct Data { + a: Field + } + } + + fn data(a: Field) -> Data { + Data { a } + } + + fn data2(a: Field) -> Data2 { + Data2 { a } + } + + mod tests { + #[test] + fn test() { + data(1); + data2(1); + } + } +} From e64406d7d8ac443a56a59cdec61e9f9c5c10dc26 Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Thu, 28 Sep 2023 12:34:58 +0000 Subject: [PATCH 26/42] update Cargo.lock --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 62452a9b7a1..9da16af1ea2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2303,7 +2303,7 @@ dependencies = [ [[package]] name = "nargo_fmt" -version = "0.14.0" +version = "0.14.1" dependencies = [ "noirc_frontend", "readonly", From 7cf0dc98fee5faba6651f4b850f0b13329e31edf Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Thu, 28 Sep 2023 14:16:34 +0000 Subject: [PATCH 27/42] rework `nargo fmt` --- tooling/nargo_cli/src/cli/fmt_cmd.rs | 50 +++++++++++++++++++--------- tooling/nargo_fmt/src/lib.rs | 21 +++++------- 2 files changed, 43 insertions(+), 28 deletions(-) diff --git a/tooling/nargo_cli/src/cli/fmt_cmd.rs b/tooling/nargo_cli/src/cli/fmt_cmd.rs index 6bb91047afd..b3a9b65c8a7 100644 --- a/tooling/nargo_cli/src/cli/fmt_cmd.rs +++ b/tooling/nargo_cli/src/cli/fmt_cmd.rs @@ -1,7 +1,12 @@ use std::path::{Path, PathBuf}; use clap::Args; -use nargo_toml::find_package_root; +use fm::FileManager; +use nargo_toml::{ + find_package_root, get_package_manifest, resolve_workspace_from_toml, PackageSelection, +}; +use noirc_errors::CustomDiagnostic; +use noirc_frontend::hir::def_map::parse_file; use crate::errors::CliError; @@ -11,24 +16,37 @@ use super::NargoConfig; pub(crate) struct FormatCommand {} pub(crate) fn run(_args: FormatCommand, config: NargoConfig) -> Result<(), CliError> { - let files = { - let package = find_package_root(&config.program_dir)?; - read_files(&package.join("src")).map_err(|error| CliError::Generic(error.to_string()))? - }; - - for file in files { - let source = - std::fs::read_to_string(&file).map_err(|error| CliError::Generic(error.to_string()))?; - - let source = match nargo_fmt::format(&source) { - Ok(t) => t, - Err(errors) => { - println!("{errors:?}"); + let toml_path = get_package_manifest(&config.program_dir)?; + let workspace = resolve_workspace_from_toml(&toml_path, PackageSelection::All)?; + + for package in &workspace { + let files = { + let package = find_package_root(&package.root_dir)?; + read_files(&package.join("src")) + .map_err(|error| CliError::Generic(error.to_string()))? + }; + + let mut file_manager = FileManager::new(&package.root_dir); + for file in files { + let file_id = file_manager.add_file(&file).expect("file exists"); + let (parsed_module, errors) = parse_file(&file_manager, file_id); + + if !errors.is_empty() { + let errors = errors + .into_iter() + .map(|error| { + let error: CustomDiagnostic = error.into(); + error.in_file(file_id) + }) + .collect(); + let _ = super::compile_cmd::report_errors::<()>(Err(errors), &file_manager, false); continue; } - }; - std::fs::write(file, source).map_err(|error| CliError::Generic(error.to_string()))?; + let source = + nargo_fmt::format(file_manager.fetch_file(file_id).source(), parsed_module); + std::fs::write(file, source).map_err(|error| CliError::Generic(error.to_string()))?; + } } Ok(()) diff --git a/tooling/nargo_fmt/src/lib.rs b/tooling/nargo_fmt/src/lib.rs index c12428e4d1d..7b53118e156 100644 --- a/tooling/nargo_fmt/src/lib.rs +++ b/tooling/nargo_fmt/src/lib.rs @@ -7,20 +7,13 @@ mod config; mod visitor; -use noirc_frontend::parser::ParserError; +use noirc_frontend::ParsedModule; use visitor::FmtVisitor; -pub fn format(source: &str) -> Result> { - let (module, errors) = noirc_frontend::parse_program(source); - - if !errors.is_empty() { - return Err(errors); - } - +pub fn format(source: &str, parsed_module: ParsedModule) -> String { let mut fmt = FmtVisitor::new(source); - fmt.visit_module(module); - - Ok(fmt.finish()) + fmt.visit_module(parsed_module); + fmt.finish() } #[cfg(test)] @@ -35,7 +28,11 @@ mod tests { let source_path = file.path(); let source = std::fs::read_to_string(&source_path).unwrap(); - let fmt_text = crate::format(&source).unwrap(); + + let (parsed_module, errors) = noirc_frontend::parse_program(&source); + let fmt_text = crate::format(&source, parsed_module); + + assert!(errors.is_empty()); let target_path: PathBuf = source_path .components() From 8e40bc68c9d71c0d70b86659435a82b1eafe6e04 Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Thu, 28 Sep 2023 17:01:52 +0000 Subject: [PATCH 28/42] rework newlines --- Cargo.lock | 7 +++++ tooling/nargo_fmt/Cargo.toml | 1 + tooling/nargo_fmt/src/visitor.rs | 31 +++++++++++++++++---- tooling/nargo_fmt/src/visitor/item.rs | 8 +++++- tooling/nargo_fmt/tests/expected/comment.nr | 6 ++++ tooling/nargo_fmt/tests/expected/expr.nr | 9 ++++++ tooling/nargo_fmt/tests/expected/print.nr | 1 + tooling/nargo_fmt/tests/expected/print2.nr | 1 + tooling/nargo_fmt/tests/expected/struct.nr | 2 ++ 9 files changed, 59 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9da16af1ea2..0c46f3d81f6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -634,6 +634,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "bytecount" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c676a478f63e9fa2dd5368a42f28bba0d6c560b775f38583c8bbaa7fcd67c9c" + [[package]] name = "bytemuck" version = "1.13.1" @@ -2305,6 +2311,7 @@ dependencies = [ name = "nargo_fmt" version = "0.14.1" dependencies = [ + "bytecount", "noirc_frontend", "readonly", ] diff --git a/tooling/nargo_fmt/Cargo.toml b/tooling/nargo_fmt/Cargo.toml index da77216c0ad..985da81fd67 100644 --- a/tooling/nargo_fmt/Cargo.toml +++ b/tooling/nargo_fmt/Cargo.toml @@ -6,5 +6,6 @@ edition.workspace = true license.workspace = true [dependencies] +bytecount = "0.6.3" noirc_frontend.workspace = true readonly = "0.2" diff --git a/tooling/nargo_fmt/src/visitor.rs b/tooling/nargo_fmt/src/visitor.rs index 9cd8e6a6329..466d82db415 100644 --- a/tooling/nargo_fmt/src/visitor.rs +++ b/tooling/nargo_fmt/src/visitor.rs @@ -10,7 +10,7 @@ mod expr; mod item; mod stmt; -use noirc_frontend::{hir::resolution::errors::Span, NoirFunction}; +use noirc_frontend::hir::resolution::errors::Span; use crate::config::Config; @@ -97,17 +97,36 @@ impl<'a> FmtVisitor<'a> { self.last_position = end; if slice.trim().is_empty() && !self.at_start() { - self.push_str("\n"); + self.push_vertical_spaces(slice); process_last_slice(self, "", slice); } else { process_last_slice(self, slice, slice); } } - fn format_fn_before_block(&self, func: NoirFunction, start: u32) -> (String, bool) { - let slice = slice!(self, start, func.span().start()); - let force_brace_newline = slice.contains("//"); - (slice.trim_end().to_string(), force_brace_newline) + fn push_vertical_spaces(&mut self, slice: &str) { + let newline_upper_bound = 2; + let newline_lower_bound = 1; + + let mut newline_count = bytecount::count(slice.as_bytes(), b'\n'); + let offset = self.buffer.chars().rev().take_while(|c| *c == '\n').count(); + + if newline_count + offset > newline_upper_bound { + if offset >= newline_upper_bound { + newline_count = 0; + } else { + newline_count = newline_upper_bound - offset; + } + } else if newline_count + offset < newline_lower_bound { + if offset >= newline_lower_bound { + newline_count = 0; + } else { + newline_count = newline_lower_bound - offset; + } + } + + let blank_lines = "\n".repeat(newline_count); + self.push_str(&blank_lines); } } diff --git a/tooling/nargo_fmt/src/visitor/item.rs b/tooling/nargo_fmt/src/visitor/item.rs index f9d2c76cdee..1e32ab22747 100644 --- a/tooling/nargo_fmt/src/visitor/item.rs +++ b/tooling/nargo_fmt/src/visitor/item.rs @@ -1,9 +1,15 @@ use noirc_frontend::{ parser::{Item, ItemKind}, - ParsedModule, + NoirFunction, ParsedModule, }; impl super::FmtVisitor<'_> { + fn format_fn_before_block(&self, func: NoirFunction, start: u32) -> (String, bool) { + let slice = slice!(self, start, func.span().start()); + let force_brace_newline = slice.contains("//"); + (slice.trim_end().to_string(), force_brace_newline) + } + pub(crate) fn visit_module(&mut self, module: ParsedModule) { for Item { kind, span } in module.items { match kind { diff --git a/tooling/nargo_fmt/tests/expected/comment.nr b/tooling/nargo_fmt/tests/expected/comment.nr index 1a7c41b0b0c..b6ac52a236a 100644 --- a/tooling/nargo_fmt/tests/expected/comment.nr +++ b/tooling/nargo_fmt/tests/expected/comment.nr @@ -6,16 +6,22 @@ fn comment1() { fn comment2() { // Test } + fn comment3() // some comment {} + fn comment4() // some comment {} + fn comment5() // some comment {} + fn comment6() // some comment some comment some comment some comment some comment some comment so {} + fn comment7() // some comment some comment some comment some comment some comment some comment some comment {} + fn comment8(/*test*/) {} diff --git a/tooling/nargo_fmt/tests/expected/expr.nr b/tooling/nargo_fmt/tests/expected/expr.nr index 8435ba4ace7..cce0b396f6a 100644 --- a/tooling/nargo_fmt/tests/expected/expr.nr +++ b/tooling/nargo_fmt/tests/expected/expr.nr @@ -1,6 +1,7 @@ // Test some empty blocks. fn qux() { {} + { /* a block with a comment */ } @@ -8,6 +9,7 @@ fn qux() { { // A block with a comment. } + { { { @@ -16,14 +18,17 @@ fn qux() { } } } + fn foo_return() { "yay" } + fn fooblock() { { "inner-block" } } + fn fooblock() { { { @@ -33,17 +38,21 @@ fn fooblock() { } } } + fn comment() { // this is a test comment 1 } + fn only_comment() { // Keep this here } + fn only_comments() { // Keep this here // Keep this here } + fn only_comments() { // Keep this here // Keep this here diff --git a/tooling/nargo_fmt/tests/expected/print.nr b/tooling/nargo_fmt/tests/expected/print.nr index 3fbd305306d..e169f565455 100644 --- a/tooling/nargo_fmt/tests/expected/print.nr +++ b/tooling/nargo_fmt/tests/expected/print.nr @@ -1,4 +1,5 @@ use dep::std; + fn main() { std::println("Hello world"); } diff --git a/tooling/nargo_fmt/tests/expected/print2.nr b/tooling/nargo_fmt/tests/expected/print2.nr index adeed82d5e9..80284444af8 100644 --- a/tooling/nargo_fmt/tests/expected/print2.nr +++ b/tooling/nargo_fmt/tests/expected/print2.nr @@ -1,4 +1,5 @@ use dep::std; + fn main( ) { std::println("Hello world"); } diff --git a/tooling/nargo_fmt/tests/expected/struct.nr b/tooling/nargo_fmt/tests/expected/struct.nr index c2b50ded890..5e3530e8364 100644 --- a/tooling/nargo_fmt/tests/expected/struct.nr +++ b/tooling/nargo_fmt/tests/expected/struct.nr @@ -46,10 +46,12 @@ struct Animal { legs: Field, eyes: u8, } + fn get_dog() -> Animal { let dog = Animal { legs: 4, eyes: 2 }; dog } + fn main(x: Field, y: Field) { let first = Foo::default(x,y); let p = Pair { first, second: 1 }; From b255896ba495c20ec08d83ced8b587e326b724cc Mon Sep 17 00:00:00 2001 From: kek kek kek Date: Thu, 28 Sep 2023 18:25:05 +0000 Subject: [PATCH 29/42] fix buig --- tooling/nargo_fmt/src/visitor/expr.rs | 4 ++++ tooling/nargo_fmt/tests/expected/expr.nr | 5 +++++ tooling/nargo_fmt/tests/input/expr.nr | 5 +++++ 3 files changed, 14 insertions(+) diff --git a/tooling/nargo_fmt/src/visitor/expr.rs b/tooling/nargo_fmt/src/visitor/expr.rs index f7ed4dd538f..b021eed84a9 100644 --- a/tooling/nargo_fmt/src/visitor/expr.rs +++ b/tooling/nargo_fmt/src/visitor/expr.rs @@ -47,6 +47,10 @@ impl FmtVisitor<'_> { self.with_indent(|this| { this.visit_stmts(block.0); }); + + let slice = slice!(self, self.last_position, block_span.end() - 1).trim_end(); + self.push_str(slice); + self.last_position = block_span.end(); self.push_str("\n"); diff --git a/tooling/nargo_fmt/tests/expected/expr.nr b/tooling/nargo_fmt/tests/expected/expr.nr index cce0b396f6a..9497c4d831a 100644 --- a/tooling/nargo_fmt/tests/expected/expr.nr +++ b/tooling/nargo_fmt/tests/expected/expr.nr @@ -57,3 +57,8 @@ fn only_comments() { // Keep this here // Keep this here } + +fn commnet() { + 1 + // +} diff --git a/tooling/nargo_fmt/tests/input/expr.nr b/tooling/nargo_fmt/tests/input/expr.nr index 6417264dfcd..9e3e4a35e1a 100644 --- a/tooling/nargo_fmt/tests/input/expr.nr +++ b/tooling/nargo_fmt/tests/input/expr.nr @@ -57,3 +57,8 @@ fn only_comments() { // Keep this here // Keep this here } + +fn commnet() { + 1 + // +} \ No newline at end of file From 0864245f585b3b00bddd318cc2465c53dbe11f39 Mon Sep 17 00:00:00 2001 From: kek kek kek Date: Thu, 28 Sep 2023 18:32:43 +0000 Subject: [PATCH 30/42] cargo fmt --- tooling/nargo_fmt/src/visitor/expr.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tooling/nargo_fmt/src/visitor/expr.rs b/tooling/nargo_fmt/src/visitor/expr.rs index b021eed84a9..c49c41113fe 100644 --- a/tooling/nargo_fmt/src/visitor/expr.rs +++ b/tooling/nargo_fmt/src/visitor/expr.rs @@ -47,7 +47,7 @@ impl FmtVisitor<'_> { self.with_indent(|this| { this.visit_stmts(block.0); }); - + let slice = slice!(self, self.last_position, block_span.end() - 1).trim_end(); self.push_str(slice); From 4390d3c953c98fdee12b227d2d663742a6954a66 Mon Sep 17 00:00:00 2001 From: kek kek kek Date: Thu, 28 Sep 2023 18:43:34 +0000 Subject: [PATCH 31/42] ops... --- tooling/nargo_cli/src/cli/fmt_cmd.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/tooling/nargo_cli/src/cli/fmt_cmd.rs b/tooling/nargo_cli/src/cli/fmt_cmd.rs index b3a9b65c8a7..7c4e82ce2ac 100644 --- a/tooling/nargo_cli/src/cli/fmt_cmd.rs +++ b/tooling/nargo_cli/src/cli/fmt_cmd.rs @@ -2,9 +2,7 @@ use std::path::{Path, PathBuf}; use clap::Args; use fm::FileManager; -use nargo_toml::{ - find_package_root, get_package_manifest, resolve_workspace_from_toml, PackageSelection, -}; +use nargo_toml::{get_package_manifest, resolve_workspace_from_toml, PackageSelection}; use noirc_errors::CustomDiagnostic; use noirc_frontend::hir::def_map::parse_file; @@ -21,8 +19,7 @@ pub(crate) fn run(_args: FormatCommand, config: NargoConfig) -> Result<(), CliEr for package in &workspace { let files = { - let package = find_package_root(&package.root_dir)?; - read_files(&package.join("src")) + read_files(&package.root_dir.join("src")) .map_err(|error| CliError::Generic(error.to_string()))? }; From fe3d25ef74076aeff139a3604f516e81f150bfc0 Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Fri, 29 Sep 2023 11:41:40 +0000 Subject: [PATCH 32/42] load config from `noirfmt.toml` --- Cargo.lock | 14 +----- tooling/nargo_cli/src/cli/fmt_cmd.rs | 11 ++++- tooling/nargo_fmt/Cargo.toml | 3 +- tooling/nargo_fmt/src/config.rs | 65 ++++++++++++++++++++++----- tooling/nargo_fmt/src/lib.rs | 12 +++-- tooling/nargo_fmt/src/visitor.rs | 16 +++---- tooling/nargo_fmt/src/visitor/expr.rs | 6 +-- 7 files changed, 86 insertions(+), 41 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0c46f3d81f6..dde4b80cdd6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2313,7 +2313,8 @@ version = "0.14.1" dependencies = [ "bytecount", "noirc_frontend", - "readonly", + "serde", + "toml", ] [[package]] @@ -2938,17 +2939,6 @@ dependencies = [ "num_cpus", ] -[[package]] -name = "readonly" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8f439da1766942fe069954da6058b2e6c1760eb878bae76f5be9fc29f56f574" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.26", -] - [[package]] name = "redox_syscall" version = "0.2.16" diff --git a/tooling/nargo_cli/src/cli/fmt_cmd.rs b/tooling/nargo_cli/src/cli/fmt_cmd.rs index 7c4e82ce2ac..c6a47fd1def 100644 --- a/tooling/nargo_cli/src/cli/fmt_cmd.rs +++ b/tooling/nargo_cli/src/cli/fmt_cmd.rs @@ -17,6 +17,9 @@ pub(crate) fn run(_args: FormatCommand, config: NargoConfig) -> Result<(), CliEr let toml_path = get_package_manifest(&config.program_dir)?; let workspace = resolve_workspace_from_toml(&toml_path, PackageSelection::All)?; + let config = nargo_fmt::Config::read(&config.program_dir) + .map_err(|err| CliError::Generic(err.to_string()))?; + for package in &workspace { let files = { read_files(&package.root_dir.join("src")) @@ -40,8 +43,12 @@ pub(crate) fn run(_args: FormatCommand, config: NargoConfig) -> Result<(), CliEr continue; } - let source = - nargo_fmt::format(file_manager.fetch_file(file_id).source(), parsed_module); + let source = nargo_fmt::format( + file_manager.fetch_file(file_id).source(), + parsed_module, + &config, + ); + std::fs::write(file, source).map_err(|error| CliError::Generic(error.to_string()))?; } } diff --git a/tooling/nargo_fmt/Cargo.toml b/tooling/nargo_fmt/Cargo.toml index 985da81fd67..c3317eb8794 100644 --- a/tooling/nargo_fmt/Cargo.toml +++ b/tooling/nargo_fmt/Cargo.toml @@ -8,4 +8,5 @@ license.workspace = true [dependencies] bytecount = "0.6.3" noirc_frontend.workspace = true -readonly = "0.2" +serde.workspace = true +toml.workspace = true diff --git a/tooling/nargo_fmt/src/config.rs b/tooling/nargo_fmt/src/config.rs index eb9b2915d26..52afdeb3d1a 100644 --- a/tooling/nargo_fmt/src/config.rs +++ b/tooling/nargo_fmt/src/config.rs @@ -1,16 +1,57 @@ -#[allow(unreachable_pub)] -#[readonly::make] -pub(crate) struct Config { - /// Maximum width of each line. - #[readonly] - pub max_width: usize, - /// Number of spaces per tab. - #[readonly] - pub tab_spaces: usize, +use std::path::Path; + +macro_rules! config { + ($($field_name:ident: $field_ty:ty, $default_value:expr, $description:expr );+ $(;)*) => ( + pub struct Config { + $( + #[doc = $description] + pub $field_name: $field_ty + ),+ + } + + impl Config { + pub fn fill_from_toml(&mut self, toml: TomlConfig) { + $( + if let Some(value) = toml.$field_name { + self.$field_name = value; + } + )+ + } + } + + impl Default for Config { + fn default() -> Self { + Self { + $( + $field_name: $default_value, + )+ + } + } + } + + #[derive(serde::Deserialize, serde::Serialize, Clone)] + pub struct TomlConfig { + $(pub $field_name: Option<$field_ty>),+ + } + ) } -impl Default for Config { - fn default() -> Self { - Self { max_width: 100, tab_spaces: 4 } +config! { + tab_spaces: usize, 4, "Number of spaces per tab"; +} + +impl Config { + pub fn read(path: &Path) -> Result { + let mut config = Self::default(); + + let raw_toml = match std::fs::read_to_string(path.join("noirfmt.toml")) { + Ok(t) => t, + Err(err) if err.kind() == std::io::ErrorKind::NotFound => String::new(), + Err(err) => return Err(err), + }; + let toml = toml::from_str(&raw_toml).expect("TODO: error hadling"); + + config.fill_from_toml(toml); + Ok(config) } } diff --git a/tooling/nargo_fmt/src/lib.rs b/tooling/nargo_fmt/src/lib.rs index 7b53118e156..8e5d1687876 100644 --- a/tooling/nargo_fmt/src/lib.rs +++ b/tooling/nargo_fmt/src/lib.rs @@ -10,8 +10,10 @@ mod visitor; use noirc_frontend::ParsedModule; use visitor::FmtVisitor; -pub fn format(source: &str, parsed_module: ParsedModule) -> String { - let mut fmt = FmtVisitor::new(source); +pub use config::Config; + +pub fn format(source: &str, parsed_module: ParsedModule, config: &Config) -> String { + let mut fmt = FmtVisitor::new(source, config); fmt.visit_module(parsed_module); fmt.finish() } @@ -20,17 +22,21 @@ pub fn format(source: &str, parsed_module: ParsedModule) -> String { mod tests { use std::{ffi::OsStr, path::PathBuf}; + use crate::Config; + #[test] fn test() { let files = std::fs::read_dir("tests/input").unwrap(); for file in files { let file = file.unwrap(); + let config = Config::default(); + let source_path = file.path(); let source = std::fs::read_to_string(&source_path).unwrap(); let (parsed_module, errors) = noirc_frontend::parse_program(&source); - let fmt_text = crate::format(&source, parsed_module); + let fmt_text = crate::format(&source, parsed_module, &config); assert!(errors.is_empty()); diff --git a/tooling/nargo_fmt/src/visitor.rs b/tooling/nargo_fmt/src/visitor.rs index 466d82db415..cf2b4d9adfd 100644 --- a/tooling/nargo_fmt/src/visitor.rs +++ b/tooling/nargo_fmt/src/visitor.rs @@ -14,19 +14,19 @@ use noirc_frontend::hir::resolution::errors::Span; use crate::config::Config; -pub(crate) struct FmtVisitor<'a> { - config: Config, +pub(crate) struct FmtVisitor<'me> { + config: &'me Config, buffer: String, - source: &'a str, + source: &'me str, block_indent: Indent, last_position: u32, } -impl<'a> FmtVisitor<'a> { - pub(crate) fn new(source: &'a str) -> Self { +impl<'me> FmtVisitor<'me> { + pub(crate) fn new(source: &'me str, config: &'me Config) -> Self { Self { - config: Config::default(), buffer: String::new(), + config, source, last_position: 0, block_indent: Indent { block_indent: 0 }, @@ -38,9 +38,9 @@ impl<'a> FmtVisitor<'a> { } fn with_indent(&mut self, f: impl FnOnce(&mut Self) -> T) -> T { - self.block_indent.block_indent(&self.config); + self.block_indent.block_indent(self.config); let ret = f(self); - self.block_indent.block_unindent(&self.config); + self.block_indent.block_unindent(self.config); ret } diff --git a/tooling/nargo_fmt/src/visitor/expr.rs b/tooling/nargo_fmt/src/visitor/expr.rs index c49c41113fe..a0128042e1d 100644 --- a/tooling/nargo_fmt/src/visitor/expr.rs +++ b/tooling/nargo_fmt/src/visitor/expr.rs @@ -15,7 +15,7 @@ impl FmtVisitor<'_> { fn format_expr(&self, Expression { kind, span }: Expression) -> String { match kind { ExpressionKind::Block(block) => { - let mut visitor = FmtVisitor::new(self.source); + let mut visitor = FmtVisitor::new(self.source, self.config); visitor.block_indent = self.block_indent; visitor.visit_block(block, span, true); @@ -66,9 +66,9 @@ impl FmtVisitor<'_> { let block_str = if comment_str.is_empty() { "{}".to_string() } else { - self.block_indent.block_indent(&self.config); + self.block_indent.block_indent(self.config); let open_indent = self.block_indent.to_string(); - self.block_indent.block_unindent(&self.config); + self.block_indent.block_unindent(self.config); let close_indent = if should_indent { self.block_indent.to_string() } else { String::new() }; From f391ae5621cd8bdfce51b26f6d14a5e1a7977d33 Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Fri, 29 Sep 2023 12:00:25 +0000 Subject: [PATCH 33/42] update `Cargo.lock` --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index c3cc5aa23c1..b75c487bb31 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2308,7 +2308,7 @@ dependencies = [ [[package]] name = "nargo_fmt" -version = "0.14.1" +version = "0.15.0" dependencies = [ "bytecount", "noirc_frontend", From 6206edf5e6bb9097e3b3a414e05572cc3aa44b41 Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Sun, 1 Oct 2023 13:14:33 +0000 Subject: [PATCH 34/42] avoid alloc vec --- tooling/nargo_cli/src/cli/fmt_cmd.rs | 47 +++++++++++++--------------- 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/tooling/nargo_cli/src/cli/fmt_cmd.rs b/tooling/nargo_cli/src/cli/fmt_cmd.rs index c6a47fd1def..b1cc976e533 100644 --- a/tooling/nargo_cli/src/cli/fmt_cmd.rs +++ b/tooling/nargo_cli/src/cli/fmt_cmd.rs @@ -1,4 +1,4 @@ -use std::path::{Path, PathBuf}; +use std::{fs::DirEntry, path::Path}; use clap::Args; use fm::FileManager; @@ -21,14 +21,10 @@ pub(crate) fn run(_args: FormatCommand, config: NargoConfig) -> Result<(), CliEr .map_err(|err| CliError::Generic(err.to_string()))?; for package in &workspace { - let files = { - read_files(&package.root_dir.join("src")) - .map_err(|error| CliError::Generic(error.to_string()))? - }; - let mut file_manager = FileManager::new(&package.root_dir); - for file in files { - let file_id = file_manager.add_file(&file).expect("file exists"); + + visit_noir_files(&package.root_dir.join("src"), &mut |entry| { + let file_id = file_manager.add_file(&entry.path()).expect("file exists"); let (parsed_module, errors) = parse_file(&file_manager, file_id); if !errors.is_empty() { @@ -39,8 +35,9 @@ pub(crate) fn run(_args: FormatCommand, config: NargoConfig) -> Result<(), CliEr error.in_file(file_id) }) .collect(); + let _ = super::compile_cmd::report_errors::<()>(Err(errors), &file_manager, false); - continue; + return Ok(()); } let source = nargo_fmt::format( @@ -49,29 +46,27 @@ pub(crate) fn run(_args: FormatCommand, config: NargoConfig) -> Result<(), CliEr &config, ); - std::fs::write(file, source).map_err(|error| CliError::Generic(error.to_string()))?; - } + std::fs::write(entry.path(), source) + }) + .map_err(|error| CliError::Generic(error.to_string()))?; } - Ok(()) } -fn read_files(path: &Path) -> color_eyre::Result> { - let mut files = vec![]; - - if path.is_dir() { - let entries = std::fs::read_dir(path)?; - - for entry in entries { - let path = entry?.path(); - +fn visit_noir_files( + dir: &Path, + cb: &mut dyn FnMut(&DirEntry) -> std::io::Result<()>, +) -> std::io::Result<()> { + if dir.is_dir() { + for entry in std::fs::read_dir(dir)? { + let entry = entry?; + let path = entry.path(); if path.is_dir() { - files.append(&mut read_files(&path)?); - } else if path.extension().map_or(false, |extension| extension == "nr") { - files.push(path); + visit_noir_files(&path, cb)?; + } else if entry.path().extension().map_or(false, |extension| extension == "nr") { + cb(&entry)?; } } } - - Ok(files) + Ok(()) } From df1d042f35b7b52b9efbec7ad2ef14fa71a1943b Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Sun, 1 Oct 2023 13:39:05 +0000 Subject: [PATCH 35/42] better error handling --- Cargo.lock | 1 + tooling/nargo_fmt/Cargo.toml | 1 + tooling/nargo_fmt/src/config.rs | 11 +++++++---- tooling/nargo_fmt/src/errors.rs | 12 ++++++++++++ tooling/nargo_fmt/src/lib.rs | 1 + 5 files changed, 22 insertions(+), 4 deletions(-) create mode 100644 tooling/nargo_fmt/src/errors.rs diff --git a/Cargo.lock b/Cargo.lock index b75c487bb31..8680f422e07 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2313,6 +2313,7 @@ dependencies = [ "bytecount", "noirc_frontend", "serde", + "thiserror", "toml", ] diff --git a/tooling/nargo_fmt/Cargo.toml b/tooling/nargo_fmt/Cargo.toml index c3317eb8794..4b034ec7e3e 100644 --- a/tooling/nargo_fmt/Cargo.toml +++ b/tooling/nargo_fmt/Cargo.toml @@ -10,3 +10,4 @@ bytecount = "0.6.3" noirc_frontend.workspace = true serde.workspace = true toml.workspace = true +thiserror.workspace = true diff --git a/tooling/nargo_fmt/src/config.rs b/tooling/nargo_fmt/src/config.rs index 52afdeb3d1a..2d76c567e8c 100644 --- a/tooling/nargo_fmt/src/config.rs +++ b/tooling/nargo_fmt/src/config.rs @@ -1,5 +1,7 @@ use std::path::Path; +use crate::errors::ConfigError; + macro_rules! config { ($($field_name:ident: $field_ty:ty, $default_value:expr, $description:expr );+ $(;)*) => ( pub struct Config { @@ -41,15 +43,16 @@ config! { } impl Config { - pub fn read(path: &Path) -> Result { + pub fn read(path: &Path) -> Result { let mut config = Self::default(); + let config_path = path.join("noirfmt.toml"); - let raw_toml = match std::fs::read_to_string(path.join("noirfmt.toml")) { + let raw_toml = match std::fs::read_to_string(&config_path) { Ok(t) => t, Err(err) if err.kind() == std::io::ErrorKind::NotFound => String::new(), - Err(err) => return Err(err), + Err(cause) => return Err(ConfigError::ReadFailed(config_path, cause)), }; - let toml = toml::from_str(&raw_toml).expect("TODO: error hadling"); + let toml = toml::from_str(&raw_toml).map_err(ConfigError::MalformedFile)?; config.fill_from_toml(toml); Ok(config) diff --git a/tooling/nargo_fmt/src/errors.rs b/tooling/nargo_fmt/src/errors.rs new file mode 100644 index 00000000000..e0a1758ae0f --- /dev/null +++ b/tooling/nargo_fmt/src/errors.rs @@ -0,0 +1,12 @@ +use std::path::PathBuf; + +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum ConfigError { + #[error("Cannot read file {0} - {1}")] + ReadFailed(PathBuf, std::io::Error), + + #[error("noirfmt.toml is badly formed, could not parse.\n\n {0}")] + MalformedFile(#[from] toml::de::Error), +} diff --git a/tooling/nargo_fmt/src/lib.rs b/tooling/nargo_fmt/src/lib.rs index 8e5d1687876..d17b5cf9133 100644 --- a/tooling/nargo_fmt/src/lib.rs +++ b/tooling/nargo_fmt/src/lib.rs @@ -5,6 +5,7 @@ #![warn(unused_qualifications, clippy::use_self)] mod config; +pub mod errors; mod visitor; use noirc_frontend::ParsedModule; From b23b7634c8e238728bb6ad0372d1d5cd5f86eb48 Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Sun, 1 Oct 2023 14:12:18 +0000 Subject: [PATCH 36/42] fix --- tooling/nargo_cli/src/cli/fmt_cmd.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tooling/nargo_cli/src/cli/fmt_cmd.rs b/tooling/nargo_cli/src/cli/fmt_cmd.rs index b1cc976e533..bfe0b1948ad 100644 --- a/tooling/nargo_cli/src/cli/fmt_cmd.rs +++ b/tooling/nargo_cli/src/cli/fmt_cmd.rs @@ -21,7 +21,8 @@ pub(crate) fn run(_args: FormatCommand, config: NargoConfig) -> Result<(), CliEr .map_err(|err| CliError::Generic(err.to_string()))?; for package in &workspace { - let mut file_manager = FileManager::new(&package.root_dir); + let mut file_manager = + FileManager::new(&package.root_dir, Box::new(|path| std::fs::read_to_string(path))); visit_noir_files(&package.root_dir.join("src"), &mut |entry| { let file_id = file_manager.add_file(&entry.path()).expect("file exists"); From fbe2a6b51345ed01d0c775b1cf2fd10087a83412 Mon Sep 17 00:00:00 2001 From: kek kek kek Date: Tue, 3 Oct 2023 06:29:26 -0700 Subject: [PATCH 37/42] remove into_unorder Co-authored-by: kevaundray --- compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs index 11047117f20..98b7d690b0a 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs @@ -461,7 +461,6 @@ impl<'a> ModCollector<'a> { context.visited_files.insert(child_file_id, location); // Parse the AST for the module we just found and then recursively look for it's defs - //let ast = parse_file(&context.file_manager, child_file_id, errors).into_unorder(); let (ast, parsing_errors) = parse_file(&context.file_manager, child_file_id); let ast = ast.into_unorder(); From 4115d07484dba51054aa9775238572d7fa40cfcf Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Thu, 5 Oct 2023 09:26:47 +0000 Subject: [PATCH 38/42] `Unordered` -> `SortedModule` --- .../src/hir/def_collector/dc_crate.rs | 4 +-- .../src/hir/def_collector/dc_mod.rs | 8 +++--- .../noirc_frontend/src/hir/def_map/mod.rs | 2 +- .../src/hir/resolution/resolver.rs | 4 +-- .../noirc_frontend/src/hir/type_check/mod.rs | 2 +- compiler/noirc_frontend/src/parser/mod.rs | 26 +++++++++---------- 6 files changed, 23 insertions(+), 23 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs index 4444ab3f35c..ea8ada25cab 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -17,7 +17,7 @@ use crate::node_interner::{ FuncId, NodeInterner, StmtId, StructId, TraitId, TraitImplKey, TypeAliasId, }; -use crate::parser::{ParserError, UnorderParsedModule}; +use crate::parser::{ParserError, SortedModule}; use crate::{ ExpressionKind, Generics, Ident, LetStatement, Literal, NoirFunction, NoirStruct, NoirTrait, NoirTypeAlias, Path, Shared, StructType, TraitItem, Type, TypeBinding, TypeVariableKind, @@ -193,7 +193,7 @@ impl DefCollector { pub fn collect( mut def_map: CrateDefMap, context: &mut Context, - ast: UnorderParsedModule, + ast: SortedModule, root_file_id: FileId, ) -> Vec<(CompilationError, FileId)> { let mut errors: Vec<(CompilationError, FileId)> = vec![]; diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs index 98b7d690b0a..b093a01a342 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs @@ -7,7 +7,7 @@ use crate::{ graph::CrateId, hir::def_collector::dc_crate::{UnresolvedStruct, UnresolvedTrait}, node_interner::TraitId, - parser::{SubModule, UnorderParsedModule}, + parser::{SubModule, SortedModule}, FunctionDefinition, Ident, LetStatement, NoirFunction, NoirStruct, NoirTrait, NoirTraitImpl, NoirTypeAlias, TraitImplItem, TraitItem, TypeImpl, }; @@ -35,7 +35,7 @@ struct ModCollector<'a> { /// This performs the entirety of the definition collection phase of the name resolution pass. pub fn collect_defs( def_collector: &mut DefCollector, - ast: UnorderParsedModule, + ast: SortedModule, file_id: FileId, module_id: LocalModuleId, crate_id: CrateId, @@ -404,7 +404,7 @@ impl<'a> ModCollector<'a> { Ok(child) => { errors.extend(collect_defs( self.def_collector, - submodule.contents.into_unorder(), + submodule.contents.into_sorted(), file_id, child, crate_id, @@ -462,7 +462,7 @@ impl<'a> ModCollector<'a> { // Parse the AST for the module we just found and then recursively look for it's defs let (ast, parsing_errors) = parse_file(&context.file_manager, child_file_id); - let ast = ast.into_unorder(); + let ast = ast.into_sorted(); errors.extend( parsing_errors.iter().map(|e| (e.clone().into(), child_file_id)).collect::>(), diff --git a/compiler/noirc_frontend/src/hir/def_map/mod.rs b/compiler/noirc_frontend/src/hir/def_map/mod.rs index 322fc6db1c5..dd98dfb4335 100644 --- a/compiler/noirc_frontend/src/hir/def_map/mod.rs +++ b/compiler/noirc_frontend/src/hir/def_map/mod.rs @@ -86,7 +86,7 @@ impl CrateDefMap { // First parse the root file. let root_file_id = context.crate_graph[crate_id].root_file_id; let (ast, parsing_errors) = parse_file(&context.file_manager, root_file_id); - let ast = ast.into_unorder(); + let ast = ast.into_sorted(); #[cfg(feature = "aztec")] let ast = match aztec_library::transform(ast, &crate_id, context) { diff --git a/compiler/noirc_frontend/src/hir/resolution/resolver.rs b/compiler/noirc_frontend/src/hir/resolution/resolver.rs index 56269f398b0..3af3ddd2363 100644 --- a/compiler/noirc_frontend/src/hir/resolution/resolver.rs +++ b/compiler/noirc_frontend/src/hir/resolution/resolver.rs @@ -1642,7 +1642,7 @@ mod test { } let mut errors = Vec::new(); - for func in program.into_unorder().functions { + for func in program.into_sorted().functions { let id = interner.push_test_function_definition(func.name().to_string()); let resolver = Resolver::new(&mut interner, &path_resolver, &def_maps, file); @@ -1658,7 +1658,7 @@ mod test { init_src_code_resolution(src); let mut all_captures: Vec> = Vec::new(); - for func in program.into_unorder().functions { + for func in program.into_sorted().functions { let name = func.name().to_string(); let id = interner.push_test_function_definition(name); path_resolver.insert_func(func.name().to_owned(), id); diff --git a/compiler/noirc_frontend/src/hir/type_check/mod.rs b/compiler/noirc_frontend/src/hir/type_check/mod.rs index 7a3e7972e06..0e288804f3f 100644 --- a/compiler/noirc_frontend/src/hir/type_check/mod.rs +++ b/compiler/noirc_frontend/src/hir/type_check/mod.rs @@ -446,7 +446,7 @@ mod test { }, ); - let func_meta = vecmap(program.into_unorder().functions, |nf| { + let func_meta = vecmap(program.into_sorted().functions, |nf| { let resolver = Resolver::new(&mut interner, &path_resolver, &def_maps, file); let (hir_func, func_meta, resolver_errors) = resolver.resolve_function(nf, main_id); assert_eq!(resolver_errors, vec![]); diff --git a/compiler/noirc_frontend/src/parser/mod.rs b/compiler/noirc_frontend/src/parser/mod.rs index 2b9b7eefb84..43bcace33d4 100644 --- a/compiler/noirc_frontend/src/parser/mod.rs +++ b/compiler/noirc_frontend/src/parser/mod.rs @@ -218,7 +218,7 @@ fn force<'a, T: 'a>(parser: impl NoirParser + 'a) -> impl NoirParser, pub functions: Vec, pub types: Vec, @@ -242,8 +242,8 @@ pub struct ParsedModule { } impl ParsedModule { - pub fn into_unorder(self) -> UnorderParsedModule { - let mut module = UnorderParsedModule::default(); + pub fn into_sorted(self) -> SortedModule { + let mut module = SortedModule::default(); for item in self.items { match item.kind { @@ -293,7 +293,7 @@ pub struct SubModule { pub is_contract: bool, } -impl UnorderParsedModule { +impl SortedModule { fn push_function(&mut self, func: NoirFunction) { self.functions.push(func); } @@ -539,37 +539,37 @@ impl std::fmt::Display for TopLevelStatement { impl std::fmt::Display for ParsedModule { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let legacy = self.clone().into_unorder(); + let module = self.clone().into_sorted(); - for decl in &legacy.module_decls { + for decl in &module.module_decls { writeln!(f, "mod {decl};")?; } - for import in &legacy.imports { + for import in &module.imports { write!(f, "{import}")?; } - for global_const in &legacy.globals { + for global_const in &module.globals { write!(f, "{global_const}")?; } - for type_ in &legacy.types { + for type_ in &module.types { write!(f, "{type_}")?; } - for function in &legacy.functions { + for function in &module.functions { write!(f, "{function}")?; } - for impl_ in &legacy.impls { + for impl_ in &module.impls { write!(f, "{impl_}")?; } - for type_alias in &legacy.type_aliases { + for type_alias in &module.type_aliases { write!(f, "{type_alias}")?; } - for submodule in &legacy.submodules { + for submodule in &module.submodules { write!(f, "{submodule}")?; } From 2df6b7c4a6a8076fe531767f731552c4ea9da3ff Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Thu, 5 Oct 2023 09:31:12 +0000 Subject: [PATCH 39/42] update `Cargo.lock` --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index e2d68688c79..87314665107 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2355,7 +2355,7 @@ dependencies = [ [[package]] name = "nargo_fmt" -version = "0.15.0" +version = "0.16.0" dependencies = [ "bytecount", "noirc_frontend", From bb0cd06a864bbf748aec95c61f181469454a94e1 Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Thu, 5 Oct 2023 10:22:26 +0000 Subject: [PATCH 40/42] `cargo fmt` --- compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs index 9af1849cef0..92c2e0fcebc 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs @@ -7,7 +7,7 @@ use crate::{ graph::CrateId, hir::def_collector::dc_crate::{UnresolvedStruct, UnresolvedTrait}, node_interner::TraitId, - parser::{SubModule, SortedModule}, + parser::{SortedModule, SubModule}, FunctionDefinition, Ident, LetStatement, NoirFunction, NoirStruct, NoirTrait, NoirTraitImpl, NoirTypeAlias, TraitImplItem, TraitItem, TypeImpl, }; From dc06112c0aa5a9d8a4fc0c38e45d71e162331415 Mon Sep 17 00:00:00 2001 From: kevaundray Date: Thu, 5 Oct 2023 12:25:32 +0100 Subject: [PATCH 41/42] Update tooling/nargo_cli/src/cli/mod.rs --- tooling/nargo_cli/src/cli/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tooling/nargo_cli/src/cli/mod.rs b/tooling/nargo_cli/src/cli/mod.rs index 54e60a505a3..9e832317331 100644 --- a/tooling/nargo_cli/src/cli/mod.rs +++ b/tooling/nargo_cli/src/cli/mod.rs @@ -53,6 +53,7 @@ pub(crate) struct NargoConfig { enum NargoCommand { Backend(backend_cmd::BackendCommand), Check(check_cmd::CheckCommand), + #[command(hide = true)] // Hidden while the feature has not been extensively tested Fmt(fmt_cmd::FormatCommand), CodegenVerifier(codegen_verifier_cmd::CodegenVerifierCommand), #[command(alias = "build")] From 62c0c98208ecec5126d6288fd15b1c123a4635c5 Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Thu, 5 Oct 2023 13:15:02 +0000 Subject: [PATCH 42/42] add docs --- tooling/nargo_fmt/src/lib.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tooling/nargo_fmt/src/lib.rs b/tooling/nargo_fmt/src/lib.rs index d17b5cf9133..754449aa425 100644 --- a/tooling/nargo_fmt/src/lib.rs +++ b/tooling/nargo_fmt/src/lib.rs @@ -4,6 +4,21 @@ #![warn(clippy::semicolon_if_nothing_returned)] #![warn(unused_qualifications, clippy::use_self)] +/// A Rust code formatting utility designed to manage and format untouched fragments of source code, +/// including comments, whitespace, and other characters. While the module doesn't directly address comments, +/// it treats them as unchanged fragments, ensuring their original placement and content remain preserved. +/// +/// Key methods include: +/// - `format_missing`: Addresses characters between the last processed position and a given end position, +/// capturing comments and other untouched sequences. +/// - `format_missing_indent`: Functions similarly to `format_missing`, but introduces added indentation. +/// - `format_missing_inner`: The core method for handling missing fragments, appending them to the output buffer. +/// Pure whitespace fragments might be replaced or adjusted based on context. +/// - `push_vertical_spaces`: Standardizes vertical spacing, eliminating potential excessive empty lines +/// or ensuring adequate vertical separation. +/// +/// By recognizing and properly handling these untouched fragments, the utility ensures comments remain intact +/// in both placement and content during the formatting process. mod config; pub mod errors; mod visitor;