aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r--crates/ra_hir/src/code_model.rs28
-rw-r--r--crates/ra_hir/src/code_model/src.rs2
-rw-r--r--crates/ra_hir/src/from_source.rs112
3 files changed, 88 insertions, 54 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index c49190a0f..b8d48a500 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -13,7 +13,7 @@ use hir_def::{
13 traits::TraitData, 13 traits::TraitData,
14 type_ref::{Mutability, TypeRef}, 14 type_ref::{Mutability, TypeRef},
15 AssocItemId, CrateModuleId, FunctionContainerId, HasModule, ImplId, LocalEnumVariantId, 15 AssocItemId, CrateModuleId, FunctionContainerId, HasModule, ImplId, LocalEnumVariantId,
16 LocalStructFieldId, Lookup, ModuleId, UnionId, 16 LocalStructFieldId, Lookup, ModuleId, TypeAliasContainerId, UnionId,
17}; 17};
18use hir_expand::{ 18use hir_expand::{
19 diagnostics::DiagnosticSink, 19 diagnostics::DiagnosticSink,
@@ -954,30 +954,34 @@ pub struct TypeAlias {
954 954
955impl TypeAlias { 955impl TypeAlias {
956 pub fn module(self, db: &impl DefDatabase) -> Module { 956 pub fn module(self, db: &impl DefDatabase) -> Module {
957 Module { id: self.id.module(db) } 957 Module { id: self.id.lookup(db).module(db) }
958 } 958 }
959 959
960 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { 960 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
961 Some(self.module(db).krate()) 961 Some(self.module(db).krate())
962 } 962 }
963 963
964 /// The containing impl block, if this is a method. 964 /// The containing impl block, if this is a type alias.
965 pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> { 965 pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> {
966 ImplBlock::containing(db, self.into()) 966 match self.container(db) {
967 Some(Container::ImplBlock(it)) => Some(it),
968 _ => None,
969 }
967 } 970 }
968 971
969 /// The containing trait, if this is a trait method definition. 972 /// The containing trait, if this is a trait type alias definition.
970 pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> { 973 pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> {
971 db.trait_items_index(self.module(db).id).get_parent_trait(self.id.into()).map(Trait::from) 974 match self.container(db) {
975 Some(Container::Trait(it)) => Some(it),
976 _ => None,
977 }
972 } 978 }
973 979
974 pub fn container(self, db: &impl DefDatabase) -> Option<Container> { 980 pub fn container(self, db: &impl DefDatabase) -> Option<Container> {
975 if let Some(impl_block) = self.impl_block(db) { 981 match self.id.lookup(db).container {
976 Some(impl_block.into()) 982 TypeAliasContainerId::TraitId(it) => Some(Container::Trait(it.into())),
977 } else if let Some(trait_) = self.parent_trait(db) { 983 TypeAliasContainerId::ImplId(it) => Some(Container::ImplBlock(it.into())),
978 Some(trait_.into()) 984 TypeAliasContainerId::ModuleId(_) => None,
979 } else {
980 None
981 } 985 }
982 } 986 }
983 987
diff --git a/crates/ra_hir/src/code_model/src.rs b/crates/ra_hir/src/code_model/src.rs
index 91cab7414..04675e08e 100644
--- a/crates/ra_hir/src/code_model/src.rs
+++ b/crates/ra_hir/src/code_model/src.rs
@@ -138,7 +138,7 @@ impl HasSource for Trait {
138impl HasSource for TypeAlias { 138impl HasSource for TypeAlias {
139 type Ast = ast::TypeAliasDef; 139 type Ast = ast::TypeAliasDef;
140 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::TypeAliasDef> { 140 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::TypeAliasDef> {
141 self.id.source(db) 141 self.id.lookup(db).source(db)
142 } 142 }
143} 143}
144impl HasSource for MacroDef { 144impl HasSource for MacroDef {
diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs
index 303d5f138..f5fdaafa3 100644
--- a/crates/ra_hir/src/from_source.rs
+++ b/crates/ra_hir/src/from_source.rs
@@ -4,7 +4,7 @@ use hir_def::{ModuleId, StructId, StructOrUnionId, UnionId};
4use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind}; 4use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind};
5use ra_syntax::{ 5use ra_syntax::{
6 ast::{self, AstNode, NameOwner}, 6 ast::{self, AstNode, NameOwner},
7 match_ast, AstPtr, 7 match_ast, AstPtr, SyntaxNode,
8}; 8};
9 9
10use crate::{ 10use crate::{
@@ -52,48 +52,27 @@ impl FromSource for Trait {
52impl FromSource for Function { 52impl FromSource for Function {
53 type Ast = ast::FnDef; 53 type Ast = ast::FnDef;
54 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { 54 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
55 // FIXME: this doesn't try to handle nested declarations 55 let items = match Container::find(db, src.as_ref().map(|it| it.syntax()))? {
56 for container in src.value.syntax().ancestors() { 56 Container::Trait(it) => it.items(db),
57 let res = match_ast! { 57 Container::ImplBlock(it) => it.items(db),
58 match container { 58 Container::Module(m) => {
59 ast::TraitDef(it) => { 59 return m
60 let c = Trait::from_source(db, src.with_value(it))?; 60 .declarations(db)
61 c.items(db) 61 .into_iter()
62 .into_iter() 62 .filter_map(|it| match it {
63 .filter_map(|it| match it { 63 ModuleDef::Function(it) => Some(it),
64 AssocItem::Function(it) => Some(it), 64 _ => None,
65 _ => None 65 })
66 }) 66 .find(|it| same_source(&it.source(db), &src))
67 .find(|it| same_source(&it.source(db), &src))? 67 }
68 }, 68 };
69 ast::ImplBlock(it) => { 69 items
70 let c = ImplBlock::from_source(db, src.with_value(it))?;
71 c.items(db)
72 .into_iter()
73 .filter_map(|it| match it {
74 AssocItem::Function(it) => Some(it),
75 _ => None
76 })
77 .find(|it| same_source(&it.source(db), &src))?
78
79 },
80 _ => { continue },
81 }
82 };
83 return Some(res);
84 }
85
86 let module_source = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax()));
87 let c = Module::from_definition(db, src.with_value(module_source))?;
88 let res = c
89 .declarations(db)
90 .into_iter() 70 .into_iter()
91 .filter_map(|it| match it { 71 .filter_map(|it| match it {
92 ModuleDef::Function(it) => Some(it), 72 AssocItem::Function(it) => Some(it),
93 _ => None, 73 _ => None,
94 }) 74 })
95 .find(|it| same_source(&it.source(db), &src)); 75 .find(|it| same_source(&it.source(db), &src))
96 res
97 } 76 }
98} 77}
99 78
@@ -114,8 +93,27 @@ impl FromSource for Static {
114impl FromSource for TypeAlias { 93impl FromSource for TypeAlias {
115 type Ast = ast::TypeAliasDef; 94 type Ast = ast::TypeAliasDef;
116 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { 95 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
117 let id = from_source(db, src)?; 96 let items = match Container::find(db, src.as_ref().map(|it| it.syntax()))? {
118 Some(TypeAlias { id }) 97 Container::Trait(it) => it.items(db),
98 Container::ImplBlock(it) => it.items(db),
99 Container::Module(m) => {
100 return m
101 .declarations(db)
102 .into_iter()
103 .filter_map(|it| match it {
104 ModuleDef::TypeAlias(it) => Some(it),
105 _ => None,
106 })
107 .find(|it| same_source(&it.source(db), &src))
108 }
109 };
110 items
111 .into_iter()
112 .filter_map(|it| match it {
113 AssocItem::TypeAlias(it) => Some(it),
114 _ => None,
115 })
116 .find(|it| same_source(&it.source(db), &src))
119 } 117 }
120} 118}
121 119
@@ -258,6 +256,38 @@ where
258 Some(DEF::from_ast(ctx, &src.value)) 256 Some(DEF::from_ast(ctx, &src.value))
259} 257}
260 258
259enum Container {
260 Trait(Trait),
261 ImplBlock(ImplBlock),
262 Module(Module),
263}
264
265impl Container {
266 fn find(db: &impl DefDatabase, src: Source<&SyntaxNode>) -> Option<Container> {
267 // FIXME: this doesn't try to handle nested declarations
268 for container in src.value.ancestors() {
269 let res = match_ast! {
270 match container {
271 ast::TraitDef(it) => {
272 let c = Trait::from_source(db, src.with_value(it))?;
273 Container::Trait(c)
274 },
275 ast::ImplBlock(it) => {
276 let c = ImplBlock::from_source(db, src.with_value(it))?;
277 Container::ImplBlock(c)
278 },
279 _ => { continue },
280 }
281 };
282 return Some(res);
283 }
284
285 let module_source = ModuleSource::from_child_node(db, src);
286 let c = Module::from_definition(db, src.with_value(module_source))?;
287 Some(Container::Module(c))
288 }
289}
290
261/// XXX: AST Nodes and SyntaxNodes have identity equality semantics: nodes are 291/// XXX: AST Nodes and SyntaxNodes have identity equality semantics: nodes are
262/// equal if they point to exactly the same object. 292/// equal if they point to exactly the same object.
263/// 293///