Skip to content

Commit

Permalink
Merge branch 'master' into zpedro/docs_0.19.3
Browse files Browse the repository at this point in the history
  • Loading branch information
signorecello authored Nov 24, 2023
2 parents 9053fda + 026a358 commit d11b444
Show file tree
Hide file tree
Showing 20 changed files with 433 additions and 268 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ hex = "0.4.2"
const_format = "0.2.30"
num-bigint = "0.4"
num-traits = "0.2"
similar-asserts = "1.5.0"

[profile.dev]
# This is required to be able to run `cargo test` in acvm_js due to the `locals exceeds maximum` error.
Expand Down
2 changes: 1 addition & 1 deletion docs/docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ const config = {
},
items: [
{
href: 'https://github.com/noir-lang/docs',
href: 'https://github.com/noir-lang/noir/tree/master/docs',
label: 'GitHub',
position: 'right',
},
Expand Down
1 change: 1 addition & 0 deletions tooling/nargo_cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ tower.workspace = true
async-lsp = { workspace = true, features = ["client-monitor", "stdio", "tracing", "tokio"] }
const_format.workspace = true
hex.workspace = true
similar-asserts.workspace = true
termcolor = "1.1.2"
color-eyre = "0.6.2"
tokio = { version = "1.0", features = ["io-std"] }
Expand Down
48 changes: 40 additions & 8 deletions tooling/nargo_cli/src/cli/fmt_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,15 @@ use super::NargoConfig;

/// Format the Noir files in a workspace
#[derive(Debug, Clone, Args)]
pub(crate) struct FormatCommand {}
pub(crate) struct FormatCommand {
/// Run noirfmt in check mode
#[arg(long)]
check: bool,
}

pub(crate) fn run(args: FormatCommand, config: NargoConfig) -> Result<(), CliError> {
let check_mode = args.check;

pub(crate) fn run(_args: FormatCommand, config: NargoConfig) -> Result<(), CliError> {
let toml_path = get_package_manifest(&config.program_dir)?;
let workspace = resolve_workspace_from_toml(
&toml_path,
Expand All @@ -26,6 +32,8 @@ pub(crate) fn run(_args: FormatCommand, config: NargoConfig) -> Result<(), CliEr
let config = nargo_fmt::Config::read(&config.program_dir)
.map_err(|err| CliError::Generic(err.to_string()))?;

let mut check_exit_code_one = false;

for package in &workspace {
let mut file_manager =
FileManager::new(&package.root_dir, Box::new(|path| std::fs::read_to_string(path)));
Expand Down Expand Up @@ -53,16 +61,40 @@ pub(crate) fn run(_args: FormatCommand, config: NargoConfig) -> Result<(), CliEr
return Ok(());
}

let source = nargo_fmt::format(
file_manager.fetch_file(file_id).source(),
parsed_module,
&config,
);
let original = file_manager.fetch_file(file_id).source();
let formatted = nargo_fmt::format(original, parsed_module, &config);

if check_mode {
let diff = similar_asserts::SimpleDiff::from_str(
original,
&formatted,
"original",
"formatted",
)
.to_string();

if !diff.lines().next().is_some_and(|line| line.contains("Invisible differences")) {
if !check_exit_code_one {
check_exit_code_one = true;
}

std::fs::write(entry.path(), source)
println!("{diff}");
}

Ok(())
} else {
std::fs::write(entry.path(), formatted)
}
})
.map_err(|error| CliError::Generic(error.to_string()))?;
}

if check_exit_code_one {
std::process::exit(1);
} else if check_mode {
println!("No formatting changes were detected");
}

Ok(())
}

Expand Down
2 changes: 1 addition & 1 deletion tooling/nargo_fmt/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ toml.workspace = true
thiserror.workspace = true

[dev-dependencies]
similar-asserts = "1.5.0"
similar-asserts.workspace = true
4 changes: 4 additions & 0 deletions tooling/nargo_fmt/src/rewrite.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
mod array;
mod expr;
mod infix;
mod parenthesized;

