diff options
Diffstat (limited to 'crates/ide')
-rw-r--r-- | crates/ide/src/diagnostics.rs | 3 | ||||
-rw-r--r-- | crates/ide/src/diagnostics/fixes.rs | 33 | ||||
-rw-r--r-- | crates/ide/src/display/navigation_target.rs | 12 | ||||
-rw-r--r-- | crates/ide/src/references.rs | 16 |
4 files changed, 57 insertions, 7 deletions
diff --git a/crates/ide/src/diagnostics.rs b/crates/ide/src/diagnostics.rs index b35bc2bae..8607139ba 100644 --- a/crates/ide/src/diagnostics.rs +++ b/crates/ide/src/diagnostics.rs | |||
@@ -136,6 +136,9 @@ pub(crate) fn diagnostics( | |||
136 | .on::<hir::diagnostics::IncorrectCase, _>(|d| { | 136 | .on::<hir::diagnostics::IncorrectCase, _>(|d| { |
137 | res.borrow_mut().push(warning_with_fix(d, &sema)); | 137 | res.borrow_mut().push(warning_with_fix(d, &sema)); |
138 | }) | 138 | }) |
139 | .on::<hir::diagnostics::ReplaceFilterMapNextWithFindMap, _>(|d| { | ||
140 | res.borrow_mut().push(warning_with_fix(d, &sema)); | ||
141 | }) | ||
139 | .on::<hir::diagnostics::InactiveCode, _>(|d| { | 142 | .on::<hir::diagnostics::InactiveCode, _>(|d| { |
140 | // If there's inactive code somewhere in a macro, don't propagate to the call-site. | 143 | // If there's inactive code somewhere in a macro, don't propagate to the call-site. |
141 | if d.display_source().file_id.expansion_info(db).is_some() { | 144 | if d.display_source().file_id.expansion_info(db).is_some() { |
diff --git a/crates/ide/src/diagnostics/fixes.rs b/crates/ide/src/diagnostics/fixes.rs index 579d5a308..cbfc66ab3 100644 --- a/crates/ide/src/diagnostics/fixes.rs +++ b/crates/ide/src/diagnostics/fixes.rs | |||
@@ -4,7 +4,7 @@ use hir::{ | |||
4 | db::AstDatabase, | 4 | db::AstDatabase, |
5 | diagnostics::{ | 5 | diagnostics::{ |
6 | Diagnostic, IncorrectCase, MissingFields, MissingOkOrSomeInTailExpr, NoSuchField, | 6 | Diagnostic, IncorrectCase, MissingFields, MissingOkOrSomeInTailExpr, NoSuchField, |
7 | RemoveThisSemicolon, UnresolvedModule, | 7 | RemoveThisSemicolon, ReplaceFilterMapNextWithFindMap, UnresolvedModule, |
8 | }, | 8 | }, |
9 | HasSource, HirDisplay, InFile, Semantics, VariantDef, | 9 | HasSource, HirDisplay, InFile, Semantics, VariantDef, |
10 | }; | 10 | }; |
@@ -15,8 +15,8 @@ use ide_db::{ | |||
15 | }; | 15 | }; |
16 | use syntax::{ | 16 | use syntax::{ |
17 | algo, | 17 | algo, |
18 | ast::{self, edit::IndentLevel, make}, | 18 | ast::{self, edit::IndentLevel, make, ArgListOwner}, |
19 | AstNode, | 19 | AstNode, TextRange, |
20 | }; | 20 | }; |
21 | use text_edit::TextEdit; | 21 | use text_edit::TextEdit; |
22 | 22 | ||
@@ -144,6 +144,33 @@ impl DiagnosticWithFix for IncorrectCase { | |||
144 | } | 144 | } |
145 | } | 145 | } |
146 | 146 | ||
147 | impl DiagnosticWithFix for ReplaceFilterMapNextWithFindMap { | ||
148 | fn fix(&self, sema: &Semantics<RootDatabase>) -> Option<Fix> { | ||
149 | let root = sema.db.parse_or_expand(self.file)?; | ||
150 | let next_expr = self.next_expr.to_node(&root); | ||
151 | let next_call = ast::MethodCallExpr::cast(next_expr.syntax().clone())?; | ||
152 | |||
153 | let filter_map_call = ast::MethodCallExpr::cast(next_call.receiver()?.syntax().clone())?; | ||
154 | let filter_map_name_range = filter_map_call.name_ref()?.ident_token()?.text_range(); | ||
155 | let filter_map_args = filter_map_call.arg_list()?; | ||
156 | |||
157 | let range_to_replace = | ||
158 | TextRange::new(filter_map_name_range.start(), next_expr.syntax().text_range().end()); | ||
159 | let replacement = format!("find_map{}", filter_map_args.syntax().text()); | ||
160 | let trigger_range = next_expr.syntax().text_range(); | ||
161 | |||
162 | let edit = TextEdit::replace(range_to_replace, replacement); | ||
163 | |||
164 | let source_change = SourceChange::from_text_edit(self.file.original_file(sema.db), edit); | ||
165 | |||
166 | Some(Fix::new( | ||
167 | "Replace filter_map(..).next() with find_map()", | ||
168 | source_change, | ||
169 | trigger_range, | ||
170 | )) | ||
171 | } | ||
172 | } | ||
173 | |||
147 | fn missing_record_expr_field_fix( | 174 | fn missing_record_expr_field_fix( |
148 | sema: &Semantics<RootDatabase>, | 175 | sema: &Semantics<RootDatabase>, |
149 | usage_file_id: FileId, | 176 | usage_file_id: FileId, |
diff --git a/crates/ide/src/display/navigation_target.rs b/crates/ide/src/display/navigation_target.rs index 16fa828ad..23d885218 100644 --- a/crates/ide/src/display/navigation_target.rs +++ b/crates/ide/src/display/navigation_target.rs | |||
@@ -173,6 +173,7 @@ impl ToNav for FileSymbol { | |||
173 | FileSymbolKind::Const => SymbolKind::Const, | 173 | FileSymbolKind::Const => SymbolKind::Const, |
174 | FileSymbolKind::Static => SymbolKind::Static, | 174 | FileSymbolKind::Static => SymbolKind::Static, |
175 | FileSymbolKind::Macro => SymbolKind::Macro, | 175 | FileSymbolKind::Macro => SymbolKind::Macro, |
176 | FileSymbolKind::Union => SymbolKind::Union, | ||
176 | }), | 177 | }), |
177 | full_range: self.range, | 178 | full_range: self.range, |
178 | focus_range: self.name_range, | 179 | focus_range: self.name_range, |
@@ -434,13 +435,16 @@ impl TryToNav for hir::TypeParam { | |||
434 | fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> { | 435 | fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> { |
435 | let src = self.source(db)?; | 436 | let src = self.source(db)?; |
436 | let full_range = match &src.value { | 437 | let full_range = match &src.value { |
437 | Either::Left(it) => it.syntax().text_range(), | 438 | Either::Left(it) => it |
439 | .name() | ||
440 | .map_or_else(|| it.syntax().text_range(), |name| name.syntax().text_range()), | ||
438 | Either::Right(it) => it.syntax().text_range(), | 441 | Either::Right(it) => it.syntax().text_range(), |
439 | }; | 442 | }; |
440 | let focus_range = match &src.value { | 443 | let focus_range = match &src.value { |
441 | Either::Left(_) => None, | 444 | Either::Left(it) => it.name(), |
442 | Either::Right(it) => it.name().map(|it| it.syntax().text_range()), | 445 | Either::Right(it) => it.name(), |
443 | }; | 446 | } |
447 | .map(|it| it.syntax().text_range()); | ||
444 | Some(NavigationTarget { | 448 | Some(NavigationTarget { |
445 | file_id: src.file_id.original_file(db), | 449 | file_id: src.file_id.original_file(db), |
446 | name: self.name(db).to_string().into(), | 450 | name: self.name(db).to_string().into(), |
diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs index 3a4f4d80b..40d9487eb 100644 --- a/crates/ide/src/references.rs +++ b/crates/ide/src/references.rs | |||
@@ -1098,4 +1098,20 @@ fn foo<const FOO$0: usize>() -> usize { | |||
1098 | "#]], | 1098 | "#]], |
1099 | ); | 1099 | ); |
1100 | } | 1100 | } |
1101 | |||
1102 | #[test] | ||
1103 | fn test_find_self_ty_in_trait_def() { | ||
1104 | check( | ||
1105 | r#" | ||
1106 | trait Foo { | ||
1107 | fn f() -> Self$0; | ||
1108 | } | ||
1109 | "#, | ||
1110 | expect![[r#" | ||
1111 | Self TypeParam FileId(0) 6..9 6..9 Other | ||
1112 | |||
1113 | FileId(0) 26..30 Other | ||
1114 | "#]], | ||
1115 | ); | ||
1116 | } | ||
1101 | } | 1117 | } |