diff options
Diffstat (limited to 'crates/ra_ide_db/src/defs.rs')
-rw-r--r-- | crates/ra_ide_db/src/defs.rs | 57 |
1 files changed, 38 insertions, 19 deletions
diff --git a/crates/ra_ide_db/src/defs.rs b/crates/ra_ide_db/src/defs.rs index f391a8e43..b51000b03 100644 --- a/crates/ra_ide_db/src/defs.rs +++ b/crates/ra_ide_db/src/defs.rs | |||
@@ -12,7 +12,7 @@ use hir::{ | |||
12 | use ra_prof::profile; | 12 | use ra_prof::profile; |
13 | use ra_syntax::{ | 13 | use ra_syntax::{ |
14 | ast::{self, AstNode}, | 14 | ast::{self, AstNode}, |
15 | match_ast, | 15 | match_ast, SyntaxNode, |
16 | }; | 16 | }; |
17 | 17 | ||
18 | use crate::RootDatabase; | 18 | use crate::RootDatabase; |
@@ -111,7 +111,7 @@ pub fn classify_name(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option | |||
111 | 111 | ||
112 | let parent = name.syntax().parent()?; | 112 | let parent = name.syntax().parent()?; |
113 | 113 | ||
114 | if let Some(bind_pat) = ast::BindPat::cast(parent.clone()) { | 114 | if let Some(bind_pat) = ast::IdentPat::cast(parent.clone()) { |
115 | if let Some(def) = sema.resolve_bind_pat_to_const(&bind_pat) { | 115 | if let Some(def) = sema.resolve_bind_pat_to_const(&bind_pat) { |
116 | return Some(NameClass::ConstReference(Definition::ModuleDef(def))); | 116 | return Some(NameClass::ConstReference(Definition::ModuleDef(def))); |
117 | } | 117 | } |
@@ -119,19 +119,38 @@ pub fn classify_name(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option | |||
119 | 119 | ||
120 | match_ast! { | 120 | match_ast! { |
121 | match parent { | 121 | match parent { |
122 | ast::Alias(it) => { | 122 | ast::Rename(it) => { |
123 | let use_tree = it.syntax().parent().and_then(ast::UseTree::cast)?; | 123 | let use_tree = it.syntax().parent().and_then(ast::UseTree::cast)?; |
124 | let path = use_tree.path()?; | 124 | let path = use_tree.path()?; |
125 | let path_segment = path.segment()?; | 125 | let path_segment = path.segment()?; |
126 | let name_ref = path_segment.name_ref()?; | 126 | let name_ref_class = path_segment |
127 | let name_ref_class = classify_name_ref(sema, &name_ref)?; | 127 | .name_ref() |
128 | // The rename might be from a `self` token, so fallback to the name higher | ||
129 | // in the use tree. | ||
130 | .or_else(||{ | ||
131 | if path_segment.self_token().is_none() { | ||
132 | return None; | ||
133 | } | ||
134 | |||
135 | let use_tree = use_tree | ||
136 | .syntax() | ||
137 | .parent() | ||
138 | .as_ref() | ||
139 | // Skip over UseTreeList | ||
140 | .and_then(SyntaxNode::parent) | ||
141 | .and_then(ast::UseTree::cast)?; | ||
142 | let path = use_tree.path()?; | ||
143 | let path_segment = path.segment()?; | ||
144 | path_segment.name_ref() | ||
145 | }) | ||
146 | .and_then(|name_ref| classify_name_ref(sema, &name_ref))?; | ||
128 | 147 | ||
129 | Some(NameClass::Definition(name_ref_class.definition())) | 148 | Some(NameClass::Definition(name_ref_class.definition())) |
130 | }, | 149 | }, |
131 | ast::BindPat(it) => { | 150 | ast::IdentPat(it) => { |
132 | let local = sema.to_def(&it)?; | 151 | let local = sema.to_def(&it)?; |
133 | 152 | ||
134 | if let Some(record_field_pat) = it.syntax().parent().and_then(ast::RecordFieldPat::cast) { | 153 | if let Some(record_field_pat) = it.syntax().parent().and_then(ast::RecordPatField::cast) { |
135 | if record_field_pat.name_ref().is_none() { | 154 | if record_field_pat.name_ref().is_none() { |
136 | if let Some(field) = sema.resolve_record_field_pat(&record_field_pat) { | 155 | if let Some(field) = sema.resolve_record_field_pat(&record_field_pat) { |
137 | let field = Definition::Field(field); | 156 | let field = Definition::Field(field); |
@@ -142,7 +161,7 @@ pub fn classify_name(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option | |||
142 | 161 | ||
143 | Some(NameClass::Definition(Definition::Local(local))) | 162 | Some(NameClass::Definition(Definition::Local(local))) |
144 | }, | 163 | }, |
145 | ast::RecordFieldDef(it) => { | 164 | ast::RecordField(it) => { |
146 | let field: hir::Field = sema.to_def(&it)?; | 165 | let field: hir::Field = sema.to_def(&it)?; |
147 | Some(NameClass::Definition(Definition::Field(field))) | 166 | Some(NameClass::Definition(Definition::Field(field))) |
148 | }, | 167 | }, |
@@ -150,39 +169,39 @@ pub fn classify_name(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option | |||
150 | let def = sema.to_def(&it)?; | 169 | let def = sema.to_def(&it)?; |
151 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) | 170 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) |
152 | }, | 171 | }, |
153 | ast::StructDef(it) => { | 172 | ast::Struct(it) => { |
154 | let def: hir::Struct = sema.to_def(&it)?; | 173 | let def: hir::Struct = sema.to_def(&it)?; |
155 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) | 174 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) |
156 | }, | 175 | }, |
157 | ast::UnionDef(it) => { | 176 | ast::Union(it) => { |
158 | let def: hir::Union = sema.to_def(&it)?; | 177 | let def: hir::Union = sema.to_def(&it)?; |
159 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) | 178 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) |
160 | }, | 179 | }, |
161 | ast::EnumDef(it) => { | 180 | ast::Enum(it) => { |
162 | let def: hir::Enum = sema.to_def(&it)?; | 181 | let def: hir::Enum = sema.to_def(&it)?; |
163 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) | 182 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) |
164 | }, | 183 | }, |
165 | ast::TraitDef(it) => { | 184 | ast::Trait(it) => { |
166 | let def: hir::Trait = sema.to_def(&it)?; | 185 | let def: hir::Trait = sema.to_def(&it)?; |
167 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) | 186 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) |
168 | }, | 187 | }, |
169 | ast::StaticDef(it) => { | 188 | ast::Static(it) => { |
170 | let def: hir::Static = sema.to_def(&it)?; | 189 | let def: hir::Static = sema.to_def(&it)?; |
171 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) | 190 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) |
172 | }, | 191 | }, |
173 | ast::EnumVariant(it) => { | 192 | ast::Variant(it) => { |
174 | let def: hir::EnumVariant = sema.to_def(&it)?; | 193 | let def: hir::EnumVariant = sema.to_def(&it)?; |
175 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) | 194 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) |
176 | }, | 195 | }, |
177 | ast::FnDef(it) => { | 196 | ast::Fn(it) => { |
178 | let def: hir::Function = sema.to_def(&it)?; | 197 | let def: hir::Function = sema.to_def(&it)?; |
179 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) | 198 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) |
180 | }, | 199 | }, |
181 | ast::ConstDef(it) => { | 200 | ast::Const(it) => { |
182 | let def: hir::Const = sema.to_def(&it)?; | 201 | let def: hir::Const = sema.to_def(&it)?; |
183 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) | 202 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) |
184 | }, | 203 | }, |
185 | ast::TypeAliasDef(it) => { | 204 | ast::TypeAlias(it) => { |
186 | let def: hir::TypeAlias = sema.to_def(&it)?; | 205 | let def: hir::TypeAlias = sema.to_def(&it)?; |
187 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) | 206 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) |
188 | }, | 207 | }, |
@@ -236,7 +255,7 @@ pub fn classify_name_ref( | |||
236 | } | 255 | } |
237 | } | 256 | } |
238 | 257 | ||
239 | if let Some(record_field) = ast::RecordField::for_field_name(name_ref) { | 258 | if let Some(record_field) = ast::RecordExprField::for_field_name(name_ref) { |
240 | if let Some((field, local)) = sema.resolve_record_field(&record_field) { | 259 | if let Some((field, local)) = sema.resolve_record_field(&record_field) { |
241 | let field = Definition::Field(field); | 260 | let field = Definition::Field(field); |
242 | let res = match local { | 261 | let res = match local { |
@@ -247,7 +266,7 @@ pub fn classify_name_ref( | |||
247 | } | 266 | } |
248 | } | 267 | } |
249 | 268 | ||
250 | if let Some(record_field_pat) = ast::RecordFieldPat::cast(parent.clone()) { | 269 | if let Some(record_field_pat) = ast::RecordPatField::cast(parent.clone()) { |
251 | if let Some(field) = sema.resolve_record_field_pat(&record_field_pat) { | 270 | if let Some(field) = sema.resolve_record_field_pat(&record_field_pat) { |
252 | let field = Definition::Field(field); | 271 | let field = Definition::Field(field); |
253 | return Some(NameRefClass::Definition(field)); | 272 | return Some(NameRefClass::Definition(field)); |