pub(crate) use array::rewrite as array;
pub(crate) use expr::{rewrite as expr, rewrite_sub_expr as sub_expr};
pub(crate) use infix::rewrite as infix;
pub(crate) use parenthesized::rewrite as parenthesized;
2 changes: 1 addition & 1 deletion tooling/nargo_fmt/src/rewrite/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub(crate) fn rewrite(mut visitor: FmtVisitor, array: Vec<Expression>, array_spa
let end = item_span.start();

let leading = visitor.slice(start..end).trim_matches(pattern);
let item = visitor.format_sub_expr(item);
let item = super::sub_expr(&visitor, visitor.shape(), item);
let next_start = items.peek().map_or(end_position, |expr| expr.span.start());
let trailing = visitor.slice(item_span.end()..next_start);
let offset = trailing
Expand Down
144 changes: 144 additions & 0 deletions tooling/nargo_fmt/src/rewrite/expr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
use noirc_frontend::{token::Token, ArrayLiteral, Expression, ExpressionKind, Literal, UnaryOp};

use crate::visitor::{
expr::{format_brackets, format_parens},
ExpressionType, FmtVisitor, Indent, Shape,
};

pub(crate) fn rewrite_sub_expr(
visitor: &FmtVisitor,
shape: Shape,
expression: Expression,
) -> String {
rewrite(visitor, expression, ExpressionType::SubExpression, shape)
}

pub(crate) fn rewrite(
visitor: &FmtVisitor,
Expression { kind, span }: Expression,
expr_type: ExpressionType,
shape: Shape,
) -> String {
match kind {
ExpressionKind::Block(block) => {
let mut visitor = visitor.fork();
visitor.visit_block(block, span);
visitor.finish()
}
ExpressionKind::Prefix(prefix) => {
let op = match prefix.operator {
UnaryOp::Minus => "-",
UnaryOp::Not => "!",
UnaryOp::MutableReference => "&mut ",
UnaryOp::Dereference { implicitly_added } => {
if implicitly_added {
""
} else {
"*"
}
}
};

format!("{op}{}", rewrite_sub_expr(visitor, shape, prefix.rhs))
}
ExpressionKind::Cast(cast) => {
format!("{} as {}", rewrite_sub_expr(visitor, shape, cast.lhs), cast.r#type)
}
kind @ ExpressionKind::Infix(_) => {
super::infix(visitor.fork(), Expression { kind, span }, shape)
}
ExpressionKind::Call(call_expr) => {
let args_span =
visitor.span_before(call_expr.func.span.end()..span.end(), Token::LeftParen);

let callee = rewrite_sub_expr(visitor, shape, *call_expr.func);
let args = format_parens(
visitor.config.fn_call_width.into(),
visitor.fork(),
shape,
false,
call_expr.arguments,
args_span,
true,
);

format!("{callee}{args}")
}
ExpressionKind::MethodCall(method_call_expr) => {
let args_span = visitor.span_before(
method_call_expr.method_name.span().end()..span.end(),
Token::LeftParen,
);

let object = rewrite_sub_expr(visitor, shape, method_call_expr.object);
let method = method_call_expr.method_name.to_string();
let args = format_parens(
visitor.config.fn_call_width.into(),
visitor.fork(),
shape,
false,
method_call_expr.arguments,
args_span,
true,
);

format!("{object}.{method}{args}")
}
ExpressionKind::MemberAccess(member_access_expr) => {
let lhs_str = rewrite_sub_expr(visitor, shape, member_access_expr.lhs);
format!("{}.{}", lhs_str, member_access_expr.rhs)
}
ExpressionKind::Index(index_expr) => {
let index_span = visitor
.span_before(index_expr.collection.span.end()..span.end(), Token::LeftBracket);

let collection = rewrite_sub_expr(visitor, shape, index_expr.collection);
let index = format_brackets(visitor.fork(), false, vec![index_expr.index], index_span);

format!("{collection}{index}")
}
ExpressionKind::Tuple(exprs) => {
format_parens(None, visitor.fork(), shape, exprs.len() == 1, exprs, span, false)
}
ExpressionKind::Literal(literal) => match literal {
Literal::Integer(_) | Literal::Bool(_) | Literal::Str(_) | Literal::FmtStr(_) => {
visitor.slice(span).to_string()
}
Literal::Array(ArrayLiteral::Repeated { repeated_element, length }) => {
let repeated = rewrite_sub_expr(visitor, shape, *repeated_element);
let length = rewrite_sub_expr(visitor, shape, *length);

format!("[{repeated}; {length}]")
}
Literal::Array(ArrayLiteral::Standard(exprs)) => {
super::array(visitor.fork(), exprs, span)
}
Literal::Unit => "()".to_string(),
},
ExpressionKind::Parenthesized(sub_expr) => {
super::parenthesized(visitor, shape, span, *sub_expr)
}
ExpressionKind::Constructor(constructor) => {
let type_name = visitor.slice(span.start()..constructor.type_name.span().end());
let fields_span = visitor
.span_before(constructor.type_name.span().end()..span.end(), Token::LeftBrace);

visitor.format_struct_lit(type_name, fields_span, *constructor)
}
ExpressionKind::If(if_expr) => {
let allow_single_line = expr_type == ExpressionType::SubExpression;

if allow_single_line {
let mut visitor = visitor.fork();
visitor.indent = Indent::default();
if let Some(line) = visitor.format_if_single_line(*if_expr.clone()) {
return line;
}
}

visitor.format_if(*if_expr)
}
ExpressionKind::Lambda(_) | ExpressionKind::Variable(_) => visitor.slice(span).to_string(),
ExpressionKind::Error => unreachable!(),
}
}
11 changes: 6 additions & 5 deletions tooling/nargo_fmt/src/rewrite/infix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ use std::iter::zip;
use noirc_frontend::{Expression, ExpressionKind};

use crate::{
rewrite,
utils::{first_line_width, is_single_line},
visitor::{ExpressionType, FmtVisitor, Shape},
visitor::{FmtVisitor, Shape},
};

pub(crate) fn rewrite(visitor: FmtVisitor, expr: Expression, shape: Shape) -> String {
Expand All @@ -16,9 +17,9 @@ pub(crate) fn rewrite(visitor: FmtVisitor, expr: Expression, shape: Shape) -> St

format!(
"{} {} {}",
visitor.format_sub_expr(infix.lhs),
rewrite::sub_expr(&visitor, shape, infix.lhs),
infix.operator.contents.as_string(),
visitor.format_sub_expr(infix.rhs)
rewrite::sub_expr(&visitor, shape, infix.rhs)
)
}
}
Expand Down Expand Up @@ -87,10 +88,10 @@ pub(crate) fn flatten(
}
_ => {
let rewrite = if result.is_empty() {
visitor.format_expr(node.clone(), ExpressionType::SubExpression)
rewrite::sub_expr(&visitor, visitor.shape(), node.clone())
} else {
visitor.indent.block_indent(visitor.config);
visitor.format_expr(node.clone(), ExpressionType::SubExpression)
rewrite::sub_expr(&visitor, visitor.shape(), node.clone())
};

result.push(rewrite);
Expand Down
67 changes: 67 additions & 0 deletions tooling/nargo_fmt/src/rewrite/parenthesized.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
use noirc_frontend::{hir::resolution::errors::Span, Expression, ExpressionKind};

use crate::visitor::{FmtVisitor, Shape};

pub(crate) fn rewrite(
visitor: &FmtVisitor<'_>,
shape: Shape,
mut span: Span,
mut sub_expr: Expression,
) -> String {
let remove_nested_parens = visitor.config.remove_nested_parens;

let mut leading;
let mut trailing;

loop {
let leading_span = span.start() + 1..sub_expr.span.start();
let trailing_span = sub_expr.span.end()..span.end() - 1;

leading = visitor.format_comment(leading_span.into());
trailing = visitor.format_comment(trailing_span.into());

if let ExpressionKind::Parenthesized(ref sub_sub_expr) = sub_expr.kind {
if remove_nested_parens && leading.is_empty() && trailing.is_empty() {
span = sub_expr.span;
sub_expr = *sub_sub_expr.clone();
continue;
}
}

break;
}

if !leading.contains("//") && !trailing.contains("//") {
let sub_expr = super::sub_expr(visitor, shape, sub_expr);
format!("({leading}{sub_expr}{trailing})")
} else {
let mut visitor = visitor.fork();

let indent = visitor.indent.to_string_with_newline();
visitor.indent.block_indent(visitor.config);
let nested_indent = visitor.indent.to_string_with_newline();

let sub_expr = super::sub_expr(&visitor, shape, sub_expr);

let mut result = String::new();
result.push('(');

if !leading.is_empty() {
result.push_str(&nested_indent);
result.push_str(&leading);
}

result.push_str(&nested_indent);
result.push_str(&sub_expr);

if !trailing.is_empty() {
result.push_str(&nested_indent);
result.push_str(&trailing);
}

result.push_str(&indent);
result.push(')');

result
}
}
Loading

0 comments on commit d11b444

Please sign in to comment.