@@ -19,8 +19,9 @@ use once_cell::unsync::Lazy;
1919use ra_db:: { SourceDatabase , SourceDatabaseExt } ;
2020use ra_prof:: profile;
2121use 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 ,
2425} ;
2526
2627use crate :: {
@@ -149,7 +150,13 @@ pub(crate) fn find_all_refs(
149150 }
150151 } ;
151152
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+ } ;
153160
154161 let references = process_definition ( db, def, name, search_scope)
155162 . into_iter ( )
@@ -218,12 +225,11 @@ fn process_definition(
218225 } else {
219226 ReferenceKind :: Other
220227 } ;
221- let access = access_mode ( d. kind , & name_ref) ;
222228
223229 refs. push ( Reference {
224230 file_range : FileRange { file_id, range } ,
225231 kind,
226- access,
232+ access : reference_access ( & d . kind , & name_ref ) ,
227233 } ) ;
228234 }
229235 }
@@ -233,7 +239,34 @@ fn process_definition(
233239 refs
234240}
235241
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 > {
237270 // Only Locals and Fields have accesses for now.
238271 match kind {
239272 NameKind :: Local ( _) | NameKind :: Field ( _) => { }
@@ -311,7 +344,7 @@ mod tests {
311344 let refs = get_all_refs ( code) ;
312345 check_result (
313346 refs,
314- "i BIND_PAT FileId(1) [33; 34) Other" ,
347+ "i BIND_PAT FileId(1) [33; 34) Other Write " ,
315348 & [
316349 "FileId(1) [67; 68) Other Write" ,
317350 "FileId(1) [71; 72) Other Read" ,
@@ -569,7 +602,7 @@ mod tests {
569602 let refs = get_all_refs ( code) ;
570603 check_result (
571604 refs,
572- "i BIND_PAT FileId(1) [36; 37) Other" ,
605+ "i BIND_PAT FileId(1) [36; 37) Other Write " ,
573606 & [ "FileId(1) [55; 56) Other Write" , "FileId(1) [59; 60) Other Read" ] ,
574607 ) ;
575608 }
@@ -594,6 +627,22 @@ mod tests {
594627 ) ;
595628 }
596629
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+
597646 fn get_all_refs ( text : & str ) -> ReferenceSearchResult {
598647 let ( analysis, position) = single_file_with_position ( text) ;
599648 analysis. find_all_refs ( position, None ) . unwrap ( ) . unwrap ( )
0 commit comments