diff options
-rw-r--r-- | crates/assists/src/handlers/invert_if.rs | 9 | ||||
-rw-r--r-- | crates/assists/src/handlers/remove_unused_param.rs | 81 | ||||
-rw-r--r-- | crates/assists/src/utils.rs | 8 | ||||
-rw-r--r-- | editors/code/src/main.ts | 18 |
4 files changed, 104 insertions, 12 deletions
diff --git a/crates/assists/src/handlers/invert_if.rs b/crates/assists/src/handlers/invert_if.rs index 91e2f5c8c..f9c33b3f7 100644 --- a/crates/assists/src/handlers/invert_if.rs +++ b/crates/assists/src/handlers/invert_if.rs | |||
@@ -78,6 +78,15 @@ mod tests { | |||
78 | } | 78 | } |
79 | 79 | ||
80 | #[test] | 80 | #[test] |
81 | fn invert_if_remove_not_parentheses() { | ||
82 | check_assist( | ||
83 | invert_if, | ||
84 | "fn f() { i<|>f !(x == 3 || x == 4 || x == 5) { 3 * 2 } else { 1 } }", | ||
85 | "fn f() { if x == 3 || x == 4 || x == 5 { 1 } else { 3 * 2 } }", | ||
86 | ) | ||
87 | } | ||
88 | |||
89 | #[test] | ||
81 | fn invert_if_remove_inequality() { | 90 | fn invert_if_remove_inequality() { |
82 | check_assist( | 91 | check_assist( |
83 | invert_if, | 92 | invert_if, |
diff --git a/crates/assists/src/handlers/remove_unused_param.rs b/crates/assists/src/handlers/remove_unused_param.rs index 1ff5e92b0..f72dd49ed 100644 --- a/crates/assists/src/handlers/remove_unused_param.rs +++ b/crates/assists/src/handlers/remove_unused_param.rs | |||
@@ -2,9 +2,10 @@ use ide_db::{defs::Definition, search::Reference}; | |||
2 | use syntax::{ | 2 | use syntax::{ |
3 | algo::find_node_at_range, | 3 | algo::find_node_at_range, |
4 | ast::{self, ArgListOwner}, | 4 | ast::{self, ArgListOwner}, |
5 | AstNode, SyntaxNode, TextRange, T, | 5 | AstNode, SyntaxKind, SyntaxNode, TextRange, T, |
6 | }; | 6 | }; |
7 | use test_utils::mark; | 7 | use test_utils::mark; |
8 | use SyntaxKind::WHITESPACE; | ||
8 | 9 | ||
9 | use crate::{ | 10 | use crate::{ |
10 | assist_context::AssistBuilder, utils::next_prev, AssistContext, AssistId, AssistKind, Assists, | 11 | assist_context::AssistBuilder, utils::next_prev, AssistContext, AssistId, AssistKind, Assists, |
@@ -56,7 +57,7 @@ pub(crate) fn remove_unused_param(acc: &mut Assists, ctx: &AssistContext) -> Opt | |||
56 | "Remove unused parameter", | 57 | "Remove unused parameter", |
57 | param.syntax().text_range(), | 58 | param.syntax().text_range(), |
58 | |builder| { | 59 | |builder| { |
59 | builder.delete(range_with_coma(param.syntax())); | 60 | builder.delete(range_to_remove(param.syntax())); |
60 | for usage in fn_def.usages(&ctx.sema).all() { | 61 | for usage in fn_def.usages(&ctx.sema).all() { |
61 | process_usage(ctx, builder, usage, param_position); | 62 | process_usage(ctx, builder, usage, param_position); |
62 | } | 63 | } |
@@ -80,19 +81,34 @@ fn process_usage( | |||
80 | let arg = call_expr.arg_list()?.args().nth(arg_to_remove)?; | 81 | let arg = call_expr.arg_list()?.args().nth(arg_to_remove)?; |
81 | 82 | ||
82 | builder.edit_file(usage.file_range.file_id); | 83 | builder.edit_file(usage.file_range.file_id); |
83 | builder.delete(range_with_coma(arg.syntax())); | 84 | builder.delete(range_to_remove(arg.syntax())); |
84 | 85 | ||
85 | Some(()) | 86 | Some(()) |
86 | } | 87 | } |
87 | 88 | ||
88 | fn range_with_coma(node: &SyntaxNode) -> TextRange { | 89 | fn range_to_remove(node: &SyntaxNode) -> TextRange { |
89 | let up_to = next_prev().find_map(|dir| { | 90 | let up_to_comma = next_prev().find_map(|dir| { |
90 | node.siblings_with_tokens(dir) | 91 | node.siblings_with_tokens(dir) |
91 | .filter_map(|it| it.into_token()) | 92 | .filter_map(|it| it.into_token()) |
92 | .find(|it| it.kind() == T![,]) | 93 | .find(|it| it.kind() == T![,]) |
94 | .map(|it| (dir, it)) | ||
93 | }); | 95 | }); |
94 | let up_to = up_to.map_or(node.text_range(), |it| it.text_range()); | 96 | if let Some((dir, token)) = up_to_comma { |
95 | node.text_range().cover(up_to) | 97 | if node.next_sibling().is_some() { |
98 | let up_to_space = token | ||
99 | .siblings_with_tokens(dir) | ||
100 | .skip(1) | ||
101 | .take_while(|it| it.kind() == WHITESPACE) | ||
102 | .last() | ||
103 | .and_then(|it| it.into_token()); | ||
104 | return node | ||
105 | .text_range() | ||
106 | .cover(up_to_space.map_or(token.text_range(), |it| it.text_range())); | ||
107 | } | ||
108 | node.text_range().cover(token.text_range()) | ||
109 | } else { | ||
110 | node.text_range() | ||
111 | } | ||
96 | } | 112 | } |
97 | 113 | ||
98 | #[cfg(test)] | 114 | #[cfg(test)] |
@@ -119,6 +135,57 @@ fn b() { foo(9, ) } | |||
119 | } | 135 | } |
120 | 136 | ||
121 | #[test] | 137 | #[test] |
138 | fn remove_unused_first_param() { | ||
139 | check_assist( | ||
140 | remove_unused_param, | ||
141 | r#" | ||
142 | fn foo(<|>x: i32, y: i32) { y; } | ||
143 | fn a() { foo(1, 2) } | ||
144 | fn b() { foo(1, 2,) } | ||
145 | "#, | ||
146 | r#" | ||
147 | fn foo(y: i32) { y; } | ||
148 | fn a() { foo(2) } | ||
149 | fn b() { foo(2,) } | ||
150 | "#, | ||
151 | ); | ||
152 | } | ||
153 | |||
154 | #[test] | ||
155 | fn remove_unused_single_param() { | ||
156 | check_assist( | ||
157 | remove_unused_param, | ||
158 | r#" | ||
159 | fn foo(<|>x: i32) { 0; } | ||
160 | fn a() { foo(1) } | ||
161 | fn b() { foo(1, ) } | ||
162 | "#, | ||
163 | r#" | ||
164 | fn foo() { 0; } | ||
165 | fn a() { foo() } | ||
166 | fn b() { foo( ) } | ||
167 | "#, | ||
168 | ); | ||
169 | } | ||
170 | |||
171 | #[test] | ||
172 | fn remove_unused_surrounded_by_parms() { | ||
173 | check_assist( | ||
174 | remove_unused_param, | ||
175 | r#" | ||
176 | fn foo(x: i32, <|>y: i32, z: i32) { x; } | ||
177 | fn a() { foo(1, 2, 3) } | ||
178 | fn b() { foo(1, 2, 3,) } | ||
179 | "#, | ||
180 | r#" | ||
181 | fn foo(x: i32, z: i32) { x; } | ||
182 | fn a() { foo(1, 3) } | ||
183 | fn b() { foo(1, 3,) } | ||
184 | "#, | ||
185 | ); | ||
186 | } | ||
187 | |||
188 | #[test] | ||
122 | fn remove_unused_qualified_call() { | 189 | fn remove_unused_qualified_call() { |
123 | check_assist( | 190 | check_assist( |
124 | remove_unused_param, | 191 | remove_unused_param, |
diff --git a/crates/assists/src/utils.rs b/crates/assists/src/utils.rs index f2cacf7c8..d41084b59 100644 --- a/crates/assists/src/utils.rs +++ b/crates/assists/src/utils.rs | |||
@@ -232,7 +232,13 @@ fn invert_special_case(expr: &ast::Expr) -> Option<ast::Expr> { | |||
232 | }; | 232 | }; |
233 | Some(make::expr_method_call(receiver, method, arg_list)) | 233 | Some(make::expr_method_call(receiver, method, arg_list)) |
234 | } | 234 | } |
235 | ast::Expr::PrefixExpr(pe) if pe.op_kind()? == ast::PrefixOp::Not => pe.expr(), | 235 | ast::Expr::PrefixExpr(pe) if pe.op_kind()? == ast::PrefixOp::Not => { |
236 | if let ast::Expr::ParenExpr(parexpr) = pe.expr()? { | ||
237 | parexpr.expr() | ||
238 | } else { | ||
239 | pe.expr() | ||
240 | } | ||
241 | } | ||
236 | // FIXME: | 242 | // FIXME: |
237 | // ast::Expr::Literal(true | false ) | 243 | // ast::Expr::Literal(true | false ) |
238 | _ => None, | 244 | _ => None, |
diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index 191960960..4b2d3c8a5 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts | |||
@@ -19,9 +19,8 @@ let ctx: Ctx | undefined; | |||
19 | const RUST_PROJECT_CONTEXT_NAME = "inRustProject"; | 19 | const RUST_PROJECT_CONTEXT_NAME = "inRustProject"; |
20 | 20 | ||
21 | export async function activate(context: vscode.ExtensionContext) { | 21 | export async function activate(context: vscode.ExtensionContext) { |
22 | // For some reason vscode not always shows pop-up error notifications | 22 | // VS Code doesn't show a notification when an extension fails to activate |
23 | // when an extension fails to activate, so we do it explicitly by ourselves. | 23 | // so we do it ourselves. |
24 | // FIXME: remove this bit of code once vscode fixes this issue: https://github.com/microsoft/vscode/issues/101242 | ||
25 | await tryActivate(context).catch(err => { | 24 | await tryActivate(context).catch(err => { |
26 | void vscode.window.showErrorMessage(`Cannot activate rust-analyzer: ${err.message}`); | 25 | void vscode.window.showErrorMessage(`Cannot activate rust-analyzer: ${err.message}`); |
27 | throw err; | 26 | throw err; |
@@ -292,6 +291,8 @@ async function getServer(config: Config, state: PersistentState): Promise<string | |||
292 | if (process.platform === "linux") platform = "linux"; | 291 | if (process.platform === "linux") platform = "linux"; |
293 | if (process.platform === "darwin") platform = "mac"; | 292 | if (process.platform === "darwin") platform = "mac"; |
294 | if (process.platform === "win32") platform = "windows"; | 293 | if (process.platform === "win32") platform = "windows"; |
294 | } else if (process.arch === "arm64" && process.platform === "darwin") { | ||
295 | platform = "mac"; | ||
295 | } | 296 | } |
296 | if (platform === undefined) { | 297 | if (platform === undefined) { |
297 | vscode.window.showErrorMessage( | 298 | vscode.window.showErrorMessage( |
@@ -340,7 +341,7 @@ async function getServer(config: Config, state: PersistentState): Promise<string | |||
340 | }); | 341 | }); |
341 | 342 | ||
342 | // Patching executable if that's NixOS. | 343 | // Patching executable if that's NixOS. |
343 | if (await fs.stat("/etc/nixos").then(_ => true).catch(_ => false)) { | 344 | if (await isNixOs()) { |
344 | await patchelf(dest); | 345 | await patchelf(dest); |
345 | } | 346 | } |
346 | 347 | ||
@@ -348,6 +349,15 @@ async function getServer(config: Config, state: PersistentState): Promise<string | |||
348 | return dest; | 349 | return dest; |
349 | } | 350 | } |
350 | 351 | ||
352 | async function isNixOs(): Promise<boolean> { | ||
353 | try { | ||
354 | const contents = await fs.readFile("/etc/os-release"); | ||
355 | return contents.indexOf("ID=nixos") !== -1; | ||
356 | } catch (e) { | ||
357 | return false; | ||
358 | } | ||
359 | } | ||
360 | |||
351 | async function downloadWithRetryDialog<T>(state: PersistentState, downloadFunc: () => Promise<T>): Promise<T> { | 361 | async function downloadWithRetryDialog<T>(state: PersistentState, downloadFunc: () => Promise<T>): Promise<T> { |
352 | while (true) { | 362 | while (true) { |
353 | try { | 363 | try { |