aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-09-11 22:11:59 +0100
committerGitHub <[email protected]>2020-09-11 22:11:59 +0100
commitc8623461a57e7882ac47b5da13a1a03efa58f603 (patch)
tree5559fe8ce90fff8f0e5ed9debf67a0c7306f668a
parent199ebf110353da2da4d706f72adede96149ba977 (diff)
parent779ea2ea0a0aa70075d28d72dd96c1bc1e709300 (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.rs41
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
44fn adjusted_macro_contents(macro_call: &ast::MacroCall) -> Option<String> { 44fn adjusted_macro_contents(macro_call: &ast::MacroCall) -> Option<String> {
45 let contents = get_valid_macrocall_contents(&macro_call, "dbg")?; 45 let contents = get_valid_macrocall_contents(&macro_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]