aboutsummaryrefslogtreecommitdiff
path: root/crates/ide/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide/src')
-rw-r--r--crates/ide/src/diagnostics.rs67
-rw-r--r--crates/ide/src/hover.rs29
-rw-r--r--crates/ide/src/references.rs34
-rw-r--r--crates/ide/src/references/rename.rs9
4 files changed, 128 insertions, 11 deletions
diff --git a/crates/ide/src/diagnostics.rs b/crates/ide/src/diagnostics.rs
index 8607139ba..fe32f39b6 100644
--- a/crates/ide/src/diagnostics.rs
+++ b/crates/ide/src/diagnostics.rs
@@ -10,15 +10,16 @@ mod field_shorthand;
10use std::cell::RefCell; 10use std::cell::RefCell;
11 11
12use hir::{ 12use hir::{
13 db::AstDatabase,
13 diagnostics::{Diagnostic as _, DiagnosticCode, DiagnosticSinkBuilder}, 14 diagnostics::{Diagnostic as _, DiagnosticCode, DiagnosticSinkBuilder},
14 Semantics, 15 InFile, Semantics,
15}; 16};
16use ide_db::{base_db::SourceDatabase, RootDatabase}; 17use ide_db::{base_db::SourceDatabase, RootDatabase};
17use itertools::Itertools; 18use itertools::Itertools;
18use rustc_hash::FxHashSet; 19use rustc_hash::FxHashSet;
19use syntax::{ 20use syntax::{
20 ast::{self, AstNode}, 21 ast::{self, AstNode},
21 SyntaxNode, TextRange, 22 SyntaxNode, SyntaxNodePtr, TextRange,
22}; 23};
23use text_edit::TextEdit; 24use text_edit::TextEdit;
24 25
@@ -147,20 +148,38 @@ pub(crate) fn diagnostics(
147 148
148 // Override severity and mark as unused. 149 // Override severity and mark as unused.
149 res.borrow_mut().push( 150 res.borrow_mut().push(
150 Diagnostic::hint(sema.diagnostics_display_range(d).range, d.message()) 151 Diagnostic::hint(
151 .with_unused(true) 152 sema.diagnostics_display_range(d.display_source()).range,
152 .with_code(Some(d.code())), 153 d.message(),
154 )
155 .with_unused(true)
156 .with_code(Some(d.code())),
153 ); 157 );
154 }) 158 })
155 .on::<hir::diagnostics::UnresolvedProcMacro, _>(|d| { 159 .on::<hir::diagnostics::UnresolvedProcMacro, _>(|d| {
156 // Use more accurate position if available. 160 // Use more accurate position if available.
157 let display_range = 161 let display_range = d
158 d.precise_location.unwrap_or_else(|| sema.diagnostics_display_range(d).range); 162 .precise_location
163 .unwrap_or_else(|| sema.diagnostics_display_range(d.display_source()).range);
159 164
160 // FIXME: it would be nice to tell the user whether proc macros are currently disabled 165 // FIXME: it would be nice to tell the user whether proc macros are currently disabled
161 res.borrow_mut() 166 res.borrow_mut()
162 .push(Diagnostic::hint(display_range, d.message()).with_code(Some(d.code()))); 167 .push(Diagnostic::hint(display_range, d.message()).with_code(Some(d.code())));
163 }) 168 })
169 .on::<hir::diagnostics::UnresolvedMacroCall, _>(|d| {
170 let last_path_segment = sema.db.parse_or_expand(d.file).and_then(|root| {
171 d.node
172 .to_node(&root)
173 .path()
174 .and_then(|it| it.segment())
175 .and_then(|it| it.name_ref())
176 .map(|it| InFile::new(d.file, SyntaxNodePtr::new(it.syntax())))
177 });
178 let diagnostics = last_path_segment.unwrap_or_else(|| d.display_source());
179 let display_range = sema.diagnostics_display_range(diagnostics).range;
180 res.borrow_mut()
181 .push(Diagnostic::error(display_range, d.message()).with_code(Some(d.code())));
182 })
164 // Only collect experimental diagnostics when they're enabled. 183 // Only collect experimental diagnostics when they're enabled.
165 .filter(|diag| !(diag.is_experimental() && config.disable_experimental)) 184 .filter(|diag| !(diag.is_experimental() && config.disable_experimental))
166 .filter(|diag| !config.disabled.contains(diag.code().as_str())); 185 .filter(|diag| !config.disabled.contains(diag.code().as_str()));
@@ -170,8 +189,11 @@ pub(crate) fn diagnostics(
170 // Diagnostics not handled above get no fix and default treatment. 189 // Diagnostics not handled above get no fix and default treatment.
171 .build(|d| { 190 .build(|d| {
172 res.borrow_mut().push( 191 res.borrow_mut().push(
173 Diagnostic::error(sema.diagnostics_display_range(d).range, d.message()) 192 Diagnostic::error(
174 .with_code(Some(d.code())), 193 sema.diagnostics_display_range(d.display_source()).range,
194 d.message(),
195 )
196 .with_code(Some(d.code())),
175 ); 197 );
176 }); 198 });
177 199
@@ -183,13 +205,13 @@ pub(crate) fn diagnostics(
183} 205}
184 206
185fn diagnostic_with_fix<D: DiagnosticWithFix>(d: &D, sema: &Semantics<RootDatabase>) -> Diagnostic { 207fn diagnostic_with_fix<D: DiagnosticWithFix>(d: &D, sema: &Semantics<RootDatabase>) -> Diagnostic {
186 Diagnostic::error(sema.diagnostics_display_range(d).range, d.message()) 208 Diagnostic::error(sema.diagnostics_display_range(d.display_source()).range, d.message())
187 .with_fix(d.fix(&sema)) 209 .with_fix(d.fix(&sema))
188 .with_code(Some(d.code())) 210 .with_code(Some(d.code()))
189} 211}
190 212
191fn warning_with_fix<D: DiagnosticWithFix>(d: &D, sema: &Semantics<RootDatabase>) -> Diagnostic { 213fn warning_with_fix<D: DiagnosticWithFix>(d: &D, sema: &Semantics<RootDatabase>) -> Diagnostic {
192 Diagnostic::hint(sema.diagnostics_display_range(d).range, d.message()) 214 Diagnostic::hint(sema.diagnostics_display_range(d.display_source()).range, d.message())
193 .with_fix(d.fix(&sema)) 215 .with_fix(d.fix(&sema))
194 .with_code(Some(d.code())) 216 .with_code(Some(d.code()))
195} 217}
@@ -646,6 +668,29 @@ fn test_fn() {
646 } 668 }
647 669
648 #[test] 670 #[test]
671 fn test_unresolved_macro_range() {
672 check_expect(
673 r#"foo::bar!(92);"#,
674 expect![[r#"
675 [
676 Diagnostic {
677 message: "unresolved macro call",
678 range: 5..8,
679 severity: Error,
680 fix: None,
681 unused: false,
682 code: Some(
683 DiagnosticCode(
684 "unresolved-macro-call",
685 ),
686 ),
687 },
688 ]
689 "#]],
690 );
691 }
692
693 #[test]
649 fn range_mapping_out_of_macros() { 694 fn range_mapping_out_of_macros() {
650 // FIXME: this is very wrong, but somewhat tricky to fix. 695 // FIXME: this is very wrong, but somewhat tricky to fix.
651 check_fix( 696 check_fix(
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs
index 9a605b09d..20b799490 100644
--- a/crates/ide/src/hover.rs
+++ b/crates/ide/src/hover.rs
@@ -3496,4 +3496,33 @@ mod foo$0;
3496 "#]], 3496 "#]],
3497 ); 3497 );
3498 } 3498 }
3499
3500 #[test]
3501 fn hover_self_in_use() {
3502 check(
3503 r#"
3504//! This should not appear
3505mod foo {
3506 /// But this should appear
3507 pub mod bar {}
3508}
3509use foo::bar::{self$0};
3510"#,
3511 expect![[r#"
3512 *self*
3513
3514 ```rust
3515 test::foo
3516 ```
3517
3518 ```rust
3519 pub mod bar
3520 ```
3521
3522 ---
3523
3524 But this should appear
3525 "#]],
3526 );
3527 }
3499} 3528}
diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs
index 55f95ebae..fef70533d 100644
--- a/crates/ide/src/references.rs
+++ b/crates/ide/src/references.rs
@@ -39,6 +39,15 @@ pub struct Declaration {
39 pub access: Option<ReferenceAccess>, 39 pub access: Option<ReferenceAccess>,
40} 40}
41 41
42// Feature: Find All References
43//
44// Shows all references of the item at the cursor location
45//
46// |===
47// | Editor | Shortcut
48//
49// | VS Code | kbd:[Shift+Alt+F12]
50// |===
42pub(crate) fn find_all_refs( 51pub(crate) fn find_all_refs(
43 sema: &Semantics<RootDatabase>, 52 sema: &Semantics<RootDatabase>,
44 position: FilePosition, 53 position: FilePosition,
@@ -1224,4 +1233,29 @@ fn test() {}
1224 "#]], 1233 "#]],
1225 ); 1234 );
1226 } 1235 }
1236
1237 #[test]
1238 fn test_const_in_pattern() {
1239 check(
1240 r#"
1241const A$0: i32 = 42;
1242
1243fn main() {
1244 match A {
1245 A => (),
1246 _ => (),
1247 }
1248 if let A = A {}
1249}
1250"#,
1251 expect![[r#"
1252 A Const FileId(0) 0..18 6..7
1253
1254 FileId(0) 42..43
1255 FileId(0) 54..55
1256 FileId(0) 97..98
1257 FileId(0) 101..102
1258 "#]],
1259 );
1260 }
1227} 1261}
diff --git a/crates/ide/src/references/rename.rs b/crates/ide/src/references/rename.rs
index 175ddd759..22ddeeae3 100644
--- a/crates/ide/src/references/rename.rs
+++ b/crates/ide/src/references/rename.rs
@@ -59,6 +59,15 @@ pub(crate) fn prepare_rename(
59 Ok(RangeInfo::new(range, ())) 59 Ok(RangeInfo::new(range, ()))
60} 60}
61 61
62// Feature: Rename
63//
64// Renames the item below the cursor and all of its references
65//
66// |===
67// | Editor | Shortcut
68//
69// | VS Code | kbd:[F2]
70// |===
62pub(crate) fn rename( 71pub(crate) fn rename(
63 db: &RootDatabase, 72 db: &RootDatabase,
64 position: FilePosition, 73 position: FilePosition,