From 0a9ea782ebbf4c63db629c9704895e990d8ce1c7 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sat, 14 Mar 2020 20:48:36 +0100 Subject: Fix completion of trait items Trait items should be public by default. --- crates/ra_hir_def/src/data.rs | 26 +++++++++++++++------- crates/ra_hir_def/src/visibility.rs | 33 +++++++++++++++++++++++++--- crates/ra_ide/src/completion/complete_dot.rs | 32 +++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 11 deletions(-) diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs index a72eb5369..85df07e60 100644 --- a/crates/ra_hir_def/src/data.rs +++ b/crates/ra_hir_def/src/data.rs @@ -34,7 +34,8 @@ pub struct FunctionData { impl FunctionData { pub(crate) fn fn_data_query(db: &impl DefDatabase, func: FunctionId) -> Arc { - let src = func.lookup(db).source(db); + let loc = func.lookup(db); + let src = loc.source(db); let name = src.value.name().map(|n| n.as_name()).unwrap_or_else(Name::missing); let mut params = Vec::new(); let mut has_self_param = false; @@ -76,7 +77,9 @@ impl FunctionData { ret_type }; - let visibility = RawVisibility::from_ast(db, src.map(|s| s.visibility())); + let vis_default = RawVisibility::default_for_container(loc.container); + let visibility = + RawVisibility::from_ast_with_default(db, vis_default, src.map(|s| s.visibility())); let sig = FunctionData { name, params, ret_type, has_self_param, visibility }; Arc::new(sig) @@ -105,10 +108,13 @@ impl TypeAliasData { db: &impl DefDatabase, typ: TypeAliasId, ) -> Arc { - let node = typ.lookup(db).source(db); + let loc = typ.lookup(db); + let node = loc.source(db); let name = node.value.name().map_or_else(Name::missing, |n| n.as_name()); let type_ref = node.value.type_ref().map(TypeRef::from_ast); - let visibility = RawVisibility::from_ast(db, node.map(|n| n.visibility())); + let vis_default = RawVisibility::default_for_container(loc.container); + let visibility = + RawVisibility::from_ast_with_default(db, vis_default, node.map(|n| n.visibility())); Arc::new(TypeAliasData { name, type_ref, visibility }) } } @@ -230,22 +236,26 @@ pub struct ConstData { impl ConstData { pub(crate) fn const_data_query(db: &impl DefDatabase, konst: ConstId) -> Arc { - let node = konst.lookup(db).source(db); - Arc::new(ConstData::new(db, node)) + let loc = konst.lookup(db); + let node = loc.source(db); + let vis_default = RawVisibility::default_for_container(loc.container); + Arc::new(ConstData::new(db, vis_default, node)) } pub(crate) fn static_data_query(db: &impl DefDatabase, konst: StaticId) -> Arc { let node = konst.lookup(db).source(db); - Arc::new(ConstData::new(db, node)) + Arc::new(ConstData::new(db, RawVisibility::private(), node)) } fn new( db: &impl DefDatabase, + vis_default: RawVisibility, node: InFile, ) -> ConstData { let name = node.value.name().map(|n| n.as_name()); let type_ref = TypeRef::from_ast_opt(node.value.ascribed_type()); - let visibility = RawVisibility::from_ast(db, node.map(|n| n.visibility())); + let visibility = + RawVisibility::from_ast_with_default(db, vis_default, node.map(|n| n.visibility())); ConstData { name, type_ref, visibility } } } diff --git a/crates/ra_hir_def/src/visibility.rs b/crates/ra_hir_def/src/visibility.rs index d8296da4b..e0c59e905 100644 --- a/crates/ra_hir_def/src/visibility.rs +++ b/crates/ra_hir_def/src/visibility.rs @@ -6,7 +6,7 @@ use ra_syntax::ast; use crate::{ db::DefDatabase, path::{ModPath, PathKind}, - ModuleId, + AssocContainerId, ModuleId, }; /// Visibility of an item, not yet resolved. @@ -20,11 +20,30 @@ pub enum RawVisibility { } impl RawVisibility { - const fn private() -> RawVisibility { + pub(crate) const fn private() -> RawVisibility { let path = ModPath { kind: PathKind::Super(0), segments: Vec::new() }; RawVisibility::Module(path) } + pub(crate) fn default_for_container(container_id: AssocContainerId) -> Self { + match container_id { + AssocContainerId::TraitId(_) => RawVisibility::Public, + _ => RawVisibility::private(), + } + } + + pub(crate) fn from_ast_with_default( + db: &impl DefDatabase, + default: RawVisibility, + node: InFile>, + ) -> RawVisibility { + Self::from_ast_with_hygiene_and_default( + node.value, + default, + &Hygiene::new(db, node.file_id), + ) + } + pub(crate) fn from_ast( db: &impl DefDatabase, node: InFile>, @@ -35,9 +54,17 @@ impl RawVisibility { pub(crate) fn from_ast_with_hygiene( node: Option, hygiene: &Hygiene, + ) -> RawVisibility { + Self::from_ast_with_hygiene_and_default(node, RawVisibility::private(), hygiene) + } + + pub(crate) fn from_ast_with_hygiene_and_default( + node: Option, + default: RawVisibility, + hygiene: &Hygiene, ) -> RawVisibility { let node = match node { - None => return RawVisibility::private(), + None => return default, Some(node) => node, }; match node.kind() { diff --git a/crates/ra_ide/src/completion/complete_dot.rs b/crates/ra_ide/src/completion/complete_dot.rs index 81e5037aa..f07611d88 100644 --- a/crates/ra_ide/src/completion/complete_dot.rs +++ b/crates/ra_ide/src/completion/complete_dot.rs @@ -401,6 +401,38 @@ mod tests { ); } + #[test] + fn completes_trait_method_from_other_module() { + assert_debug_snapshot!( + do_ref_completion( + r" + struct A {} + mod m { + pub trait Trait { fn the_method(&self); } + } + use m::Trait; + impl Trait for A {} + fn foo(a: A) { + a.<|> + } + ", + ), + @r###" + [ + CompletionItem { + label: "the_method()", + source_range: [219; 219), + delete: [219; 219), + insert: "the_method()$0", + kind: Method, + lookup: "the_method", + detail: "fn the_method(&self)", + }, + ] + "### + ); + } + #[test] fn test_no_non_self_method() { assert_debug_snapshot!( -- cgit v1.2.3