diff options
Diffstat (limited to 'crates/ra_ide_db/src/defs.rs')
-rw-r--r-- | crates/ra_ide_db/src/defs.rs | 85 |
1 files changed, 52 insertions, 33 deletions
diff --git a/crates/ra_ide_db/src/defs.rs b/crates/ra_ide_db/src/defs.rs index 04c214624..93f32ba85 100644 --- a/crates/ra_ide_db/src/defs.rs +++ b/crates/ra_ide_db/src/defs.rs | |||
@@ -6,8 +6,8 @@ | |||
6 | // FIXME: this badly needs rename/rewrite (matklad, 2020-02-06). | 6 | // FIXME: this badly needs rename/rewrite (matklad, 2020-02-06). |
7 | 7 | ||
8 | use hir::{ | 8 | use hir::{ |
9 | Adt, FieldSource, HasSource, ImplBlock, InFile, Local, MacroDef, Module, ModuleDef, | 9 | Adt, FieldSource, HasSource, ImplBlock, Local, MacroDef, Module, ModuleDef, Semantics, |
10 | SourceBinder, StructField, TypeParam, | 10 | StructField, TypeParam, |
11 | }; | 11 | }; |
12 | use ra_prof::profile; | 12 | use ra_prof::profile; |
13 | use ra_syntax::{ | 13 | use ra_syntax::{ |
@@ -68,78 +68,97 @@ impl NameDefinition { | |||
68 | } | 68 | } |
69 | } | 69 | } |
70 | 70 | ||
71 | pub fn classify_name( | 71 | pub enum NameClass { |
72 | sb: &mut SourceBinder<RootDatabase>, | 72 | NameDefinition(NameDefinition), |
73 | name: InFile<&ast::Name>, | 73 | /// `None` in `if let None = Some(82) {}` |
74 | ) -> Option<NameDefinition> { | 74 | ConstReference(NameDefinition), |
75 | } | ||
76 | |||
77 | impl NameClass { | ||
78 | pub fn into_definition(self) -> Option<NameDefinition> { | ||
79 | match self { | ||
80 | NameClass::NameDefinition(it) => Some(it), | ||
81 | NameClass::ConstReference(_) => None, | ||
82 | } | ||
83 | } | ||
84 | |||
85 | pub fn definition(self) -> NameDefinition { | ||
86 | match self { | ||
87 | NameClass::NameDefinition(it) | NameClass::ConstReference(it) => it, | ||
88 | } | ||
89 | } | ||
90 | } | ||
91 | |||
92 | pub fn classify_name(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option<NameClass> { | ||
93 | if let Some(bind_pat) = name.syntax().parent().and_then(ast::BindPat::cast) { | ||
94 | if let Some(def) = sema.resolve_bind_pat_to_const(&bind_pat) { | ||
95 | return Some(NameClass::ConstReference(NameDefinition::ModuleDef(def))); | ||
96 | } | ||
97 | } | ||
98 | |||
99 | classify_name_inner(sema, name).map(NameClass::NameDefinition) | ||
100 | } | ||
101 | |||
102 | fn classify_name_inner(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option<NameDefinition> { | ||
75 | let _p = profile("classify_name"); | 103 | let _p = profile("classify_name"); |
76 | let parent = name.value.syntax().parent()?; | 104 | let parent = name.syntax().parent()?; |
77 | 105 | ||
78 | match_ast! { | 106 | match_ast! { |
79 | match parent { | 107 | match parent { |
80 | ast::BindPat(it) => { | 108 | ast::BindPat(it) => { |
81 | let src = name.with_value(it); | 109 | let local = sema.to_def(&it)?; |
82 | let local = sb.to_def(src)?; | ||
83 | Some(NameDefinition::Local(local)) | 110 | Some(NameDefinition::Local(local)) |
84 | }, | 111 | }, |
85 | ast::RecordFieldDef(it) => { | 112 | ast::RecordFieldDef(it) => { |
86 | let src = name.with_value(it); | 113 | let field: hir::StructField = sema.to_def(&it)?; |
87 | let field: hir::StructField = sb.to_def(src)?; | ||
88 | Some(from_struct_field(field)) | 114 | Some(from_struct_field(field)) |
89 | }, | 115 | }, |
90 | ast::Module(it) => { | 116 | ast::Module(it) => { |
91 | let def = sb.to_def(name.with_value(it))?; | 117 | let def = sema.to_def(&it)?; |
92 | Some(from_module_def(def.into())) | 118 | Some(from_module_def(def.into())) |
93 | }, | 119 | }, |
94 | ast::StructDef(it) => { | 120 | ast::StructDef(it) => { |
95 | let src = name.with_value(it); | 121 | let def: hir::Struct = sema.to_def(&it)?; |
96 | let def: hir::Struct = sb.to_def(src)?; | 122 | Some(from_module_def(def.into())) |
123 | }, | ||
124 | ast::UnionDef(it) => { | ||
125 | let def: hir::Union = sema.to_def(&it)?; | ||
97 | Some(from_module_def(def.into())) | 126 | Some(from_module_def(def.into())) |
98 | }, | 127 | }, |
99 | ast::EnumDef(it) => { | 128 | ast::EnumDef(it) => { |
100 | let src = name.with_value(it); | 129 | let def: hir::Enum = sema.to_def(&it)?; |
101 | let def: hir::Enum = sb.to_def(src)?; | ||
102 | Some(from_module_def(def.into())) | 130 | Some(from_module_def(def.into())) |
103 | }, | 131 | }, |
104 | ast::TraitDef(it) => { | 132 | ast::TraitDef(it) => { |
105 | let src = name.with_value(it); | 133 | let def: hir::Trait = sema.to_def(&it)?; |
106 | let def: hir::Trait = sb.to_def(src)?; | ||
107 | Some(from_module_def(def.into())) | 134 | Some(from_module_def(def.into())) |
108 | }, | 135 | }, |
109 | ast::StaticDef(it) => { | 136 | ast::StaticDef(it) => { |
110 | let src = name.with_value(it); | 137 | let def: hir::Static = sema.to_def(&it)?; |
111 | let def: hir::Static = sb.to_def(src)?; | ||
112 | Some(from_module_def(def.into())) | 138 | Some(from_module_def(def.into())) |
113 | }, | 139 | }, |
114 | ast::EnumVariant(it) => { | 140 | ast::EnumVariant(it) => { |
115 | let src = name.with_value(it); | 141 | let def: hir::EnumVariant = sema.to_def(&it)?; |
116 | let def: hir::EnumVariant = sb.to_def(src)?; | ||
117 | Some(from_module_def(def.into())) | 142 | Some(from_module_def(def.into())) |
118 | }, | 143 | }, |
119 | ast::FnDef(it) => { | 144 | ast::FnDef(it) => { |
120 | let src = name.with_value(it); | 145 | let def: hir::Function = sema.to_def(&it)?; |
121 | let def: hir::Function = sb.to_def(src)?; | ||
122 | Some(from_module_def(def.into())) | 146 | Some(from_module_def(def.into())) |
123 | }, | 147 | }, |
124 | ast::ConstDef(it) => { | 148 | ast::ConstDef(it) => { |
125 | let src = name.with_value(it); | 149 | let def: hir::Const = sema.to_def(&it)?; |
126 | let def: hir::Const = sb.to_def(src)?; | ||
127 | Some(from_module_def(def.into())) | 150 | Some(from_module_def(def.into())) |
128 | }, | 151 | }, |
129 | ast::TypeAliasDef(it) => { | 152 | ast::TypeAliasDef(it) => { |
130 | let src = name.with_value(it); | 153 | let def: hir::TypeAlias = sema.to_def(&it)?; |
131 | let def: hir::TypeAlias = sb.to_def(src)?; | ||
132 | Some(from_module_def(def.into())) | 154 | Some(from_module_def(def.into())) |
133 | }, | 155 | }, |
134 | ast::MacroCall(it) => { | 156 | ast::MacroCall(it) => { |
135 | let src = name.with_value(it); | 157 | let def = sema.to_def(&it)?; |
136 | let def = sb.to_def(src.clone())?; | ||
137 | |||
138 | Some(NameDefinition::Macro(def)) | 158 | Some(NameDefinition::Macro(def)) |
139 | }, | 159 | }, |
140 | ast::TypeParam(it) => { | 160 | ast::TypeParam(it) => { |
141 | let src = name.with_value(it); | 161 | let def = sema.to_def(&it)?; |
142 | let def = sb.to_def(src)?; | ||
143 | Some(NameDefinition::TypeParam(def)) | 162 | Some(NameDefinition::TypeParam(def)) |
144 | }, | 163 | }, |
145 | _ => None, | 164 | _ => None, |