diff options
| author | Marcus Klaas <mail@marcusklaas.nl> | 2015-11-22 16:07:38 +0100 |
|---|---|---|
| committer | Marcus Klaas <mail@marcusklaas.nl> | 2015-11-22 16:07:38 +0100 |
| commit | 840012b5e02db35a121bc69b91c77cde05f63ae7 (patch) | |
| tree | 563e1b039e5c25902b90646fc209a841399094b6 /src | |
| parent | 559f00ba9951b29c73339d94bcaeb5efa94b332a (diff) | |
Format bare function types
Fix https://github.com/rust-lang-nursery/rustfmt/issues/616. Fix https://github.com/rust-lang-nursery/rustfmt/issues/276. Close https://github.com/rust-lang-nursery/rustfmt/issues/350.
Diffstat (limited to 'src')
| -rw-r--r-- | src/items.rs | 15 | ||||
| -rw-r--r-- | src/types.rs | 130 | ||||
| -rw-r--r-- | src/utils.rs | 15 |
3 files changed, 107 insertions, 53 deletions
diff --git a/src/items.rs b/src/items.rs index d1502d173da..bbe51c73c40 100644 --- a/src/items.rs +++ b/src/items.rs @@ -80,11 +80,7 @@ impl Rewrite for ast::Local { impl<'a> FmtVisitor<'a> { pub fn format_foreign_mod(&mut self, fm: &ast::ForeignMod, span: Span) { - self.buffer.push_str("extern "); - - if fm.abi != abi::Abi::C { - self.buffer.push_str(&format!("{} ", fm.abi)); - } + self.buffer.push_str(&::utils::format_abi(fm.abi)); let snippet = self.snippet(span); let brace_pos = snippet.find_uncommented("{").unwrap() as u32; @@ -856,17 +852,14 @@ fn rewrite_fn_base(context: &RewriteContext, let mut result = String::with_capacity(1024); // Vis unsafety abi. result.push_str(format_visibility(vis)); + result.push_str(::utils::format_unsafety(unsafety)); - if let ast::Unsafety::Unsafe = unsafety { - result.push_str("unsafe "); - } if let ast::Constness::Const = constness { result.push_str("const "); } + if abi != abi::Rust { - result.push_str("extern "); - result.push_str(&abi.to_string()); - result.push(' '); + result.push_str(&::utils::format_abi(abi)); } // fn foo diff --git a/src/types.rs b/src/types.rs index 6d8ee483b14..807f0f17a43 100644 --- a/src/types.rs +++ b/src/types.rs @@ -8,9 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use syntax::ast::{self, Mutability}; +use syntax::ast::{self, Mutability, FunctionRetTy}; use syntax::print::pprust; use syntax::codemap::{self, Span, BytePos}; +use syntax::abi; use Indent; use lists::{format_item_list, itemize_list, format_fn_args}; @@ -214,43 +215,12 @@ fn rewrite_segment(expr_context: bool, format!("{}<{}>", separator, list_str) } ast::PathParameters::ParenthesizedParameters(ref data) => { - // 2 for () - let budget = try_opt!(width.checked_sub(2)); - // 1 for ( - let offset = offset + 1; - let list_lo = span_after(data.span, "(", context.codemap); - let items = itemize_list(context.codemap, - data.inputs.iter(), - ")", - |ty| ty.span.lo, - |ty| ty.span.hi, - |ty| ty.rewrite(context, budget, offset), - list_lo, - span_hi); - println!("got here"); - - let list_str = try_opt!(format_fn_args(items, budget, offset, context.config)); - - println!("got here 2"); - let output = match data.output { - Some(ref ty) => { - let budget = try_opt!(width.checked_sub(4)); - let type_str = try_opt!(ty.rewrite(context, budget, offset + 4)); - format!(" -> {}", type_str) - } - None => String::new(), - }; - - println!("got here 3"); - - let infix = if output.len() + list_str.len() > width { - format!("\n{}", (offset - 1).to_string(context.config)) - } else { - String::new() - }; - println!("({}){}{}", &list_str, &infix, &output); - - format!("({}){}{}", list_str, infix, output) + try_opt!(format_function_type(data.inputs.iter().map(|x| &**x), + data.output.as_ref().map(|x| &**x), + data.span, + context, + width, + offset)) } _ => String::new(), }; @@ -258,6 +228,49 @@ fn rewrite_segment(expr_context: bool, Some(format!("{}{}", segment.identifier, params)) } +fn format_function_type<'a, I>(inputs: I, + output: Option<&ast::Ty>, + span: Span, + context: &RewriteContext, + width: usize, + offset: Indent) + -> Option<String> + where I: Iterator<Item = &'a ast::Ty> +{ + // 2 for () + let budget = try_opt!(width.checked_sub(2)); + // 1 for ( + let offset = offset + 1; + let list_lo = span_after(span, "(", context.codemap); + let items = itemize_list(context.codemap, + inputs, + ")", + |ty| ty.span.lo, + |ty| ty.span.hi, + |ty| ty.rewrite(context, budget, offset), + list_lo, + span.hi); + + let list_str = try_opt!(format_fn_args(items, budget, offset, context.config)); + + let output = match output { + Some(ref ty) => { + let budget = try_opt!(width.checked_sub(4)); + let type_str = try_opt!(ty.rewrite(context, budget, offset + 4)); + format!(" -> {}", type_str) + } + None => String::new(), + }; + + let infix = if output.len() + list_str.len() > width { + format!("\n{}", (offset - 1).to_string(context.config)) + } else { + String::new() + }; + + Some(format!("({}){}{}", list_str, infix, output)) +} + impl Rewrite for ast::WherePredicate { fn rewrite(&self, context: &RewriteContext, width: usize, offset: Indent) -> Option<String> { // TODO: dead spans? @@ -501,14 +514,47 @@ impl Rewrite for ast::Ty { None } } - ast::TyBareFn(ref bare_fn) => bare_fn.rewrite(context, width, offset), + ast::TyBareFn(ref bare_fn) => { + rewrite_bare_fn(bare_fn, self.span, context, width, offset) + } ast::TyMac(..) | ast::TyTypeof(..) => unreachable!(), } } } -impl Rewrite for ast::BareFnTy { - fn rewrite(&self, context: &RewriteContext, width: usize, offset: Indent) -> Option<String> { - None +fn rewrite_bare_fn(bare_fn: &ast::BareFnTy, + span: Span, + context: &RewriteContext, + width: usize, + offset: Indent) + -> Option<String> { + let mut result = String::with_capacity(128); + + result.push_str(&::utils::format_unsafety(bare_fn.unsafety)); + + if bare_fn.abi != abi::Rust { + result.push_str(&::utils::format_abi(bare_fn.abi)); } + + result.push_str("fn"); + + let output = match bare_fn.decl.output { + FunctionRetTy::Return(ref ty) => Some(&**ty), + FunctionRetTy::NoReturn(..) => None, + FunctionRetTy::DefaultReturn(..) => unreachable!(), + }; + + let budget = try_opt!(width.checked_sub(result.len())); + let indent = offset + result.len(); + + let rewrite = try_opt!(format_function_type(bare_fn.decl.inputs.iter().map(|x| &*(x.ty)), + output, + span, + context, + budget, + indent)); + + result.push_str(&rewrite); + + Some(result) } diff --git a/src/utils.rs b/src/utils.rs index 37dfb756972..6170b0c5ee0 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -12,6 +12,7 @@ use std::cmp::Ordering; use syntax::ast::{self, Visibility, Attribute, MetaItem, MetaItem_}; use syntax::codemap::{CodeMap, Span, BytePos}; +use syntax::abi; use Indent; use comment::FindUncommented; @@ -46,6 +47,14 @@ pub fn format_visibility(vis: Visibility) -> &'static str { } #[inline] +pub fn format_unsafety(unsafety: ast::Unsafety) -> &'static str { + match unsafety { + ast::Unsafety::Unsafe => "unsafe ", + ast::Unsafety::Normal => "", + } +} + +#[inline] pub fn format_mutability(mutability: ast::Mutability) -> &'static str { match mutability { ast::Mutability::MutMutable => "mut ", @@ -53,6 +62,12 @@ pub fn format_mutability(mutability: ast::Mutability) -> &'static str { } } +#[inline] +// FIXME(#451): include "C"? +pub fn format_abi(abi: abi::Abi) -> String { + format!("extern {} ", abi) +} + // The width of the first line in s. #[inline] pub fn first_line_width(s: &str) -> usize { |
