Skip to content

Commit

Permalink
WIP: Attempt to break long expressions into multiple lines
Browse files Browse the repository at this point in the history
Fixes #3474
  • Loading branch information
cr-fuel committed Oct 24, 2023
1 parent 1cc0740 commit 472be7e
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 7 deletions.
14 changes: 10 additions & 4 deletions swayfmt/src/formatter/shape.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ pub(crate) struct CodeLine {
pub(crate) expr_kind: ExprKind,
/// Used in determining `SameLineWhere` formatting.
pub(crate) has_where_clause: bool,
/// Expression is too long to fit in a single line
pub(crate) expr_new_line: bool,
}

impl CodeLine {
Expand All @@ -121,6 +123,7 @@ impl CodeLine {
line_style,
expr_kind,
has_where_clause: Default::default(),
expr_new_line: false,
}
}
pub(crate) fn reset_width(&mut self) {
Expand All @@ -147,6 +150,10 @@ impl CodeLine {
pub(crate) fn update_where_clause(&mut self, has_where_clause: bool) {
self.has_where_clause = has_where_clause;
}

pub(crate) fn update_expr_new_line(&mut self, expr_new_line: bool) {
self.expr_new_line = expr_new_line;
}
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
Expand Down Expand Up @@ -300,10 +307,9 @@ impl Shape {
}
/// Create a new `Shape` with default `CodeLine`.
pub(crate) fn with_default_code_line(self) -> Self {
Self {
code_line: CodeLine::default(),
..self
}
let mut code_line = CodeLine::default();
code_line.update_expr_new_line(self.code_line.expr_new_line);
Self { code_line, ..self }
}
}

Expand Down
23 changes: 21 additions & 2 deletions swayfmt/src/utils/language/expr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,8 +275,20 @@ impl Format for Expr {
name,
} => {
target.format(formatted_code, formatter)?;
write!(formatted_code, "{}", dot_token.span().as_str())?;
name.format(formatted_code, formatter)?;
if formatter.shape.code_line.expr_new_line {
formatter.indent();
write!(
formatted_code,
"\n{}{}",
formatter.indent_to_str()?,
dot_token.span().as_str()
)?;
name.format(formatted_code, formatter)?;
formatter.unindent();
} else {
write!(formatted_code, "{}", dot_token.span().as_str())?;
name.format(formatted_code, formatter)?;
}
}
Self::TupleFieldProjection {
target,
Expand Down Expand Up @@ -646,6 +658,13 @@ fn format_method_call(
write!(formatted_code, "{}", formatter.indent_to_str()?)?;
}
target.format(formatted_code, formatter)?;

if formatter.shape.code_line.expr_new_line {
formatter.indent();
write!(formatted_code, "\n{}", formatter.indent_to_str()?)?;
formatter.unindent();
}

write!(formatted_code, "{}", dot_token.span().as_str())?;
path_seg.format(formatted_code, formatter)?;
if let Some(contract_args) = &contract_args_opt {
Expand Down
11 changes: 10 additions & 1 deletion swayfmt/src/utils/language/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,16 @@ fn format_statement(
expr,
semicolon_token_opt,
} => {
expr.format(formatted_code, formatter)?;
let mut temp_expr = FormattedCode::new();
expr.format(&mut temp_expr, formatter)?;
if temp_expr.len() > formatter.config.whitespace.max_width {
formatter.shape.code_line.expr_new_line = true;
// reformat the expression adding a break
expr.format(formatted_code, formatter)?;
formatter.shape.code_line.expr_new_line = false;
} else {
write!(formatted_code, "{}", temp_expr)?;
}
if let Some(semicolon) = semicolon_token_opt {
if formatter.shape.code_line.line_style == LineStyle::Inline {
write!(formatted_code, "{}", semicolon.span().as_str())?;
Expand Down
48 changes: 48 additions & 0 deletions swayfmt/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1716,3 +1716,51 @@ impl OrdEq for u256 {}
"#,
);
}

#[test]
fn chained_methods() {
check(
r#"
library;
fn test() {
fuelcoin.really_long_field.other_really_long_field.foo().bar().baz.quux().yet_another_call().to_go_above_max_line_length();
}
"#,
r#"library;
fn test() {
fuelcoin
.really_long_field
.other_really_long_field
.foo()
.bar()
.baz
.quux()
.yet_another_call()
.to_go_above_max_line_length();
}
"#,
);
}

#[test]
fn comment_in_the_middle() {
check(
r#"
library;
fn test() {
let number: /* this number is for counting */ u64 = 10;
}"#,
r#"library;
fn test() {
let number: /* this number is for counting */ u64 = 10;
}
"#,
);
}

0 comments on commit 472be7e

Please sign in to comment.