mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 08:44:35 +00:00
Complete paths in use trees
This commit is contained in:
parent
06fbc6e3ed
commit
6d253b58da
@ -105,6 +105,9 @@ fn classify_name_ref(name_ref: ast::NameRef) -> Option<NameRefKind> {
|
||||
let parent = name_ref.syntax().parent()?;
|
||||
if let Some(segment) = ast::PathSegment::cast(parent) {
|
||||
let path = segment.parent_path();
|
||||
if let Some(crate_path) = crate_path(path) {
|
||||
return Some(NameRefKind::CratePath(crate_path));
|
||||
}
|
||||
if path.qualifier().is_none() {
|
||||
let enclosing_fn = name_ref
|
||||
.syntax()
|
||||
@ -113,9 +116,6 @@ fn classify_name_ref(name_ref: ast::NameRef) -> Option<NameRefKind> {
|
||||
.find_map(ast::FnDef::cast);
|
||||
return Some(NameRefKind::LocalRef { enclosing_fn });
|
||||
}
|
||||
if let Some(crate_path) = crate_path(path) {
|
||||
return Some(NameRefKind::CratePath(crate_path));
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
@ -129,10 +129,21 @@ fn crate_path(mut path: ast::Path) -> Option<Vec<ast::NameRef>> {
|
||||
ast::PathSegmentKind::CrateKw => break,
|
||||
ast::PathSegmentKind::SelfKw | ast::PathSegmentKind::SuperKw => return None,
|
||||
}
|
||||
path = path.qualifier()?;
|
||||
path = qualifier(path)?;
|
||||
}
|
||||
res.reverse();
|
||||
Some(res)
|
||||
return Some(res);
|
||||
|
||||
fn qualifier(path: ast::Path) -> Option<ast::Path> {
|
||||
if let Some(q) = path.qualifier() {
|
||||
return Some(q);
|
||||
}
|
||||
// TODO: this bottom up traversal is not too precise.
|
||||
// Should we handle do a top-down analysiss, recording results?
|
||||
let use_tree_list = path.syntax().ancestors().find_map(ast::UseTreeList::cast)?;
|
||||
let use_tree = use_tree_list.parent_use_tree();
|
||||
use_tree.path()
|
||||
}
|
||||
}
|
||||
|
||||
fn complete_fn(name_ref: ast::NameRef, scopes: &FnScopes, acc: &mut Vec<CompletionItem>) {
|
||||
|
@ -452,3 +452,44 @@ fn test_complete_crate_path() {
|
||||
&completions,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_complete_crate_path_with_braces() {
|
||||
let (analysis, position) = analysis_and_position(
|
||||
"
|
||||
//- /lib.rs
|
||||
mod foo;
|
||||
struct Spam;
|
||||
//- /foo.rs
|
||||
use crate::{Sp<|>};
|
||||
",
|
||||
);
|
||||
let completions = analysis.completions(position).unwrap().unwrap();
|
||||
assert_eq_dbg(
|
||||
r#"[CompletionItem { label: "foo", lookup: None, snippet: None },
|
||||
CompletionItem { label: "Spam", lookup: None, snippet: None }]"#,
|
||||
&completions,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_complete_crate_path_in_nested_tree() {
|
||||
let (analysis, position) = analysis_and_position(
|
||||
"
|
||||
//- /lib.rs
|
||||
mod foo;
|
||||
pub mod bar {
|
||||
pub mod baz {
|
||||
pub struct Spam;
|
||||
}
|
||||
}
|
||||
//- /foo.rs
|
||||
use crate::{bar::{baz::Sp<|>}};
|
||||
",
|
||||
);
|
||||
let completions = analysis.completions(position).unwrap().unwrap();
|
||||
assert_eq_dbg(
|
||||
r#"[CompletionItem { label: "Spam", lookup: None, snippet: None }]"#,
|
||||
&completions,
|
||||
);
|
||||
}
|
||||
|
@ -296,6 +296,15 @@ impl<'a> PathSegment<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> UseTreeList<'a> {
|
||||
pub fn parent_use_tree(self) -> UseTree<'a> {
|
||||
self.syntax()
|
||||
.parent()
|
||||
.and_then(UseTree::cast)
|
||||
.expect("UseTreeLists are always nested in UseTrees")
|
||||
}
|
||||
}
|
||||
|
||||
fn child_opt<'a, P: AstNode<'a>, C: AstNode<'a>>(parent: P) -> Option<C> {
|
||||
children(parent).next()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user