From 7d448c2b26bd26825d8c83315992cc9175e1d09c Mon Sep 17 00:00:00 2001 From: topecongiro Date: Fri, 29 Sep 2017 12:45:42 +0900 Subject: [PATCH 1/6] Implement FnSig type --- src/items.rs | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/src/items.rs b/src/items.rs index 9d35c83501f..805be05c44b 100644 --- a/src/items.rs +++ b/src/items.rs @@ -15,6 +15,7 @@ use syntax::{abi, ast, ptr, symbol}; use syntax::ast::ImplItem; use syntax::codemap::{BytePos, Span}; +use syntax::visit; use spanned::Spanned; use codemap::{LineRangeUtils, SpanUtils}; @@ -159,6 +160,74 @@ enum BodyElement<'a> { ForeignItem(&'a ast::ForeignItem), } +/// Represents a fn's signature. +pub struct FnSig<'a> { + decl: &'a ast::FnDecl, + generics: &'a ast::Generics, + abi: abi::Abi, + constness: ast::Constness, + defaultness: ast::Defaultness, + unsafety: ast::Unsafety, + visibility: ast::Visibility, +} + +impl<'a> FnSig<'a> { + pub fn new( + decl: &'a ast::FnDecl, + generics: &'a ast::Generics, + vis: ast::Visibility, + ) -> FnSig<'a> { + FnSig { + decl: decl, + generics: generics, + abi: abi::Abi::Rust, + constness: ast::Constness::NotConst, + defaultness: ast::Defaultness::Final, + unsafety: ast::Unsafety::Normal, + visibility: vis, + } + } + + pub fn from_method_sig(method_sig: &'a ast::MethodSig) -> FnSig { + FnSig { + unsafety: method_sig.unsafety, + constness: method_sig.constness.node, + defaultness: ast::Defaultness::Final, + abi: method_sig.abi, + decl: &*method_sig.decl, + generics: &method_sig.generics, + visibility: ast::Visibility::Inherited, + } + } + + pub fn from_fn_kind( + fn_kind: &'a visit::FnKind, + decl: &'a ast::FnDecl, + defualtness: ast::Defaultness, + ) -> FnSig<'a> { + match *fn_kind { + visit::FnKind::ItemFn(_, generics, unsafety, constness, abi, visibility, _) => FnSig { + decl: decl, + generics: generics, + abi: abi, + constness: constness.node, + defaultness: defualtness, + unsafety: unsafety, + visibility: visibility.clone(), + }, + visit::FnKind::Method(_, ref method_sig, vis, _) => { + let mut fn_sig = FnSig::from_method_sig(method_sig); + fn_sig.defaultness = defualtness; + if let Some(vis) = vis { + fn_sig.visibility = vis.clone(); + } + fn_sig + } + _ => unreachable!(), + } + } +} + impl<'a> FmtVisitor<'a> { fn format_item(&mut self, item: Item) { self.buffer.push_str(&item.abi); From 2e6825cc8cf5447b7b13423a56a723d80c6116d9 Mon Sep 17 00:00:00 2001 From: topecongiro Date: Fri, 29 Sep 2017 12:49:39 +0900 Subject: [PATCH 2/6] Use FnSig in rewrite_fn() and rewrite_fn_base() --- src/items.rs | 65 ++++++++++++++------------------------------------ src/visitor.rs | 22 ++++------------- 2 files changed, 23 insertions(+), 64 deletions(-) diff --git a/src/items.rs b/src/items.rs index 805be05c44b..f74ae83cdf4 100644 --- a/src/items.rs +++ b/src/items.rs @@ -285,13 +285,7 @@ pub fn rewrite_fn( &mut self, indent: Indent, ident: ast::Ident, - fd: &ast::FnDecl, - generics: &ast::Generics, - unsafety: ast::Unsafety, - constness: ast::Constness, - defaultness: ast::Defaultness, - abi: abi::Abi, - vis: &ast::Visibility, + fn_sig: &FnSig, span: Span, block: &ast::Block, ) -> Option { @@ -300,19 +294,14 @@ pub fn rewrite_fn( let block_snippet = self.snippet(mk_sp(block.span.lo(), block.span.hi())); let has_body = !block_snippet[1..block_snippet.len() - 1].trim().is_empty() || !context.config.fn_empty_single_line(); - let mut newline_brace = newline_for_brace(self.config, &generics.where_clause, has_body); + let mut newline_brace = + newline_for_brace(self.config, &fn_sig.generics.where_clause, has_body); let (mut result, force_newline_brace) = try_opt!(rewrite_fn_base( &context, indent, ident, - fd, - generics, - unsafety, - constness, - defaultness, - abi, - vis, + fn_sig, span, newline_brace, has_body, @@ -357,13 +346,7 @@ pub fn rewrite_required_fn( &context, indent, ident, - &sig.decl, - &sig.generics, - sig.unsafety, - sig.constness.node, - ast::Defaultness::Final, - sig.abi, - &ast::Visibility::Inherited, + &FnSig::from_method_sig(sig), span, false, false, @@ -1765,13 +1748,7 @@ fn rewrite_fn_base( context: &RewriteContext, indent: Indent, ident: ast::Ident, - fd: &ast::FnDecl, - generics: &ast::Generics, - unsafety: ast::Unsafety, - constness: ast::Constness, - defaultness: ast::Defaultness, - abi: abi::Abi, - vis: &ast::Visibility, + fn_sig: &FnSig, span: Span, newline_brace: bool, has_body: bool, @@ -1779,16 +1756,16 @@ fn rewrite_fn_base( ) -> Option<(String, bool)> { let mut force_new_line_for_brace = false; - let where_clause = &generics.where_clause; + let where_clause = &fn_sig.generics.where_clause; let mut result = String::with_capacity(1024); // Vis defaultness constness unsafety abi. - result.push_str(&*format_visibility(vis)); - result.push_str(format_defaultness(defaultness)); - result.push_str(format_constness(constness)); - result.push_str(format_unsafety(unsafety)); - if abi != abi::Abi::Rust { - result.push_str(&format_abi(abi, context.config.force_explicit_abi())); + result.push_str(&*format_visibility(&fn_sig.visibility)); + result.push_str(format_defaultness(fn_sig.defaultness)); + result.push_str(format_constness(fn_sig.constness)); + result.push_str(format_unsafety(fn_sig.unsafety)); + if fn_sig.abi != abi::Abi::Rust { + result.push_str(&format_abi(fn_sig.abi, context.config.force_explicit_abi())); } // fn foo @@ -1810,8 +1787,9 @@ fn rewrite_fn_base( indent: indent, offset: used_width, }; + let fd = fn_sig.decl; let g_span = mk_sp(span.lo(), fd.output.span().lo()); - let generics_str = try_opt!(rewrite_generics(context, generics, shape, g_span)); + let generics_str = try_opt!(rewrite_generics(context, fn_sig.generics, shape, g_span)); result.push_str(&generics_str); let snuggle_angle_bracket = generics_str @@ -1873,7 +1851,8 @@ fn rewrite_fn_base( } // A conservative estimation, to goal is to be over all parens in generics - let args_start = generics + let args_start = fn_sig + .generics .ty_params .last() .map_or(span.lo(), |tp| end_typaram(tp)); @@ -2826,15 +2805,7 @@ fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option { context, shape.indent, self.ident, - fn_decl, - generics, - ast::Unsafety::Normal, - ast::Constness::NotConst, - ast::Defaultness::Final, - // These are not actually rust functions, - // but we format them as such. - abi::Abi::Rust, - &self.vis, + &FnSig::new(fn_decl, generics, self.vis.clone()), span, false, false, diff --git a/src/visitor.rs b/src/visitor.rs index f6f46ca6188..b4657f2e0d9 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -24,7 +24,7 @@ use config::{BraceStyle, Config}; use items::{format_impl, format_struct, format_struct_struct, format_trait, rewrite_associated_impl_type, rewrite_associated_type, rewrite_static, - rewrite_type_alias}; + rewrite_type_alias, FnSig}; use lists::{itemize_list, write_list, DefinitiveListTactic, ListFormatting, SeparatorPlace, SeparatorTactic}; use macros::{rewrite_macro, MacroPosition}; @@ -237,34 +237,22 @@ fn visit_fn( let indent = self.block_indent; let block; let rewrite = match fk { - visit::FnKind::ItemFn(ident, generics, unsafety, constness, abi, vis, b) => { + visit::FnKind::ItemFn(ident, _, _, _, _, _, b) => { block = b; self.rewrite_fn( indent, ident, - fd, - generics, - unsafety, - constness.node, - defaultness, - abi, - vis, + &FnSig::from_fn_kind(&fk, fd, defaultness), mk_sp(s.lo(), b.span.lo()), b, ) } - visit::FnKind::Method(ident, sig, vis, b) => { + visit::FnKind::Method(ident, _, _, b) => { block = b; self.rewrite_fn( indent, ident, - fd, - &sig.generics, - sig.unsafety, - sig.constness.node, - defaultness, - sig.abi, - vis.unwrap_or(&ast::Visibility::Inherited), + &FnSig::from_fn_kind(&fk, fd, defaultness), mk_sp(s.lo(), b.span.lo()), b, ) From d8fc9ec05e80850f46090dfcd186d457c66fba2d Mon Sep 17 00:00:00 2001 From: topecongiro Date: Fri, 29 Sep 2017 12:50:35 +0900 Subject: [PATCH 3/6] Remove has_braces from argument --- src/items.rs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/items.rs b/src/items.rs index f74ae83cdf4..98f0dc4430e 100644 --- a/src/items.rs +++ b/src/items.rs @@ -304,7 +304,6 @@ pub fn rewrite_fn( fn_sig, span, newline_brace, - has_body, true, )); @@ -350,7 +349,6 @@ pub fn rewrite_required_fn( span, false, false, - false, )); // Re-attach semicolon @@ -1752,7 +1750,6 @@ fn rewrite_fn_base( span: Span, newline_brace: bool, has_body: bool, - has_braces: bool, ) -> Option<(String, bool)> { let mut force_new_line_for_brace = false; @@ -1773,7 +1770,7 @@ fn rewrite_fn_base( result.push_str(&ident.to_string()); // Generics. - let overhead = if has_braces && !newline_brace { + let overhead = if has_body && !newline_brace { // 4 = `() {` 4 } else { @@ -1814,7 +1811,7 @@ fn rewrite_fn_base( indent, ret_str_len, newline_brace, - has_braces, + has_body, multi_line_ret_str, )); @@ -2035,7 +2032,7 @@ fn rewrite_fn_base( } } - let option = WhereClauseOption::new(!has_braces, put_args_in_block && ret_str.is_empty()); + let option = WhereClauseOption::new(!has_body, put_args_in_block && ret_str.is_empty()); let where_clause_str = try_opt!(rewrite_where_clause( context, where_clause, @@ -2809,7 +2806,6 @@ fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option { span, false, false, - false, ).map(|(s, _)| format!("{};", s)) } ast::ForeignItemKind::Static(ref ty, is_mutable) => { From 9537437e524dcadd1da79bb833d4ed499eaa49d2 Mon Sep 17 00:00:00 2001 From: topecongiro Date: Fri, 29 Sep 2017 12:51:06 +0900 Subject: [PATCH 4/6] Use is_empty_block() --- src/items.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/items.rs b/src/items.rs index 98f0dc4430e..a22d1ec292b 100644 --- a/src/items.rs +++ b/src/items.rs @@ -291,9 +291,8 @@ pub fn rewrite_fn( ) -> Option { let context = self.get_context(); - let block_snippet = self.snippet(mk_sp(block.span.lo(), block.span.hi())); - let has_body = !block_snippet[1..block_snippet.len() - 1].trim().is_empty() - || !context.config.fn_empty_single_line(); + let has_body = + !is_empty_block(block, self.codemap) || !context.config.fn_empty_single_line(); let mut newline_brace = newline_for_brace(self.config, &fn_sig.generics.where_clause, has_body); From 62e38860b90238f901ce6d5ea7ce7ca0108b51e5 Mon Sep 17 00:00:00 2001 From: topecongiro Date: Fri, 29 Sep 2017 15:08:48 +0900 Subject: [PATCH 5/6] Handle 'extern "Rust"' in format_abi() --- src/items.rs | 10 +++------- src/types.rs | 14 ++++++-------- src/utils.rs | 6 ++++-- 3 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/items.rs b/src/items.rs index a22d1ec292b..f32ea1c803f 100644 --- a/src/items.rs +++ b/src/items.rs @@ -10,6 +10,7 @@ // Formatting top-level items - functions, structs, enums, traits, impls. +use std::borrow::Cow; use std::cmp::min; use syntax::{abi, ast, ptr, symbol}; @@ -126,7 +127,7 @@ fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option { #[allow(dead_code)] struct Item<'a> { keyword: &'static str, - abi: String, + abi: Cow<'static, str>, vis: Option<&'a ast::Visibility>, body: Vec>, span: Span, @@ -134,14 +135,9 @@ struct Item<'a> { impl<'a> Item<'a> { fn from_foreign_mod(fm: &'a ast::ForeignMod, span: Span, config: &Config) -> Item<'a> { - let abi = if fm.abi == abi::Abi::C && !config.force_explicit_abi() { - "extern".into() - } else { - format!("extern {}", fm.abi) - }; Item { keyword: "", - abi: abi, + abi: format_abi(fm.abi, config.force_explicit_abi(), true), vis: None, body: fm.items .iter() diff --git a/src/types.rs b/src/types.rs index 311192889d3..1d6c80fb939 100644 --- a/src/types.rs +++ b/src/types.rs @@ -11,7 +11,6 @@ use std::iter::ExactSizeIterator; use std::ops::Deref; -use syntax::abi; use syntax::ast::{self, FunctionRetTy, Mutability}; use syntax::codemap::{self, BytePos, Span}; use syntax::print::pprust; @@ -26,7 +25,7 @@ SeparatorPlace, SeparatorTactic}; use rewrite::{Rewrite, RewriteContext}; use shape::Shape; -use utils::{colon_spaces, extra_offset, format_mutability, last_line_width, mk_sp}; +use utils::{colon_spaces, extra_offset, format_abi, format_mutability, last_line_width, mk_sp}; #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum PathContext { @@ -792,12 +791,11 @@ fn rewrite_bare_fn( result.push_str(::utils::format_unsafety(bare_fn.unsafety)); - if bare_fn.abi != abi::Abi::Rust { - result.push_str(&::utils::format_abi( - bare_fn.abi, - context.config.force_explicit_abi(), - )); - } + result.push_str(&format_abi( + bare_fn.abi, + context.config.force_explicit_abi(), + false, + )); result.push_str("fn"); diff --git a/src/utils.rs b/src/utils.rs index 3c97044f5c4..a01e22aae29 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -88,8 +88,10 @@ pub fn format_mutability(mutability: ast::Mutability) -> &'static str { } #[inline] -pub fn format_abi(abi: abi::Abi, explicit_abi: bool) -> Cow<'static, str> { - if abi == abi::Abi::C && !explicit_abi { +pub fn format_abi(abi: abi::Abi, explicit_abi: bool, is_mod: bool) -> Cow<'static, str> { + if abi == abi::Abi::Rust && !is_mod { + Cow::from("") + } else if abi == abi::Abi::C && !explicit_abi { Cow::from("extern ") } else { Cow::from(format!("extern {} ", abi)) From 921e0c22ab0999e963fef21a0f2e162a9c809542 Mon Sep 17 00:00:00 2001 From: topecongiro Date: Fri, 29 Sep 2017 15:09:13 +0900 Subject: [PATCH 6/6] Factor out FnSig::to_str() --- src/items.rs | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/items.rs b/src/items.rs index f32ea1c803f..7e3d4442874 100644 --- a/src/items.rs +++ b/src/items.rs @@ -222,12 +222,26 @@ pub fn from_fn_kind( _ => unreachable!(), } } + + fn to_str(&self, context: &RewriteContext) -> String { + let mut result = String::with_capacity(128); + // Vis defaultness constness unsafety abi. + result.push_str(&*format_visibility(&self.visibility)); + result.push_str(format_defaultness(self.defaultness)); + result.push_str(format_constness(self.constness)); + result.push_str(format_unsafety(self.unsafety)); + result.push_str(&format_abi( + self.abi, + context.config.force_explicit_abi(), + false, + )); + result + } } impl<'a> FmtVisitor<'a> { fn format_item(&mut self, item: Item) { self.buffer.push_str(&item.abi); - self.buffer.push_str(" "); let snippet = self.snippet(item.span); let brace_pos = snippet.find_uncommented("{").unwrap(); @@ -1751,14 +1765,7 @@ fn rewrite_fn_base( let where_clause = &fn_sig.generics.where_clause; let mut result = String::with_capacity(1024); - // Vis defaultness constness unsafety abi. - result.push_str(&*format_visibility(&fn_sig.visibility)); - result.push_str(format_defaultness(fn_sig.defaultness)); - result.push_str(format_constness(fn_sig.constness)); - result.push_str(format_unsafety(fn_sig.unsafety)); - if fn_sig.abi != abi::Abi::Rust { - result.push_str(&format_abi(fn_sig.abi, context.config.force_explicit_abi())); - } + result.push_str(&fn_sig.to_str(context)); // fn foo result.push_str("fn ");