Merge pull request #637 from marcusklaas/fn-type
Improve function type formatting
This commit is contained in:
commit
0b845c10eb
8 changed files with 960 additions and 852 deletions
1590
src/items.rs
1590
src/items.rs
File diff suppressed because it is too large
Load diff
126
src/types.rs
126
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};
|
||||
|
@ -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)
|
||||
}
|
||||
|
|
15
src/utils.rs
15
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;
|
||||
|
@ -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 {
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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!() ;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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!();
|
||||
}
|
||||
|
|
|
@ -69,7 +69,8 @@ fn main() {
|
|||
C,
|
||||
D,
|
||||
// pre comment
|
||||
E /* last comment */) -> &SomeType
|
||||
E /* last comment */)
|
||||
-> &SomeType
|
||||
{
|
||||
arg(a, b, c, d, e)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue