mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-27 20:35:09 +00:00
Some cleanup and additional tests
This commit is contained in:
parent
d571d26955
commit
c5852f422f
7 changed files with 138 additions and 31 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -5,4 +5,3 @@ crates/*/target
|
||||||
*.log
|
*.log
|
||||||
*.iml
|
*.iml
|
||||||
.vscode/settings.json
|
.vscode/settings.json
|
||||||
**/*.snap.new
|
|
||||||
|
|
|
@ -46,7 +46,6 @@ pub(crate) enum Scope {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum Resolution {
|
pub enum Resolution {
|
||||||
// FIXME make these tuple variants
|
|
||||||
/// An item
|
/// An item
|
||||||
Def(ModuleDef),
|
Def(ModuleDef),
|
||||||
/// A local binding (only value namespace)
|
/// A local binding (only value namespace)
|
||||||
|
@ -85,7 +84,7 @@ impl Resolver {
|
||||||
|
|
||||||
pub fn all_names(&self) -> FxHashMap<Name, PerNs<Resolution>> {
|
pub fn all_names(&self) -> FxHashMap<Name, PerNs<Resolution>> {
|
||||||
let mut names = FxHashMap::default();
|
let mut names = FxHashMap::default();
|
||||||
for scope in &self.scopes {
|
for scope in self.scopes.iter().rev() {
|
||||||
scope.collect_names(&mut |name, res| {
|
scope.collect_names(&mut |name, res| {
|
||||||
let current: &mut PerNs<Resolution> = names.entry(name).or_default();
|
let current: &mut PerNs<Resolution> = names.entry(name).or_default();
|
||||||
if current.types.is_none() {
|
if current.types.is_none() {
|
||||||
|
|
|
@ -204,12 +204,13 @@ pub fn macro_symbols(db: &impl HirDatabase, file_id: FileId) -> Vec<(SmolStr, Te
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolver_for_position(db: &impl HirDatabase, position: FilePosition) -> Resolver {
|
pub fn resolver_for_position(db: &impl HirDatabase, position: FilePosition) -> Resolver {
|
||||||
let file = db.parse(position.file_id);
|
let file_id = position.file_id;
|
||||||
|
let file = db.parse(file_id);
|
||||||
find_leaf_at_offset(file.syntax(), position.offset)
|
find_leaf_at_offset(file.syntax(), position.offset)
|
||||||
.find_map(|node| {
|
.find_map(|node| {
|
||||||
node.ancestors().find_map(|node| {
|
node.ancestors().find_map(|node| {
|
||||||
if ast::Expr::cast(node).is_some() || ast::Block::cast(node).is_some() {
|
if ast::Expr::cast(node).is_some() || ast::Block::cast(node).is_some() {
|
||||||
if let Some(func) = function_from_child_node(db, position.file_id, node) {
|
if let Some(func) = function_from_child_node(db, file_id, node) {
|
||||||
let scopes = func.scopes(db);
|
let scopes = func.scopes(db);
|
||||||
let scope = scopes.scope_for_offset(position.offset);
|
let scope = scopes.scope_for_offset(position.offset);
|
||||||
Some(expr::resolver_for_scope(func.body(db), db, scope))
|
Some(expr::resolver_for_scope(func.body(db), db, scope))
|
||||||
|
@ -218,9 +219,15 @@ pub fn resolver_for_position(db: &impl HirDatabase, position: FilePosition) -> R
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
} else if let Some(module) = ast::Module::cast(node) {
|
} else if let Some(module) = ast::Module::cast(node) {
|
||||||
Some(module_from_declaration(db, position.file_id, module)?.resolver(db))
|
Some(module_from_declaration(db, file_id, module)?.resolver(db))
|
||||||
} else if let Some(_) = ast::SourceFile::cast(node) {
|
} else if let Some(_) = ast::SourceFile::cast(node) {
|
||||||
Some(module_from_source(db, position.file_id.into(), None)?.resolver(db))
|
Some(module_from_source(db, file_id.into(), None)?.resolver(db))
|
||||||
|
} else if let Some(s) = ast::StructDef::cast(node) {
|
||||||
|
let module = module_from_child_node(db, file_id, s.syntax())?;
|
||||||
|
Some(struct_from_module(db, module, s).resolver(db))
|
||||||
|
} else if let Some(e) = ast::EnumDef::cast(node) {
|
||||||
|
let module = module_from_child_node(db, file_id, e.syntax())?;
|
||||||
|
Some(enum_from_module(db, module, e).resolver(db))
|
||||||
} else {
|
} else {
|
||||||
// TODO add missing cases
|
// TODO add missing cases
|
||||||
None
|
None
|
||||||
|
@ -246,6 +253,12 @@ pub fn resolver_for_node(db: &impl HirDatabase, file_id: FileId, node: &SyntaxNo
|
||||||
Some(module_from_declaration(db, file_id, module)?.resolver(db))
|
Some(module_from_declaration(db, file_id, module)?.resolver(db))
|
||||||
} else if let Some(_) = ast::SourceFile::cast(node) {
|
} else if let Some(_) = ast::SourceFile::cast(node) {
|
||||||
Some(module_from_source(db, file_id.into(), None)?.resolver(db))
|
Some(module_from_source(db, file_id.into(), None)?.resolver(db))
|
||||||
|
} else if let Some(s) = ast::StructDef::cast(node) {
|
||||||
|
let module = module_from_child_node(db, file_id, s.syntax())?;
|
||||||
|
Some(struct_from_module(db, module, s).resolver(db))
|
||||||
|
} else if let Some(e) = ast::EnumDef::cast(node) {
|
||||||
|
let module = module_from_child_node(db, file_id, e.syntax())?;
|
||||||
|
Some(enum_from_module(db, module, e).resolver(db))
|
||||||
} else {
|
} else {
|
||||||
// TODO add missing cases
|
// TODO add missing cases
|
||||||
None
|
None
|
||||||
|
|
|
@ -65,6 +65,17 @@ mod tests {
|
||||||
check_completion(code, expected_completions, CompletionKind::Reference);
|
check_completion(code, expected_completions, CompletionKind::Reference);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[ignore] // should not complete foo, which currently doesn't work
|
||||||
|
fn dont_complete_current_use() {
|
||||||
|
check_reference_completion(
|
||||||
|
"dont_complete_current_use",
|
||||||
|
r"
|
||||||
|
use self::foo<|>;
|
||||||
|
",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn completes_mod_with_docs() {
|
fn completes_mod_with_docs() {
|
||||||
check_reference_completion(
|
check_reference_completion(
|
||||||
|
|
|
@ -6,29 +6,15 @@ pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) {
|
||||||
}
|
}
|
||||||
let names = ctx.resolver.all_names();
|
let names = ctx.resolver.all_names();
|
||||||
|
|
||||||
// let module_scope = module.scope(ctx.db);
|
names.into_iter().for_each(|(name, res)| {
|
||||||
names
|
CompletionItem::new(
|
||||||
.into_iter()
|
CompletionKind::Reference,
|
||||||
// FIXME check tests
|
ctx.source_range(),
|
||||||
// .filter(|(_name, res)| {
|
name.to_string(),
|
||||||
// // For cases like `use self::foo<|>` don't suggest foo itself.
|
)
|
||||||
// match res.import {
|
.from_resolution(ctx, &res)
|
||||||
// None => true,
|
.add_to(acc)
|
||||||
// Some(import) => {
|
});
|
||||||
// let source = module.import_source(ctx.db, import);
|
|
||||||
// !source.syntax().range().is_subrange(&ctx.leaf.range())
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
.for_each(|(name, res)| {
|
|
||||||
CompletionItem::new(
|
|
||||||
CompletionKind::Reference,
|
|
||||||
ctx.source_range(),
|
|
||||||
name.to_string(),
|
|
||||||
)
|
|
||||||
.from_resolution(ctx, &res)
|
|
||||||
.add_to(acc)
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -86,6 +72,30 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn completes_generic_params() {
|
||||||
|
check_reference_completion(
|
||||||
|
"generic_params",
|
||||||
|
r"
|
||||||
|
fn quux<T>() {
|
||||||
|
<|>
|
||||||
|
}
|
||||||
|
",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn completes_generic_params_in_struct() {
|
||||||
|
check_reference_completion(
|
||||||
|
"generic_params_in_struct",
|
||||||
|
r"
|
||||||
|
struct X<T> {
|
||||||
|
x: <|>
|
||||||
|
}
|
||||||
|
",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn completes_module_items() {
|
fn completes_module_items() {
|
||||||
check_reference_completion(
|
check_reference_completion(
|
||||||
|
@ -145,5 +155,4 @@ mod tests {
|
||||||
fn completes_self_in_methods() {
|
fn completes_self_in_methods() {
|
||||||
check_reference_completion("self_in_methods", r"impl S { fn foo(&self) { <|> } }")
|
check_reference_completion("self_in_methods", r"impl S { fn foo(&self) { <|> } }")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
---
|
||||||
|
created: "2019-02-01T22:20:40.580128393+00:00"
|
||||||
|
creator: insta@0.5.3
|
||||||
|
expression: kind_completions
|
||||||
|
source: crates/ra_ide_api/src/completion/completion_item.rs
|
||||||
|
---
|
||||||
|
[
|
||||||
|
CompletionItem {
|
||||||
|
completion_kind: Reference,
|
||||||
|
label: "T",
|
||||||
|
kind: Some(
|
||||||
|
TypeParam
|
||||||
|
),
|
||||||
|
detail: None,
|
||||||
|
documentation: None,
|
||||||
|
lookup: None,
|
||||||
|
insert_text: None,
|
||||||
|
insert_text_format: PlainText,
|
||||||
|
source_range: [44; 44),
|
||||||
|
text_edit: None
|
||||||
|
},
|
||||||
|
CompletionItem {
|
||||||
|
completion_kind: Reference,
|
||||||
|
label: "quux",
|
||||||
|
kind: Some(
|
||||||
|
Function
|
||||||
|
),
|
||||||
|
detail: Some(
|
||||||
|
"fn quux<T>()"
|
||||||
|
),
|
||||||
|
documentation: None,
|
||||||
|
lookup: None,
|
||||||
|
insert_text: Some(
|
||||||
|
"quux()$0"
|
||||||
|
),
|
||||||
|
insert_text_format: Snippet,
|
||||||
|
source_range: [44; 44),
|
||||||
|
text_edit: None
|
||||||
|
}
|
||||||
|
]
|
|
@ -0,0 +1,36 @@
|
||||||
|
---
|
||||||
|
created: "2019-02-01T22:23:21.508620224+00:00"
|
||||||
|
creator: insta@0.5.3
|
||||||
|
expression: kind_completions
|
||||||
|
source: crates/ra_ide_api/src/completion/completion_item.rs
|
||||||
|
---
|
||||||
|
[
|
||||||
|
CompletionItem {
|
||||||
|
completion_kind: Reference,
|
||||||
|
label: "T",
|
||||||
|
kind: Some(
|
||||||
|
TypeParam
|
||||||
|
),
|
||||||
|
detail: None,
|
||||||
|
documentation: None,
|
||||||
|
lookup: None,
|
||||||
|
insert_text: None,
|
||||||
|
insert_text_format: PlainText,
|
||||||
|
source_range: [46; 46),
|
||||||
|
text_edit: None
|
||||||
|
},
|
||||||
|
CompletionItem {
|
||||||
|
completion_kind: Reference,
|
||||||
|
label: "X",
|
||||||
|
kind: Some(
|
||||||
|
Struct
|
||||||
|
),
|
||||||
|
detail: None,
|
||||||
|
documentation: None,
|
||||||
|
lookup: None,
|
||||||
|
insert_text: None,
|
||||||
|
insert_text_format: PlainText,
|
||||||
|
source_range: [46; 46),
|
||||||
|
text_edit: None
|
||||||
|
}
|
||||||
|
]
|
Loading…
Reference in a new issue