Skip to content

Commit 69122c8

Browse files
authored
Adds Generics handling to sway-fmt-v2 (#2110)
1 parent 719310d commit 69122c8

File tree

9 files changed

+179
-118
lines changed

9 files changed

+179
-118
lines changed

sway-fmt-v2/src/fmt.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ impl Formatter {
4949
let program_type = module.kind;
5050

5151
// Formatted code will be pushed here with raw newline stlye.
52-
// Which means newlines are not converted into system-specific versions by apply_newline_style
53-
// Use the length of src as a hint of the memory size needed for raw_formatted_code,
52+
// Which means newlines are not converted into system-specific versions by `apply_newline_style`.
53+
// Use the length of src as a hint of the memory size needed for `raw_formatted_code`,
5454
// which will reduce the number of reallocations
5555
let mut raw_formatted_code = String::with_capacity(src_len);
5656

@@ -124,14 +124,14 @@ pub struct Foo { bar: u64, baz: bool }"#;
124124
#[test]
125125
fn test_struct_multiline_line_alignment() {
126126
let sway_code_to_format = r#"contract;
127-
pub struct Foo {
127+
pub struct Foo<T, P> {
128128
barbazfoo: u64,
129129
baz : bool,
130130
}
131131
"#;
132132
let correct_sway_code = r#"contract;
133133
134-
pub struct Foo {
134+
pub struct Foo<T, P> {
135135
barbazfoo: u64,
136136
baz : bool,
137137
}"#;
@@ -239,7 +239,7 @@ enum Color {
239239
let sway_code_to_format = r#"contract;
240240
241241
abi StorageMapExample {
242-
#[storage(write,)]fn insert_into_map1(key: u64, value: u64);
242+
#[storage(write)]fn insert_into_map1(key: u64, value: u64);
243243
244244
fn hello(key: u64, value: u64);
245245
}"#;

sway-fmt-v2/src/items/item_abi.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ impl Format for ItemAbi {
1515
formatter: &mut Formatter,
1616
) -> Result<(), FormatterError> {
1717
// Add enum token
18-
formatted_code.push_str(self.abi_token.span().as_str());
19-
formatted_code.push(' ');
18+
write!(formatted_code, "{} ", self.abi_token.span().as_str())?;
2019

2120
// Add name of the abi
2221
formatted_code.push_str(self.name.as_str());
@@ -70,6 +69,7 @@ impl Format for ItemAbi {
7069
}
7170
}
7271
Self::close_curly_brace(formatted_code, formatter)?;
72+
7373
Ok(())
7474
}
7575
}

sway-fmt-v2/src/items/item_enum.rs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ use crate::{
55
FormatterError,
66
};
77
use std::fmt::Write;
8-
use sway_parse::{token::Delimiter, ItemEnum};
8+
use sway_parse::{
9+
token::{Delimiter, PunctKind},
10+
ItemEnum,
11+
};
912
use sway_types::Spanned;
1013

1114
impl Format for ItemEnum {
@@ -17,13 +20,11 @@ impl Format for ItemEnum {
1720
let enum_variant_align_threshold = formatter.config.structures.enum_variant_align_threshold;
1821

1922
if let Some(visibility_token) = &self.visibility {
20-
formatted_code.push_str(visibility_token.span().as_str());
21-
formatted_code.push(' ');
23+
write!(formatted_code, "{} ", visibility_token.span().as_str())?;
2224
}
2325

2426
// Add enum token
25-
formatted_code.push_str(self.enum_token.span().as_str());
26-
formatted_code.push(' ');
27+
write!(formatted_code, "{} ", self.enum_token.span().as_str())?;
2728

2829
// Add name of the enum.
2930
formatted_code.push_str(self.name.as_str());
@@ -51,8 +52,12 @@ impl Format for ItemEnum {
5152
for (index, type_field) in type_fields.iter().enumerate() {
5253
let type_field = &type_field.0;
5354
// Push the current indentation level
54-
formatted_code.push_str(&formatter.shape.indent.to_string(formatter));
55-
formatted_code.push_str(type_field.name.as_str());
55+
write!(
56+
formatted_code,
57+
"{}{}",
58+
&formatter.shape.indent.to_string(formatter),
59+
type_field.name.as_str()
60+
)?;
5661

5762
// Currently does not apply custom formatting for ty,
5863
let current_variant_length = variant_length[index];
@@ -65,10 +70,14 @@ impl Format for ItemEnum {
6570
// TODO: Improve handling this
6671
formatted_code.push_str(&(0..required_alignment).map(|_| ' ').collect::<String>());
6772
}
68-
formatted_code.push_str(" : ");
6973
// TODO: We are currently converting ty to string directly but we will probably need to format ty before adding.
70-
formatted_code.push_str(type_field.ty.span().as_str());
71-
formatted_code.push(',');
74+
write!(
75+
formatted_code,
76+
" {} {}{}",
77+
type_field.colon_token.span().as_str(),
78+
type_field.ty.span().as_str(),
79+
PunctKind::Comma.as_char(),
80+
)?;
7281

7382
// TODO: Here we assume that next enum variant is going to be in the new line but
7483
// from the config we may understand next enum variant should be in the same line instead.

sway-fmt-v2/src/items/item_struct.rs

Lines changed: 28 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
use crate::{
22
config::items::ItemBraceStyle,
33
fmt::{Format, FormattedCode, Formatter},
4-
utils::{
5-
bracket::{AngleBracket, CurlyBrace},
6-
item_len::ItemLen,
7-
},
4+
utils::{bracket::CurlyBrace, item_len::ItemLen},
85
FormatterError,
96
};
10-
use sway_parse::ItemStruct;
7+
use std::fmt::Write;
8+
use sway_parse::{
9+
token::{Delimiter, PunctKind},
10+
ItemStruct,
11+
};
1112
use sway_types::Spanned;
1213

1314
impl Format for ItemStruct {
@@ -26,12 +27,11 @@ impl Format for ItemStruct {
2627
let struct_lit_single_line = formatter.config.structures.struct_lit_single_line;
2728

2829
// Get the width limit of a struct to be formatted into single line if struct_lit_single_line is true.
29-
let config_whitespace = formatter.config.whitespace;
3030
let width_heuristics = formatter
3131
.config
3232
.heuristics
3333
.heuristics_pref
34-
.to_width_heuristics(&config_whitespace);
34+
.to_width_heuristics(&formatter.config.whitespace);
3535
let struct_lit_width = width_heuristics.struct_lit_width;
3636

3737
let multiline = !struct_lit_single_line || self.get_formatted_len() > struct_lit_width;
@@ -65,43 +65,29 @@ fn format_struct(
6565
) -> Result<(), FormatterError> {
6666
// If there is a visibility token add it to the formatted_code with a ` ` after it.
6767
if let Some(visibility) = &item_struct.visibility {
68-
formatted_code.push_str(visibility.span().as_str());
69-
formatted_code.push(' ');
68+
write!(formatted_code, "{} ", visibility.span().as_str())?;
7069
}
7170
// Add struct token
72-
formatted_code.push_str(item_struct.struct_token.span().as_str());
73-
formatted_code.push(' ');
71+
write!(
72+
formatted_code,
73+
"{} ",
74+
item_struct.struct_token.span().as_str()
75+
)?;
7476

7577
// Add struct name
7678
formatted_code.push_str(item_struct.name.as_str());
7779

78-
// Check if there is generic provided
80+
// Format `GenericParams`, if any
7981
if let Some(generics) = &item_struct.generics {
80-
// Push angle brace
81-
ItemStruct::open_angle_bracket(formatted_code, formatter)?;
82-
// Get generics fields
83-
let generics = generics.parameters.inner.value_separator_pairs.clone();
84-
for (index, generic) in generics.iter().enumerate() {
85-
// Push ident
86-
formatted_code.push_str(generic.0.as_str());
87-
if index != generics.len() - 1 {
88-
// Push `, ` if this is not the last generic
89-
formatted_code.push_str(", ");
90-
}
91-
}
82+
generics.format(formatted_code, formatter)?;
9283
}
9384

9485
// Handle openning brace
9586
if multiline {
9687
ItemStruct::open_curly_brace(formatted_code, formatter)?;
9788
formatted_code.push('\n');
9889
} else {
99-
// Push a single whitespace before `{`
100-
formatted_code.push(' ');
101-
// Push open brace
102-
formatted_code.push('{');
103-
// Push a single whitespace after `{`
104-
formatted_code.push(' ');
90+
write!(formatted_code, " {} ", Delimiter::Brace.as_open_char())?;
10591
}
10692

10793
let items = item_struct
@@ -140,17 +126,19 @@ fn format_struct(
140126
// TODO: Improve handling this
141127
formatted_code.push_str(&(0..required_alignment).map(|_| ' ').collect::<String>());
142128
}
143-
// Add `:`
144-
formatted_code.push_str(type_field.colon_token.ident().as_str());
145-
formatted_code.push(' ');
129+
// Add `:` and ty
146130
// TODO: We are currently converting ty to string directly but we will probably need to format ty before adding.
147-
// Add ty
148-
formatted_code.push_str(type_field.ty.span().as_str());
131+
write!(
132+
formatted_code,
133+
"{} {}",
134+
type_field.colon_token.ident().as_str(),
135+
type_field.ty.span().as_str()
136+
)?;
149137
// Add `, ` if this isn't the last field.
150138
if !multiline && item_index != items.len() - 1 {
151-
formatted_code.push_str(", ");
139+
write!(formatted_code, "{} ", PunctKind::Comma.as_char())?;
152140
} else if multiline {
153-
formatted_code.push_str(",\n");
141+
writeln!(formatted_code, "{}", PunctKind::Comma.as_char())?;
154142
}
155143
}
156144
if !multiline {
@@ -181,12 +169,12 @@ impl CurlyBrace for ItemStruct {
181169
match brace_style {
182170
ItemBraceStyle::AlwaysNextLine => {
183171
// Add openning brace to the next line.
184-
line.push_str("\n{");
172+
write!(line, "\n{}", Delimiter::Brace.as_open_char())?;
185173
shape = shape.block_indent(extra_width);
186174
}
187175
_ => {
188176
// Add opening brace to the same line
189-
line.push_str(" {");
177+
write!(line, " {}", Delimiter::Brace.as_open_char())?;
190178
shape = shape.block_indent(extra_width);
191179
}
192180
}
@@ -199,7 +187,7 @@ impl CurlyBrace for ItemStruct {
199187
line: &mut String,
200188
formatter: &mut Formatter,
201189
) -> Result<(), FormatterError> {
202-
line.push('}');
190+
line.push(Delimiter::Brace.as_close_char());
203191
// If shape is becoming left-most alligned or - indent just have the defualt shape
204192
formatter.shape = formatter
205193
.shape
@@ -208,21 +196,3 @@ impl CurlyBrace for ItemStruct {
208196
Ok(())
209197
}
210198
}
211-
212-
impl AngleBracket for ItemStruct {
213-
fn open_angle_bracket(
214-
line: &mut String,
215-
_formatter: &mut Formatter,
216-
) -> Result<(), FormatterError> {
217-
line.push('<');
218-
Ok(())
219-
}
220-
221-
fn close_angle_bracket(
222-
line: &mut String,
223-
_formatter: &mut Formatter,
224-
) -> Result<(), FormatterError> {
225-
line.push('>');
226-
Ok(())
227-
}
228-
}

sway-fmt-v2/src/utils.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
pub mod attribute;
2-
pub mod bracket;
3-
pub mod indent_style;
4-
pub mod item;
5-
pub mod item_len;
6-
pub mod newline_style;
7-
pub mod program_type;
1+
pub(crate) mod attribute;
2+
pub(crate) mod bracket;
3+
pub(crate) mod generics;
4+
pub(crate) mod indent_style;
5+
pub(crate) mod item;
6+
pub(crate) mod item_len;
7+
pub(crate) mod newline_style;
8+
pub(crate) mod program_type;
9+
pub(crate) mod punctuated;

sway-fmt-v2/src/utils/attribute.rs

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,11 @@ impl<T: Parse + Format> Format for Annotated<T> {
1818
formatted_code: &mut FormattedCode,
1919
formatter: &mut Formatter,
2020
) -> Result<(), FormatterError> {
21-
let attributes = &self.attribute_list;
22-
23-
for attr in attributes {
21+
// format each `Attribute`
22+
for attr in &self.attribute_list {
2423
attr.format(formatted_code, formatter)?;
2524
}
26-
25+
// format `ItemKind`
2726
self.value.format(formatted_code, formatter)
2827
}
2928
}
@@ -47,22 +46,9 @@ impl FormatDecl for AttributeDecl {
4746
line.push_str(attr.name.span().as_str());
4847
// `(`
4948
Self::open_parenthesis(line, formatter)?;
50-
// format and add args `read, write`
49+
// format and add args e.g. `read, write`
5150
if let Some(args) = attr.args {
52-
let args = args.into_inner().value_separator_pairs;
53-
let mut buf = args
54-
.iter()
55-
.map(|arg| format!("{}{}", arg.0.as_str(), arg.1.span().as_str()))
56-
.collect::<Vec<String>>()
57-
.join(" ");
58-
if args.len() == 1 {
59-
buf.pop(); // pop the ending comma
60-
line.push_str(&buf);
61-
} else {
62-
buf.pop(); // pop the ending space
63-
buf.pop(); // pop the ending comma
64-
line.push_str(&buf);
65-
}
51+
args.into_inner().format(line, formatter)?;
6652
}
6753
// ')'
6854
Self::close_parenthesis(line, formatter)?;
@@ -77,7 +63,7 @@ impl SquareBracket for AttributeDecl {
7763
line: &mut String,
7864
_formatter: &mut Formatter,
7965
) -> Result<(), FormatterError> {
80-
write!(line, "{}", Delimiter::Bracket.as_open_char())?;
66+
line.push(Delimiter::Bracket.as_open_char());
8167
Ok(())
8268
}
8369
fn close_square_bracket(
@@ -94,14 +80,14 @@ impl Parenthesis for AttributeDecl {
9480
line: &mut String,
9581
_formatter: &mut Formatter,
9682
) -> Result<(), FormatterError> {
97-
write!(line, "{}", Delimiter::Parenthesis.as_open_char())?;
83+
line.push(Delimiter::Parenthesis.as_open_char());
9884
Ok(())
9985
}
10086
fn close_parenthesis(
10187
line: &mut String,
10288
_formatter: &mut Formatter,
10389
) -> Result<(), FormatterError> {
104-
write!(line, "{}", Delimiter::Parenthesis.as_close_char())?;
90+
line.push(Delimiter::Parenthesis.as_close_char());
10591
Ok(())
10692
}
10793
}

0 commit comments

Comments
 (0)