From 71faa8984d9b82b0e0a4d0e145fd541512697c7d Mon Sep 17 00:00:00 2001 From: Marcus Klaas Date: Mon, 21 Sep 2015 20:02:45 +0200 Subject: [PATCH] Format foreign functions and statics --- src/items.rs | 130 ++++++++++++++++++++++++++++++++++++----- src/visitor.rs | 17 +++--- tests/source/extern.rs | 21 +++++++ tests/target/extern.rs | 29 +++++++++ 4 files changed, 172 insertions(+), 25 deletions(-) create mode 100644 tests/source/extern.rs create mode 100644 tests/target/extern.rs diff --git a/src/items.rs b/src/items.rs index a61925798d3..33e0a2a11b4 100644 --- a/src/items.rs +++ b/src/items.rs @@ -33,8 +33,18 @@ impl<'a> FmtVisitor<'a> { let mut infix = String::new(); if let Some(ref ty) = local.ty { - infix.push_str(": "); - infix.push_str(&ty.rewrite(&self.get_context(), 1000, Indent::empty()).unwrap()); + // 2 = ": ".len() + let offset = self.block_indent + 2; + let width = self.config.max_width - offset.width(); + let rewrite = ty.rewrite(&self.get_context(), width, offset); + + match rewrite { + Some(result) => { + infix.push_str(": "); + infix.push_str(&result); + } + None => return, + } } if local.init.is_some() { @@ -88,15 +98,103 @@ impl<'a> FmtVisitor<'a> { self.last_pos = span.hi; } + 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)); + } + + let snippet = self.snippet(span); + let brace_pos = snippet.find_uncommented("{").unwrap() as u32; + + // FIXME: this skips comments between the extern keyword and the opening + // brace. + self.last_pos = span.lo + BytePos(brace_pos); + self.block_indent = self.block_indent.block_indent(self.config); + + for item in &fm.items { + self.format_foreign_item(&*item); + } + + self.block_indent = self.block_indent.block_unindent(self.config); + self.format_missing_with_indent(span.hi - BytePos(1)); + self.buffer.push_str("}"); + self.last_pos = span.hi; + } + + fn format_foreign_item(&mut self, item: &ast::ForeignItem) { + self.format_missing_with_indent(item.span.lo); + // Drop semicolon or it will be interpreted as comment. + // FIXME: this may be a faulty span from libsyntax. + let span = codemap::mk_sp(item.span.lo, item.span.hi - BytePos(1)); + + match item.node { + ast::ForeignItem_::ForeignItemFn(ref fn_decl, ref generics) => { + let indent = self.block_indent; + let rewrite = self.rewrite_fn_base(indent, + item.ident, + fn_decl, + None, + generics, + ast::Unsafety::Normal, + ast::Constness::NotConst, + // These are not actually rust functions, + // but we format them as such. + abi::Abi::Rust, + ast::Visibility::Inherited, + span, + false); + + match rewrite { + Some(new_fn) => { + self.buffer.push_str(format_visibility(item.vis)); + self.buffer.push_str(&new_fn); + self.buffer.push_str(";"); + } + None => self.format_missing(item.span.hi), + } + } + ast::ForeignItem_::ForeignItemStatic(ref ty, is_mutable) => { + // FIXME(#21): we're dropping potential comments in between the + // function keywords here. + let mut_str = if is_mutable { + "mut " + } else { + "" + }; + let prefix = format!("{}static {}{}: ", + format_visibility(item.vis), + mut_str, + item.ident); + let offset = self.block_indent + prefix.len(); + // 1 = ; + let width = self.config.max_width - offset.width() - 1; + let rewrite = ty.rewrite(&self.get_context(), width, offset); + + match rewrite { + Some(result) => { + self.buffer.push_str(&prefix); + self.buffer.push_str(&result); + self.buffer.push_str(";"); + } + None => self.format_missing(item.span.hi), + } + } + } + + self.last_pos = item.span.hi; + } + pub fn rewrite_fn(&mut self, indent: Indent, ident: ast::Ident, fd: &ast::FnDecl, explicit_self: Option<&ast::ExplicitSelf>, generics: &ast::Generics, - unsafety: &ast::Unsafety, - constness: &ast::Constness, - abi: &abi::Abi, + unsafety: ast::Unsafety, + constness: ast::Constness, + abi: abi::Abi, vis: ast::Visibility, span: Span) -> Option { @@ -147,9 +245,9 @@ impl<'a> FmtVisitor<'a> { &sig.decl, Some(&sig.explicit_self), &sig.generics, - &sig.unsafety, - &sig.constness, - &sig.abi, + sig.unsafety, + sig.constness, + sig.abi, ast::Visibility::Inherited, span, false)); @@ -166,9 +264,9 @@ impl<'a> FmtVisitor<'a> { fd: &ast::FnDecl, explicit_self: Option<&ast::ExplicitSelf>, generics: &ast::Generics, - unsafety: &ast::Unsafety, - constness: &ast::Constness, - abi: &abi::Abi, + unsafety: ast::Unsafety, + constness: ast::Constness, + abi: abi::Abi, vis: ast::Visibility, span: Span, newline_brace: bool) @@ -182,13 +280,13 @@ impl<'a> FmtVisitor<'a> { // Vis unsafety abi. result.push_str(format_visibility(vis)); - if let &ast::Unsafety::Unsafe = unsafety { + if let ast::Unsafety::Unsafe = unsafety { result.push_str("unsafe "); } - if let &ast::Constness::Const = constness { + if let ast::Constness::Const = constness { result.push_str("const "); } - if *abi != abi::Rust { + if abi != abi::Rust { result.push_str("extern "); result.push_str(&abi.to_string()); result.push(' '); @@ -497,11 +595,11 @@ impl<'a> FmtVisitor<'a> { } self.block_indent = self.block_indent.block_unindent(self.config); - self.format_missing_with_indent(span.lo + BytePos(enum_snippet.rfind('}').unwrap() as u32)); + self.format_missing_with_indent(span.hi - BytePos(1)); self.buffer.push_str("}"); } - // Variant of an enum + // Variant of an enum. fn visit_variant(&mut self, field: &ast::Variant, last_field: bool, next_span_start: BytePos) { if self.visit_attrs(&field.node.attrs) { return; diff --git a/src/visitor.rs b/src/visitor.rs index f15c2e07b82..8c46d69ebfc 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -132,12 +132,7 @@ impl<'a, 'v> visit::Visitor<'v> for FmtVisitor<'a> { let indent = self.block_indent; let rewrite = match fk { - visit::FnKind::ItemFn(ident, - ref generics, - ref unsafety, - ref constness, - ref abi, - vis) => { + visit::FnKind::ItemFn(ident, ref generics, unsafety, constness, abi, vis) => { self.rewrite_fn(indent, ident, fd, @@ -155,9 +150,9 @@ impl<'a, 'v> visit::Visitor<'v> for FmtVisitor<'a> { fd, Some(&sig.explicit_self), &sig.generics, - &sig.unsafety, - &sig.constness, - &sig.abi, + sig.unsafety, + sig.constness, + sig.abi, vis.unwrap_or(ast::Visibility::Inherited), codemap::mk_sp(s.lo, b.span.lo)) } @@ -224,6 +219,10 @@ impl<'a, 'v> visit::Visitor<'v> for FmtVisitor<'a> { // See rust lang issue #28424. // visit::walk_item(self, item); } + ast::Item_::ItemForeignMod(ref foreign_mod) => { + self.format_missing_with_indent(item.span.lo); + self.format_foreign_mod(foreign_mod, item.span); + } _ => { visit::walk_item(self, item); } diff --git a/tests/source/extern.rs b/tests/source/extern.rs new file mode 100644 index 00000000000..2e7b6c14646 --- /dev/null +++ b/tests/source/extern.rs @@ -0,0 +1,21 @@ + + extern "C" { + fn c_func(x: *mut *mut libc::c_void); + + fn c_func(x: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX, y: YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY); + + #[test123] + fn foo() -> uint64_t; + +pub fn bar() ; + } + +extern { + fn DMR_GetDevice(pHDev: *mut HDEV, searchMode: DeviceSearchMode, pSearchString: *const c_char, devNr: c_uint, wildcard: c_char) -> TDMR_ERROR; + + fn quux() -> (); // Post comment +} + +extern "Rust" { static ext: u32; + // Some comment. + pub static mut var : SomeType ; } diff --git a/tests/target/extern.rs b/tests/target/extern.rs new file mode 100644 index 00000000000..2c6f4936bff --- /dev/null +++ b/tests/target/extern.rs @@ -0,0 +1,29 @@ + +extern { + fn c_func(x: *mut *mut libc::c_void); + + fn c_func(x: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX, + y: YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY); + + #[test123] + fn foo() -> uint64_t; + + pub fn bar(); +} + +extern { + fn DMR_GetDevice(pHDev: *mut HDEV, + searchMode: DeviceSearchMode, + pSearchString: *const c_char, + devNr: c_uint, + wildcard: c_char) + -> TDMR_ERROR; + + fn quux() -> (); // Post comment +} + +extern "Rust" { + static ext: u32; + // Some comment. + pub static mut var: SomeType; +}