aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_assists/src/handlers
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_assists/src/handlers')
-rw-r--r--crates/ide_assists/src/handlers/add_lifetime_to_type.rs5
-rw-r--r--crates/ide_assists/src/handlers/add_turbo_fish.rs2
-rw-r--r--crates/ide_assists/src/handlers/convert_comment_block.rs5
-rw-r--r--crates/ide_assists/src/handlers/expand_glob_import.rs19
-rw-r--r--crates/ide_assists/src/handlers/move_bounds.rs6
-rw-r--r--crates/ide_assists/src/handlers/qualify_path.rs74
-rw-r--r--crates/ide_assists/src/handlers/reorder_impl.rs2
-rw-r--r--crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs34
8 files changed, 84 insertions, 63 deletions
diff --git a/crates/ide_assists/src/handlers/add_lifetime_to_type.rs b/crates/ide_assists/src/handlers/add_lifetime_to_type.rs
index 2edf7b204..844928754 100644
--- a/crates/ide_assists/src/handlers/add_lifetime_to_type.rs
+++ b/crates/ide_assists/src/handlers/add_lifetime_to_type.rs
@@ -29,8 +29,7 @@ pub(crate) fn add_lifetime_to_type(acc: &mut Assists, ctx: &AssistContext) -> Op
29 let node = ctx.find_node_at_offset::<ast::Adt>()?; 29 let node = ctx.find_node_at_offset::<ast::Adt>()?;
30 let has_lifetime = node 30 let has_lifetime = node
31 .generic_param_list() 31 .generic_param_list()
32 .map(|gen_list| gen_list.lifetime_params().count() > 0) 32 .map_or(false, |gen_list| gen_list.lifetime_params().next().is_some());
33 .unwrap_or_default();
34 33
35 if has_lifetime { 34 if has_lifetime {
36 return None; 35 return None;
@@ -41,7 +40,7 @@ pub(crate) fn add_lifetime_to_type(acc: &mut Assists, ctx: &AssistContext) -> Op
41 40
42 acc.add( 41 acc.add(
43 AssistId("add_lifetime_to_type", AssistKind::Generate), 42 AssistId("add_lifetime_to_type", AssistKind::Generate),
44 "Add lifetime`", 43 "Add lifetime",
45 target, 44 target,
46 |builder| { 45 |builder| {
47 match node.generic_param_list() { 46 match node.generic_param_list() {
diff --git a/crates/ide_assists/src/handlers/add_turbo_fish.rs b/crates/ide_assists/src/handlers/add_turbo_fish.rs
index 436767895..e4bb61c4e 100644
--- a/crates/ide_assists/src/handlers/add_turbo_fish.rs
+++ b/crates/ide_assists/src/handlers/add_turbo_fish.rs
@@ -26,7 +26,7 @@ use crate::{
26pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { 26pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
27 let ident = ctx.find_token_syntax_at_offset(SyntaxKind::IDENT).or_else(|| { 27 let ident = ctx.find_token_syntax_at_offset(SyntaxKind::IDENT).or_else(|| {
28 let arg_list = ctx.find_node_at_offset::<ast::ArgList>()?; 28 let arg_list = ctx.find_node_at_offset::<ast::ArgList>()?;
29 if arg_list.args().count() > 0 { 29 if arg_list.args().next().is_some() {
30 return None; 30 return None;
31 } 31 }
32 cov_mark::hit!(add_turbo_fish_after_call); 32 cov_mark::hit!(add_turbo_fish_after_call);
diff --git a/crates/ide_assists/src/handlers/convert_comment_block.rs b/crates/ide_assists/src/handlers/convert_comment_block.rs
index cdc45fc42..9dc3ee28f 100644
--- a/crates/ide_assists/src/handlers/convert_comment_block.rs
+++ b/crates/ide_assists/src/handlers/convert_comment_block.rs
@@ -1,5 +1,4 @@
1use itertools::Itertools; 1use itertools::Itertools;
2use std::convert::identity;
3use syntax::{ 2use syntax::{
4 ast::{ 3 ast::{
5 self, 4 self,
@@ -140,7 +139,7 @@ fn relevant_line_comments(comment: &ast::Comment) -> Vec<Comment> {
140 .filter(|s| !skippable(s)) 139 .filter(|s| !skippable(s))
141 .map(|not| not.into_token().and_then(Comment::cast).filter(same_prefix)) 140 .map(|not| not.into_token().and_then(Comment::cast).filter(same_prefix))
142 .take_while(|opt_com| opt_com.is_some()) 141 .take_while(|opt_com| opt_com.is_some())
143 .filter_map(identity) 142 .flatten()
144 .skip(1); // skip the first element so we don't duplicate it in next_comments 143 .skip(1); // skip the first element so we don't duplicate it in next_comments
145 144
146 let next_comments = comment 145 let next_comments = comment
@@ -149,7 +148,7 @@ fn relevant_line_comments(comment: &ast::Comment) -> Vec<Comment> {
149 .filter(|s| !skippable(s)) 148 .filter(|s| !skippable(s))
150 .map(|not| not.into_token().and_then(Comment::cast).filter(same_prefix)) 149 .map(|not| not.into_token().and_then(Comment::cast).filter(same_prefix))
151 .take_while(|opt_com| opt_com.is_some()) 150 .take_while(|opt_com| opt_com.is_some())
152 .filter_map(identity); 151 .flatten();
153 152
154 let mut comments: Vec<_> = prev_comments.collect(); 153 let mut comments: Vec<_> = prev_comments.collect();
155 comments.reverse(); 154 comments.reverse();
diff --git a/crates/ide_assists/src/handlers/expand_glob_import.rs b/crates/ide_assists/src/handlers/expand_glob_import.rs
index 83aa11d52..98389e4f7 100644
--- a/crates/ide_assists/src/handlers/expand_glob_import.rs
+++ b/crates/ide_assists/src/handlers/expand_glob_import.rs
@@ -136,18 +136,13 @@ impl Refs {
136 .into_iter() 136 .into_iter()
137 .filter(|r| { 137 .filter(|r| {
138 if let Def::ModuleDef(ModuleDef::Trait(tr)) = r.def { 138 if let Def::ModuleDef(ModuleDef::Trait(tr)) = r.def {
139 if tr 139 if tr.items(ctx.db()).into_iter().any(|ai| {
140 .items(ctx.db()) 140 if let AssocItem::Function(f) = ai {
141 .into_iter() 141 Def::ModuleDef(ModuleDef::Function(f)).is_referenced_in(ctx)
142 .find(|ai| { 142 } else {
143 if let AssocItem::Function(f) = *ai { 143 false
144 Def::ModuleDef(ModuleDef::Function(f)).is_referenced_in(ctx) 144 }
145 } else { 145 }) {
146 false
147 }
148 })
149 .is_some()
150 {
151 return true; 146 return true;
152 } 147 }
153 } 148 }
diff --git a/crates/ide_assists/src/handlers/move_bounds.rs b/crates/ide_assists/src/handlers/move_bounds.rs
index 9ad0c9816..b5dec8014 100644
--- a/crates/ide_assists/src/handlers/move_bounds.rs
+++ b/crates/ide_assists/src/handlers/move_bounds.rs
@@ -50,8 +50,8 @@ pub(crate) fn move_bounds_to_where_clause(acc: &mut Assists, ctx: &AssistContext
50 50
51 for type_param in type_param_list.type_params() { 51 for type_param in type_param_list.type_params() {
52 if let Some(tbl) = type_param.type_bound_list() { 52 if let Some(tbl) = type_param.type_bound_list() {
53 if let Some(predicate) = build_predicate(type_param.clone()) { 53 if let Some(predicate) = build_predicate(type_param) {
54 where_clause.add_predicate(predicate.clone_for_update()) 54 where_clause.add_predicate(predicate)
55 } 55 }
56 tbl.remove() 56 tbl.remove()
57 } 57 }
@@ -69,7 +69,7 @@ fn build_predicate(param: ast::TypeParam) -> Option<ast::WherePred> {
69 make::path_unqualified(segment) 69 make::path_unqualified(segment)
70 }; 70 };
71 let predicate = make::where_pred(path, param.type_bound_list()?.bounds()); 71 let predicate = make::where_pred(path, param.type_bound_list()?.bounds());
72 Some(predicate) 72 Some(predicate.clone_for_update())
73} 73}
74 74
75#[cfg(test)] 75#[cfg(test)]
diff --git a/crates/ide_assists/src/handlers/qualify_path.rs b/crates/ide_assists/src/handlers/qualify_path.rs
index 30b23da6c..f91770a76 100644
--- a/crates/ide_assists/src/handlers/qualify_path.rs
+++ b/crates/ide_assists/src/handlers/qualify_path.rs
@@ -14,11 +14,10 @@ use syntax::{
14 14
15use crate::{ 15use crate::{
16 assist_context::{AssistContext, Assists}, 16 assist_context::{AssistContext, Assists},
17 handlers::auto_import::find_importable_node,
17 AssistId, AssistKind, GroupLabel, 18 AssistId, AssistKind, GroupLabel,
18}; 19};
19 20
20use super::auto_import::find_importable_node;
21
22// Assist: qualify_path 21// Assist: qualify_path
23// 22//
24// If the name is unresolved, provides all possible qualified paths for it. 23// If the name is unresolved, provides all possible qualified paths for it.
@@ -43,22 +42,20 @@ pub(crate) fn qualify_path(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
43 return None; 42 return None;
44 } 43 }
45 44
46 let candidate = import_assets.import_candidate();
47 let range = ctx.sema.original_range(&syntax_under_caret).range; 45 let range = ctx.sema.original_range(&syntax_under_caret).range;
48 46 let candidate = import_assets.import_candidate();
49 let qualify_candidate = match candidate { 47 let qualify_candidate = match candidate {
50 ImportCandidate::Path(candidate) => { 48 ImportCandidate::Path(candidate) if candidate.qualifier.is_some() => {
51 if candidate.qualifier.is_some() { 49 cov_mark::hit!(qualify_path_qualifier_start);
52 cov_mark::hit!(qualify_path_qualifier_start); 50 let path = ast::Path::cast(syntax_under_caret)?;
53 let path = ast::Path::cast(syntax_under_caret)?; 51 let (prev_segment, segment) = (path.qualifier()?.segment()?, path.segment()?);
54 let (prev_segment, segment) = (path.qualifier()?.segment()?, path.segment()?); 52 QualifyCandidate::QualifierStart(segment, prev_segment.generic_arg_list())
55 QualifyCandidate::QualifierStart(segment, prev_segment.generic_arg_list()) 53 }
56 } else { 54 ImportCandidate::Path(_) => {
57 cov_mark::hit!(qualify_path_unqualified_name); 55 cov_mark::hit!(qualify_path_unqualified_name);
58 let path = ast::Path::cast(syntax_under_caret)?; 56 let path = ast::Path::cast(syntax_under_caret)?;
59 let generics = path.segment()?.generic_arg_list(); 57 let generics = path.segment()?.generic_arg_list();
60 QualifyCandidate::UnqualifiedName(generics) 58 QualifyCandidate::UnqualifiedName(generics)
61 }
62 } 59 }
63 ImportCandidate::TraitAssocItem(_) => { 60 ImportCandidate::TraitAssocItem(_) => {
64 cov_mark::hit!(qualify_path_trait_assoc_item); 61 cov_mark::hit!(qualify_path_trait_assoc_item);
@@ -119,7 +116,7 @@ impl QualifyCandidate<'_> {
119 QualifyCandidate::TraitAssocItem(qualifier, segment) => { 116 QualifyCandidate::TraitAssocItem(qualifier, segment) => {
120 replacer(format!("<{} as {}>::{}", qualifier, import, segment)); 117 replacer(format!("<{} as {}>::{}", qualifier, import, segment));
121 } 118 }
122 &QualifyCandidate::TraitMethod(db, ref mcall_expr) => { 119 QualifyCandidate::TraitMethod(db, mcall_expr) => {
123 Self::qualify_trait_method(db, mcall_expr, replacer, import, item); 120 Self::qualify_trait_method(db, mcall_expr, replacer, import, item);
124 } 121 }
125 } 122 }
@@ -201,15 +198,10 @@ fn group_label(candidate: &ImportCandidate) -> GroupLabel {
201 198
202fn label(candidate: &ImportCandidate, import: &LocatedImport) -> String { 199fn label(candidate: &ImportCandidate, import: &LocatedImport) -> String {
203 match candidate { 200 match candidate {
204 ImportCandidate::Path(candidate) => { 201 ImportCandidate::Path(candidate) if candidate.qualifier.is_none() => {
205 if candidate.qualifier.is_some() { 202 format!("Qualify as `{}`", import.import_path)
206 format!("Qualify with `{}`", import.import_path)
207 } else {
208 format!("Qualify as `{}`", import.import_path)
209 }
210 } 203 }
211 ImportCandidate::TraitAssocItem(_) => format!("Qualify `{}`", import.import_path), 204 _ => format!("Qualify with `{}`", import.import_path),
212 ImportCandidate::TraitMethod(_) => format!("Qualify with cast as `{}`", import.import_path),
213 } 205 }
214} 206}
215 207
@@ -544,6 +536,38 @@ fn main() {
544 } 536 }
545 537
546 #[test] 538 #[test]
539 #[ignore = "FIXME: non-trait assoc items completion is unsupported yet, see FIXME in the import_assets.rs for more details"]
540 fn associated_struct_const_unqualified() {
541 check_assist(
542 qualify_path,
543 r"
544 mod test_mod {
545 pub struct TestStruct {}
546 impl TestStruct {
547 const TEST_CONST: u8 = 42;
548 }
549 }
550
551 fn main() {
552 TEST_CONST$0
553 }
554 ",
555 r"
556 mod test_mod {
557 pub struct TestStruct {}
558 impl TestStruct {
559 const TEST_CONST: u8 = 42;
560 }
561 }
562
563 fn main() {
564 test_mod::TestStruct::TEST_CONST
565 }
566 ",
567 );
568 }
569
570 #[test]
547 fn associated_trait_function() { 571 fn associated_trait_function() {
548 check_assist( 572 check_assist(
549 qualify_path, 573 qualify_path,
diff --git a/crates/ide_assists/src/handlers/reorder_impl.rs b/crates/ide_assists/src/handlers/reorder_impl.rs
index edf4b0bfe..f976e73ad 100644
--- a/crates/ide_assists/src/handlers/reorder_impl.rs
+++ b/crates/ide_assists/src/handlers/reorder_impl.rs
@@ -95,7 +95,7 @@ fn compute_method_ranks(path: &ast::Path, ctx: &AssistContext) -> Option<FxHashM
95 _ => None, 95 _ => None,
96 }) 96 })
97 .enumerate() 97 .enumerate()
98 .map(|(idx, func)| ((func.name(ctx.db()).to_string(), idx))) 98 .map(|(idx, func)| (func.name(ctx.db()).to_string(), idx))
99 .collect(), 99 .collect(),
100 ) 100 )
101} 101}
diff --git a/crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs b/crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs
index 88fe2fe90..4f0ef52ca 100644
--- a/crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs
+++ b/crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs
@@ -1,5 +1,5 @@
1use hir::ModuleDef; 1use hir::ModuleDef;
2use ide_db::helpers::mod_path_to_ast; 2use ide_db::helpers::{import_assets::NameToImport, mod_path_to_ast};
3use ide_db::items_locator; 3use ide_db::items_locator;
4use itertools::Itertools; 4use itertools::Itertools;
5use syntax::{ 5use syntax::{
@@ -65,20 +65,24 @@ pub(crate) fn replace_derive_with_manual_impl(
65 let current_module = ctx.sema.scope(annotated_name.syntax()).module()?; 65 let current_module = ctx.sema.scope(annotated_name.syntax()).module()?;
66 let current_crate = current_module.krate(); 66 let current_crate = current_module.krate();
67 67
68 let found_traits = 68 let found_traits = items_locator::items_with_name(
69 items_locator::with_exact_name(&ctx.sema, current_crate, trait_token.text().to_string()) 69 &ctx.sema,
70 .into_iter() 70 current_crate,
71 .filter_map(|item| match ModuleDef::from(item.as_module_def_id()?) { 71 NameToImport::Exact(trait_token.text().to_string()),
72 ModuleDef::Trait(trait_) => Some(trait_), 72 items_locator::AssocItemSearch::Exclude,
73 _ => None, 73 Some(items_locator::DEFAULT_QUERY_SEARCH_LIMIT),
74 }) 74 )
75 .flat_map(|trait_| { 75 .filter_map(|item| match ModuleDef::from(item.as_module_def_id()?) {
76 current_module 76 ModuleDef::Trait(trait_) => Some(trait_),
77 .find_use_path(ctx.sema.db, hir::ModuleDef::Trait(trait_)) 77 _ => None,
78 .as_ref() 78 })
79 .map(mod_path_to_ast) 79 .flat_map(|trait_| {
80 .zip(Some(trait_)) 80 current_module
81 }); 81 .find_use_path(ctx.sema.db, hir::ModuleDef::Trait(trait_))
82 .as_ref()
83 .map(mod_path_to_ast)
84 .zip(Some(trait_))
85 });
82 86
83 let mut no_traits_found = true; 87 let mut no_traits_found = true;
84 for (trait_path, trait_) in found_traits.inspect(|_| no_traits_found = false) { 88 for (trait_path, trait_) in found_traits.inspect(|_| no_traits_found = false) {