@@ -125,7 +125,12 @@ fn insert(path: &Path, entry: IndexEntry) -> anyhow::Result<()> {
125
125
let path = str_from_path ( path) ?;
126
126
127
127
let index = index. entry ( path. to_string ( ) ) . or_default ( ) ;
128
+ index_insert ( index, entry) ;
128
129
130
+ Ok ( ( ) )
131
+ }
132
+
133
+ fn index_insert ( index : & mut HashMap < String , IndexEntry > , entry : IndexEntry ) {
129
134
// We generally retain only the first occurrence in the index. In the
130
135
// future we'll track every occurrences and their scopes but for now we
131
136
// only track the first definition of an object (in a way, its
@@ -139,8 +144,6 @@ fn insert(path: &Path, entry: IndexEntry) -> anyhow::Result<()> {
139
144
} else {
140
145
index. insert ( entry. key . clone ( ) , entry) ;
141
146
}
142
-
143
- Ok ( ( ) )
144
147
}
145
148
146
149
fn clear ( path : & Path ) -> anyhow:: Result < ( ) > {
@@ -408,7 +411,9 @@ fn index_comment(
408
411
mod tests {
409
412
use std:: path:: PathBuf ;
410
413
414
+ use assert_matches:: assert_matches;
411
415
use insta:: assert_debug_snapshot;
416
+ use tower_lsp:: lsp_types;
412
417
413
418
use super :: * ;
414
419
use crate :: lsp:: documents:: Document ;
@@ -539,4 +544,67 @@ class <- R6::R6Class(
539
544
"#
540
545
) ;
541
546
}
547
+
548
+ #[ test]
549
+ fn test_index_insert_priority ( ) {
550
+ let mut index = HashMap :: new ( ) ;
551
+
552
+ let section_entry = IndexEntry {
553
+ key : "foo" . to_string ( ) ,
554
+ range : Range :: new (
555
+ lsp_types:: Position :: new ( 0 , 0 ) ,
556
+ lsp_types:: Position :: new ( 0 , 3 ) ,
557
+ ) ,
558
+ data : IndexEntryData :: Section {
559
+ level : 1 ,
560
+ title : "foo" . to_string ( ) ,
561
+ } ,
562
+ } ;
563
+
564
+ let variable_entry = IndexEntry {
565
+ key : "foo" . to_string ( ) ,
566
+ range : Range :: new (
567
+ lsp_types:: Position :: new ( 1 , 0 ) ,
568
+ lsp_types:: Position :: new ( 1 , 3 ) ,
569
+ ) ,
570
+ data : IndexEntryData :: Variable {
571
+ name : "foo" . to_string ( ) ,
572
+ } ,
573
+ } ;
574
+
575
+ // The Variable has priority and should replace the Section
576
+ index_insert ( & mut index, section_entry. clone ( ) ) ;
577
+ index_insert ( & mut index, variable_entry. clone ( ) ) ;
578
+ assert_matches ! (
579
+ & index. get( "foo" ) . unwrap( ) . data,
580
+ IndexEntryData :: Variable { name } => assert_eq!( name, "foo" )
581
+ ) ;
582
+
583
+ // Inserting a Section again with the same key does not override the Variable
584
+ index_insert ( & mut index, section_entry. clone ( ) ) ;
585
+ assert_matches ! (
586
+ & index. get( "foo" ) . unwrap( ) . data,
587
+ IndexEntryData :: Variable { name } => assert_eq!( name, "foo" )
588
+ ) ;
589
+
590
+ let function_entry = IndexEntry {
591
+ key : "foo" . to_string ( ) ,
592
+ range : Range :: new (
593
+ lsp_types:: Position :: new ( 2 , 0 ) ,
594
+ lsp_types:: Position :: new ( 2 , 3 ) ,
595
+ ) ,
596
+ data : IndexEntryData :: Function {
597
+ name : "foo" . to_string ( ) ,
598
+ arguments : vec ! [ "a" . to_string( ) ] ,
599
+ } ,
600
+ } ;
601
+
602
+ // Inserting another kind of variable (e.g., Function) with the same key
603
+ // does not override it either. The first occurrence is generally retained.
604
+ index_insert ( & mut index, function_entry. clone ( ) ) ;
605
+ assert_matches ! (
606
+ & index. get( "foo" ) . unwrap( ) . data,
607
+ IndexEntryData :: Variable { name } => assert_eq!( name, "foo" )
608
+ ) ;
609
+ }
542
610
}
0 commit comments