aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_ide_api/src/name_kind.rs93
-rw-r--r--crates/ra_ide_api/src/references.rs2
2 files changed, 59 insertions, 36 deletions
diff --git a/crates/ra_ide_api/src/name_kind.rs b/crates/ra_ide_api/src/name_kind.rs
index 0effeb8a1..5dc6b1a13 100644
--- a/crates/ra_ide_api/src/name_kind.rs
+++ b/crates/ra_ide_api/src/name_kind.rs
@@ -1,13 +1,19 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use hir::{Either, FromSource}; 3use hir::{Either, FromSource, HasSource};
4use ra_db::FileId; 4use ra_db::FileId;
5use ra_syntax::{ast, AstNode, AstPtr}; 5use ra_syntax::{ast, ast::VisibilityOwner, AstNode, AstPtr};
6use test_utils::tested_by; 6use test_utils::tested_by;
7 7
8use crate::db::RootDatabase; 8use crate::db::RootDatabase;
9 9
10pub enum NameKind { 10pub(crate) struct Declaration {
11 visibility: Option<ast::Visibility>,
12 container: hir::ModuleSource,
13 pub item: NameKind,
14}
15
16pub(crate) enum NameKind {
11 Macro(hir::MacroDef), 17 Macro(hir::MacroDef),
12 FieldAccess(hir::StructField), 18 FieldAccess(hir::StructField),
13 AssocItem(hir::AssocItem), 19 AssocItem(hir::AssocItem),
@@ -96,7 +102,7 @@ pub(crate) fn classify_name(
96 db: &RootDatabase, 102 db: &RootDatabase,
97 file_id: FileId, 103 file_id: FileId,
98 name: &ast::Name, 104 name: &ast::Name,
99) -> Option<NameKind> { 105) -> Option<Declaration> {
100 use NameKind::*; 106 use NameKind::*;
101 107
102 let parent = name.syntax().parent()?; 108 let parent = name.syntax().parent()?;
@@ -105,89 +111,106 @@ pub(crate) fn classify_name(
105 macro_rules! match_ast { 111 macro_rules! match_ast {
106 (match $node:ident { 112 (match $node:ident {
107 $( ast::$ast:ident($it:ident) => $res:block, )* 113 $( ast::$ast:ident($it:ident) => $res:block, )*
108 _ => $catch_all:expr, 114 _ => $catch_all:block,
109 }) => {{ 115 }) => {{
110 $( if let Some($it) = ast::$ast::cast($node.clone()) $res else )* 116 $( if let Some($it) = ast::$ast::cast($node.clone()) $res else )*
111 { $catch_all } 117 $catch_all
112 }}; 118 }};
113 } 119 }
114 120
121 let container = parent.ancestors().find_map(|n| {
122 match_ast! {
123 match n {
124 ast::Module(it) => { Some(hir::ModuleSource::Module(it)) },
125 ast::SourceFile(it) => { Some(hir::ModuleSource::SourceFile(it)) },
126 _ => { None },
127 }
128 }
129 })?;
130
115 // FIXME: add ast::MacroCall(it) 131 // FIXME: add ast::MacroCall(it)
116 match_ast! { 132 let (item, visibility) = match_ast! {
117 match parent { 133 match parent {
118 ast::BindPat(it) => { 134 ast::BindPat(it) => {
119 let pat = AstPtr::new(&it); 135 let pat = AstPtr::new(&it);
120 Some(Pat(pat)) 136 (Pat(pat), None)
121 }, 137 },
122 ast::RecordFieldDef(it) => { 138 ast::RecordFieldDef(it) => {
123 let src = hir::Source { file_id, ast: hir::FieldSource::Named(it) }; 139 let src = hir::Source { file_id, ast: hir::FieldSource::Named(it) };
124 let field = hir::StructField::from_source(db, src)?; 140 let field = hir::StructField::from_source(db, src)?;
125 Some(FieldAccess(field)) 141 let visibility = match field.parent_def(db) {
142 hir::VariantDef::Struct(s) => s.source(db).ast.visibility(),
143 hir::VariantDef::EnumVariant(e) => e.source(db).ast.parent_enum().visibility(),
144 };
145 (FieldAccess(field), visibility)
126 }, 146 },
127 ast::FnDef(it) => { 147 ast::FnDef(it) => {
128 if parent.parent().and_then(ast::ItemList::cast).is_some() { 148 if parent.parent().and_then(ast::ItemList::cast).is_some() {
129 let src = hir::Source { file_id, ast: ast::ImplItem::from(it) }; 149 let src = hir::Source { file_id, ast: ast::ImplItem::from(it.clone()) };
130 let item = hir::AssocItem::from_source(db, src)?; 150 let item = hir::AssocItem::from_source(db, src)?;
131 Some(AssocItem(item)) 151 (AssocItem(item), it.visibility())
132 } else { 152 } else {
133 let src = hir::Source { file_id, ast: it }; 153 let src = hir::Source { file_id, ast: it.clone() };
134 let def = hir::Function::from_source(db, src)?; 154 let def = hir::Function::from_source(db, src)?;
135 Some(Def(def.into())) 155 (Def(def.into()), it.visibility())
136 } 156 }
137 }, 157 },
138 ast::ConstDef(it) => { 158 ast::ConstDef(it) => {
139 if parent.parent().and_then(ast::ItemList::cast).is_some() { 159 if parent.parent().and_then(ast::ItemList::cast).is_some() {
140 let src = hir::Source { file_id, ast: ast::ImplItem::from(it) }; 160 let src = hir::Source { file_id, ast: ast::ImplItem::from(it.clone()) };
141 let item = hir::AssocItem::from_source(db, src)?; 161 let item = hir::AssocItem::from_source(db, src)?;
142 Some(AssocItem(item)) 162 (AssocItem(item), it.visibility())
143 } else { 163 } else {
144 let src = hir::Source { file_id, ast: it }; 164 let src = hir::Source { file_id, ast: it.clone() };
145 let def = hir::Const::from_source(db, src)?; 165 let def = hir::Const::from_source(db, src)?;
146 Some(Def(def.into())) 166 (Def(def.into()), it.visibility())
147 } 167 }
148 }, 168 },
149 ast::TypeAliasDef(it) => { 169 ast::TypeAliasDef(it) => {
150 if parent.parent().and_then(ast::ItemList::cast).is_some() { 170 if parent.parent().and_then(ast::ItemList::cast).is_some() {
151 let src = hir::Source { file_id, ast: ast::ImplItem::from(it) }; 171 let src = hir::Source { file_id, ast: ast::ImplItem::from(it.clone()) };
152 let item = hir::AssocItem::from_source(db, src)?; 172 let item = hir::AssocItem::from_source(db, src)?;
153 Some(AssocItem(item)) 173 (AssocItem(item), it.visibility())
154 } else { 174 } else {
155 let src = hir::Source { file_id, ast: it }; 175 let src = hir::Source { file_id, ast: it.clone() };
156 let def = hir::TypeAlias::from_source(db, src)?; 176 let def = hir::TypeAlias::from_source(db, src)?;
157 Some(Def(def.into())) 177 (Def(def.into()), it.visibility())
158 } 178 }
159 }, 179 },
160 ast::Module(it) => { 180 ast::Module(it) => {
161 let src = hir::Source { file_id, ast: hir::ModuleSource::Module(it) }; 181 let src = hir::Source { file_id, ast: hir::ModuleSource::Module(it.clone()) };
162 let def = hir::Module::from_definition(db, src)?; 182 let def = hir::Module::from_definition(db, src)?;
163 Some(Def(def.into())) 183 (Def(def.into()), it.visibility())
164 }, 184 },
165 ast::StructDef(it) => { 185 ast::StructDef(it) => {
166 let src = hir::Source { file_id, ast: it }; 186 let src = hir::Source { file_id, ast: it.clone() };
167 let def = hir::Struct::from_source(db, src)?; 187 let def = hir::Struct::from_source(db, src)?;
168 Some(Def(def.into())) 188 (Def(def.into()), it.visibility())
169 }, 189 },
170 ast::EnumDef(it) => { 190 ast::EnumDef(it) => {
171 let src = hir::Source { file_id, ast: it }; 191 let src = hir::Source { file_id, ast: it.clone() };
172 let def = hir::Enum::from_source(db, src)?; 192 let def = hir::Enum::from_source(db, src)?;
173 Some(Def(def.into())) 193 (Def(def.into()), it.visibility())
174 }, 194 },
175 ast::TraitDef(it) => { 195 ast::TraitDef(it) => {
176 let src = hir::Source { file_id, ast: it }; 196 let src = hir::Source { file_id, ast: it.clone() };
177 let def = hir::Trait::from_source(db, src)?; 197 let def = hir::Trait::from_source(db, src)?;
178 Some(Def(def.into())) 198 (Def(def.into()), it.visibility())
179 }, 199 },
180 ast::StaticDef(it) => { 200 ast::StaticDef(it) => {
181 let src = hir::Source { file_id, ast: it }; 201 let src = hir::Source { file_id, ast: it.clone() };
182 let def = hir::Static::from_source(db, src)?; 202 let def = hir::Static::from_source(db, src)?;
183 Some(Def(def.into())) 203 (Def(def.into()), it.visibility())
184 }, 204 },
185 ast::EnumVariant(it) => { 205 ast::EnumVariant(it) => {
186 let src = hir::Source { file_id, ast: it }; 206 let src = hir::Source { file_id, ast: it.clone() };
187 let def = hir::EnumVariant::from_source(db, src)?; 207 let def = hir::EnumVariant::from_source(db, src)?;
188 Some(Def(def.into())) 208 (Def(def.into()), it.parent_enum().visibility())
209 },
210 _ => {
211 return None;
189 }, 212 },
190 _ => None,
191 } 213 }
192 } 214 };
215 Some(Declaration { item, container, visibility })
193} 216}
diff --git a/crates/ra_ide_api/src/references.rs b/crates/ra_ide_api/src/references.rs
index 6a8407c51..6777aa5f3 100644
--- a/crates/ra_ide_api/src/references.rs
+++ b/crates/ra_ide_api/src/references.rs
@@ -92,7 +92,7 @@ pub(crate) fn find_all_refs(
92 ) -> Option<RangeInfo<(hir::SourceAnalyzer, NameKind)>> { 92 ) -> Option<RangeInfo<(hir::SourceAnalyzer, NameKind)>> {
93 if let Some(name) = find_node_at_offset::<ast::Name>(&syntax, position.offset) { 93 if let Some(name) = find_node_at_offset::<ast::Name>(&syntax, position.offset) {
94 let analyzer = hir::SourceAnalyzer::new(db, position.file_id, name.syntax(), None); 94 let analyzer = hir::SourceAnalyzer::new(db, position.file_id, name.syntax(), None);
95 let name_kind = classify_name(db, position.file_id, &name)?; 95 let name_kind = classify_name(db, position.file_id, &name)?.item;
96 let range = name.syntax().text_range(); 96 let range = name.syntax().text_range();
97 return Some(RangeInfo::new(range, (analyzer, name_kind))); 97 return Some(RangeInfo::new(range, (analyzer, name_kind)));
98 } 98 }