aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide/src')
-rw-r--r--crates/ra_ide/src/call_hierarchy.rs2
-rw-r--r--crates/ra_ide/src/call_info.rs59
-rw-r--r--crates/ra_ide/src/completion/complete_dot.rs20
-rw-r--r--crates/ra_ide/src/completion/complete_path.rs28
-rw-r--r--crates/ra_ide/src/extend_selection.rs2
-rw-r--r--crates/ra_ide/src/references.rs13
-rw-r--r--crates/ra_ide/src/references/search_scope.rs3
7 files changed, 66 insertions, 61 deletions
diff --git a/crates/ra_ide/src/call_hierarchy.rs b/crates/ra_ide/src/call_hierarchy.rs
index 1cb712e32..aa5d60c7b 100644
--- a/crates/ra_ide/src/call_hierarchy.rs
+++ b/crates/ra_ide/src/call_hierarchy.rs
@@ -121,7 +121,7 @@ pub(crate) fn outgoing_calls(db: &RootDatabase, position: FilePosition) -> Optio
121 Some(macro_def.to_nav(db)) 121 Some(macro_def.to_nav(db))
122 } 122 }
123 } { 123 } {
124 Some((func_target.clone(), name_ref.value.text_range())) 124 Some((func_target, name_ref.value.text_range()))
125 } else { 125 } else {
126 None 126 None
127 } 127 }
diff --git a/crates/ra_ide/src/call_info.rs b/crates/ra_ide/src/call_info.rs
index a7023529b..72a68522e 100644
--- a/crates/ra_ide/src/call_info.rs
+++ b/crates/ra_ide/src/call_info.rs
@@ -1,10 +1,10 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2
3use hir::db::AstDatabase; 2use hir::db::AstDatabase;
4use ra_syntax::{ 3use ra_syntax::{
5 ast::{self, ArgListOwner}, 4 ast::{self, ArgListOwner},
6 match_ast, AstNode, SyntaxNode, 5 match_ast, AstNode, SyntaxNode,
7}; 6};
7
8use test_utils::tested_by; 8use test_utils::tested_by;
9 9
10use crate::{ 10use crate::{
@@ -51,36 +51,39 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal
51 // If we have a calling expression let's find which argument we are on 51 // If we have a calling expression let's find which argument we are on
52 let num_params = call_info.parameters().len(); 52 let num_params = call_info.parameters().len();
53 53
54 if num_params == 1 { 54 match num_params {
55 if !has_self { 55 0 => (),
56 call_info.active_parameter = Some(0); 56 1 => {
57 } 57 if !has_self {
58 } else if num_params > 1 { 58 call_info.active_parameter = Some(0);
59 // Count how many parameters into the call we are.
60 if let Some(arg_list) = calling_node.arg_list() {
61 // Number of arguments specified at the call site
62 let num_args_at_callsite = arg_list.args().count();
63
64 let arg_list_range = arg_list.syntax().text_range();
65 if !arg_list_range.contains_inclusive(position.offset) {
66 tested_by!(call_info_bad_offset);
67 return None;
68 } 59 }
60 }
61 _ => {
62 if let Some(arg_list) = calling_node.arg_list() {
63 // Number of arguments specified at the call site
64 let num_args_at_callsite = arg_list.args().count();
65
66 let arg_list_range = arg_list.syntax().text_range();
67 if !arg_list_range.contains_inclusive(position.offset) {
68 tested_by!(call_info_bad_offset);
69 return None;
70 }
69 71
70 let mut param = std::cmp::min( 72 let mut param = std::cmp::min(
71 num_args_at_callsite, 73 num_args_at_callsite,
72 arg_list 74 arg_list
73 .args() 75 .args()
74 .take_while(|arg| arg.syntax().text_range().end() < position.offset) 76 .take_while(|arg| arg.syntax().text_range().end() < position.offset)
75 .count(), 77 .count(),
76 ); 78 );
77 79
78 // If we are in a method account for `self` 80 // If we are in a method account for `self`
79 if has_self { 81 if has_self {
80 param += 1; 82 param += 1;
81 } 83 }
82 84
83 call_info.active_parameter = Some(param); 85 call_info.active_parameter = Some(param);
86 }
84 } 87 }
85 } 88 }
86 89
diff --git a/crates/ra_ide/src/completion/complete_dot.rs b/crates/ra_ide/src/completion/complete_dot.rs
index 210a685e4..2ca78c927 100644
--- a/crates/ra_ide/src/completion/complete_dot.rs
+++ b/crates/ra_ide/src/completion/complete_dot.rs
@@ -27,7 +27,7 @@ pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) {
27 complete_methods(acc, ctx, &receiver_ty); 27 complete_methods(acc, ctx, &receiver_ty);
28 28
29 // Suggest .await syntax for types that implement Future trait 29 // Suggest .await syntax for types that implement Future trait
30 if ctx.analyzer.impls_future(ctx.db, receiver_ty) { 30 if receiver_ty.impls_future(ctx.db) {
31 CompletionItem::new(CompletionKind::Keyword, ctx.source_range(), "await") 31 CompletionItem::new(CompletionKind::Keyword, ctx.source_range(), "await")
32 .detail("expr.await") 32 .detail("expr.await")
33 .insert_text("await") 33 .insert_text("await")
@@ -53,13 +53,16 @@ fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: &Ty
53} 53}
54 54
55fn complete_methods(acc: &mut Completions, ctx: &CompletionContext, receiver: &Type) { 55fn complete_methods(acc: &mut Completions, ctx: &CompletionContext, receiver: &Type) {
56 let mut seen_methods = FxHashSet::default(); 56 if let Some(krate) = ctx.module.map(|it| it.krate()) {
57 ctx.analyzer.iterate_method_candidates(ctx.db, receiver, None, |_ty, func| { 57 let mut seen_methods = FxHashSet::default();
58 if func.has_self_param(ctx.db) && seen_methods.insert(func.name(ctx.db)) { 58 let traits_in_scope = ctx.analyzer.traits_in_scope(ctx.db);
59 acc.add_function(ctx, func); 59 receiver.iterate_method_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, func| {
60 } 60 if func.has_self_param(ctx.db) && seen_methods.insert(func.name(ctx.db)) {
61 None::<()> 61 acc.add_function(ctx, func);
62 }); 62 }
63 None::<()>
64 });
65 }
63} 66}
64 67
65#[cfg(test)] 68#[cfg(test)]
@@ -525,6 +528,7 @@ mod tests {
525 528
526 //- /std/lib.rs 529 //- /std/lib.rs
527 pub mod future { 530 pub mod future {
531 #[lang = "future_trait"]
528 pub trait Future {} 532 pub trait Future {}
529 } 533 }
530 "###, CompletionKind::Keyword), 534 "###, CompletionKind::Keyword),
diff --git a/crates/ra_ide/src/completion/complete_path.rs b/crates/ra_ide/src/completion/complete_path.rs
index cc1f7c830..af24e9f48 100644
--- a/crates/ra_ide/src/completion/complete_path.rs
+++ b/crates/ra_ide/src/completion/complete_path.rs
@@ -26,7 +26,7 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
26 } 26 }
27 if let ScopeDef::Unknown = def { 27 if let ScopeDef::Unknown = def {
28 if let Some(name_ref) = ctx.name_ref_syntax.as_ref() { 28 if let Some(name_ref) = ctx.name_ref_syntax.as_ref() {
29 if &name_ref.syntax().text() == name.to_string().as_str() { 29 if name_ref.syntax().text() == name.to_string().as_str() {
30 // for `use self::foo<|>`, don't suggest `foo` as a completion 30 // for `use self::foo<|>`, don't suggest `foo` as a completion
31 tested_by!(dont_complete_current_use); 31 tested_by!(dont_complete_current_use);
32 continue; 32 continue;
@@ -49,22 +49,24 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
49 hir::ModuleDef::TypeAlias(a) => a.ty(ctx.db), 49 hir::ModuleDef::TypeAlias(a) => a.ty(ctx.db),
50 _ => unreachable!(), 50 _ => unreachable!(),
51 }; 51 };
52 ctx.analyzer.iterate_path_candidates(ctx.db, &ty, None, |_ty, item| {
53 match item {
54 hir::AssocItem::Function(func) => {
55 if !func.has_self_param(ctx.db) {
56 acc.add_function(ctx, func);
57 }
58 }
59 hir::AssocItem::Const(ct) => acc.add_const(ctx, ct),
60 hir::AssocItem::TypeAlias(ty) => acc.add_type_alias(ctx, ty),
61 }
62 None::<()>
63 });
64 // Iterate assoc types separately 52 // Iterate assoc types separately
65 // FIXME: complete T::AssocType 53 // FIXME: complete T::AssocType
66 let krate = ctx.module.map(|m| m.krate()); 54 let krate = ctx.module.map(|m| m.krate());
67 if let Some(krate) = krate { 55 if let Some(krate) = krate {
56 let traits_in_scope = ctx.analyzer.traits_in_scope(ctx.db);
57 ty.iterate_path_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, item| {
58 match item {
59 hir::AssocItem::Function(func) => {
60 if !func.has_self_param(ctx.db) {
61 acc.add_function(ctx, func);
62 }
63 }
64 hir::AssocItem::Const(ct) => acc.add_const(ctx, ct),
65 hir::AssocItem::TypeAlias(ty) => acc.add_type_alias(ctx, ty),
66 }
67 None::<()>
68 });
69
68 ty.iterate_impl_items(ctx.db, krate, |item| { 70 ty.iterate_impl_items(ctx.db, krate, |item| {
69 match item { 71 match item {
70 hir::AssocItem::Function(_) | hir::AssocItem::Const(_) => {} 72 hir::AssocItem::Function(_) | hir::AssocItem::Const(_) => {}
diff --git a/crates/ra_ide/src/extend_selection.rs b/crates/ra_ide/src/extend_selection.rs
index 70b6fde82..930e0c4c2 100644
--- a/crates/ra_ide/src/extend_selection.rs
+++ b/crates/ra_ide/src/extend_selection.rs
@@ -339,7 +339,7 @@ mod tests {
339 let (cursor, before) = extract_offset(before); 339 let (cursor, before) = extract_offset(before);
340 let (analysis, file_id) = single_file(&before); 340 let (analysis, file_id) = single_file(&before);
341 let range = TextRange::offset_len(cursor, 0.into()); 341 let range = TextRange::offset_len(cursor, 0.into());
342 let mut frange = FileRange { file_id: file_id, range }; 342 let mut frange = FileRange { file_id, range };
343 343
344 for &after in afters { 344 for &after in afters {
345 frange.range = analysis.extend_selection(frange).unwrap(); 345 frange.range = analysis.extend_selection(frange).unwrap();
diff --git a/crates/ra_ide/src/references.rs b/crates/ra_ide/src/references.rs
index 4e52e0e7b..2c753dade 100644
--- a/crates/ra_ide/src/references.rs
+++ b/crates/ra_ide/src/references.rs
@@ -166,7 +166,7 @@ pub(crate) fn find_all_refs(
166 Some(RangeInfo::new(range, ReferenceSearchResult { declaration, references })) 166 Some(RangeInfo::new(range, ReferenceSearchResult { declaration, references }))
167} 167}
168 168
169fn find_name<'a>( 169fn find_name(
170 db: &RootDatabase, 170 db: &RootDatabase,
171 syntax: &SyntaxNode, 171 syntax: &SyntaxNode,
172 position: FilePosition, 172 position: FilePosition,
@@ -253,13 +253,10 @@ fn decl_access(
253 let stmt = find_node_at_offset::<ast::LetStmt>(syntax, range.start())?; 253 let stmt = find_node_at_offset::<ast::LetStmt>(syntax, range.start())?;
254 if let Some(_) = stmt.initializer() { 254 if let Some(_) = stmt.initializer() {
255 let pat = stmt.pat()?; 255 let pat = stmt.pat()?;
256 match pat { 256 if let ast::Pat::BindPat(it) = pat {
257 ast::Pat::BindPat(it) => { 257 if it.name()?.text().as_str() == name {
258 if it.name()?.text().as_str() == name { 258 return Some(ReferenceAccess::Write);
259 return Some(ReferenceAccess::Write);
260 }
261 } 259 }
262 _ => {}
263 } 260 }
264 } 261 }
265 262
@@ -286,7 +283,7 @@ fn reference_access(kind: &NameKind, name_ref: &ast::NameRef) -> Option<Referenc
286 } 283 }
287 } 284 }
288 } 285 }
289 return Some(ReferenceAccess::Read); 286 Some(ReferenceAccess::Read)
290 }, 287 },
291 _ => {None} 288 _ => {None}
292 } 289 }
diff --git a/crates/ra_ide/src/references/search_scope.rs b/crates/ra_ide/src/references/search_scope.rs
index 241dd358f..f8211a746 100644
--- a/crates/ra_ide/src/references/search_scope.rs
+++ b/crates/ra_ide/src/references/search_scope.rs
@@ -82,8 +82,7 @@ impl NameDefinition {
82 return SearchScope::new(res); 82 return SearchScope::new(res);
83 } 83 }
84 84
85 let vis = 85 let vis = self.visibility.as_ref().map(|v| v.syntax().to_string()).unwrap_or_default();
86 self.visibility.as_ref().map(|v| v.syntax().to_string()).unwrap_or("".to_string());
87 86
88 if vis.as_str() == "pub(super)" { 87 if vis.as_str() == "pub(super)" {
89 if let Some(parent_module) = self.container.parent(db) { 88 if let Some(parent_module) = self.container.parent(db) {