diff options
author | Aleksey Kladov <[email protected]> | 2018-09-03 13:46:14 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-09-03 13:46:14 +0100 |
commit | 2f2feef9afe8f1c75f743a56f945a1560ca85af4 (patch) | |
tree | e0c38474c39feaf4aae0de4ac2f4ec7d8ad91c79 /crates | |
parent | 4798a89a12f40af17174a160f6d6a2f1c53db8d6 (diff) |
completion for trait params
Diffstat (limited to 'crates')
-rw-r--r-- | crates/libeditor/src/completion.rs | 41 | ||||
-rw-r--r-- | crates/libsyntax2/src/ast/generated.rs | 1 | ||||
-rw-r--r-- | crates/libsyntax2/src/grammar.ron | 1 |
3 files changed, 33 insertions, 10 deletions
diff --git a/crates/libeditor/src/completion.rs b/crates/libeditor/src/completion.rs index 6c3775127..c25b4c217 100644 --- a/crates/libeditor/src/completion.rs +++ b/crates/libeditor/src/completion.rs | |||
@@ -35,11 +35,17 @@ pub fn scope_completion(file: &File, offset: TextUnit) -> Option<Vec<CompletionI | |||
35 | let mut res = Vec::new(); | 35 | let mut res = Vec::new(); |
36 | if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(file.syntax(), offset) { | 36 | if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(file.syntax(), offset) { |
37 | has_completions = true; | 37 | has_completions = true; |
38 | complete_name_ref(&file, name_ref, &mut res) | 38 | complete_name_ref(&file, name_ref, &mut res); |
39 | // special case, `trait T { fn foo(i_am_a_name_ref) {} }` | ||
40 | if is_node::<ast::Param>(name_ref.syntax()) { | ||
41 | param_completions(name_ref.syntax(), &mut res); | ||
42 | } | ||
39 | } | 43 | } |
40 | if let Some(name) = find_node_at_offset::<ast::Name>(file.syntax(), offset) { | 44 | if let Some(name) = find_node_at_offset::<ast::Name>(file.syntax(), offset) { |
41 | has_completions = true; | 45 | if is_node::<ast::Param>(name.syntax()) { |
42 | complete_name(&file, name, &mut res) | 46 | has_completions = true; |
47 | param_completions(name.syntax(), &mut res); | ||
48 | } | ||
43 | } | 49 | } |
44 | if has_completions { | 50 | if has_completions { |
45 | Some(res) | 51 | Some(res) |
@@ -71,15 +77,12 @@ fn complete_name_ref(file: &File, name_ref: ast::NameRef, acc: &mut Vec<Completi | |||
71 | } | 77 | } |
72 | } | 78 | } |
73 | 79 | ||
74 | fn complete_name(_file: &File, name: ast::Name, acc: &mut Vec<CompletionItem>) { | 80 | fn param_completions(ctx: SyntaxNodeRef, acc: &mut Vec<CompletionItem>) { |
75 | if !is_node::<ast::Param>(name.syntax()) { | ||
76 | return; | ||
77 | } | ||
78 | |||
79 | let mut params = HashMap::new(); | 81 | let mut params = HashMap::new(); |
80 | for node in ancestors(name.syntax()) { | 82 | for node in ancestors(ctx) { |
81 | let _ = visitor_ctx(&mut params) | 83 | let _ = visitor_ctx(&mut params) |
82 | .visit::<ast::Root, _>(process) | 84 | .visit::<ast::Root, _>(process) |
85 | .visit::<ast::ItemList, _>(process) | ||
83 | .accept(node); | 86 | .accept(node); |
84 | } | 87 | } |
85 | params.into_iter() | 88 | params.into_iter() |
@@ -420,16 +423,34 @@ mod tests { | |||
420 | } | 423 | } |
421 | 424 | ||
422 | #[test] | 425 | #[test] |
423 | fn test_param_completion() { | 426 | fn test_param_completion_last_param() { |
424 | check_scope_completion(r" | 427 | check_scope_completion(r" |
425 | fn foo(file_id: FileId) {} | 428 | fn foo(file_id: FileId) {} |
426 | fn bar(file_id: FileId) {} | 429 | fn bar(file_id: FileId) {} |
427 | fn baz(file<|>) {} | 430 | fn baz(file<|>) {} |
428 | ", r#"[CompletionItem { label: "file_id: FileId", lookup: Some("file_id"), snippet: None }]"#); | 431 | ", r#"[CompletionItem { label: "file_id: FileId", lookup: Some("file_id"), snippet: None }]"#); |
432 | } | ||
433 | |||
434 | #[test] | ||
435 | fn test_param_completion_nth_param() { | ||
429 | check_scope_completion(r" | 436 | check_scope_completion(r" |
430 | fn foo(file_id: FileId) {} | 437 | fn foo(file_id: FileId) {} |
431 | fn bar(file_id: FileId) {} | 438 | fn bar(file_id: FileId) {} |
432 | fn baz(file<|>, x: i32) {} | 439 | fn baz(file<|>, x: i32) {} |
433 | ", r#"[CompletionItem { label: "file_id: FileId", lookup: Some("file_id"), snippet: None }]"#); | 440 | ", r#"[CompletionItem { label: "file_id: FileId", lookup: Some("file_id"), snippet: None }]"#); |
434 | } | 441 | } |
442 | |||
443 | #[test] | ||
444 | fn test_param_completion_trait_param() { | ||
445 | check_scope_completion(r" | ||
446 | pub(crate) trait SourceRoot { | ||
447 | pub fn contains(&self, file_id: FileId) -> bool; | ||
448 | pub fn module_map(&self) -> &ModuleMap; | ||
449 | pub fn lines(&self, file_id: FileId) -> &LineIndex; | ||
450 | pub fn syntax(&self, file<|>) | ||
451 | } | ||
452 | ", r#"[CompletionItem { label: "self", lookup: None, snippet: None }, | ||
453 | CompletionItem { label: "SourceRoot", lookup: None, snippet: None }, | ||
454 | CompletionItem { label: "file_id: FileId", lookup: Some("file_id"), snippet: None }]"#); | ||
455 | } | ||
435 | } | 456 | } |
diff --git a/crates/libsyntax2/src/ast/generated.rs b/crates/libsyntax2/src/ast/generated.rs index 4a57837df..a239f0630 100644 --- a/crates/libsyntax2/src/ast/generated.rs +++ b/crates/libsyntax2/src/ast/generated.rs | |||
@@ -698,6 +698,7 @@ impl<'a> AstNode<'a> for ItemList<'a> { | |||
698 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | 698 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } |
699 | } | 699 | } |
700 | 700 | ||
701 | impl<'a> ast::FnDefOwner<'a> for ItemList<'a> {} | ||
701 | impl<'a> ItemList<'a> { | 702 | impl<'a> ItemList<'a> { |
702 | pub fn items(self) -> impl Iterator<Item = ModuleItem<'a>> + 'a { | 703 | pub fn items(self) -> impl Iterator<Item = ModuleItem<'a>> + 'a { |
703 | super::children(self) | 704 | super::children(self) |
diff --git a/crates/libsyntax2/src/grammar.ron b/crates/libsyntax2/src/grammar.ron index 8a2b780f0..6ed658daa 100644 --- a/crates/libsyntax2/src/grammar.ron +++ b/crates/libsyntax2/src/grammar.ron | |||
@@ -275,6 +275,7 @@ Grammar( | |||
275 | options: [ "ItemList" ] | 275 | options: [ "ItemList" ] |
276 | ), | 276 | ), |
277 | "ItemList": ( | 277 | "ItemList": ( |
278 | traits: [ "FnDefOwner" ], | ||
278 | collections: [ ["items", "ModuleItem"] ] | 279 | collections: [ ["items", "ModuleItem"] ] |
279 | ), | 280 | ), |
280 | "ConstDef": ( traits: [ | 281 | "ConstDef": ( traits: [ |