Skip to content

Commit

Permalink
reworking
Browse files Browse the repository at this point in the history
  • Loading branch information
f01dab1e committed Oct 15, 2023
1 parent 1bd3080 commit 8701923
Show file tree
Hide file tree
Showing 6 changed files with 191 additions and 48 deletions.
20 changes: 15 additions & 5 deletions tooling/nargo_fmt/src/visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub(crate) struct FmtVisitor<'me> {
config: &'me Config,
buffer: String,
pub(crate) source: &'me str,
block_indent: Indent,
indent: Indent,
last_position: u32,
}

Expand All @@ -29,7 +29,17 @@ impl<'me> FmtVisitor<'me> {
config,
source,
last_position: 0,
block_indent: Indent { block_indent: 0 },
indent: Indent { block_indent: 0 },
}
}

pub(crate) fn fork(&self) -> Self {
Self {
buffer: String::new(),
config: self.config,
source: self.source,
last_position: self.last_position,
indent: self.indent,
}
}

Expand All @@ -38,9 +48,9 @@ impl<'me> FmtVisitor<'me> {
}

fn with_indent<T>(&mut self, f: impl FnOnce(&mut Self) -> T) -> T {
self.block_indent.block_indent(self.config);
self.indent.block_indent(self.config);
let ret = f(self);
self.block_indent.block_unindent(self.config);
self.indent.block_unindent(self.config);
ret
}

Expand Down Expand Up @@ -72,7 +82,7 @@ impl<'me> FmtVisitor<'me> {
}

if should_indent {
let indent = this.block_indent.to_string();
let indent = this.indent.to_string();
this.push_str(&indent);
}
});
Expand Down
122 changes: 79 additions & 43 deletions tooling/nargo_fmt/src/visitor/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use noirc_frontend::{
ExpressionKind, Literal, Statement,
};

use super::FmtVisitor;
use crate::utils::{self, FindToken};
use super::{FmtVisitor, Indent};
use crate::utils::{self, Expr, FindToken};

impl FmtVisitor<'_> {
pub(crate) fn visit_expr(&mut self, expr: Expression) {
Expand All @@ -21,11 +21,8 @@ impl FmtVisitor<'_> {
pub(crate) fn format_expr(&self, Expression { kind, span }: Expression) -> String {
match kind {
ExpressionKind::Block(block) => {
let mut visitor = FmtVisitor::new(self.source, self.config);

visitor.block_indent = self.block_indent;
let mut visitor = self.fork();
visitor.visit_block(block, span, true);

visitor.buffer
}
ExpressionKind::Prefix(prefix) => {
Expand Down Expand Up @@ -81,36 +78,8 @@ impl FmtVisitor<'_> {
let formatted_index = self.format_expr(index_expr.index);
format!("{}[{}]", formatted_collection, formatted_index)
}
ExpressionKind::Tuple(elements) => {
let mut visitor = FmtVisitor::new(self.source, self.config);
visitor.block_indent = self.block_indent;
visitor.block_indent.block_indent(self.config);

let mut exprs = utils::Exprs::new(&mut visitor, span, elements).collect::<Vec<_>>();

if exprs.len() == 1 {
let expr = exprs.pop().unwrap();
let comma =
if expr.trailing.find_token(Token::Comma).is_none() { "," } else { "" };

let newline_with_indent = if expr.newlines {
"\n".to_string() + &visitor.block_indent.to_string()
} else {
String::new()
};
let end_newline = if expr.newlines {
"\n".to_string() + &self.block_indent.to_string()
} else {
String::new()
};

format!(
"({newline_with_indent}{}{newline_with_indent}{}{}{comma}{end_newline})",
expr.leading, expr.expr, expr.trailing
)
} else {
slice!(self, span.start(), span.end()).into()
}
ExpressionKind::Tuple(exprs) => {
format_parens(self.fork(), exprs.len() == 1, exprs, span)
}
ExpressionKind::Literal(literal) => match literal {
Literal::Integer(_) => slice!(self, span.start(), span.end()).to_string(),
Expand All @@ -128,7 +97,9 @@ impl FmtVisitor<'_> {
literal.to_string()
}
},
ExpressionKind::Parenthesized(subexpr) => format!("({})", self.format_expr(*subexpr)),
ExpressionKind::Parenthesized(subexpr) => {
format_parens(self.fork(), false, vec![*subexpr], span)
}
// TODO:
_expr => slice!(self, span.start(), span.end()).to_string(),
}
Expand Down Expand Up @@ -161,7 +132,7 @@ impl FmtVisitor<'_> {

self.push_str("\n");
if should_indent {
self.push_str(&self.block_indent.to_string());
self.push_str(&self.indent.to_string());
}
self.push_str("}");
}
Expand All @@ -181,11 +152,10 @@ impl FmtVisitor<'_> {
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() };
self.indent.block_indent(self.config);
let open_indent = self.indent.to_string();
self.indent.block_unindent(self.config);
let close_indent = if should_indent { self.indent.to_string() } else { String::new() };

