diff options
author | Ekaterina Babshukova <[email protected]> | 2019-10-03 04:08:44 +0100 |
---|---|---|
committer | Ekaterina Babshukova <[email protected]> | 2019-10-22 21:47:31 +0100 |
commit | 83f780eabfdaf37cb50c10c79af87506f2cc2afe (patch) | |
tree | d5bbaec54f17df66f26aad023e5e37729a4853c8 /crates/ra_ide_api/src | |
parent | 0b5d0a41fde1ae03bc6643dad3b904f579f716b5 (diff) |
return Declaration from classify_name
Diffstat (limited to 'crates/ra_ide_api/src')
-rw-r--r-- | crates/ra_ide_api/src/name_kind.rs | 93 | ||||
-rw-r--r-- | crates/ra_ide_api/src/references.rs | 2 |
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 | ||
3 | use hir::{Either, FromSource}; | 3 | use hir::{Either, FromSource, HasSource}; |
4 | use ra_db::FileId; | 4 | use ra_db::FileId; |
5 | use ra_syntax::{ast, AstNode, AstPtr}; | 5 | use ra_syntax::{ast, ast::VisibilityOwner, AstNode, AstPtr}; |
6 | use test_utils::tested_by; | 6 | use test_utils::tested_by; |
7 | 7 | ||
8 | use crate::db::RootDatabase; | 8 | use crate::db::RootDatabase; |
9 | 9 | ||
10 | pub enum NameKind { | 10 | pub(crate) struct Declaration { |
11 | visibility: Option<ast::Visibility>, | ||
12 | container: hir::ModuleSource, | ||
13 | pub item: NameKind, | ||
14 | } | ||
15 | |||
16 | pub(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 | } |