From 1b8f0ff1b634b5d1f00aad646b5e4a5ee6eee3ff Mon Sep 17 00:00:00 2001 From: Seiichi Uchida Date: Fri, 31 Aug 2018 18:10:47 +0900 Subject: [PATCH 1/6] Add a test for #2907 --- tests/source/chains_with_comment.rs | 26 ++++++++++++++++++++++++++ tests/target/chains_with_comment.rs | 22 ++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/tests/source/chains_with_comment.rs b/tests/source/chains_with_comment.rs index 80c118d9eccb..91160711b890 100644 --- a/tests/source/chains_with_comment.rs +++ b/tests/source/chains_with_comment.rs @@ -93,3 +93,29 @@ fn dirty_rev_dep_graph( .map(|(k, deps)| (k.clone(), deps.iter().cloned().filter(|d| dirties.contains(&d)).collect())) } } + +// #2907 +fn foo() { + let x = foo + .bar?? ? // comment + .baz; + let x = foo + .bar? ?? + // comment + .baz; + let x = foo + .bar? ? ? // comment + // comment + .baz; + let x = foo + .bar? ?? // comment + // comment + ? ?? + // comment + ? ?? + // comment + ??? + // comment + ? ? ? + .baz; +} diff --git a/tests/target/chains_with_comment.rs b/tests/target/chains_with_comment.rs index a1df27102343..35c713d80b2c 100644 --- a/tests/target/chains_with_comment.rs +++ b/tests/target/chains_with_comment.rs @@ -116,3 +116,25 @@ fn dirty_rev_dep_graph( }) } } + +// #2907 +fn foo() { + let x = foo + .bar??? // comment + .baz; + let x = foo + .bar??? + // comment + .baz; + let x = foo + .bar??? // comment + // comment + .baz; + let x = foo + .bar??????????????? // comment + // comment + // comment + // comment + // comment + .baz; +} From 2880d59ec0441476323cf2048b911e53b0cf0c37 Mon Sep 17 00:00:00 2001 From: Seiichi Uchida Date: Fri, 31 Aug 2018 18:11:52 +0900 Subject: [PATCH 2/6] Add trim_tries --- src/chains.rs | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/chains.rs b/src/chains.rs index 3f5ff75a7228..650acbd69379 100644 --- a/src/chains.rs +++ b/src/chains.rs @@ -65,7 +65,7 @@ //! .qux //! ``` -use comment::rewrite_comment; +use comment::{rewrite_comment, CharClasses, FullCodeCharKind, RichChar}; use config::IndentStyle; use expr::rewrite_call; use lists::{extract_post_comment, extract_pre_comment, get_comment_end}; @@ -870,3 +870,28 @@ fn is_block_expr(context: &RewriteContext, expr: &ast::Expr, repr: &str) -> bool _ => false, } } + +/// Remove try operators (`?`s) that appear in the given string. If removing +/// them leaves an empty line, remove that line as well unless it is the first +/// line (we need the first newline for detecting pre/post comment). +fn trim_tries(s: &str) -> String { + let mut result = String::with_capacity(s.len()); + let mut line_buffer = String::with_capacity(s.len()); + for (kind, rich_char) in CharClasses::new(s.chars()) { + match rich_char.get_char() { + '\n' => { + if result.is_empty() || !line_buffer.trim().is_empty() { + result.push_str(&line_buffer); + result.push('\n') + } + line_buffer.clear(); + } + '?' if kind == FullCodeCharKind::Normal => continue, + c => line_buffer.push(c), + } + } + if !line_buffer.trim().is_empty() { + result.push_str(&line_buffer); + } + result +} From 612f1af7347a618d96d0700e161bdac5131f6c05 Mon Sep 17 00:00:00 2001 From: Seiichi Uchida Date: Fri, 31 Aug 2018 18:11:59 +0900 Subject: [PATCH 3/6] Use trim_tries to extract pre-comments over simple trim_matches --- src/chains.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/chains.rs b/src/chains.rs index 650acbd69379..d93995c94845 100644 --- a/src/chains.rs +++ b/src/chains.rs @@ -334,9 +334,8 @@ fn handle_post_comment( // Pre-comment if handle_comment { let pre_comment_span = mk_sp(prev_span_end, chain_item.span.lo()); - let pre_comment_snippet = context.snippet(pre_comment_span); - let pre_comment_snippet = pre_comment_snippet.trim().trim_matches('?'); - let (pre_comment, _) = extract_pre_comment(pre_comment_snippet); + let pre_comment_snippet = trim_tries(context.snippet(pre_comment_span)); + let (pre_comment, _) = extract_pre_comment(&pre_comment_snippet); match pre_comment { Some(ref comment) if !comment.is_empty() => { children.push(ChainItem::comment( From 9df1dbe1aca8989d018ad85f66a1e84862c1032e Mon Sep 17 00:00:00 2001 From: Seiichi Uchida Date: Fri, 31 Aug 2018 18:16:50 +0900 Subject: [PATCH 4/6] Use trim_tries to extract post comment over simple trim_matches --- src/chains.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/chains.rs b/src/chains.rs index d93995c94845..f73f57a19a6a 100644 --- a/src/chains.rs +++ b/src/chains.rs @@ -288,9 +288,9 @@ fn handle_post_comment( return; } // HACK: Treat `?`s as separators. - let trimmed_snippet = post_comment_snippet.trim_matches('?'); - let comment_end = get_comment_end(trimmed_snippet, "?", "", false); - let maybe_post_comment = extract_post_comment(trimmed_snippet, comment_end, "?") + let trimmed_snippet = trim_tries(post_comment_snippet); + let comment_end = get_comment_end(&trimmed_snippet, "?", "", false); + let maybe_post_comment = extract_post_comment(&trimmed_snippet, comment_end, "?") .and_then(|comment| { if comment.is_empty() { None From 20aac086d6b460373c5b896c3e1680dac14d8081 Mon Sep 17 00:00:00 2001 From: Seiichi Uchida Date: Fri, 31 Aug 2018 18:19:13 +0900 Subject: [PATCH 5/6] Simplify post-comment extraction --- src/chains.rs | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/chains.rs b/src/chains.rs index f73f57a19a6a..a0174c622d50 100644 --- a/src/chains.rs +++ b/src/chains.rs @@ -68,7 +68,7 @@ use comment::{rewrite_comment, CharClasses, FullCodeCharKind, RichChar}; use config::IndentStyle; use expr::rewrite_call; -use lists::{extract_post_comment, extract_pre_comment, get_comment_end}; +use lists::extract_pre_comment; use macros::convert_try_mac; use rewrite::{Rewrite, RewriteContext}; use shape::Shape; @@ -273,6 +273,20 @@ fn is_tries(s: &str) -> bool { s.chars().all(|c| c == '?') } + fn is_post_comment(s: &str) -> bool { + let comment_start_index = s.chars().position(|c| c == '/'); + if comment_start_index.is_none() { + return false; + } + + let newline_index = s.chars().position(|c| c == '\n'); + if newline_index.is_none() { + return true; + } + + comment_start_index.unwrap() < newline_index.unwrap() + } + fn handle_post_comment( post_comment_span: Span, post_comment_snippet: &str, @@ -287,25 +301,14 @@ fn handle_post_comment( // No post comment. return; } - // HACK: Treat `?`s as separators. let trimmed_snippet = trim_tries(post_comment_snippet); - let comment_end = get_comment_end(&trimmed_snippet, "?", "", false); - let maybe_post_comment = extract_post_comment(&trimmed_snippet, comment_end, "?") - .and_then(|comment| { - if comment.is_empty() { - None - } else { - Some((comment, comment_end)) - } - }); - - if let Some((post_comment, comment_end)) = maybe_post_comment { + if is_post_comment(&trimmed_snippet) { children.push(ChainItem::comment( post_comment_span, - post_comment, + trimmed_snippet.trim().to_owned(), CommentPosition::Back, )); - *prev_span_end = *prev_span_end + BytePos(comment_end as u32); + *prev_span_end = post_comment_span.hi(); } } From ba9e15972248b043c6101cc240271dfaf1bc8fa5 Mon Sep 17 00:00:00 2001 From: Seiichi Uchida Date: Fri, 31 Aug 2018 18:19:34 +0900 Subject: [PATCH 6/6] Update tests --- tests/target/chains_with_comment.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/tests/target/chains_with_comment.rs b/tests/target/chains_with_comment.rs index 35c713d80b2c..522d70713bcd 100644 --- a/tests/target/chains_with_comment.rs +++ b/tests/target/chains_with_comment.rs @@ -31,8 +31,7 @@ fn main() { ) }); - let y = expr - /* comment */ + let y = expr /* comment */ .kaas()? // comment .test(); @@ -50,11 +49,9 @@ fn main() { let y = a .very - .loooooooooooooooooooooooooooooooooooooong() - /* comment */ + .loooooooooooooooooooooooooooooooooooooong() /* comment */ .chain() - .inside() - /* comment */ + .inside() /* comment */ .weeeeeeeeeeeeeee()? .test() .0