let ret = format!("{{\n{open_indent}{comment_str}\n{close_indent}}}");
ret
Expand All @@ -194,3 +164,69 @@ impl FmtVisitor<'_> {
self.push_str(&block_str);
}
}

fn format_parens(
mut visitor: FmtVisitor,
trailing_comma: bool,
exprs: Vec<Expression>,
span: Span,
) -> String {
visitor.indent.block_indent(visitor.config);

let nested_indent = visitor.indent;
let exprs: Vec<_> = utils::Exprs::new(&visitor, span, exprs).collect();
let (exprs, force_one_line) = format_exprs(trailing_comma, exprs, nested_indent);

visitor.indent.block_unindent(visitor.config);

wrap_exprs(exprs, nested_indent, visitor.indent, force_one_line)
}

fn format_exprs(trailing_comma: bool, exprs: Vec<Expr>, indent: Indent) -> (String, bool) {
let mut result = String::new();
let mut force_one_line = true;
let indent_str = indent.to_string();
let mut exprs = exprs.into_iter().enumerate().peekable();

while let Some((index, expr)) = exprs.next() {
let is_first = index == 0;
let separate = exprs.peek().is_some() || trailing_comma;

if !is_first && force_one_line {
result.push(' ');
}

result.push_str(&expr.leading);

if expr.newlines {
force_one_line = false;
result.push('\n');
result.push_str(&indent_str);
}

result.push_str(&expr.expr);
result.push_str(&expr.trailing);

if separate && expr.trailing.find_token(Token::Comma).is_none() {
result.push(',');
}
}

(result, force_one_line)
}

fn wrap_exprs(
exprs: String,
nested_indent: Indent,
indent: Indent,
force_one_line: bool,
) -> String {
if force_one_line {
format!("({exprs})")
} else {
let nested_indent_str = "\n".to_string() + &nested_indent.to_string();
let indent_str = "\n".to_string() + &indent.to_string();

format!("({nested_indent_str}{exprs}{indent_str})")
}
}
11 changes: 11 additions & 0 deletions tooling/nargo_fmt/tests/expected/expr.nr
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,14 @@ fn parenthesized() {
fn parenthesized() {
(i as u8) + (j as u8) + (k as u8) + x + y + z
}

fn parenthesized() {
value + (/*test*/x as Field/*test*/)
}

fn parenthesized() {
value + (
// line
x as Field
)
}
37 changes: 37 additions & 0 deletions tooling/nargo_fmt/tests/expected/tuple.nr
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,41 @@ fn main() {
);
(/*hello*/1,);
(1/*hello*/,);
(1,);
(/*test*/1,);
(/*a*/1/*b*/,);
(/*a*/1/*b*/, /*c*/ 2/*d*/, /*c*/ 2/*d*/);
(/*a*/1/*b*/, /*c*/ 2/*d*/, /*c*/ 2/*d*/, /*e*/ 3/*f*/);

(1/*1*/ , 2/* 2*/);

(
/*a*/
1/*b*/,
/*c*/2/*d*/,
/*c*/2/*d*/,
/*e*/3/*f*/
);

// FIXME:
(1/*test*/,);

(
//
1,
);

(
// 1
1,
// 2,
2,
);

(/*1*/1/*2*/, 2);

(((
//2
1,
),),)
}
11 changes: 11 additions & 0 deletions tooling/nargo_fmt/tests/input/expr.nr
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,14 @@ fn parenthesized() {
fn parenthesized() {
( i as u8 ) + ( j as u8 ) + ( k as u8 ) + x + y + z
}

fn parenthesized() {
value + ( /*test*/x as Field /*test*/ )
}

fn parenthesized() {
value + (
// line
x as Field
)
}
38 changes: 38 additions & 0 deletions tooling/nargo_fmt/tests/input/tuple.nr
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,42 @@ fn main() {
1,);
(/*hello*/1,);
(1,/*hello*/);
( 1, );
( /*test*/1, );
( /*a*/1/*b*/, );
( /*a*/1/*b*/, /*c*/2/*d*/, /*c*/2/*d*/ );
( /*a*/1/*b*/, /*c*/2/*d*/, /*c*/2/*d*/, /*e*/3/*f*/ );

( 1 /*1*/ , 2 /* 2*/ );

(
/*a*/
1
/*b*/,
/*c*/
2/*d*/,
/*c*/2/*d*/,
/*e*/3/*f*/
);

// FIXME:
( 1, /*test*/ );

(
//
1,
);

(
// 1
1,
// 2,
2,
);

(/*1*/1, /*2*/2);

(((
//2
1,),),)
}

0 comments on commit 8701923

Please sign in to comment.