Merge pull request #637 from marcusklaas/fn-type

Improve function type formatting
This commit is contained in:
Nick Cameron 2015-11-23 07:22:26 +13:00
commit 0b845c10eb
8 changed files with 960 additions and 852 deletions

File diff suppressed because it is too large Load diff

View file

@ -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};
@ -200,11 +201,7 @@ fn rewrite_segment(expr_context: bool,
">",
|param| param.get_span().lo,
|param| param.get_span().hi,
|seg| {
seg.rewrite(context,
context.config.max_width,
offset + extra_offset)
},
|seg| seg.rewrite(context, list_width, offset + extra_offset),
list_lo,
span_hi);
let list_str = try_opt!(format_item_list(items,
@ -218,30 +215,12 @@ fn rewrite_segment(expr_context: bool,
format!("{}<{}>", separator, list_str)
}
ast::PathParameters::ParenthesizedParameters(ref data) => {
let output = match data.output {
Some(ref ty) => {
let type_str = try_opt!(ty.rewrite(context, width, offset));
format!(" -> {}", type_str)
}
None => String::new(),
};
// 2 for ()
let budget = try_opt!(width.checked_sub(output.len() + 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);
let list_str = try_opt!(format_fn_args(items, budget, offset, context.config));
format!("({}){}", list_str, 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(),
};
@ -249,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?
@ -492,13 +514,47 @@ impl Rewrite for ast::Ty {
None
}
}
ast::TyBareFn(..) => {
wrap_str(pprust::ty_to_string(self),
context.config.max_width,
width,
offset)
ast::TyBareFn(ref bare_fn) => {
rewrite_bare_fn(bare_fn, self.span, context, width, offset)
}
ast::TyMac(..) | ast::TyTypeof(..) => unreachable!(),
}
}
}
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)
}

View file

@ -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;
@ -45,6 +46,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 {
@ -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 {

View file

@ -220,20 +220,24 @@ impl<'a> FmtVisitor<'a> {
self.last_pos = item.span.hi;
}
ast::Item_::ItemStruct(ref def, ref generics) => {
let indent = self.block_indent;
let rewrite = self.format_struct("struct ",
item.ident,
item.vis,
def,
Some(generics),
item.span,
indent)
.map(|s| {
match *def {
ast::VariantData::Tuple(..) => s + ";",
_ => s,
}
});
let rewrite = {
let indent = self.block_indent;
let context = self.get_context();
::items::format_struct(&context,
"struct ",
item.ident,
item.vis,
def,
Some(generics),
item.span,
indent)
.map(|s| {
match *def {
ast::VariantData::Tuple(..) => s + ";",
_ => s,
}
})
};
self.push_rewrite(item.span, rewrite);
}
ast::Item_::ItemEnum(ref def, ref generics) => {

View file

@ -1,6 +1,9 @@
fn simple(/*pre-comment on a function!?*/ i: i32/*yes, it's possible! */
,response: NoWay /* hose */) {"cool"}
,response: NoWay /* hose */) {
fn op(x: Typ, key : &[u8], upd : Box<Fn(Option<&memcache::Item>) -> (memcache::Status, Result<memcache::Item, Option<String>>)>) -> MapResult {}
"cool"}
fn weird_comment(/* /*/ double level */ comment */ x: Hello /*/*/* tripple, even */*/*/,
@ -29,3 +32,12 @@ fn zzzzzzzzzzzzzzzzzzzz<Type, NodeType>
(selff: Type, mut handle: node::Handle<IdRef<'id, Node<K, V>>, Type, NodeType>)
-> SearchStack<'a, K, V, Type, NodeType>{
}
unsafe fn generic_call(cx: *mut JSContext, argc: libc::c_uint, vp: *mut JSVal,
is_lenient: bool,
call: unsafe extern fn(*const JSJitInfo, *mut JSContext,
HandleObject, *mut libc::c_void, u32,
*mut JSVal)
-> u8) {
let f: fn ( _ , _ ) -> _ = panic!() ;
}

View file

@ -1,5 +1,5 @@
extern {
extern "C" {
fn c_func(x: *mut *mut libc::c_void);
fn c_func(x: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,
@ -11,7 +11,7 @@ extern {
pub fn bar();
}
extern {
extern "C" {
fn DMR_GetDevice(pHDev: *mut HDEV,
searchMode: DeviceSearchMode,
pSearchString: *const c_char,
@ -28,7 +28,7 @@ extern "Rust" {
pub static mut var: SomeType;
}
extern {
extern "C" {
fn syscall(number: libc::c_long, // comment 1
// comm 2
... /* sup? */)
@ -37,7 +37,7 @@ extern {
fn foo(x: *const c_char, ...) -> libc::c_long;
}
extern {
extern "C" {
pub fn freopen(filename: *const c_char,
mode: *const c_char,
mode2: *const c_char,

View file

@ -2,6 +2,13 @@
fn simple(// pre-comment on a function!?
i: i32, // yes, it's possible!
response: NoWay /* hose */) {
fn op(x: Typ,
key: &[u8],
upd: Box<Fn(Option<&memcache::Item>)
-> (memcache::Status, Result<memcache::Item, Option<String>>)>)
-> MapResult {
}
"cool"
}
@ -23,7 +30,8 @@ fn generic<T>(arg: T) -> &SomeType
C,
D,
// pre comment
E /* last comment */) -> &SomeType
E /* last comment */)
-> &SomeType
{
arg(a, b, c, d, e)
}
@ -42,3 +50,17 @@ fn zzzzzzzzzzzzzzzzzzzz<Type, NodeType>(selff: Type,
NodeType>)
-> SearchStack<'a, K, V, Type, NodeType> {
}
unsafe fn generic_call(cx: *mut JSContext,
argc: libc::c_uint,
vp: *mut JSVal,
is_lenient: bool,
call: unsafe extern "C" fn(*const JSJitInfo,
*mut JSContext,
HandleObject,
*mut libc::c_void,
u32,
*mut JSVal)
-> u8) {
let f: fn(_, _) -> _ = panic!();
}

View file

@ -69,7 +69,8 @@ fn main() {
C,
D,
// pre comment
E /* last comment */) -> &SomeType
E /* last comment */)
-> &SomeType
{
arg(a, b, c, d, e)
}