diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-09-11 22:11:59 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-09-11 22:11:59 +0100 |
commit | c8623461a57e7882ac47b5da13a1a03efa58f603 (patch) | |
tree | 5559fe8ce90fff8f0e5ed9debf67a0c7306f668a | |
parent | 199ebf110353da2da4d706f72adede96149ba977 (diff) | |
parent | 779ea2ea0a0aa70075d28d72dd96c1bc1e709300 (diff) |
Merge #5981
5981: Properly preserve macro braces during dbg! removal r=jonas-schievink a=SomeoneToIgnore
Do `dbg![2 + 2] * 5` -> `(2 + 2) * 5`
This PR also implicitly handles the `{}` case too, but I decided not to add it into the test case since it's a compiler error on the latest stable rustc.
Co-authored-by: Kirill Bulatov <[email protected]>
-rw-r--r-- | crates/assists/src/handlers/remove_dbg.rs | 41 |
1 files changed, 16 insertions, 25 deletions
diff --git a/crates/assists/src/handlers/remove_dbg.rs b/crates/assists/src/handlers/remove_dbg.rs index 0b581dc22..a8ab2aecc 100644 --- a/crates/assists/src/handlers/remove_dbg.rs +++ b/crates/assists/src/handlers/remove_dbg.rs | |||
@@ -43,15 +43,18 @@ pub(crate) fn remove_dbg(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | |||
43 | 43 | ||
44 | fn adjusted_macro_contents(macro_call: &ast::MacroCall) -> Option<String> { | 44 | fn adjusted_macro_contents(macro_call: &ast::MacroCall) -> Option<String> { |
45 | let contents = get_valid_macrocall_contents(¯o_call, "dbg")?; | 45 | let contents = get_valid_macrocall_contents(¯o_call, "dbg")?; |
46 | let is_leaf = macro_call.syntax().next_sibling().is_none(); | ||
47 | let macro_text_with_brackets = macro_call.token_tree()?.syntax().text(); | 46 | let macro_text_with_brackets = macro_call.token_tree()?.syntax().text(); |
48 | let slice_index = if is_leaf || !needs_parentheses_around_macro_contents(contents) { | 47 | let macro_text_in_brackets = macro_text_with_brackets.slice(TextRange::new( |
49 | TextRange::new(TextSize::of('('), macro_text_with_brackets.len() - TextSize::of(')')) | 48 | TextSize::of('('), |
49 | macro_text_with_brackets.len() - TextSize::of(')'), | ||
50 | )); | ||
51 | |||
52 | let is_leaf = macro_call.syntax().next_sibling().is_none(); | ||
53 | Some(if !is_leaf && needs_parentheses_around_macro_contents(contents) { | ||
54 | format!("({})", macro_text_in_brackets) | ||
50 | } else { | 55 | } else { |
51 | // leave parenthesis around macro contents to preserve the semantics | 56 | macro_text_in_brackets.to_string() |
52 | TextRange::up_to(macro_text_with_brackets.len()) | 57 | }) |
53 | }; | ||
54 | Some(macro_text_with_brackets.slice(slice_index).to_string()) | ||
55 | } | 58 | } |
56 | 59 | ||
57 | /// Verifies that the given macro_call actually matches the given name | 60 | /// Verifies that the given macro_call actually matches the given name |
@@ -90,19 +93,10 @@ fn needs_parentheses_around_macro_contents(macro_contents: Vec<SyntaxElement>) - | |||
90 | if macro_contents.len() < 2 { | 93 | if macro_contents.len() < 2 { |
91 | return false; | 94 | return false; |
92 | } | 95 | } |
93 | |||
94 | let mut macro_contents_kind_not_in_brackets = Vec::with_capacity(macro_contents.len()); | ||
95 | |||
96 | let mut first_bracket_in_macro = None; | ||
97 | let mut unpaired_brackets_in_contents = Vec::new(); | 96 | let mut unpaired_brackets_in_contents = Vec::new(); |
98 | for element in macro_contents { | 97 | for element in macro_contents { |
99 | match element.kind() { | 98 | match element.kind() { |
100 | T!['('] | T!['['] | T!['{'] => { | 99 | T!['('] | T!['['] | T!['{'] => unpaired_brackets_in_contents.push(element), |
101 | if let None = first_bracket_in_macro { | ||
102 | first_bracket_in_macro = Some(element.clone()) | ||
103 | } | ||
104 | unpaired_brackets_in_contents.push(element); | ||
105 | } | ||
106 | T![')'] => { | 100 | T![')'] => { |
107 | if !matches!(unpaired_brackets_in_contents.pop(), Some(correct_bracket) if correct_bracket.kind() == T!['(']) | 101 | if !matches!(unpaired_brackets_in_contents.pop(), Some(correct_bracket) if correct_bracket.kind() == T!['(']) |
108 | { | 102 | { |
@@ -121,19 +115,15 @@ fn needs_parentheses_around_macro_contents(macro_contents: Vec<SyntaxElement>) - | |||
121 | return true; | 115 | return true; |
122 | } | 116 | } |
123 | } | 117 | } |
124 | other_kind => { | 118 | symbol_kind => { |
125 | if unpaired_brackets_in_contents.is_empty() { | 119 | let symbol_not_in_bracket = unpaired_brackets_in_contents.is_empty(); |
126 | macro_contents_kind_not_in_brackets.push(other_kind); | 120 | if symbol_not_in_bracket && symbol_kind.is_punct() { |
121 | return true; | ||
127 | } | 122 | } |
128 | } | 123 | } |
129 | } | 124 | } |
130 | } | 125 | } |
131 | |||
132 | !unpaired_brackets_in_contents.is_empty() | 126 | !unpaired_brackets_in_contents.is_empty() |
133 | || matches!(first_bracket_in_macro, Some(bracket) if bracket.kind() != T!['(']) | ||
134 | || macro_contents_kind_not_in_brackets | ||
135 | .into_iter() | ||
136 | .any(|macro_contents_kind| macro_contents_kind.is_punct()) | ||
137 | } | 127 | } |
138 | 128 | ||
139 | #[cfg(test)] | 129 | #[cfg(test)] |
@@ -244,6 +234,7 @@ fn main() { | |||
244 | ); | 234 | ); |
245 | 235 | ||
246 | check_assist(remove_dbg, r#"let res = <|>dbg!(2 + 2) * 5"#, r#"let res = (2 + 2) * 5"#); | 236 | check_assist(remove_dbg, r#"let res = <|>dbg!(2 + 2) * 5"#, r#"let res = (2 + 2) * 5"#); |
237 | check_assist(remove_dbg, r#"let res = <|>dbg![2 + 2] * 5"#, r#"let res = (2 + 2) * 5"#); | ||
247 | } | 238 | } |
248 | 239 | ||
249 | #[test] | 240 | #[test] |