aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_db/src/defs.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide_db/src/defs.rs')
-rw-r--r--crates/ra_ide_db/src/defs.rs57
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::{
12use ra_prof::profile; 12use ra_prof::profile;
13use ra_syntax::{ 13use ra_syntax::{
14 ast::{self, AstNode}, 14 ast::{self, AstNode},
15 match_ast, 15 match_ast, SyntaxNode,
16}; 16};
17 17
18use crate::RootDatabase; 18use 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));