From ac226021cfd26a9332b5971f3e05118d77822af5 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 26 Aug 2018 12:09:28 +0300 Subject: scope based comletion --- crates/libeditor/src/code_actions.rs | 2 +- crates/libeditor/src/completion.rs | 42 ++++++++++++++++++++++++++++++------ crates/libeditor/tests/test.rs | 34 ++++++++++++++--------------- 3 files changed, 53 insertions(+), 25 deletions(-) (limited to 'crates/libeditor') diff --git a/crates/libeditor/src/code_actions.rs b/crates/libeditor/src/code_actions.rs index f53a8f9c6..e6ba83d2e 100644 --- a/crates/libeditor/src/code_actions.rs +++ b/crates/libeditor/src/code_actions.rs @@ -9,7 +9,7 @@ use libsyntax2::{ SyntaxNodeRef, algo::{ Direction, siblings, - find_leaf_at_offset, ancestors, + find_leaf_at_offset, }, }; diff --git a/crates/libeditor/src/completion.rs b/crates/libeditor/src/completion.rs index cf61ec784..16c9ead74 100644 --- a/crates/libeditor/src/completion.rs +++ b/crates/libeditor/src/completion.rs @@ -1,7 +1,11 @@ use libsyntax2::{ - File, TextUnit, - ast, - algo::find_leaf_at_offset, + File, TextUnit, AstNode, SyntaxNodeRef, + ast::{self, NameOwner}, + algo::{ + ancestors, + visit::{visitor_ctx, VisitorCtx}, + walk::preorder, + }, }; use { @@ -25,7 +29,33 @@ pub fn scope_completion(file: &File, offset: TextUnit) -> Option Vec { - vec![CompletionItem { - name: "foo".to_string() - }] + let mut res = Vec::new(); + for node in ancestors(name_ref.syntax()) { + process_scope(node, &mut res); + } + res +} + +fn process_scope(node: SyntaxNodeRef, sink: &mut Vec) { + let _ = visitor_ctx(sink) + .visit::(|block, sink| { + block.let_stmts() + .filter_map(|it| it.pat()) + .for_each(move |it| process_pat(it, sink)) + }) + .visit::(|fn_def, sink| { + fn_def.param_list().into_iter() + .flat_map(|it| it.params()) + .filter_map(|it| it.pat()) + .for_each(move |it| process_pat(it, sink)) + }) + .accept(node); + + fn process_pat(pat: ast::Pat, sink: &mut Vec) { + let items = preorder(pat.syntax()) + .filter_map(ast::BindPat::cast) + .filter_map(ast::BindPat::name) + .map(|name| CompletionItem { name: name.text().to_string() }); + sink.extend(items); + } } diff --git a/crates/libeditor/tests/test.rs b/crates/libeditor/tests/test.rs index 20de2f240..ecdc149c7 100644 --- a/crates/libeditor/tests/test.rs +++ b/crates/libeditor/tests/test.rs @@ -256,25 +256,23 @@ struct Foo { f: u32 } "); } -// #[test] -// fn test_completion() { -// fn do_check(code: &str, expected_completions: &str) { -// let (off, code) = extract_offset(&code); -// let file = file(&code); -// let completions = scope_completion(&file, off).unwrap(); -// assert_eq_dbg(expected_completions, &completions); -// } +#[test] +fn test_completion() { + fn do_check(code: &str, expected_completions: &str) { + let (off, code) = extract_offset(&code); + let file = file(&code); + let completions = scope_completion(&file, off).unwrap(); + assert_eq_dbg(expected_completions, &completions); + } -// do_check(r" -// fn foo(foo: i32) { -// let bar = 92; -// 1 + <|> -// } -// ", r#" -// CompletionItem { name: "bar" }, -// CompletionItem { name: "foo" }, -// "#); -// } + do_check(r" +fn quux(x: i32) { + let y = 92; + 1 + <|> +} +", r#"[CompletionItem { name: "y" }, + CompletionItem { name: "x" }]"#); +} fn file(text: &str) -> File { File::parse(text) -- cgit v1.2.3