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

Improve forc-fmt to format std lib and core #5410

Merged
merged 15 commits into from
Dec 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 7 additions & 0 deletions Cargo.lock

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

8 changes: 4 additions & 4 deletions examples/asm_return_tuple_pointer/src/main.sw
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ script;
fn adder(a: u64, b: u64, c: u64) -> (u64, u64) {
let empty_tuple = (0u64, 0u64);
asm(output: empty_tuple, r1: a, r2: b, r3: c, r4, r5) {
add r4 r1 r2; // add a & b and put the result in r4
add r5 r2 r3; // add b & c and put the result in r5
sw output r4 i0; // store the word in r4 in output + 0 words
sw output r5 i1; // store the word in r5 in output + 1 word
add r4 r1 r2; // add a & b and put the result in r4
add r5 r2 r3; // add b & c and put the result in r5
sw output r4 i0; // store the word in r4 in output + 0 words
sw output r5 i1; // store the word in r5 in output + 1 word
output: (u64, u64) // return both values
}
}
Expand Down
1 change: 1 addition & 0 deletions swayfmt/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ thiserror = "1.0.30"
toml = { version = "0.7", features = ["parse"] }

[dev-dependencies]
difference = "2.0.0"
paste = "1.0"
prettydiff = "0.6"
test-macros = { path = "test_macros" }
14 changes: 10 additions & 4 deletions swayfmt/src/utils/language/attribute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use sway_types::{
Spanned,
};

