diff options
Diffstat (limited to 'crates/ide_db')
-rw-r--r-- | crates/ide_db/src/apply_change.rs | 6 | ||||
-rw-r--r-- | crates/ide_db/src/call_info.rs | 10 | ||||
-rw-r--r-- | crates/ide_db/src/call_info/tests.rs | 27 | ||||
-rw-r--r-- | crates/ide_db/src/helpers.rs | 5 | ||||
-rw-r--r-- | crates/ide_db/src/helpers/famous_defs_fixture.rs | 8 | ||||
-rw-r--r-- | crates/ide_db/src/helpers/import_assets.rs | 22 | ||||
-rw-r--r-- | crates/ide_db/src/helpers/rust_doc.rs | 34 |
7 files changed, 103 insertions, 9 deletions
diff --git a/crates/ide_db/src/apply_change.rs b/crates/ide_db/src/apply_change.rs index 111e9325a..eac5ef6b9 100644 --- a/crates/ide_db/src/apply_change.rs +++ b/crates/ide_db/src/apply_change.rs | |||
@@ -152,6 +152,10 @@ impl RootDatabase { | |||
152 | hir::db::FileItemTreeQuery | 152 | hir::db::FileItemTreeQuery |
153 | hir::db::BlockDefMapQuery | 153 | hir::db::BlockDefMapQuery |
154 | hir::db::CrateDefMapQueryQuery | 154 | hir::db::CrateDefMapQueryQuery |
155 | hir::db::FieldsAttrsQuery | ||
156 | hir::db::VariantsAttrsQuery | ||
157 | hir::db::FieldsAttrsSourceMapQuery | ||
158 | hir::db::VariantsAttrsSourceMapQuery | ||
155 | hir::db::StructDataQuery | 159 | hir::db::StructDataQuery |
156 | hir::db::UnionDataQuery | 160 | hir::db::UnionDataQuery |
157 | hir::db::EnumDataQuery | 161 | hir::db::EnumDataQuery |
@@ -197,7 +201,7 @@ impl RootDatabase { | |||
197 | hir::db::InternImplTraitIdQuery | 201 | hir::db::InternImplTraitIdQuery |
198 | hir::db::InternClosureQuery | 202 | hir::db::InternClosureQuery |
199 | hir::db::AssociatedTyValueQuery | 203 | hir::db::AssociatedTyValueQuery |
200 | hir::db::TraitSolveQuery | 204 | hir::db::TraitSolveQueryQuery |
201 | 205 | ||
202 | // SymbolsDatabase | 206 | // SymbolsDatabase |
203 | crate::symbol_index::FileSymbolsQuery | 207 | crate::symbol_index::FileSymbolsQuery |
diff --git a/crates/ide_db/src/call_info.rs b/crates/ide_db/src/call_info.rs index e583a52f4..bad277a95 100644 --- a/crates/ide_db/src/call_info.rs +++ b/crates/ide_db/src/call_info.rs | |||
@@ -4,8 +4,9 @@ use either::Either; | |||
4 | use hir::{HasAttrs, HirDisplay, Semantics, Type}; | 4 | use hir::{HasAttrs, HirDisplay, Semantics, Type}; |
5 | use stdx::format_to; | 5 | use stdx::format_to; |
6 | use syntax::{ | 6 | use syntax::{ |
7 | algo, | ||
7 | ast::{self, ArgListOwner, NameOwner}, | 8 | ast::{self, ArgListOwner, NameOwner}, |
8 | match_ast, AstNode, SyntaxNode, SyntaxToken, TextRange, TextSize, | 9 | match_ast, AstNode, Direction, SyntaxNode, SyntaxToken, TextRange, TextSize, |
9 | }; | 10 | }; |
10 | 11 | ||
11 | use crate::RootDatabase; | 12 | use crate::RootDatabase; |
@@ -43,7 +44,12 @@ pub fn call_info(db: &RootDatabase, position: FilePosition) -> Option<CallInfo> | |||
43 | let sema = Semantics::new(db); | 44 | let sema = Semantics::new(db); |
44 | let file = sema.parse(position.file_id); | 45 | let file = sema.parse(position.file_id); |
45 | let file = file.syntax(); | 46 | let file = file.syntax(); |
46 | let token = file.token_at_offset(position.offset).next()?; | 47 | let token = file |
48 | .token_at_offset(position.offset) | ||
49 | .left_biased() | ||
50 | // if the cursor is sandwiched between two space tokens and the call is unclosed | ||
51 | // this prevents us from leaving the CallExpression | ||
52 | .and_then(|tok| algo::skip_trivia_token(tok, Direction::Prev))?; | ||
47 | let token = sema.descend_into_macros(token); | 53 | let token = sema.descend_into_macros(token); |
48 | 54 | ||
49 | let (callable, active_parameter) = call_info_impl(&sema, token)?; | 55 | let (callable, active_parameter) = call_info_impl(&sema, token)?; |
diff --git a/crates/ide_db/src/call_info/tests.rs b/crates/ide_db/src/call_info/tests.rs index 281a081a3..be1cc12de 100644 --- a/crates/ide_db/src/call_info/tests.rs +++ b/crates/ide_db/src/call_info/tests.rs | |||
@@ -522,3 +522,30 @@ fn main(f: fn(i32, f64) -> char) { | |||
522 | "#]], | 522 | "#]], |
523 | ) | 523 | ) |
524 | } | 524 | } |
525 | |||
526 | #[test] | ||
527 | fn call_info_for_unclosed_call() { | ||
528 | check( | ||
529 | r#" | ||
530 | fn foo(foo: u32, bar: u32) {} | ||
531 | fn main() { | ||
532 | foo($0 | ||
533 | }"#, | ||
534 | expect![[r#" | ||
535 | fn foo(foo: u32, bar: u32) | ||
536 | (<foo: u32>, bar: u32) | ||
537 | "#]], | ||
538 | ); | ||
539 | // check with surrounding space | ||
540 | check( | ||
541 | r#" | ||
542 | fn foo(foo: u32, bar: u32) {} | ||
543 | fn main() { | ||
544 | foo( $0 | ||
545 | }"#, | ||
546 | expect![[r#" | ||
547 | fn foo(foo: u32, bar: u32) | ||
548 | (<foo: u32>, bar: u32) | ||
549 | "#]], | ||
550 | ) | ||
551 | } | ||
diff --git a/crates/ide_db/src/helpers.rs b/crates/ide_db/src/helpers.rs index 66798ea3a..720de0d1f 100644 --- a/crates/ide_db/src/helpers.rs +++ b/crates/ide_db/src/helpers.rs | |||
@@ -1,6 +1,7 @@ | |||
1 | //! A module with ide helpers for high-level ide features. | 1 | //! A module with ide helpers for high-level ide features. |
2 | pub mod insert_use; | 2 | pub mod insert_use; |
3 | pub mod import_assets; | 3 | pub mod import_assets; |
4 | pub mod rust_doc; | ||
4 | 5 | ||
5 | use std::collections::VecDeque; | 6 | use std::collections::VecDeque; |
6 | 7 | ||
@@ -113,6 +114,10 @@ impl FamousDefs<'_, '_> { | |||
113 | self.find_module("core:iter") | 114 | self.find_module("core:iter") |
114 | } | 115 | } |
115 | 116 | ||
117 | pub fn core_ops_Deref(&self) -> Option<Trait> { | ||
118 | self.find_trait("core:ops:Deref") | ||
119 | } | ||
120 | |||
116 | fn find_trait(&self, path: &str) -> Option<Trait> { | 121 | fn find_trait(&self, path: &str) -> Option<Trait> { |
117 | match self.find_def(path)? { | 122 | match self.find_def(path)? { |
118 | hir::ScopeDef::ModuleDef(hir::ModuleDef::Trait(it)) => Some(it), | 123 | hir::ScopeDef::ModuleDef(hir::ModuleDef::Trait(it)) => Some(it), |
diff --git a/crates/ide_db/src/helpers/famous_defs_fixture.rs b/crates/ide_db/src/helpers/famous_defs_fixture.rs index 4d79e064e..29ae12dcf 100644 --- a/crates/ide_db/src/helpers/famous_defs_fixture.rs +++ b/crates/ide_db/src/helpers/famous_defs_fixture.rs | |||
@@ -112,6 +112,12 @@ pub mod ops { | |||
112 | type Output; | 112 | type Output; |
113 | extern "rust-call" fn call_once(self, args: Args) -> Self::Output; | 113 | extern "rust-call" fn call_once(self, args: Args) -> Self::Output; |
114 | } | 114 | } |
115 | |||
116 | #[lang = "deref"] | ||
117 | pub trait Deref { | ||
118 | type Target: ?Sized; | ||
119 | fn deref(&self) -> &Self::Target; | ||
120 | } | ||
115 | } | 121 | } |
116 | 122 | ||
117 | pub mod option { | 123 | pub mod option { |
@@ -141,3 +147,5 @@ mod return_keyword {} | |||
141 | 147 | ||
142 | /// Docs for prim_str | 148 | /// Docs for prim_str |
143 | mod prim_str {} | 149 | mod prim_str {} |
150 | |||
151 | pub use core::ops; \ No newline at end of file | ||
diff --git a/crates/ide_db/src/helpers/import_assets.rs b/crates/ide_db/src/helpers/import_assets.rs index 8ce648367..91d6a4665 100644 --- a/crates/ide_db/src/helpers/import_assets.rs +++ b/crates/ide_db/src/helpers/import_assets.rs | |||
@@ -436,6 +436,8 @@ fn trait_applicable_items( | |||
436 | }) | 436 | }) |
437 | .collect(); | 437 | .collect(); |
438 | 438 | ||
439 | let related_dyn_traits = | ||
440 | trait_candidate.receiver_ty.applicable_inherent_traits(db).collect::<FxHashSet<_>>(); | ||
439 | let mut located_imports = FxHashSet::default(); | 441 | let mut located_imports = FxHashSet::default(); |
440 | 442 | ||
441 | if trait_assoc_item { | 443 | if trait_assoc_item { |
@@ -451,12 +453,16 @@ fn trait_applicable_items( | |||
451 | return None; | 453 | return None; |
452 | } | 454 | } |
453 | } | 455 | } |
456 | let located_trait = assoc.containing_trait(db)?; | ||
457 | if related_dyn_traits.contains(&located_trait) { | ||
458 | return None; | ||
459 | } | ||
454 | 460 | ||
455 | let item = ItemInNs::from(ModuleDef::from(assoc.containing_trait(db)?)); | 461 | let trait_item = ItemInNs::from(ModuleDef::from(located_trait)); |
456 | let original_item = assoc_to_item(assoc); | 462 | let original_item = assoc_to_item(assoc); |
457 | located_imports.insert(LocatedImport::new( | 463 | located_imports.insert(LocatedImport::new( |
458 | mod_path(item)?, | 464 | mod_path(trait_item)?, |
459 | item, | 465 | trait_item, |
460 | original_item, | 466 | original_item, |
461 | mod_path(original_item), | 467 | mod_path(original_item), |
462 | )); | 468 | )); |
@@ -473,11 +479,15 @@ fn trait_applicable_items( | |||
473 | |_, function| { | 479 | |_, function| { |
474 | let assoc = function.as_assoc_item(db)?; | 480 | let assoc = function.as_assoc_item(db)?; |
475 | if required_assoc_items.contains(&assoc) { | 481 | if required_assoc_items.contains(&assoc) { |
476 | let item = ItemInNs::from(ModuleDef::from(assoc.containing_trait(db)?)); | 482 | let located_trait = assoc.containing_trait(db)?; |
483 | if related_dyn_traits.contains(&located_trait) { | ||
484 | return None; | ||
485 | } | ||
486 | let trait_item = ItemInNs::from(ModuleDef::from(located_trait)); | ||
477 | let original_item = assoc_to_item(assoc); | 487 | let original_item = assoc_to_item(assoc); |
478 | located_imports.insert(LocatedImport::new( | 488 | located_imports.insert(LocatedImport::new( |
479 | mod_path(item)?, | 489 | mod_path(trait_item)?, |
480 | item, | 490 | trait_item, |
481 | original_item, | 491 | original_item, |
482 | mod_path(original_item), | 492 | mod_path(original_item), |
483 | )); | 493 | )); |
diff --git a/crates/ide_db/src/helpers/rust_doc.rs b/crates/ide_db/src/helpers/rust_doc.rs new file mode 100644 index 000000000..e27e23867 --- /dev/null +++ b/crates/ide_db/src/helpers/rust_doc.rs | |||
@@ -0,0 +1,34 @@ | |||
1 | //! Rustdoc specific doc comment handling | ||
2 | |||
3 | // stripped down version of https://github.com/rust-lang/rust/blob/392ba2ba1a7d6c542d2459fb8133bebf62a4a423/src/librustdoc/html/markdown.rs#L810-L933 | ||
4 | pub fn is_rust_fence(s: &str) -> bool { | ||
5 | let mut seen_rust_tags = false; | ||
6 | let mut seen_other_tags = false; | ||
7 | |||
8 | let tokens = s | ||
9 | .trim() | ||
10 | .split(|c| c == ',' || c == ' ' || c == '\t') | ||
11 | .map(str::trim) | ||
12 | .filter(|t| !t.is_empty()); | ||
13 | |||
14 | for token in tokens { | ||
15 | match token { | ||
16 | "should_panic" | "no_run" | "ignore" | "allow_fail" => { | ||
17 | seen_rust_tags = !seen_other_tags | ||
18 | } | ||
19 | "rust" => seen_rust_tags = true, | ||
20 | "test_harness" | "compile_fail" => seen_rust_tags = !seen_other_tags || seen_rust_tags, | ||
21 | x if x.starts_with("edition") => {} | ||
22 | x if x.starts_with('E') && x.len() == 5 => { | ||
23 | if x[1..].parse::<u32>().is_ok() { | ||
24 | seen_rust_tags = !seen_other_tags || seen_rust_tags; | ||
25 | } else { | ||
26 | seen_other_tags = true; | ||
27 | } | ||
28 | } | ||
29 | _ => seen_other_tags = true, | ||
30 | } | ||
31 | } | ||
32 | |||
33 | !seen_other_tags || seen_rust_tags | ||
34 | } | ||