@@ -42,74 +42,6 @@ pub enum Definition {
42
42
}
43
43
44
44
impl Definition {
45
- pub fn from_token (
46
- sema : & Semantics < RootDatabase > ,
47
- token : & SyntaxToken ,
48
- ) -> ArrayVec < Definition , 2 > {
49
- let parent = match token. parent ( ) {
50
- Some ( parent) => parent,
51
- None => return Default :: default ( ) ,
52
- } ;
53
- // resolve derives if possible
54
- if let Some ( ident) = ast:: Ident :: cast ( token. clone ( ) ) {
55
- let attr = ast:: TokenTree :: cast ( parent. clone ( ) )
56
- . and_then ( |tt| tt. parent_meta ( ) )
57
- . and_then ( |meta| meta. parent_attr ( ) ) ;
58
- if let Some ( attr) = attr {
59
- return sema
60
- . resolve_derive_ident ( & attr, & ident)
61
- . map ( Into :: into)
62
- . into_iter ( )
63
- . collect ( ) ;
64
- }
65
- }
66
- Self :: from_node ( sema, & parent)
67
- }
68
-
69
- pub fn from_node ( sema : & Semantics < RootDatabase > , node : & SyntaxNode ) -> ArrayVec < Definition , 2 > {
70
- let mut res = ArrayVec :: new ( ) ;
71
- ( || {
72
- match_ast ! {
73
- match node {
74
- ast:: Name ( name) => {
75
- match NameClass :: classify( & sema, & name) ? {
76
- NameClass :: Definition ( it) | NameClass :: ConstReference ( it) => res. push( it) ,
77
- NameClass :: PatFieldShorthand { local_def, field_ref } => {
78
- res. push( Definition :: Local ( local_def) ) ;
79
- res. push( Definition :: Field ( field_ref) ) ;
80
- }
81
- }
82
- } ,
83
- ast:: NameRef ( name_ref) => {
84
- match NameRefClass :: classify( sema, & name_ref) ? {
85
- NameRefClass :: Definition ( it) => res. push( it) ,
86
- NameRefClass :: FieldShorthand { local_ref, field_ref } => {
87
- res. push( Definition :: Local ( local_ref) ) ;
88
- res. push( Definition :: Field ( field_ref) ) ;
89
- }
90
- }
91
- } ,
92
- ast:: Lifetime ( lifetime) => {
93
- let def = if let Some ( x) = NameClass :: classify_lifetime( & sema, & lifetime) {
94
- NameClass :: defined( x)
95
- } else {
96
- NameRefClass :: classify_lifetime( & sema, & lifetime) . and_then( |class| match class {
97
- NameRefClass :: Definition ( it) => Some ( it) ,
98
- _ => None ,
99
- } )
100
- } ;
101
- if let Some ( def) = def {
102
- res. push( def) ;
103
- }
104
- } ,
105
- _ => ( ) ,
106
- }
107
- }
108
- Some ( ( ) )
109
- } ) ( ) ;
110
- res
111
- }
112
-
113
45
pub fn canonical_module_path ( & self , db : & RootDatabase ) -> Option < impl Iterator < Item = Module > > {
114
46
self . module ( db) . map ( |it| it. path_to_root ( db) . into_iter ( ) . rev ( ) )
115
47
}
@@ -184,6 +116,65 @@ impl Definition {
184
116
}
185
117
}
186
118
119
+ pub enum IdentClass {
120
+ NameClass ( NameClass ) ,
121
+ NameRefClass ( NameRefClass ) ,
122
+ }
123
+
124
+ impl IdentClass {
125
+ pub fn classify_node ( sema : & Semantics < RootDatabase > , node : & SyntaxNode ) -> Option < IdentClass > {
126
+ match_ast ! {
127
+ match node {
128
+ ast:: Name ( name) => NameClass :: classify( sema, & name) . map( IdentClass :: NameClass ) ,
129
+ ast:: NameRef ( name_ref) => NameRefClass :: classify( sema, & name_ref) . map( IdentClass :: NameRefClass ) ,
130
+ ast:: Lifetime ( lifetime) => {
131
+ NameClass :: classify_lifetime( sema, & lifetime)
132
+ . map( IdentClass :: NameClass )
133
+ . or_else( || NameRefClass :: classify_lifetime( sema, & lifetime) . map( IdentClass :: NameRefClass ) )
134
+ } ,
135
+ _ => None ,
136
+ }
137
+ }
138
+ }
139
+
140
+ pub fn classify_token (
141
+ sema : & Semantics < RootDatabase > ,
142
+ token : & SyntaxToken ,
143
+ ) -> Option < IdentClass > {
144
+ let parent = token. parent ( ) ?;
145
+ // resolve derives if possible
146
+ if let Some ( ident) = ast:: Ident :: cast ( token. clone ( ) ) {
147
+ let attr = ast:: TokenTree :: cast ( parent. clone ( ) )
148
+ . and_then ( |tt| tt. parent_meta ( ) )
149
+ . and_then ( |meta| meta. parent_attr ( ) ) ;
150
+ if let Some ( attr) = attr {
151
+ return NameRefClass :: classify_derive ( sema, & attr, & ident)
152
+ . map ( IdentClass :: NameRefClass ) ;
153
+ }
154
+ }
155
+ Self :: classify_node ( sema, & parent)
156
+ }
157
+
158
+ pub fn definitions ( self ) -> ArrayVec < Definition , 2 > {
159
+ let mut res = ArrayVec :: new ( ) ;
160
+ match self {
161
+ IdentClass :: NameClass ( NameClass :: Definition ( it) | NameClass :: ConstReference ( it) ) => {
162
+ res. push ( it)
163
+ }
164
+ IdentClass :: NameClass ( NameClass :: PatFieldShorthand { local_def, field_ref } ) => {
165
+ res. push ( Definition :: Local ( local_def) ) ;
166
+ res. push ( Definition :: Field ( field_ref) ) ;
167
+ }
168
+ IdentClass :: NameRefClass ( NameRefClass :: Definition ( it) ) => res. push ( it) ,
169
+ IdentClass :: NameRefClass ( NameRefClass :: FieldShorthand { local_ref, field_ref } ) => {
170
+ res. push ( Definition :: Local ( local_ref) ) ;
171
+ res. push ( Definition :: Field ( field_ref) ) ;
172
+ }
173
+ }
174
+ res
175
+ }
176
+ }
177
+
187
178
/// On a first blush, a single `ast::Name` defines a single definition at some
188
179
/// scope. That is, that, by just looking at the syntactical category, we can
189
180
/// unambiguously define the semantic category.
@@ -465,6 +456,14 @@ impl NameRefClass {
465
456
_ => None ,
466
457
}
467
458
}
459
+
460
+ pub fn classify_derive (
461
+ sema : & Semantics < RootDatabase > ,
462
+ attr : & ast:: Attr ,
463
+ ident : & ast:: Ident ,
464
+ ) -> Option < NameRefClass > {
465
+ sema. resolve_derive_ident ( & attr, & ident) . map ( Definition :: from) . map ( NameRefClass :: Definition )
466
+ }
468
467
}
469
468
470
469
impl_from ! (
0 commit comments