From c5852f422ff45adaa21815c1a15e03b067a56a82 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 1 Feb 2019 23:06:57 +0100 Subject: Some cleanup and additional tests --- crates/ra_hir/src/resolve.rs | 3 +- crates/ra_hir/src/source_binder.rs | 21 ++++++-- crates/ra_ide_api/src/completion/complete_path.rs | 11 +++++ crates/ra_ide_api/src/completion/complete_scope.rs | 57 +++++++++++++--------- .../snapshots/completion_item__generic_params.snap | 40 +++++++++++++++ .../completion_item__generic_params_in_struct.snap | 36 ++++++++++++++ 6 files changed, 138 insertions(+), 30 deletions(-) create mode 100644 crates/ra_ide_api/src/completion/snapshots/completion_item__generic_params.snap create mode 100644 crates/ra_ide_api/src/completion/snapshots/completion_item__generic_params_in_struct.snap (limited to 'crates') diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs index 7929e8b7c..6c87d0df7 100644 --- a/crates/ra_hir/src/resolve.rs +++ b/crates/ra_hir/src/resolve.rs @@ -46,7 +46,6 @@ pub(crate) enum Scope { #[derive(Debug, Clone, PartialEq, Eq)] pub enum Resolution { - // FIXME make these tuple variants /// An item Def(ModuleDef), /// A local binding (only value namespace) @@ -85,7 +84,7 @@ impl Resolver { pub fn all_names(&self) -> FxHashMap> { let mut names = FxHashMap::default(); - for scope in &self.scopes { + for scope in self.scopes.iter().rev() { scope.collect_names(&mut |name, res| { let current: &mut PerNs = names.entry(name).or_default(); if current.types.is_none() { diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index ce929cf3e..59f782277 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -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 { - 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_map(|node| { node.ancestors().find_map(|node| { 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 scope = scopes.scope_for_offset(position.offset); 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 } } 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) { - 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 { // TODO add missing cases 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)) } else if let Some(_) = ast::SourceFile::cast(node) { 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 { // TODO add missing cases None diff --git a/crates/ra_ide_api/src/completion/complete_path.rs b/crates/ra_ide_api/src/completion/complete_path.rs index 8e0f6a79e..0b9948d4b 100644 --- a/crates/ra_ide_api/src/completion/complete_path.rs +++ b/crates/ra_ide_api/src/completion/complete_path.rs @@ -65,6 +65,17 @@ mod tests { 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] fn completes_mod_with_docs() { check_reference_completion( diff --git a/crates/ra_ide_api/src/completion/complete_scope.rs b/crates/ra_ide_api/src/completion/complete_scope.rs index 3488d6480..44514ab2b 100644 --- a/crates/ra_ide_api/src/completion/complete_scope.rs +++ b/crates/ra_ide_api/src/completion/complete_scope.rs @@ -6,29 +6,15 @@ pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) { } let names = ctx.resolver.all_names(); - // let module_scope = module.scope(ctx.db); - names - .into_iter() - // FIXME check tests - // .filter(|(_name, res)| { - // // For cases like `use self::foo<|>` don't suggest foo itself. - // match res.import { - // None => true, - // 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) - }); + names.into_iter().for_each(|(name, res)| { + CompletionItem::new( + CompletionKind::Reference, + ctx.source_range(), + name.to_string(), + ) + .from_resolution(ctx, &res) + .add_to(acc) + }); } #[cfg(test)] @@ -86,6 +72,30 @@ mod tests { ); } + #[test] + fn completes_generic_params() { + check_reference_completion( + "generic_params", + r" + fn quux() { + <|> + } + ", + ); + } + + #[test] + fn completes_generic_params_in_struct() { + check_reference_completion( + "generic_params_in_struct", + r" + struct X { + x: <|> + } + ", + ); + } + #[test] fn completes_module_items() { check_reference_completion( @@ -145,5 +155,4 @@ mod tests { fn completes_self_in_methods() { check_reference_completion("self_in_methods", r"impl S { fn foo(&self) { <|> } }") } - } diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__generic_params.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__generic_params.snap new file mode 100644 index 000000000..71cb55a5b --- /dev/null +++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__generic_params.snap @@ -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()" + ), + documentation: None, + lookup: None, + insert_text: Some( + "quux()$0" + ), + insert_text_format: Snippet, + source_range: [44; 44), + text_edit: None + } +] diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__generic_params_in_struct.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__generic_params_in_struct.snap new file mode 100644 index 000000000..a35c0cd13 --- /dev/null +++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__generic_params_in_struct.snap @@ -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 + } +] -- cgit v1.2.3