@@ -86,30 +86,38 @@ pub struct HoverResult {
86
86
// image::https://user-images.githubusercontent.com/48062697/113020658-b5f98b80-917a-11eb-9f88-3dbc27320c95.gif[]
87
87
pub ( crate ) fn hover (
88
88
db : & RootDatabase ,
89
- file_range : FileRange ,
89
+ frange @ FileRange { file_id , range } : FileRange ,
90
90
config : & HoverConfig ,
91
91
) -> Option < RangeInfo < HoverResult > > {
92
92
let sema = & hir:: Semantics :: new ( db) ;
93
- let mut res = hover_impl ( sema, file_range, config) ?;
93
+ let file = sema. parse ( file_id) . syntax ( ) . clone ( ) ;
94
+ let mut res = if range. is_empty ( ) {
95
+ hover_simple ( sema, FilePosition { file_id, offset : range. start ( ) } , file, config)
96
+ } else {
97
+ hover_ranged ( sema, frange, file, config)
98
+ } ?;
99
+
94
100
if let HoverDocFormat :: PlainText = config. format {
95
101
res. info . markup = remove_markdown ( res. info . markup . as_str ( ) ) . into ( ) ;
96
102
}
97
103
Some ( res)
98
104
}
99
105
100
- fn hover_impl (
106
+ fn hover_simple (
101
107
sema : & Semantics < ' _ , RootDatabase > ,
102
- FileRange { file_id, range } : FileRange ,
108
+ FilePosition { file_id, offset } : FilePosition ,
109
+ file : SyntaxNode ,
103
110
config : & HoverConfig ,
104
111
) -> Option < RangeInfo < HoverResult > > {
105
- let file = sema. parse ( file_id) . syntax ( ) . clone ( ) ;
106
- if !range. is_empty ( ) {
107
- return hover_ranged ( & file, range, sema, config) ;
108
- }
109
- let offset = range. start ( ) ;
110
-
111
112
let original_token = pick_best_token ( file. token_at_offset ( offset) , |kind| match kind {
112
- IDENT | INT_NUMBER | LIFETIME_IDENT | T ! [ self ] | T ! [ super ] | T ! [ crate ] | T ! [ Self ] => 4 ,
113
+ IDENT
114
+ | INT_NUMBER
115
+ | LIFETIME_IDENT
116
+ | T ! [ self ]
117
+ | T ! [ super ]
118
+ | T ! [ crate ]
119
+ | T ! [ Self ]
120
+ | T ! [ _] => 4 ,
113
121
// index and prefix ops
114
122
T ! [ '[' ] | T ! [ ']' ] | T ! [ ?] | T ! [ * ] | T ! [ -] | T ! [ !] => 3 ,
115
123
kind if kind. is_keyword ( ) => 2 ,
@@ -142,19 +150,18 @@ fn hover_impl(
142
150
} else {
143
151
sema. descend_into_macros_with_same_text ( original_token. clone ( ) )
144
152
} ;
153
+ let descended = || descended. iter ( ) ;
145
154
146
- // try lint hover
147
- let result = descended
148
- . iter ( )
155
+ let result = descended ( )
156
+ // try lint hover
149
157
. find_map ( |token| {
150
158
// FIXME: Definition should include known lints and the like instead of having this special case here
151
159
let attr = token. parent_ancestors ( ) . find_map ( ast:: Attr :: cast) ?;
152
160
render:: try_for_lint ( & attr, token)
153
161
} )
154
- // try item definitions
162
+ // try definitions
155
163
. or_else ( || {
156
- descended
157
- . iter ( )
164
+ descended ( )
158
165
. filter_map ( |token| {
159
166
let node = token. parent ( ) ?;
160
167
let class = IdentClass :: classify_token ( sema, token) ?;
@@ -175,10 +182,12 @@ fn hover_impl(
175
182
} )
176
183
} )
177
184
// try keywords
178
- . or_else ( || descended. iter ( ) . find_map ( |token| render:: keyword ( sema, config, token) ) )
179
- // try rest item hover
185
+ . or_else ( || descended ( ) . find_map ( |token| render:: keyword ( sema, config, token) ) )
186
+ // try _ hovers
187
+ . or_else ( || descended ( ) . find_map ( |token| render:: underscore ( sema, config, token) ) )
188
+ // try rest pattern hover
180
189
. or_else ( || {
181
- descended. iter ( ) . find_map ( |token| {
190
+ descended ( ) . find_map ( |token| {
182
191
if token. kind ( ) != DOT2 {
183
192
return None ;
184
193
}
@@ -201,39 +210,13 @@ fn hover_impl(
201
210
} )
202
211
// fallback to type hover if there aren't any other suggestions
203
212
// this finds its own range instead of using the closest token's range
204
- . or_else ( || {
205
- descended. iter ( ) . find_map ( |token| hover_type_fallback ( sema, config, token, token) )
206
- } )
207
- }
208
-
209
- pub ( crate ) fn hover_for_definition (
210
- sema : & Semantics < ' _ , RootDatabase > ,
211
- file_id : FileId ,
212
- definition : Definition ,
213
- node : & SyntaxNode ,
214
- config : & HoverConfig ,
215
- ) -> Option < HoverResult > {
216
- let famous_defs = match & definition {
217
- Definition :: BuiltinType ( _) => Some ( FamousDefs ( sema, sema. scope ( node) ?. krate ( ) ) ) ,
218
- _ => None ,
219
- } ;
220
- render:: definition ( sema. db , definition, famous_defs. as_ref ( ) , config) . map ( |markup| {
221
- HoverResult {
222
- markup : render:: process_markup ( sema. db , definition, & markup, config) ,
223
- actions : show_implementations_action ( sema. db , definition)
224
- . into_iter ( )
225
- . chain ( show_fn_references_action ( sema. db , definition) )
226
- . chain ( runnable_action ( sema, definition, file_id) )
227
- . chain ( goto_type_action_for_def ( sema. db , definition) )
228
- . collect ( ) ,
229
- }
230
- } )
213
+ . or_else ( || descended ( ) . find_map ( |token| hover_type_fallback ( sema, config, token, token) ) )
231
214
}
232
215
233
216
fn hover_ranged (
234
- file : & SyntaxNode ,
235
- range : syntax:: TextRange ,
236
217
sema : & Semantics < ' _ , RootDatabase > ,
218
+ FileRange { range, .. } : FileRange ,
219
+ file : SyntaxNode ,
237
220
config : & HoverConfig ,
238
221
) -> Option < RangeInfo < HoverResult > > {
239
222
// FIXME: make this work in attributes
@@ -248,7 +231,7 @@ fn hover_ranged(
248
231
}
249
232
_ => None ,
250
233
} ;
251
- let res = res. or_else ( || render:: type_info ( sema, config, & expr_or_pat) ) ;
234
+ let res = res. or_else ( || render:: type_info_of ( sema, config, & expr_or_pat) ) ;
252
235
res. map ( |it| {
253
236
let range = match expr_or_pat {
254
237
Either :: Left ( it) => it. syntax ( ) . text_range ( ) ,
@@ -258,6 +241,33 @@ fn hover_ranged(
258
241
} )
259
242
}
260
243
244
+ pub ( crate ) fn hover_for_definition (
245
+ sema : & Semantics < ' _ , RootDatabase > ,
246
+ file_id : FileId ,
247
+ definition : Definition ,
248
+ node : & SyntaxNode ,
249
+ config : & HoverConfig ,
250
+ ) -> Option < HoverResult > {
251
+ let famous_defs = match & definition {
252
+ Definition :: BuiltinType ( _) => Some ( FamousDefs ( sema, sema. scope ( node) ?. krate ( ) ) ) ,
253
+ _ => None ,
254
+ } ;
255
+ render:: definition ( sema. db , definition, famous_defs. as_ref ( ) , config) . map ( |markup| {
256
+ HoverResult {
257
+ markup : render:: process_markup ( sema. db , definition, & markup, config) ,
258
+ actions : [
259
+ show_implementations_action ( sema. db , definition) ,
260
+ show_fn_references_action ( sema. db , definition) ,
261
+ runnable_action ( sema, definition, file_id) ,
262
+ goto_type_action_for_def ( sema. db , definition) ,
263
+ ]
264
+ . into_iter ( )
265
+ . flatten ( )
266
+ . collect ( ) ,
267
+ }
268
+ } )
269
+ }
270
+
261
271
fn hover_type_fallback (
262
272
sema : & Semantics < ' _ , RootDatabase > ,
263
273
config : & HoverConfig ,
@@ -282,7 +292,7 @@ fn hover_type_fallback(
282
292
}
283
293
} ;
284
294
285
- let res = render:: type_info ( sema, config, & expr_or_pat) ?;
295
+ let res = render:: type_info_of ( sema, config, & expr_or_pat) ?;
286
296
287
297
let range = sema
288
298
. original_range_opt ( & node)
0 commit comments