6
6
// FIXME: this badly needs rename/rewrite (matklad, 2020-02-06).
7
7
8
8
use hir:: {
9
- Adt , FieldSource , HasSource , ImplDef , Local , MacroDef , Module , ModuleDef , Name , Semantics ,
10
- StructField , TypeParam ,
9
+ Adt , FieldSource , HasSource , ImplDef , Local , MacroDef , Module , ModuleDef , Name , PathResolution ,
10
+ Semantics , StructField , TypeParam ,
11
11
} ;
12
12
use ra_prof:: profile;
13
13
use ra_syntax:: {
@@ -117,6 +117,8 @@ impl NameClass {
117
117
}
118
118
119
119
pub fn classify_name ( sema : & Semantics < RootDatabase > , name : & ast:: Name ) -> Option < NameClass > {
120
+ let _p = profile ( "classify_name" ) ;
121
+
120
122
if let Some ( bind_pat) = name. syntax ( ) . parent ( ) . and_then ( ast:: BindPat :: cast) {
121
123
if let Some ( def) = sema. resolve_bind_pat_to_const ( & bind_pat) {
122
124
return Some ( NameClass :: ConstReference ( Definition :: ModuleDef ( def) ) ) ;
@@ -127,7 +129,6 @@ pub fn classify_name(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option
127
129
}
128
130
129
131
fn classify_name_inner ( sema : & Semantics < RootDatabase > , name : & ast:: Name ) -> Option < Definition > {
130
- let _p = profile ( "classify_name" ) ;
131
132
let parent = name. syntax ( ) . parent ( ) ?;
132
133
133
134
match_ast ! {
@@ -192,3 +193,74 @@ fn classify_name_inner(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Opti
192
193
}
193
194
}
194
195
}
196
+
197
+ pub enum NameRefClass {
198
+ Definition ( Definition ) ,
199
+ FieldShorthand { local : Local , field : Definition } ,
200
+ }
201
+
202
+ impl NameRefClass {
203
+ pub fn definition ( self ) -> Definition {
204
+ match self {
205
+ NameRefClass :: Definition ( def) => def,
206
+ NameRefClass :: FieldShorthand { local, field : _ } => Definition :: Local ( local) ,
207
+ }
208
+ }
209
+ }
210
+
211
+ pub fn classify_name_ref (
212
+ sema : & Semantics < RootDatabase > ,
213
+ name_ref : & ast:: NameRef ,
214
+ ) -> Option < NameRefClass > {
215
+ let _p = profile ( "classify_name_ref" ) ;
216
+
217
+ let parent = name_ref. syntax ( ) . parent ( ) ?;
218
+
219
+ if let Some ( method_call) = ast:: MethodCallExpr :: cast ( parent. clone ( ) ) {
220
+ if let Some ( func) = sema. resolve_method_call ( & method_call) {
221
+ return Some ( NameRefClass :: Definition ( Definition :: ModuleDef ( func. into ( ) ) ) ) ;
222
+ }
223
+ }
224
+
225
+ if let Some ( field_expr) = ast:: FieldExpr :: cast ( parent. clone ( ) ) {
226
+ if let Some ( field) = sema. resolve_field ( & field_expr) {
227
+ return Some ( NameRefClass :: Definition ( Definition :: StructField ( field) ) ) ;
228
+ }
229
+ }
230
+
231
+ if let Some ( record_field) = ast:: RecordField :: cast ( parent. clone ( ) ) {
232
+ if let Some ( ( field, local) ) = sema. resolve_record_field ( & record_field) {
233
+ let field = Definition :: StructField ( field) ;
234
+ let res = match local {
235
+ None => NameRefClass :: Definition ( field) ,
236
+ Some ( local) => NameRefClass :: FieldShorthand { field, local } ,
237
+ } ;
238
+ return Some ( res) ;
239
+ }
240
+ }
241
+
242
+ if let Some ( macro_call) = parent. ancestors ( ) . find_map ( ast:: MacroCall :: cast) {
243
+ if let Some ( macro_def) = sema. resolve_macro_call ( & macro_call) {
244
+ return Some ( NameRefClass :: Definition ( Definition :: Macro ( macro_def) ) ) ;
245
+ }
246
+ }
247
+
248
+ let path = name_ref. syntax ( ) . ancestors ( ) . find_map ( ast:: Path :: cast) ?;
249
+ let resolved = sema. resolve_path ( & path) ?;
250
+ let res = match resolved {
251
+ PathResolution :: Def ( def) => Definition :: ModuleDef ( def) ,
252
+ PathResolution :: AssocItem ( item) => {
253
+ let def = match item {
254
+ hir:: AssocItem :: Function ( it) => it. into ( ) ,
255
+ hir:: AssocItem :: Const ( it) => it. into ( ) ,
256
+ hir:: AssocItem :: TypeAlias ( it) => it. into ( ) ,
257
+ } ;
258
+ Definition :: ModuleDef ( def)
259
+ }
260
+ PathResolution :: Local ( local) => Definition :: Local ( local) ,
261
+ PathResolution :: TypeParam ( par) => Definition :: TypeParam ( par) ,
262
+ PathResolution :: Macro ( def) => Definition :: Macro ( def) ,
263
+ PathResolution :: SelfType ( impl_def) => Definition :: SelfType ( impl_def) ,
264
+ } ;
265
+ Some ( NameRefClass :: Definition ( res) )
266
+ }
0 commit comments