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.rs85
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
8use hir::{ 8use 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};
12use ra_prof::profile; 12use ra_prof::profile;
13use ra_syntax::{ 13use ra_syntax::{
@@ -68,78 +68,97 @@ impl NameDefinition {
68 } 68 }
69} 69}
70 70
71pub fn classify_name( 71pub 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
77impl 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
92pub 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
102fn 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,