@@ -19,8 +19,9 @@ use once_cell::unsync::Lazy;
19
19
use ra_db:: { SourceDatabase , SourceDatabaseExt } ;
20
20
use ra_prof:: profile;
21
21
use ra_syntax:: {
22
- algo:: find_node_at_offset, ast, match_ast, AstNode , SourceFile , SyntaxKind , SyntaxNode ,
23
- TextUnit , TokenAtOffset ,
22
+ algo:: find_node_at_offset,
23
+ ast:: { self , NameOwner } ,
24
+ match_ast, AstNode , SourceFile , SyntaxKind , SyntaxNode , TextRange , TextUnit , TokenAtOffset ,
24
25
} ;
25
26
26
27
use crate :: {
@@ -149,7 +150,13 @@ pub(crate) fn find_all_refs(
149
150
}
150
151
} ;
151
152
152
- let declaration = Declaration { nav : declaration, kind : ReferenceKind :: Other , access : None } ;
153
+ let decl_range = declaration. range ( ) ;
154
+
155
+ let declaration = Declaration {
156
+ nav : declaration,
157
+ kind : ReferenceKind :: Other ,
158
+ access : decl_access ( & def. kind , & name, & syntax, decl_range) ,
159
+ } ;
153
160
154
161
let references = process_definition ( db, def, name, search_scope)
155
162
. into_iter ( )
@@ -218,12 +225,11 @@ fn process_definition(
218
225
} else {
219
226
ReferenceKind :: Other
220
227
} ;
221
- let access = access_mode ( d. kind , & name_ref) ;
222
228
223
229
refs. push ( Reference {
224
230
file_range : FileRange { file_id, range } ,
225
231
kind,
226
- access,
232
+ access : reference_access ( & d . kind , & name_ref ) ,
227
233
} ) ;
228
234
}
229
235
}
@@ -233,7 +239,34 @@ fn process_definition(
233
239
refs
234
240
}
235
241
236
- fn access_mode ( kind : NameKind , name_ref : & ast:: NameRef ) -> Option < ReferenceAccess > {
242
+ fn decl_access (
243
+ kind : & NameKind ,
244
+ name : & str ,
245
+ syntax : & SyntaxNode ,
246
+ range : TextRange ,
247
+ ) -> Option < ReferenceAccess > {
248
+ match kind {
249
+ NameKind :: Local ( _) | NameKind :: Field ( _) => { }
250
+ _ => return None ,
251
+ } ;
252
+
253
+ let stmt = find_node_at_offset :: < ast:: LetStmt > ( syntax, range. start ( ) ) ?;
254
+ if let Some ( _) = stmt. initializer ( ) {
255
+ let pat = stmt. pat ( ) ?;
256
+ match pat {
257
+ ast:: Pat :: BindPat ( it) => {
258
+ if it. name ( ) ?. text ( ) . as_str ( ) == name {
259
+ return Some ( ReferenceAccess :: Write ) ;
260
+ }
261
+ }
262
+ _ => { }
263
+ }
264
+ }
265
+
266
+ None
267
+ }
268
+
269
+ fn reference_access ( kind : & NameKind , name_ref : & ast:: NameRef ) -> Option < ReferenceAccess > {
237
270
// Only Locals and Fields have accesses for now.
238
271
match kind {
239
272
NameKind :: Local ( _) | NameKind :: Field ( _) => { }
@@ -311,7 +344,7 @@ mod tests {
311
344
let refs = get_all_refs ( code) ;
312
345
check_result (
313
346
refs,
314
- "i BIND_PAT FileId(1) [33; 34) Other" ,
347
+ "i BIND_PAT FileId(1) [33; 34) Other Write " ,
315
348
& [
316
349
"FileId(1) [67; 68) Other Write" ,
317
350
"FileId(1) [71; 72) Other Read" ,
@@ -569,7 +602,7 @@ mod tests {
569
602
let refs = get_all_refs ( code) ;
570
603
check_result (
571
604
refs,
572
- "i BIND_PAT FileId(1) [36; 37) Other" ,
605
+ "i BIND_PAT FileId(1) [36; 37) Other Write " ,
573
606
& [ "FileId(1) [55; 56) Other Write" , "FileId(1) [59; 60) Other Read" ] ,
574
607
) ;
575
608
}
@@ -594,6 +627,22 @@ mod tests {
594
627
) ;
595
628
}
596
629
630
+ #[ test]
631
+ fn test_basic_highlight_decl_no_write ( ) {
632
+ let code = r#"
633
+ fn foo() {
634
+ let i<|>;
635
+ i = 1;
636
+ }"# ;
637
+
638
+ let refs = get_all_refs ( code) ;
639
+ check_result (
640
+ refs,
641
+ "i BIND_PAT FileId(1) [36; 37) Other" ,
642
+ & [ "FileId(1) [51; 52) Other Write" ] ,
643
+ ) ;
644
+ }
645
+
597
646
fn get_all_refs ( text : & str ) -> ReferenceSearchResult {
598
647
let ( analysis, position) = single_file_with_position ( text) ;
599
648
analysis. find_all_refs ( position, None ) . unwrap ( ) . unwrap ( )
0 commit comments