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

Adds Generics handling to sway-fmt-v2 #2110

Merged
merged 22 commits into from
Jun 28, 2022
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
10 changes: 5 additions & 5 deletions sway-fmt-v2/src/fmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ impl Formatter {
let program_type = module.kind;

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

Expand Down Expand Up @@ -124,14 +124,14 @@ pub struct Foo { bar: u64, baz: bool }"#;
#[test]
fn test_struct_multiline_line_alignment() {
let sway_code_to_format = r#"contract;
pub struct Foo {
pub struct Foo<T, P> {
barbazfoo: u64,
baz : bool,
}
"#;
let correct_sway_code = r#"contract;

pub struct Foo {
pub struct Foo<T, P> {
barbazfoo: u64,
baz : bool,
}"#;
Expand Down Expand Up @@ -239,7 +239,7 @@ enum Color {
let sway_code_to_format = r#"contract;

abi StorageMapExample {
#[storage(write,)]fn insert_into_map1(key: u64, value: u64);
#[storage(write)]fn insert_into_map1(key: u64, value: u64);

fn hello(key: u64, value: u64);
}"#;
Expand Down
4 changes: 2 additions & 2 deletions sway-fmt-v2/src/items/item_abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ impl Format for ItemAbi {
formatter: &mut Formatter,
) -> Result<(), FormatterError> {
// Add enum token
formatted_code.push_str(self.abi_token.span().as_str());
formatted_code.push(' ');
write!(formatted_code, "{} ", self.abi_token.span().as_str())?;

// Add name of the abi
formatted_code.push_str(self.name.as_str());
Expand Down Expand Up @@ -70,6 +69,7 @@ impl Format for ItemAbi {
}
}
Self::close_curly_brace(formatted_code, formatter)?;

Ok(())
}
}
Expand Down
29 changes: 19 additions & 10 deletions sway-fmt-v2/src/items/item_enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ use crate::{
FormatterError,
};
use std::fmt::Write;
use sway_parse::{token::Delimiter, ItemEnum};
use sway_parse::{
token::{Delimiter, PunctKind},
ItemEnum,
};
use sway_types::Spanned;

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

if let Some(visibility_token) = &self.visibility {
formatted_code.push_str(visibility_token.span().as_str());
formatted_code.push(' ');
write!(formatted_code, "{} ", visibility_token.span().as_str())?;
}

// Add enum token
formatted_code.push_str(self.enum_token.span().as_str());
formatted_code.push(' ');
write!(formatted_code, "{} ", self.enum_token.span().as_str())?;

// Add name of the enum.
formatted_code.push_str(self.name.as_str());
Expand Down Expand Up @@ -51,8 +52,12 @@ impl Format for ItemEnum {
for (index, type_field) in type_fields.iter().enumerate() {
let type_field = &type_field.0;
// Push the current indentation level
formatted_code.push_str(&formatter.shape.indent.to_string(formatter));
formatted_code.push_str(type_field.name.as_str());
write!(
formatted_code,
"{}{}",
&formatter.shape.indent.to_string(formatter),
type_field.name.as_str()
)?;

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

// TODO: Here we assume that next enum variant is going to be in the new line but
// from the config we may understand next enum variant should be in the same line instead.
Expand Down
86 changes: 28 additions & 58 deletions sway-fmt-v2/src/items/item_struct.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
use crate::{
config::items::ItemBraceStyle,
fmt::{Format, FormattedCode, Formatter},
utils::{
bracket::{AngleBracket, CurlyBrace},
item_len::ItemLen,
},
utils::{bracket::CurlyBrace, item_len::ItemLen},
FormatterError,
};
use sway_parse::ItemStruct;
use std::fmt::Write;
use sway_parse::{
token::{Delimiter, PunctKind},
ItemStruct,
};
use sway_types::Spanned;

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

// Get the width limit of a struct to be formatted into single line if struct_lit_single_line is true.
let config_whitespace = formatter.config.whitespace;
let width_heuristics = formatter
.config
.heuristics
.heuristics_pref
.to_width_heuristics(&config_whitespace);
.to_width_heuristics(&formatter.config.whitespace);
let struct_lit_width = width_heuristics.struct_lit_width;

let multiline = !struct_lit_single_line || self.get_formatted_len() > struct_lit_width;
Expand Down Expand Up @@ -65,43 +65,29 @@ fn format_struct(
) -> Result<(), FormatterError> {
// If there is a visibility token add it to the formatted_code with a ` ` after it.
if let Some(visibility) = &item_struct.visibility {
formatted_code.push_str(visibility.span().as_str());
formatted_code.push(' ');
write!(formatted_code, "{} ", visibility.span().as_str())?;
}
// Add struct token
formatted_code.push_str(item_struct.struct_token.span().as_str());
formatted_code.push(' ');
write!(
formatted_code,
"{} ",
item_struct.struct_token.span().as_str()
)?;

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

// Check if there is generic provided
// Format `GenericParams`, if any
if let Some(generics) = &item_struct.generics {
// Push angle brace
ItemStruct::open_angle_bracket(formatted_code, formatter)?;
// Get generics fields
let generics = generics.parameters.inner.value_separator_pairs.clone();
for (index, generic) in generics.iter().enumerate() {
// Push ident
formatted_code.push_str(generic.0.as_str());
if index != generics.len() - 1 {
// Push `, ` if this is not the last generic
formatted_code.push_str(", ");
}
}
generics.format(formatted_code, formatter)?;
}

// Handle openning brace
if multiline {
ItemStruct::open_curly_brace(formatted_code, formatter)?;
formatted_code.push('\n');
} else {
// Push a single whitespace before `{`
formatted_code.push(' ');
// Push open brace
formatted_code.push('{');
// Push a single whitespace after `{`
formatted_code.push(' ');
write!(formatted_code, " {} ", Delimiter::Brace.as_open_char())?;
}

let items = item_struct
Expand Down Expand Up @@ -140,17 +126,19 @@ fn format_struct(
// TODO: Improve handling this
formatted_code.push_str(&(0..required_alignment).map(|_| ' ').collect::<String>());
}
// Add `:`
formatted_code.push_str(type_field.colon_token.ident().as_str());
formatted_code.push(' ');
// Add `:` and ty
// TODO: We are currently converting ty to string directly but we will probably need to format ty before adding.
// Add ty
formatted_code.push_str(type_field.ty.span().as_str());
write!(
formatted_code,
"{} {}",
type_field.colon_token.ident().as_str(),
type_field.ty.span().as_str()
)?;
// Add `, ` if this isn't the last field.
if !multiline && item_index != items.len() - 1 {
formatted_code.push_str(", ");
write!(formatted_code, "{} ", PunctKind::Comma.as_char())?;
} else if multiline {
formatted_code.push_str(",\n");
writeln!(formatted_code, "{}", PunctKind::Comma.as_char())?;
}
}
if !multiline {
Expand Down Expand Up @@ -181,12 +169,12 @@ impl CurlyBrace for ItemStruct {
match brace_style {
ItemBraceStyle::AlwaysNextLine => {
// Add openning brace to the next line.
line.push_str("\n{");
write!(line, "\n{}", Delimiter::Brace.as_open_char())?;
shape = shape.block_indent(extra_width);
}
_ => {
// Add opening brace to the same line
line.push_str(" {");
write!(line, " {}", Delimiter::Brace.as_open_char())?;
shape = shape.block_indent(extra_width);
}
}
Expand All @@ -199,7 +187,7 @@ impl CurlyBrace for ItemStruct {
line: &mut String,
formatter: &mut Formatter,
) -> Result<(), FormatterError> {
line.push('}');
line.push(Delimiter::Brace.as_close_char());
// If shape is becoming left-most alligned or - indent just have the defualt shape
formatter.shape = formatter
.shape
Expand All @@ -208,21 +196,3 @@ impl CurlyBrace for ItemStruct {
Ok(())
}
}

impl AngleBracket for ItemStruct {
fn open_angle_bracket(
line: &mut String,
_formatter: &mut Formatter,
) -> Result<(), FormatterError> {
line.push('<');
Ok(())
}

fn close_angle_bracket(
line: &mut String,
_formatter: &mut Formatter,
) -> Result<(), FormatterError> {
line.push('>');
Ok(())
}
}
16 changes: 9 additions & 7 deletions sway-fmt-v2/src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
pub mod attribute;
pub mod bracket;
pub mod indent_style;
pub mod item;
pub mod item_len;
pub mod newline_style;
pub mod program_type;
pub(crate) mod attribute;
pub(crate) mod bracket;
pub(crate) mod generics;
pub(crate) mod indent_style;
pub(crate) mod item;
pub(crate) mod item_len;
pub(crate) mod newline_style;
pub(crate) mod program_type;
pub(crate) mod punctuated;
30 changes: 8 additions & 22 deletions sway-fmt-v2/src/utils/attribute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,11 @@ impl<T: Parse + Format> Format for Annotated<T> {
formatted_code: &mut FormattedCode,
formatter: &mut Formatter,
) -> Result<(), FormatterError> {
let attributes = &self.attribute_list;

for attr in attributes {
// format each `Attribute`
for attr in &self.attribute_list {
attr.format(formatted_code, formatter)?;
}

// format `ItemKind`
self.value.format(formatted_code, formatter)
}
}
Expand All @@ -47,22 +46,9 @@ impl FormatDecl for AttributeDecl {
line.push_str(attr.name.span().as_str());
// `(`
Self::open_parenthesis(line, formatter)?;
// format and add args `read, write`
// format and add args e.g. `read, write`
if let Some(args) = attr.args {
let args = args.into_inner().value_separator_pairs;
let mut buf = args
.iter()
.map(|arg| format!("{}{}", arg.0.as_str(), arg.1.span().as_str()))
.collect::<Vec<String>>()
.join(" ");
if args.len() == 1 {
buf.pop(); // pop the ending comma
line.push_str(&buf);
} else {
buf.pop(); // pop the ending space
buf.pop(); // pop the ending comma
line.push_str(&buf);
}
args.into_inner().format(line, formatter)?;
}
// ')'
Self::close_parenthesis(line, formatter)?;
Expand All @@ -77,7 +63,7 @@ impl SquareBracket for AttributeDecl {
line: &mut String,
_formatter: &mut Formatter,
) -> Result<(), FormatterError> {
write!(line, "{}", Delimiter::Bracket.as_open_char())?;
line.push(Delimiter::Bracket.as_open_char());
Ok(())
}
fn close_square_bracket(
Expand All @@ -94,14 +80,14 @@ impl Parenthesis for AttributeDecl {
line: &mut String,
_formatter: &mut Formatter,
) -> Result<(), FormatterError> {
write!(line, "{}", Delimiter::Parenthesis.as_open_char())?;
line.push(Delimiter::Parenthesis.as_open_char());
Ok(())
}
fn close_parenthesis(
line: &mut String,
_formatter: &mut Formatter,
) -> Result<(), FormatterError> {
write!(line, "{}", Delimiter::Parenthesis.as_close_char())?;
line.push(Delimiter::Parenthesis.as_close_char());
Ok(())
}
}
Loading