Merge pull request #208 from cassiersg/rewrite-attrs
Implement Rewrite for [ast::Attribute]
This commit is contained in:
commit
9e4e445315
40
src/expr.rs
40
src/expr.rs
@ -31,7 +31,7 @@ impl Rewrite for ast::Expr {
|
|||||||
ast::Lit_::LitStr(ref is, ast::StrStyle::CookedStr) => {
|
ast::Lit_::LitStr(ref is, ast::StrStyle::CookedStr) => {
|
||||||
rewrite_string_lit(context, &is, l.span, width, offset)
|
rewrite_string_lit(context, &is, l.span, width, offset)
|
||||||
}
|
}
|
||||||
_ => context.codemap.span_to_snippet(self.span).ok(),
|
_ => Some(context.snippet(self.span)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::Expr_::ExprCall(ref callee, ref args) => {
|
ast::Expr_::ExprCall(ref callee, ref args) => {
|
||||||
@ -137,7 +137,7 @@ impl Rewrite for ast::Expr {
|
|||||||
_ => {
|
_ => {
|
||||||
// We do not format these expressions yet, but they should still
|
// We do not format these expressions yet, but they should still
|
||||||
// satisfy our width restrictions.
|
// satisfy our width restrictions.
|
||||||
let snippet = context.codemap.span_to_snippet(self.span).unwrap();
|
let snippet = context.snippet(self.span);
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut lines = snippet.lines();
|
let mut lines = snippet.lines();
|
||||||
@ -243,7 +243,7 @@ fn rewrite_closure(capture: ast::CaptureClause,
|
|||||||
|
|
||||||
impl Rewrite for ast::Block {
|
impl Rewrite for ast::Block {
|
||||||
fn rewrite(&self, context: &RewriteContext, width: usize, offset: usize) -> Option<String> {
|
fn rewrite(&self, context: &RewriteContext, width: usize, offset: usize) -> Option<String> {
|
||||||
let user_str = context.codemap.span_to_snippet(self.span).unwrap();
|
let user_str = context.snippet(self.span);
|
||||||
if user_str == "{}" && width >= 2 {
|
if user_str == "{}" && width >= 2 {
|
||||||
return Some(user_str);
|
return Some(user_str);
|
||||||
}
|
}
|
||||||
@ -254,7 +254,7 @@ impl Rewrite for ast::Block {
|
|||||||
let prefix = match self.rules {
|
let prefix = match self.rules {
|
||||||
ast::BlockCheckMode::PushUnsafeBlock(..) |
|
ast::BlockCheckMode::PushUnsafeBlock(..) |
|
||||||
ast::BlockCheckMode::UnsafeBlock(..) => {
|
ast::BlockCheckMode::UnsafeBlock(..) => {
|
||||||
let snippet = try_opt!(context.codemap.span_to_snippet(self.span).ok());
|
let snippet = context.snippet(self.span);
|
||||||
let open_pos = try_opt!(snippet.find_uncommented("{"));
|
let open_pos = try_opt!(snippet.find_uncommented("{"));
|
||||||
visitor.last_pos = self.span.lo + BytePos(open_pos as u32);
|
visitor.last_pos = self.span.lo + BytePos(open_pos as u32);
|
||||||
|
|
||||||
@ -289,7 +289,7 @@ impl Rewrite for ast::Block {
|
|||||||
// FIXME(#18): implement pattern formatting
|
// FIXME(#18): implement pattern formatting
|
||||||
impl Rewrite for ast::Pat {
|
impl Rewrite for ast::Pat {
|
||||||
fn rewrite(&self, context: &RewriteContext, _: usize, _: usize) -> Option<String> {
|
fn rewrite(&self, context: &RewriteContext, _: usize, _: usize) -> Option<String> {
|
||||||
context.codemap.span_to_snippet(self.span).ok()
|
Some(context.snippet(self.span))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -547,11 +547,9 @@ fn rewrite_match(context: &RewriteContext,
|
|||||||
for (i, arm) in arms.iter().enumerate() {
|
for (i, arm) in arms.iter().enumerate() {
|
||||||
// Make sure we get the stuff between arms.
|
// Make sure we get the stuff between arms.
|
||||||
let missed_str = if i == 0 {
|
let missed_str = if i == 0 {
|
||||||
context.codemap.span_to_snippet(mk_sp(open_brace_pos + BytePos(1),
|
context.snippet(mk_sp(open_brace_pos + BytePos(1), arm_start_pos(arm)))
|
||||||
arm_start_pos(arm))).unwrap()
|
|
||||||
} else {
|
} else {
|
||||||
context.codemap.span_to_snippet(mk_sp(arm_end_pos(&arms[i-1]),
|
context.snippet(mk_sp(arm_end_pos(&arms[i-1]), arm_start_pos(arm)))
|
||||||
arm_start_pos(arm))).unwrap()
|
|
||||||
};
|
};
|
||||||
let missed_str = match missed_str.find_uncommented(",") {
|
let missed_str = match missed_str.find_uncommented(",") {
|
||||||
Some(n) => &missed_str[n+1..],
|
Some(n) => &missed_str[n+1..],
|
||||||
@ -582,8 +580,7 @@ fn rewrite_match(context: &RewriteContext,
|
|||||||
result.push_str(arm_str);
|
result.push_str(arm_str);
|
||||||
} else {
|
} else {
|
||||||
// We couldn't format the arm, just reproduce the source.
|
// We couldn't format the arm, just reproduce the source.
|
||||||
let snippet = context.codemap.span_to_snippet(mk_sp(arm_start_pos(arm),
|
let snippet = context.snippet(mk_sp(arm_start_pos(arm), arm_end_pos(arm)));
|
||||||
arm_end_pos(arm))).unwrap();
|
|
||||||
result.push_str(&snippet);
|
result.push_str(&snippet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -626,8 +623,7 @@ impl Rewrite for ast::Arm {
|
|||||||
attr_visitor.last_pos = attrs[0].span.lo;
|
attr_visitor.last_pos = attrs[0].span.lo;
|
||||||
if attr_visitor.visit_attrs(attrs) {
|
if attr_visitor.visit_attrs(attrs) {
|
||||||
// Attributes included a skip instruction.
|
// Attributes included a skip instruction.
|
||||||
let snippet = context.codemap.span_to_snippet(mk_sp(attrs[0].span.lo,
|
let snippet = context.snippet(mk_sp(attrs[0].span.lo, body.span.hi));
|
||||||
body.span.hi)).unwrap();
|
|
||||||
return Some(snippet);
|
return Some(snippet);
|
||||||
}
|
}
|
||||||
attr_visitor.format_missing(pats[0].span.lo);
|
attr_visitor.format_missing(pats[0].span.lo);
|
||||||
@ -652,7 +648,7 @@ impl Rewrite for ast::Arm {
|
|||||||
// If the patterns were previously stacked, keep them stacked.
|
// If the patterns were previously stacked, keep them stacked.
|
||||||
// FIXME should be an option.
|
// FIXME should be an option.
|
||||||
let pat_span = mk_sp(pats[0].span.lo, pats[pats.len() - 1].span.hi);
|
let pat_span = mk_sp(pats[0].span.lo, pats[pats.len() - 1].span.hi);
|
||||||
let pat_str = context.codemap.span_to_snippet(pat_span).unwrap();
|
let pat_str = context.snippet(pat_span);
|
||||||
vertical = pat_str.find('\n').is_some();
|
vertical = pat_str.find('\n').is_some();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -831,7 +827,7 @@ fn rewrite_string_lit(context: &RewriteContext,
|
|||||||
let l_loc = context.codemap.lookup_char_pos(span.lo);
|
let l_loc = context.codemap.lookup_char_pos(span.lo);
|
||||||
let r_loc = context.codemap.lookup_char_pos(span.hi);
|
let r_loc = context.codemap.lookup_char_pos(span.hi);
|
||||||
if l_loc.line == r_loc.line && r_loc.col.to_usize() <= context.config.max_width {
|
if l_loc.line == r_loc.line && r_loc.col.to_usize() <= context.config.max_width {
|
||||||
return context.codemap.span_to_snippet(span).ok();
|
return Some(context.snippet(span));
|
||||||
}
|
}
|
||||||
let fmt = StringFormat {
|
let fmt = StringFormat {
|
||||||
opener: "\"",
|
opener: "\"",
|
||||||
@ -880,7 +876,7 @@ fn rewrite_call(context: &RewriteContext,
|
|||||||
// Take old span when rewrite fails.
|
// Take old span when rewrite fails.
|
||||||
|item| {
|
|item| {
|
||||||
item.rewrite(inner_context, remaining_width, offset)
|
item.rewrite(inner_context, remaining_width, offset)
|
||||||
.unwrap_or(context.codemap.span_to_snippet(item.span).unwrap())
|
.unwrap_or(context.snippet(item.span))
|
||||||
},
|
},
|
||||||
callee.span.hi + BytePos(1),
|
callee.span.hi + BytePos(1),
|
||||||
span.hi);
|
span.hi);
|
||||||
@ -977,15 +973,13 @@ fn rewrite_struct_lit<'a>(context: &RewriteContext,
|
|||||||
match *item {
|
match *item {
|
||||||
StructLitField::Regular(ref field) => {
|
StructLitField::Regular(ref field) => {
|
||||||
rewrite_field(inner_context, &field, h_budget, indent)
|
rewrite_field(inner_context, &field, h_budget, indent)
|
||||||
.unwrap_or(context.codemap.span_to_snippet(field.span)
|
.unwrap_or(context.snippet(field.span))
|
||||||
.unwrap())
|
|
||||||
}
|
}
|
||||||
StructLitField::Base(ref expr) => {
|
StructLitField::Base(ref expr) => {
|
||||||
// 2 = ..
|
// 2 = ..
|
||||||
expr.rewrite(inner_context, h_budget - 2, indent + 2)
|
expr.rewrite(inner_context, h_budget - 2, indent + 2)
|
||||||
.map(|s| format!("..{}", s))
|
.map(|s| format!("..{}", s))
|
||||||
.unwrap_or(context.codemap.span_to_snippet(expr.span)
|
.unwrap_or(context.snippet(expr.span))
|
||||||
.unwrap())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -1053,7 +1047,7 @@ fn rewrite_tuple_lit(context: &RewriteContext,
|
|||||||
|item| {
|
|item| {
|
||||||
let inner_width = context.config.max_width - indent - 1;
|
let inner_width = context.config.max_width - indent - 1;
|
||||||
item.rewrite(context, inner_width, indent)
|
item.rewrite(context, inner_width, indent)
|
||||||
.unwrap_or(context.codemap.span_to_snippet(item.span).unwrap())
|
.unwrap_or(context.snippet(item.span))
|
||||||
},
|
},
|
||||||
span.lo + BytePos(1), // Remove parens
|
span.lo + BytePos(1), // Remove parens
|
||||||
span.hi - BytePos(1));
|
span.hi - BytePos(1));
|
||||||
@ -1072,7 +1066,7 @@ fn rewrite_binary_op(context: &RewriteContext,
|
|||||||
-> Option<String> {
|
-> Option<String> {
|
||||||
// FIXME: format comments between operands and operator
|
// FIXME: format comments between operands and operator
|
||||||
|
|
||||||
let operator_str = context.codemap.span_to_snippet(op.span).unwrap();
|
let operator_str = context.snippet(op.span);
|
||||||
|
|
||||||
// Get "full width" rhs and see if it fits on the current line. This
|
// Get "full width" rhs and see if it fits on the current line. This
|
||||||
// usually works fairly well since it tends to place operands of
|
// usually works fairly well since it tends to place operands of
|
||||||
@ -1150,7 +1144,7 @@ fn rewrite_assignment(context: &RewriteContext,
|
|||||||
offset: usize)
|
offset: usize)
|
||||||
-> Option<String> {
|
-> Option<String> {
|
||||||
let operator_str = match op {
|
let operator_str = match op {
|
||||||
Some(op) => context.codemap.span_to_snippet(op.span).unwrap(),
|
Some(op) => context.snippet(op.span),
|
||||||
None => "=".to_owned(),
|
None => "=".to_owned(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -17,7 +17,6 @@ use lists::{write_list, itemize_list, ListItem, ListFormatting, SeparatorTactic,
|
|||||||
use expr::rewrite_assign_rhs;
|
use expr::rewrite_assign_rhs;
|
||||||
use comment::FindUncommented;
|
use comment::FindUncommented;
|
||||||
use visitor::FmtVisitor;
|
use visitor::FmtVisitor;
|
||||||
|
|
||||||
use rewrite::Rewrite;
|
use rewrite::Rewrite;
|
||||||
use config::Config;
|
use config::Config;
|
||||||
|
|
||||||
@ -699,7 +698,11 @@ impl<'a> FmtVisitor<'a> {
|
|||||||
let typ = pprust::ty_to_string(&field.node.ty);
|
let typ = pprust::ty_to_string(&field.node.ty);
|
||||||
|
|
||||||
let indent = self.block_indent + self.config.tab_spaces;
|
let indent = self.block_indent + self.config.tab_spaces;
|
||||||
let mut attr_str = self.rewrite_attrs(&field.node.attrs, indent);
|
let mut attr_str = field.node.attrs
|
||||||
|
.rewrite(&self.get_context(),
|
||||||
|
self.config.max_width - indent,
|
||||||
|
indent)
|
||||||
|
.unwrap();
|
||||||
if !attr_str.is_empty() {
|
if !attr_str.is_empty() {
|
||||||
attr_str.push('\n');
|
attr_str.push('\n');
|
||||||
attr_str.push_str(&make_indent(indent));
|
attr_str.push_str(&make_indent(indent));
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
// A generic trait to abstract the rewriting of an element (of the AST).
|
// A generic trait to abstract the rewriting of an element (of the AST).
|
||||||
|
|
||||||
use syntax::codemap::CodeMap;
|
use syntax::codemap::{CodeMap, Span};
|
||||||
|
|
||||||
use config::Config;
|
use config::Config;
|
||||||
|
|
||||||
@ -39,4 +39,8 @@ impl<'a> RewriteContext<'a> {
|
|||||||
block_indent: self.block_indent + self.config.tab_spaces,
|
block_indent: self.block_indent + self.config.tab_spaces,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn snippet(&self, span: Span) -> String {
|
||||||
|
self.codemap.span_to_snippet(span).unwrap()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ use strings::string_buffer::StringBuffer;
|
|||||||
use utils;
|
use utils;
|
||||||
use config::Config;
|
use config::Config;
|
||||||
use rewrite::{Rewrite, RewriteContext};
|
use rewrite::{Rewrite, RewriteContext};
|
||||||
|
use comment::rewrite_comment;
|
||||||
|
|
||||||
pub struct FmtVisitor<'a> {
|
pub struct FmtVisitor<'a> {
|
||||||
pub codemap: &'a CodeMap,
|
pub codemap: &'a CodeMap,
|
||||||
@ -293,7 +294,10 @@ impl<'a> FmtVisitor<'a> {
|
|||||||
if utils::contains_skip(attrs) {
|
if utils::contains_skip(attrs) {
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
let rewrite = self.rewrite_attrs(attrs, self.block_indent);
|
let rewrite = attrs.rewrite(&self.get_context(),
|
||||||
|
self.config.max_width - self.block_indent,
|
||||||
|
self.block_indent)
|
||||||
|
.unwrap();
|
||||||
self.buffer.push_str(&rewrite);
|
self.buffer.push_str(&rewrite);
|
||||||
let last = attrs.last().unwrap();
|
let last = attrs.last().unwrap();
|
||||||
self.last_pos = last.span.hi;
|
self.last_pos = last.span.hi;
|
||||||
@ -301,40 +305,6 @@ impl<'a> FmtVisitor<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rewrite_attrs(&self, attrs: &[ast::Attribute], indent: usize) -> String {
|
|
||||||
let mut result = String::new();
|
|
||||||
let indent = utils::make_indent(indent);
|
|
||||||
|
|
||||||
for (i, a) in attrs.iter().enumerate() {
|
|
||||||
let a_str = self.snippet(a.span);
|
|
||||||
|
|
||||||
if i > 0 {
|
|
||||||
let comment = self.snippet(codemap::mk_sp(attrs[i-1].span.hi, a.span.lo));
|
|
||||||
// This particular horror show is to preserve line breaks in between doc
|
|
||||||
// comments. An alternative would be to force such line breaks to start
|
|
||||||
// with the usual doc comment token.
|
|
||||||
let multi_line = a_str.starts_with("//") && comment.matches('\n').count() > 1;
|
|
||||||
let comment = comment.trim();
|
|
||||||
if !comment.is_empty() {
|
|
||||||
result.push_str(&indent);
|
|
||||||
result.push_str(comment);
|
|
||||||
result.push('\n');
|
|
||||||
} else if multi_line {
|
|
||||||
result.push('\n');
|
|
||||||
}
|
|
||||||
result.push_str(&indent);
|
|
||||||
}
|
|
||||||
|
|
||||||
result.push_str(&a_str);
|
|
||||||
|
|
||||||
if i < attrs.len() - 1 {
|
|
||||||
result.push('\n');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result
|
|
||||||
}
|
|
||||||
|
|
||||||
fn format_mod(&mut self, m: &ast::Mod, s: Span, ident: ast::Ident) {
|
fn format_mod(&mut self, m: &ast::Mod, s: Span, ident: ast::Ident) {
|
||||||
debug!("FmtVisitor::format_mod: ident: {:?}, span: {:?}", ident, s);
|
debug!("FmtVisitor::format_mod: ident: {:?}, span: {:?}", ident, s);
|
||||||
|
|
||||||
@ -402,3 +372,46 @@ impl<'a> FmtVisitor<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> Rewrite for [ast::Attribute] {
|
||||||
|
fn rewrite(&self, context: &RewriteContext, _: usize, offset: usize) -> Option<String> {
|
||||||
|
let mut result = String::new();
|
||||||
|
if self.is_empty() {
|
||||||
|
return Some(result);
|
||||||
|
}
|
||||||
|
let indent = utils::make_indent(offset);
|
||||||
|
|
||||||
|
for (i, a) in self.iter().enumerate() {
|
||||||
|
let a_str = context.snippet(a.span);
|
||||||
|
|
||||||
|
if i > 0 {
|
||||||
|
let comment = context.snippet(codemap::mk_sp(self[i-1].span.hi, a.span.lo));
|
||||||
|
// This particular horror show is to preserve line breaks in between doc
|
||||||
|
// comments. An alternative would be to force such line breaks to start
|
||||||
|
// with the usual doc comment token.
|
||||||
|
let multi_line = a_str.starts_with("//") && comment.matches('\n').count() > 1;
|
||||||
|
let comment = comment.trim();
|
||||||
|
if !comment.is_empty() {
|
||||||
|
let comment = rewrite_comment(comment,
|
||||||
|
false,
|
||||||
|
context.config.max_width - offset,
|
||||||
|
offset);
|
||||||
|
result.push_str(&indent);
|
||||||
|
result.push_str(&comment);
|
||||||
|
result.push('\n');
|
||||||
|
} else if multi_line {
|
||||||
|
result.push('\n');
|
||||||
|
}
|
||||||
|
result.push_str(&indent);
|
||||||
|
}
|
||||||
|
|
||||||
|
result.push_str(&a_str);
|
||||||
|
|
||||||
|
if i < self.len() - 1 {
|
||||||
|
result.push('\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
43
tests/source/attrib.rs
Normal file
43
tests/source/attrib.rs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// Test attributes and doc comments are preserved.
|
||||||
|
|
||||||
|
/// Blah blah blah.
|
||||||
|
/// Blah blah blah.
|
||||||
|
/// Blah blah blah.
|
||||||
|
/// Blah blah blah.
|
||||||
|
|
||||||
|
/// Blah blah blah.
|
||||||
|
impl Bar {
|
||||||
|
/// Blah blah blooo.
|
||||||
|
/// Blah blah blooo.
|
||||||
|
/// Blah blah blooo.
|
||||||
|
/// Blah blah blooo.
|
||||||
|
#[an_attribute]
|
||||||
|
fn foo(&mut self) -> isize {
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Blah blah bing.
|
||||||
|
/// Blah blah bing.
|
||||||
|
/// Blah blah bing.
|
||||||
|
|
||||||
|
|
||||||
|
/// Blah blah bing.
|
||||||
|
/// Blah blah bing.
|
||||||
|
/// Blah blah bing.
|
||||||
|
pub fn f2(self) {
|
||||||
|
(foo, bar)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[another_attribute]
|
||||||
|
fn f3(self) -> Dog {
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Blah blah bing.
|
||||||
|
|
||||||
|
#[attrib1]
|
||||||
|
/// Blah blah bing.
|
||||||
|
#[attrib2]
|
||||||
|
// Another comment that needs rewrite because it's tooooooooooooooooooooooooooooooo loooooooooooong.
|
||||||
|
/// Blah blah bing.
|
||||||
|
fn f4(self) -> Cat {
|
||||||
|
}
|
||||||
|
}
|
@ -29,4 +29,14 @@ impl Bar {
|
|||||||
#[another_attribute]
|
#[another_attribute]
|
||||||
fn f3(self) -> Dog {
|
fn f3(self) -> Dog {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Blah blah bing.
|
||||||
|
#[attrib1]
|
||||||
|
/// Blah blah bing.
|
||||||
|
#[attrib2]
|
||||||
|
// Another comment that needs rewrite because it's tooooooooooooooooooooooooooooooo
|
||||||
|
// loooooooooooong.
|
||||||
|
/// Blah blah bing.
|
||||||
|
fn f4(self) -> Cat {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user