impl<T: Format + Spanned> Format for Annotated<T> {
impl<T: Format + Spanned + std::fmt::Debug> Format for Annotated<T> {
fn format(
&self,
formatted_code: &mut FormattedCode,
Expand All @@ -24,11 +24,17 @@ impl<T: Format + Spanned> Format for Annotated<T> {
// format each `Attribute`
let mut start = None;
for attr in &self.attribute_list {
if let Some(start) = start {
// Write any comments that may have been defined in between the
// attributes and the value
write_comments(formatted_code, start..attr.span().start(), formatter)?;
if !formatted_code.ends_with(NEW_LINE) {
write!(formatted_code, "{}", NEW_LINE)?;
}
}
formatter.write_indent_into_buffer(formatted_code)?;
attr.format(formatted_code, formatter)?;
if start.is_none() {
start = Some(attr.span().end());
}
start = Some(attr.span().end());
}
if let Some(start) = start {
// Write any comments that may have been defined in between the
Expand Down
49 changes: 41 additions & 8 deletions swayfmt/src/utils/language/expr/asm_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,21 +61,54 @@ fn format_asm_block(
formatter.with_shape(
formatter.shape.with_default_code_line(),
|formatter| -> Result<(), FormatterError> {
AsmBlock::open_parenthesis(formatted_code, formatter)?;
formatter
.shape
.code_line
.update_line_style(LineStyle::Normal);

let mut inline_arguments = FormattedCode::new();
asm_block
.registers
.get()
.format(formatted_code, formatter)?;
AsmBlock::close_parenthesis(formatted_code, formatter)?;
.format(&mut inline_arguments, formatter)?;

formatter.shape.code_line.update_expr_new_line(false);
formatter
.shape
.code_line
.update_expr_kind(shape::ExprKind::Function);
if inline_arguments.len() > formatter.shape.width_heuristics.fn_call_width {
formatter
.shape
.code_line
.update_line_style(LineStyle::Multiline);
AsmBlock::open_parenthesis(formatted_code, formatter)?;
formatter.indent();
asm_block
.registers
.get()
.format(formatted_code, formatter)?;
formatter.unindent();
write!(formatted_code, "{}", formatter.indent_to_str()?)?;
AsmBlock::close_parenthesis(formatted_code, formatter)?;
} else {
AsmBlock::open_parenthesis(formatted_code, formatter)?;
write!(formatted_code, "{}", inline_arguments)?;
AsmBlock::close_parenthesis(formatted_code, formatter)?;
}

formatter
.shape
.code_line
.update_line_style(LineStyle::Multiline);
AsmBlock::open_curly_brace(formatted_code, formatter)?;
asm_block.contents.get().format(formatted_code, formatter)?;
AsmBlock::close_curly_brace(formatted_code, formatter)?;

Ok(())
},
)?;

AsmBlock::open_curly_brace(formatted_code, formatter)?;
asm_block.contents.get().format(formatted_code, formatter)?;
AsmBlock::close_curly_brace(formatted_code, formatter)?;

Ok(())
}

Expand Down Expand Up @@ -156,7 +189,7 @@ impl Format for Instruction {
formatted_code: &mut FormattedCode,
_formatter: &mut Formatter,
) -> Result<(), FormatterError> {
write!(formatted_code, "{:<4}", &self.op_code_ident().as_str())?;
write!(formatted_code, "{}", &self.op_code_ident().as_str())?;
for arg in self.register_arg_idents() {
write!(formatted_code, " {}", arg.as_str())?
}
Expand Down
118 changes: 84 additions & 34 deletions swayfmt/src/utils/language/expr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,64 @@ pub(crate) mod struct_field;
#[cfg(test)]
mod tests;

#[inline]
fn two_parts_expr(
lhs: &Expr,
operator: &str,
rhs: &Expr,
formatted_code: &mut FormattedCode,
formatter: &mut Formatter,
) -> Result<(), FormatterError> {
let mut rhs_code = FormattedCode::new();
rhs.format(&mut rhs_code, formatter)?;

if !formatter.shape.code_line.expr_new_line
&& rhs_code.len() > formatter.shape.width_heuristics.collection_width
{
// Right hand side is too long to fit in a single line, and
// the current expr is not being rendered multiline at the
// expr level, then add an indentation to the following
// expression and generate the code
formatter.with_shape(
formatter
.shape
.with_code_line_from(LineStyle::Multiline, ExprKind::Undetermined),
|formatter| -> Result<(), FormatterError> {
formatter.shape.code_line.update_expr_new_line(true);

lhs.format(formatted_code, formatter)?;
formatter.indent();
write!(
formatted_code,
"\n{}{} ",
formatter.indent_to_str()?,
operator,
)?;
rhs.format(formatted_code, formatter)?;
formatter.unindent();
Ok(())
},
)?;
} else {
lhs.format(formatted_code, formatter)?;
match formatter.shape.code_line.line_style {
LineStyle::Multiline => {
write!(
formatted_code,
"\n{}{} ",
formatter.indent_to_str()?,
operator,
)?;
}
_ => {
write!(formatted_code, " {} ", operator,)?;
}
}
write!(formatted_code, "{}", rhs_code)?;
}
Ok(())
}

impl Format for Expr {
fn format(
&self,
Expand Down Expand Up @@ -107,9 +165,15 @@ impl Format for Expr {
)?;
}
Self::Parens(expr) => {
if formatter.shape.code_line.expr_new_line {
formatter.indent();
}
Self::open_parenthesis(formatted_code, formatter)?;
expr.get().format(formatted_code, formatter)?;
Self::close_parenthesis(formatted_code, formatter)?;
if formatter.shape.code_line.expr_new_line {
formatter.unindent();
}
}
Self::Block(code_block) => {
if !code_block.get().statements.is_empty()
Expand Down Expand Up @@ -544,46 +608,26 @@ impl Format for Expr {
double_ampersand_token,
rhs,
} => {
lhs.format(formatted_code, formatter)?;
match formatter.shape.code_line.line_style {
LineStyle::Multiline => {
write!(
formatted_code,
"\n{}{} ",
formatter.indent_to_str()?,
double_ampersand_token.span().as_str()
)?;
}
_ => {
write!(
formatted_code,
" {} ",
double_ampersand_token.span().as_str()
)?;
}
}
rhs.format(formatted_code, formatter)?;
two_parts_expr(
lhs,
double_ampersand_token.span().as_str(),
rhs,
formatted_code,
formatter,
)?;
}
Self::LogicalOr {
lhs,
double_pipe_token,
rhs,
} => {
lhs.format(formatted_code, formatter)?;
match formatter.shape.code_line.line_style {
LineStyle::Multiline => {
write!(
formatted_code,
"\n{}{} ",
formatter.indent_to_str()?,
double_pipe_token.span().as_str()
)?;
}
_ => {
write!(formatted_code, " {} ", double_pipe_token.span().as_str())?;
}
}
rhs.format(formatted_code, formatter)?;
two_parts_expr(
lhs,
double_pipe_token.span().as_str(),
rhs,
formatted_code,
formatter,
)?;
}
Self::Reassignment {
assignable,
Expand Down Expand Up @@ -703,6 +747,12 @@ fn same_line_if_only_argument(expr: &Expr) -> bool {
matches!(
expr,
Expr::Struct { path: _, fields: _ }
| Expr::Tuple(_)
| Expr::Parens(_)
| Expr::Not {
bang_token: _,
expr: _
}
| Expr::Path(_)
| Expr::FuncApp { func: _, args: _ }
| Expr::Match {
Expand Down
29 changes: 27 additions & 2 deletions swayfmt/src/utils/language/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,35 @@ fn format_statement(

remove_arguments_from_expr(expr.clone()).format(&mut temp_expr, formatter)?;
if temp_expr.len() > formatter.shape.width_heuristics.chain_width {
formatter.shape.code_line.expr_new_line = true;
let update_expr_new_line = if !matches!(
expr,
Expr::MethodCall { .. }
| Expr::FuncApp { func: _, args: _ }
| Expr::If(_)
| Expr::While {
while_token: _,
condition: _,
block: _
}
) {
// Method calls, If, While should not tamper with the
// expr_new_line because that would be inherited for all
// statements. That should be applied at the lowest level
// possible (ideally at the expression level)
formatter.shape.code_line.expr_new_line
} else if formatter.shape.code_line.expr_new_line {
// already enabled
true
} else {
formatter.shape.code_line.update_expr_new_line(true);
false
};
// reformat the expression adding a break
expr.format(formatted_code, formatter)?;
formatter.shape.code_line.expr_new_line = false;
formatter
.shape
.code_line
.update_expr_new_line(update_expr_new_line);
} else {
expr.format(formatted_code, formatter)?;
}
Expand Down
Loading
Loading