From 9e963b87fced64c0df49f263da2e577153480944 Mon Sep 17 00:00:00 2001 From: topecongiro Date: Thu, 5 Oct 2017 16:17:04 +0900 Subject: [PATCH 1/3] Add InString field to FullCodeCharKind --- src/comment.rs | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/src/comment.rs b/src/comment.rs index f74684e5862..a236c2699a6 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -464,7 +464,7 @@ impl FindUncommented for str { return Some(i - pat.len()); } Some(c) => match kind { - FullCodeCharKind::Normal if b == c => {} + FullCodeCharKind::Normal | FullCodeCharKind::InString if b == c => {} _ => { needle_iter = pat.chars(); } @@ -487,7 +487,7 @@ impl FindUncommented for str { pub fn find_comment_end(s: &str) -> Option { let mut iter = CharClasses::new(s.char_indices()); for (kind, (i, _c)) in &mut iter { - if kind == FullCodeCharKind::Normal { + if kind == FullCodeCharKind::Normal || kind == FullCodeCharKind::InString { return Some(i); } } @@ -568,15 +568,17 @@ enum FullCodeCharKind { InComment, /// Last character of a comment, '\n' for a line comment, '/' for a block comment. EndComment, + /// Inside a string. + InString, } impl FullCodeCharKind { fn is_comment(&self) -> bool { match *self { - FullCodeCharKind::Normal => false, FullCodeCharKind::StartComment | FullCodeCharKind::InComment | FullCodeCharKind::EndComment => true, + _ => false, } } @@ -612,13 +614,23 @@ where fn next(&mut self) -> Option<(FullCodeCharKind, T::Item)> { let item = try_opt!(self.base.next()); let chr = item.get_char(); + let mut char_kind = FullCodeCharKind::Normal; self.status = match self.status { CharClassesStatus::LitString => match chr { '"' => CharClassesStatus::Normal, - '\\' => CharClassesStatus::LitStringEscape, - _ => CharClassesStatus::LitString, + '\\' => { + char_kind = FullCodeCharKind::InString; + CharClassesStatus::LitStringEscape + } + _ => { + char_kind = FullCodeCharKind::InString; + CharClassesStatus::LitString + } }, - CharClassesStatus::LitStringEscape => CharClassesStatus::LitString, + CharClassesStatus::LitStringEscape => { + char_kind = FullCodeCharKind::InString; + CharClassesStatus::LitString + } CharClassesStatus::LitChar => match chr { '\\' => CharClassesStatus::LitCharEscape, '\'' => CharClassesStatus::Normal, @@ -626,7 +638,10 @@ where }, CharClassesStatus::LitCharEscape => CharClassesStatus::LitChar, CharClassesStatus::Normal => match chr { - '"' => CharClassesStatus::LitString, + '"' => { + char_kind = FullCodeCharKind::InString; + CharClassesStatus::LitString + } '\'' => CharClassesStatus::LitChar, '/' => match self.base.peek() { Some(next) if next.get_char() == '*' => { @@ -680,7 +695,7 @@ where } }, }; - Some((FullCodeCharKind::Normal, item)) + Some((char_kind, item)) } } @@ -707,9 +722,12 @@ impl<'a> Iterator for UngroupedCommentCodeSlices<'a> { fn next(&mut self) -> Option { let (kind, (start_idx, _)) = try_opt!(self.iter.next()); match kind { - FullCodeCharKind::Normal => { + FullCodeCharKind::Normal | FullCodeCharKind::InString => { // Consume all the Normal code - while let Some(&(FullCodeCharKind::Normal, (_, _))) = self.iter.peek() { + while let Some(&(char_kind, _)) = self.iter.peek() { + if char_kind.is_comment() { + break; + } let _ = self.iter.next(); } } @@ -1032,7 +1050,7 @@ mod test { fn uncommented(text: &str) -> String { CharClasses::new(text.chars()) .filter_map(|(s, c)| match s { - FullCodeCharKind::Normal => Some(c), + FullCodeCharKind::Normal | FullCodeCharKind::InString => Some(c), _ => None, }) .collect() From 106625bc5c43da24673c84c2e85e082e3f591a15 Mon Sep 17 00:00:00 2001 From: topecongiro Date: Thu, 5 Oct 2017 16:17:59 +0900 Subject: [PATCH 2/3] Remove trailing whitespaces in macro def --- src/comment.rs | 29 +++++++++++++++++++++++++++++ src/visitor.rs | 6 +++--- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/comment.rs b/src/comment.rs index a236c2699a6..3c863086a36 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -505,6 +505,35 @@ pub fn contains_comment(text: &str) -> bool { CharClasses::new(text.chars()).any(|(kind, _)| kind.is_comment()) } +/// Remove trailing spaces from the specified snippet. We do not remove spaces +/// inside strings or comments. +pub fn remove_trailing_white_spaces(text: &str) -> String { + let mut buffer = String::with_capacity(text.len()); + let mut space_buffer = String::with_capacity(128); + for (char_kind, c) in CharClasses::new(text.chars()) { + match c { + '\n' => { + if char_kind == FullCodeCharKind::InString { + buffer.push_str(&space_buffer); + } + space_buffer.clear(); + buffer.push('\n'); + } + _ if c.is_whitespace() => { + space_buffer.push(c); + } + _ => { + if !space_buffer.is_empty() { + buffer.push_str(&space_buffer); + space_buffer.clear(); + } + buffer.push(c); + } + } + } + buffer +} + struct CharClasses where T: Iterator, diff --git a/src/visitor.rs b/src/visitor.rs index f6f46ca6188..29eaea39a7f 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -18,8 +18,8 @@ use syntax::parse::ParseSess; use spanned::Spanned; use codemap::{LineRangeUtils, SpanUtils}; -use comment::{contains_comment, recover_missing_comment_in_span, CodeCharKind, CommentCodeSlices, - FindUncommented}; +use comment::{contains_comment, recover_missing_comment_in_span, remove_trailing_white_spaces, + CodeCharKind, CommentCodeSlices, FindUncommented}; use comment::rewrite_comment; use config::{BraceStyle, Config}; use items::{format_impl, format_struct, format_struct_struct, format_trait, @@ -470,7 +470,7 @@ impl<'a> FmtVisitor<'a> { } ast::ItemKind::MacroDef(..) => { // FIXME(#1539): macros 2.0 - let mac_snippet = Some(self.snippet(item.span)); + let mac_snippet = Some(remove_trailing_white_spaces(&self.snippet(item.span))); self.push_rewrite(item.span, mac_snippet); } } From 00f8610d9b0557eaf9dc28ce3e768c6d9e5d542b Mon Sep 17 00:00:00 2001 From: topecongiro Date: Thu, 5 Oct 2017 19:44:45 +0900 Subject: [PATCH 3/3] Add a test --- tests/source/macros.rs | 9 +++++++++ tests/target/macros.rs | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/tests/source/macros.rs b/tests/source/macros.rs index 10f6e2d7ea0..616a275876f 100644 --- a/tests/source/macros.rs +++ b/tests/source/macros.rs @@ -189,3 +189,12 @@ fn __bindgen_test_layout_HandleWithDtor_open0_int_close0_instantiation() { ); assert_eq ! ( :: std :: mem :: align_of :: < HandleWithDtor < :: std :: os :: raw :: c_int > > ( ) , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( HandleWithDtor < :: std :: os :: raw :: c_int > ) ) ); } + +// #878 +macro_rules! try_opt { + ($expr:expr) => (match $expr { + Some(val) => val, + + None => { return None; } + }) +} diff --git a/tests/target/macros.rs b/tests/target/macros.rs index d47063d255c..394cac3820f 100644 --- a/tests/target/macros.rs +++ b/tests/target/macros.rs @@ -240,3 +240,12 @@ fn __bindgen_test_layout_HandleWithDtor_open0_int_close0_instantiation() { ) ); } + +// #878 +macro_rules! try_opt { + ($expr:expr) => (match $expr { + Some(val) => val, + + None => { return None; } + }) +}