@@ -5,7 +5,7 @@ use ra_db::SourceDatabase;
5
5
use ra_syntax:: {
6
6
algo:: { ancestors_at_offset, find_covering_element, find_node_at_offset} ,
7
7
ast:: { self , DocCommentsOwner } ,
8
- match_ast , AstNode ,
8
+ AstNode ,
9
9
} ;
10
10
11
11
use crate :: {
@@ -14,7 +14,7 @@ use crate::{
14
14
description_from_symbol, docs_from_symbol, macro_label, rust_code_markup,
15
15
rust_code_markup_with_doc, ShortLabel ,
16
16
} ,
17
- references:: { classify_name_ref, NameKind :: * } ,
17
+ references:: { classify_name , classify_name_ref, NameKind , NameKind :: * } ,
18
18
FilePosition , FileRange , RangeInfo ,
19
19
} ;
20
20
@@ -92,65 +92,88 @@ fn hover_text(docs: Option<String>, desc: Option<String>) -> Option<String> {
92
92
}
93
93
}
94
94
95
+ fn hover_text_from_name_kind (
96
+ db : & RootDatabase ,
97
+ name_kind : NameKind ,
98
+ no_fallback : & mut bool ,
99
+ ) -> Option < String > {
100
+ return match name_kind {
101
+ Macro ( it) => {
102
+ let src = it. source ( db) ;
103
+ hover_text ( src. ast . doc_comment_text ( ) , Some ( macro_label ( & src. ast ) ) )
104
+ }
105
+ Field ( it) => {
106
+ let src = it. source ( db) ;
107
+ match src. ast {
108
+ hir:: FieldSource :: Named ( it) => hover_text ( it. doc_comment_text ( ) , it. short_label ( ) ) ,
109
+ _ => None ,
110
+ }
111
+ }
112
+ AssocItem ( it) => match it {
113
+ hir:: AssocItem :: Function ( it) => from_def_source ( db, it) ,
114
+ hir:: AssocItem :: Const ( it) => from_def_source ( db, it) ,
115
+ hir:: AssocItem :: TypeAlias ( it) => from_def_source ( db, it) ,
116
+ } ,
117
+ Def ( it) => match it {
118
+ hir:: ModuleDef :: Module ( it) => match it. definition_source ( db) . ast {
119
+ hir:: ModuleSource :: Module ( it) => {
120
+ hover_text ( it. doc_comment_text ( ) , it. short_label ( ) )
121
+ }
122
+ _ => None ,
123
+ } ,
124
+ hir:: ModuleDef :: Function ( it) => from_def_source ( db, it) ,
125
+ hir:: ModuleDef :: Adt ( Adt :: Struct ( it) ) => from_def_source ( db, it) ,
126
+ hir:: ModuleDef :: Adt ( Adt :: Union ( it) ) => from_def_source ( db, it) ,
127
+ hir:: ModuleDef :: Adt ( Adt :: Enum ( it) ) => from_def_source ( db, it) ,
128
+ hir:: ModuleDef :: EnumVariant ( it) => from_def_source ( db, it) ,
129
+ hir:: ModuleDef :: Const ( it) => from_def_source ( db, it) ,
130
+ hir:: ModuleDef :: Static ( it) => from_def_source ( db, it) ,
131
+ hir:: ModuleDef :: Trait ( it) => from_def_source ( db, it) ,
132
+ hir:: ModuleDef :: TypeAlias ( it) => from_def_source ( db, it) ,
133
+ hir:: ModuleDef :: BuiltinType ( it) => Some ( it. to_string ( ) ) ,
134
+ } ,
135
+ SelfType ( ty) => match ty. as_adt ( ) {
136
+ Some ( ( adt_def, _) ) => match adt_def {
137
+ hir:: Adt :: Struct ( it) => from_def_source ( db, it) ,
138
+ hir:: Adt :: Union ( it) => from_def_source ( db, it) ,
139
+ hir:: Adt :: Enum ( it) => from_def_source ( db, it) ,
140
+ } ,
141
+ _ => None ,
142
+ } ,
143
+ Local ( _) => {
144
+ // Hover for these shows type names
145
+ * no_fallback = true ;
146
+ None
147
+ }
148
+ GenericParam ( _) => {
149
+ // FIXME: Hover for generic param
150
+ None
151
+ }
152
+ } ;
153
+
154
+ fn from_def_source < A , D > ( db : & RootDatabase , def : D ) -> Option < String >
155
+ where
156
+ D : HasSource < Ast = A > ,
157
+ A : ast:: DocCommentsOwner + ast:: NameOwner + ShortLabel ,
158
+ {
159
+ let src = def. source ( db) ;
160
+ hover_text ( src. ast . doc_comment_text ( ) , src. ast . short_label ( ) )
161
+ }
162
+ }
163
+
95
164
pub ( crate ) fn hover ( db : & RootDatabase , position : FilePosition ) -> Option < RangeInfo < HoverResult > > {
96
165
let parse = db. parse ( position. file_id ) ;
97
166
let file = parse. tree ( ) ;
167
+
98
168
let mut res = HoverResult :: new ( ) ;
99
169
100
- let mut range = None ;
101
- if let Some ( name_ref) = find_node_at_offset :: < ast:: NameRef > ( file. syntax ( ) , position. offset ) {
170
+ let mut range = if let Some ( name_ref) =
171
+ find_node_at_offset :: < ast:: NameRef > ( file. syntax ( ) , position. offset )
172
+ {
102
173
let mut no_fallback = false ;
103
- let name_kind = classify_name_ref ( db, position. file_id , & name_ref) . map ( |d| d. kind ) ;
104
- match name_kind {
105
- Some ( Macro ( it) ) => {
106
- let src = it. source ( db) ;
107
- res. extend ( hover_text ( src. ast . doc_comment_text ( ) , Some ( macro_label ( & src. ast ) ) ) ) ;
108
- }
109
- Some ( Field ( it) ) => {
110
- let src = it. source ( db) ;
111
- if let hir:: FieldSource :: Named ( it) = src. ast {
112
- res. extend ( hover_text ( it. doc_comment_text ( ) , it. short_label ( ) ) ) ;
113
- }
114
- }
115
- Some ( AssocItem ( it) ) => res. extend ( match it {
116
- hir:: AssocItem :: Function ( it) => from_def_source ( db, it) ,
117
- hir:: AssocItem :: Const ( it) => from_def_source ( db, it) ,
118
- hir:: AssocItem :: TypeAlias ( it) => from_def_source ( db, it) ,
119
- } ) ,
120
- Some ( Def ( it) ) => match it {
121
- hir:: ModuleDef :: Module ( it) => {
122
- if let hir:: ModuleSource :: Module ( it) = it. definition_source ( db) . ast {
123
- res. extend ( hover_text ( it. doc_comment_text ( ) , it. short_label ( ) ) )
124
- }
125
- }
126
- hir:: ModuleDef :: Function ( it) => res. extend ( from_def_source ( db, it) ) ,
127
- hir:: ModuleDef :: Adt ( Adt :: Struct ( it) ) => res. extend ( from_def_source ( db, it) ) ,
128
- hir:: ModuleDef :: Adt ( Adt :: Union ( it) ) => res. extend ( from_def_source ( db, it) ) ,
129
- hir:: ModuleDef :: Adt ( Adt :: Enum ( it) ) => res. extend ( from_def_source ( db, it) ) ,
130
- hir:: ModuleDef :: EnumVariant ( it) => res. extend ( from_def_source ( db, it) ) ,
131
- hir:: ModuleDef :: Const ( it) => res. extend ( from_def_source ( db, it) ) ,
132
- hir:: ModuleDef :: Static ( it) => res. extend ( from_def_source ( db, it) ) ,
133
- hir:: ModuleDef :: Trait ( it) => res. extend ( from_def_source ( db, it) ) ,
134
- hir:: ModuleDef :: TypeAlias ( it) => res. extend ( from_def_source ( db, it) ) ,
135
- hir:: ModuleDef :: BuiltinType ( it) => res. extend ( Some ( it. to_string ( ) ) ) ,
136
- } ,
137
- Some ( SelfType ( ty) ) => {
138
- if let Some ( ( adt_def, _) ) = ty. as_adt ( ) {
139
- res. extend ( match adt_def {
140
- hir:: Adt :: Struct ( it) => from_def_source ( db, it) ,
141
- hir:: Adt :: Union ( it) => from_def_source ( db, it) ,
142
- hir:: Adt :: Enum ( it) => from_def_source ( db, it) ,
143
- } )
144
- }
145
- }
146
- Some ( Local ( _) ) => {
147
- // Hover for these shows type names
148
- no_fallback = true ;
149
- }
150
- Some ( GenericParam ( _) ) => {
151
- // FIXME: Hover for generic param
152
- }
153
- None => { }
174
+ if let Some ( name_kind) = classify_name_ref ( db, position. file_id , & name_ref) . map ( |d| d. kind )
175
+ {
176
+ res. extend ( hover_text_from_name_kind ( db, name_kind, & mut no_fallback) )
154
177
}
155
178
156
179
if res. is_empty ( ) && !no_fallback {
@@ -164,55 +187,24 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn
164
187
}
165
188
166
189
if !res. is_empty ( ) {
167
- range = Some ( name_ref. syntax ( ) . text_range ( ) )
190
+ Some ( name_ref. syntax ( ) . text_range ( ) )
191
+ } else {
192
+ None
168
193
}
169
194
} else if let Some ( name) = find_node_at_offset :: < ast:: Name > ( file. syntax ( ) , position. offset ) {
170
- if let Some ( parent) = name. syntax ( ) . parent ( ) {
171
- let text = match_ast ! {
172
- match parent {
173
- ast:: StructDef ( it) => {
174
- hover_text( it. doc_comment_text( ) , it. short_label( ) )
175
- } ,
176
- ast:: EnumDef ( it) => {
177
- hover_text( it. doc_comment_text( ) , it. short_label( ) )
178
- } ,
179
- ast:: EnumVariant ( it) => {
180
- hover_text( it. doc_comment_text( ) , it. short_label( ) )
181
- } ,
182
- ast:: FnDef ( it) => {
183
- hover_text( it. doc_comment_text( ) , it. short_label( ) )
184
- } ,
185
- ast:: TypeAliasDef ( it) => {
186
- hover_text( it. doc_comment_text( ) , it. short_label( ) )
187
- } ,
188
- ast:: ConstDef ( it) => {
189
- hover_text( it. doc_comment_text( ) , it. short_label( ) )
190
- } ,
191
- ast:: StaticDef ( it) => {
192
- hover_text( it. doc_comment_text( ) , it. short_label( ) )
193
- } ,
194
- ast:: TraitDef ( it) => {
195
- hover_text( it. doc_comment_text( ) , it. short_label( ) )
196
- } ,
197
- ast:: RecordFieldDef ( it) => {
198
- hover_text( it. doc_comment_text( ) , it. short_label( ) )
199
- } ,
200
- ast:: Module ( it) => {
201
- hover_text( it. doc_comment_text( ) , it. short_label( ) )
202
- } ,
203
- ast:: MacroCall ( it) => {
204
- hover_text( it. doc_comment_text( ) , None )
205
- } ,
206
- _ => None ,
207
- }
208
- } ;
209
- res. extend ( text) ;
195
+ if let Some ( name_kind) = classify_name ( db, position. file_id , & name) . map ( |d| d. kind ) {
196
+ let mut _b: bool = true ;
197
+ res. extend ( hover_text_from_name_kind ( db, name_kind, & mut _b) ) ;
210
198
}
211
199
212
- if !res. is_empty ( ) && range. is_none ( ) {
213
- range = Some ( name. syntax ( ) . text_range ( ) ) ;
200
+ if !res. is_empty ( ) {
201
+ Some ( name. syntax ( ) . text_range ( ) )
202
+ } else {
203
+ None
214
204
}
215
- }
205
+ } else {
206
+ None
207
+ } ;
216
208
217
209
if range. is_none ( ) {
218
210
let node = ancestors_at_offset ( file. syntax ( ) , position. offset ) . find ( |n| {
@@ -221,23 +213,13 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn
221
213
let frange = FileRange { file_id : position. file_id , range : node. text_range ( ) } ;
222
214
res. extend ( type_of ( db, frange) . map ( rust_code_markup) ) ;
223
215
range = Some ( node. text_range ( ) ) ;
224
- }
216
+ } ;
225
217
226
218
let range = range?;
227
219
if res. is_empty ( ) {
228
220
return None ;
229
221
}
230
- let res = RangeInfo :: new ( range, res) ;
231
- return Some ( res) ;
232
-
233
- fn from_def_source < A , D > ( db : & RootDatabase , def : D ) -> Option < String >
234
- where
235
- D : HasSource < Ast = A > ,
236
- A : ast:: DocCommentsOwner + ast:: NameOwner + ShortLabel ,
237
- {
238
- let src = def. source ( db) ;
239
- hover_text ( src. ast . doc_comment_text ( ) , src. ast . short_label ( ) )
240
- }
222
+ Some ( RangeInfo :: new ( range, res) )
241
223
}
242
224
243
225
pub ( crate ) fn type_of ( db : & RootDatabase , frange : FileRange ) -> Option < String > {
0 commit comments