Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: provide formatting subcommand #2640

Merged
merged 53 commits into from Oct 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
ccf813d
first attempt
Sep 11, 2023
5a869e5
merge branch 'master' into fmt
Sep 14, 2023
88336fc
move to tooling and minor fixes
Sep 15, 2023
e26baa4
set `license.workspace = true`
Sep 15, 2023
86fc87c
fix confusion with .gitignore
Sep 15, 2023
bffe2eb
impl `ParsedModule::into_legacy`
Sep 15, 2023
bde580d
add `nargo fmt` command
Sep 15, 2023
61f158d
simple emit fn parameters
Sep 15, 2023
4f228a9
merge branch 'master' into fmt
Sep 15, 2023
d5ac3a6
basic rewrite stmt
Sep 15, 2023
945bc1c
fix clippy
Sep 15, 2023
ecf15b3
Merge branch 'master' into fmt
Sep 15, 2023
44ef7ea
update Cargo.lock
Sep 15, 2023
77607d3
ops..
Sep 15, 2023
31461d7
fix
Sep 16, 2023
6df3d0a
specifically for handling comments within empty function parameters
Sep 21, 2023
529c1de
Merge branch 'master' into fmt
Sep 25, 2023
ea90042
fixed errors after the merge
Sep 25, 2023
787f56a
cargo fmt
Sep 25, 2023
7de95ce
a naive attempt not to lose comments
Sep 25, 2023
69181be
write as is
Sep 25, 2023
76e0b7a
Merge branch 'master' into fmt
Sep 27, 2023
0eef49a
fixed errors after the merge
Sep 27, 2023
fa298b8
make clippy happy
Sep 27, 2023
b83925b
for simplicity MVP abandon the complex
Sep 27, 2023
a1108bc
fix `read_array`
Sep 27, 2023
c7b58fa
add `format_missing`
Sep 27, 2023
240ce40
add tests
Sep 27, 2023
b2655d0
add `with_indent`
Sep 27, 2023
b8d6ffd
smol refactoring
Sep 28, 2023
34b15ce
Merge branch 'master' into fmt
Sep 28, 2023
e64406d
update Cargo.lock
Sep 28, 2023
7cf0dc9
rework `nargo fmt`
Sep 28, 2023
8e40bc6
rework newlines
Sep 28, 2023
b255896
fix buig
Sep 28, 2023
0864245
cargo fmt
Sep 28, 2023
4390d3c
ops...
Sep 28, 2023
fe3d25e
load config from `noirfmt.toml`
Sep 29, 2023
5df2d76
Merge branch 'master' into fmt
Sep 29, 2023
f391ae5
update `Cargo.lock`
Sep 29, 2023
6206edf
avoid alloc vec
Oct 1, 2023
df1d042
better error handling
Oct 1, 2023
8c9deb5
Merge branch 'master' into fmt
Oct 1, 2023
b23b763
fix
Oct 1, 2023
c5c045b
Merge branch 'master' into fmt
Oct 2, 2023
fbe2a6b
remove into_unorder
Oct 3, 2023
4115d07
`Unordered` -> `SortedModule`
Oct 5, 2023
aa0457a
Merge branch 'master' into fmt
Oct 5, 2023
2df6b7c
update `Cargo.lock`
Oct 5, 2023
bb0cd06
`cargo fmt`
Oct 5, 2023
dc06112
Update tooling/nargo_cli/src/cli/mod.rs
kevaundray Oct 5, 2023
5712d09
Merge branch 'master' into fmt
Oct 5, 2023
62c0c98
add docs
Oct 5, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ members = [
"tooling/bb_abstraction_leaks",
"tooling/lsp",
"tooling/nargo",
"tooling/nargo_fmt",
"tooling/nargo_cli",
"tooling/nargo_toml",
"tooling/noirc_abi",
Expand Down Expand Up @@ -49,6 +50,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" }
Expand Down
20 changes: 13 additions & 7 deletions compiler/noirc_frontend/src/ast/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use std::fmt::Display;

use crate::token::{Attributes, Token};
use crate::{
Distinctness, Ident, Path, Pattern, Recoverable, Statement, UnresolvedTraitConstraint,
UnresolvedType, UnresolvedTypeData, Visibility,
Distinctness, Ident, Path, Pattern, Recoverable, Statement, StatementKind,
UnresolvedTraitConstraint, UnresolvedType, UnresolvedTypeData, Visibility,
};
use acvm::FieldElement;
use iter_extended::vecmap;
Expand Down Expand Up @@ -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 }))
Expand Down Expand Up @@ -429,8 +435,8 @@ pub struct IndexExpression {
pub struct BlockExpression(pub Vec<Statement>);

impl BlockExpression {
pub fn pop(&mut self) -> Option<Statement> {
self.0.pop()
pub fn pop(&mut self) -> Option<StatementKind> {
self.0.pop().map(|stmt| stmt.kind)
}

pub fn len(&self) -> usize {
Expand Down Expand Up @@ -497,7 +503,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}")?;
}
Expand Down
89 changes: 50 additions & 39 deletions compiler/noirc_frontend/src/ast/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -32,62 +38,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<Token>,
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
}
// A semicolon on a for loop is optional and does nothing
Statement::For(_) => self,
StatementKind::For(_) => 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::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.
Expand All @@ -96,7 +107,7 @@ impl Statement {
operator: Token,
mut expression: Expression,
span: Span,
) -> Statement {
) -> StatementKind {
// Desugar `a <op>= b` to `a = a <op> 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 {
Expand All @@ -111,7 +122,7 @@ impl Statement {
expression = Expression::new(ExpressionKind::Infix(Box::new(infix)), span);
}

Statement::Assign(AssignStatement { lvalue, expression })
StatementKind::Assign(AssignStatement { lvalue, expression })
}
}

Expand Down Expand Up @@ -468,16 +479,16 @@ pub struct ForLoopStatement {
pub block: Expression,
}

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::For(for_loop) => for_loop.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::For(for_loop) => for_loop.fmt(f),
StatementKind::Semi(semi) => write!(f, "{semi};"),
StatementKind::Error => write!(f, "Error"),
}
}
}
Expand Down
9 changes: 4 additions & 5 deletions compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,11 @@ use crate::node_interner::{
FuncId, NodeInterner, StmtId, StructId, TraitId, TraitImplKey, TypeAliasId,
};

use crate::parser::ParserError;

use crate::parser::{ParserError, SortedModule};
use crate::{
ExpressionKind, Generics, Ident, LetStatement, Literal, NoirFunction, NoirStruct, NoirTrait,
NoirTypeAlias, ParsedModule, Path, Shared, StructType, TraitItem, Type, TypeBinding,
TypeVariableKind, UnresolvedGenerics, UnresolvedType,
NoirTypeAlias, Path, Shared, StructType, TraitItem, Type, TypeBinding, TypeVariableKind,
UnresolvedGenerics, UnresolvedType,
};
use fm::FileId;
use iter_extended::vecmap;
Expand Down Expand Up @@ -195,7 +194,7 @@ impl DefCollector {
pub fn collect(
mut def_map: CrateDefMap,
context: &mut Context,
ast: ParsedModule,
ast: SortedModule,
root_file_id: FileId,
) -> Vec<(CompilationError, FileId)> {
let mut errors: Vec<(CompilationError, FileId)> = vec![];
Expand Down
10 changes: 5 additions & 5 deletions compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ use crate::{
graph::CrateId,
hir::def_collector::dc_crate::{UnresolvedStruct, UnresolvedTrait},
node_interner::TraitId,
parser::SubModule,
parser::{SortedModule, SubModule},
FunctionDefinition, Ident, LetStatement, NoirFunction, NoirStruct, NoirTrait, NoirTraitImpl,
NoirTypeAlias, ParsedModule, TraitImplItem, TraitItem, TypeImpl,
NoirTypeAlias, TraitImplItem, TraitItem, TypeImpl,
};

use super::{
Expand All @@ -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: ParsedModule,
ast: SortedModule,
file_id: FileId,
module_id: LocalModuleId,
crate_id: CrateId,
Expand Down Expand Up @@ -410,7 +410,7 @@ impl<'a> ModCollector<'a> {
Ok(child) => {
errors.extend(collect_defs(
self.def_collector,
submodule.contents,
submodule.contents.into_sorted(),
file_id,
child,
crate_id,
Expand Down Expand Up @@ -467,8 +467,8 @@ 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);
let (ast, parsing_errors) = parse_file(&context.file_manager, child_file_id);
let ast = ast.into_sorted();

errors.extend(
parsing_errors.iter().map(|e| (e.clone().into(), child_file_id)).collect::<Vec<_>>(),
Expand Down
1 change: 1 addition & 0 deletions compiler/noirc_frontend/src/hir/def_map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +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_sorted();

#[cfg(feature = "aztec")]
let ast = match aztec_library::transform(ast, &crate_id, context) {
Expand Down
Loading
Loading