@@ -10,14 +10,14 @@ use compiler::{
1010} ;
1111use indexmap:: IndexSet ;
1212use tower_lsp_server:: lsp_types:: { Range , TextEdit } ;
13+ use tracing:: error;
1314
1415use crate :: document:: Document ;
1516
1617pub ( crate ) struct ScopeAnnotationPass < ' a > {
1718 ast : & ' a AnnotatedAst < ParseMetadata > ,
1819 content : Document ,
19- assigned_names : Vec < IndexSet < String > > ,
20- to_add : Vec < Vec < Range > > ,
20+ annotations : Vec < Vec < ( Option < Substr > , Range ) > > ,
2121 edits : Vec < TextEdit > ,
2222}
2323
@@ -26,8 +26,7 @@ impl<'a> ScopeAnnotationPass<'a> {
2626 Self {
2727 ast,
2828 content : Document :: new ( & ast. text , 0 ) ,
29- assigned_names : vec ! [ Default :: default ( ) ] ,
30- to_add : vec ! [ Default :: default ( ) ] ,
29+ annotations : vec ! [ Default :: default ( ) ] ,
3130 edits : vec ! [ ] ,
3231 }
3332 }
@@ -53,6 +52,36 @@ impl<'a> ScopeAnnotationPass<'a> {
5352 }
5453}
5554
55+ fn increment_or_add_zero ( input : & str ) -> String {
56+ // Find the index where the trailing digits start
57+ let split_idx = input
58+ . char_indices ( )
59+ . rev ( )
60+ . take_while ( |( _, c) | c. is_ascii_digit ( ) )
61+ . last ( )
62+ . map ( |( i, _) | i) ;
63+
64+ match split_idx {
65+ Some ( idx) => {
66+ let ( prefix, suffix) = input. split_at ( idx) ;
67+
68+ // Parse the number
69+ if let Ok ( num) = suffix. parse :: < u64 > ( ) {
70+ // Increment and maintain the original width for leading zeros
71+ let incremented = num + 1 ;
72+ format ! ( "{}{:0width$}" , prefix, incremented, width = suffix. len( ) )
73+ } else {
74+ // Handle cases where the number is too large for u64
75+ format ! ( "{}0" , input)
76+ }
77+ }
78+ None => {
79+ // No digits at the end, just add '0'
80+ format ! ( "{}0" , input)
81+ }
82+ }
83+ }
84+
5685impl < ' a > AstTransformer for ScopeAnnotationPass < ' a > {
5786 type InputMetadata = ParseMetadata ;
5887 type OutputMetadata = ParseMetadata ;
@@ -115,16 +144,16 @@ impl<'a> AstTransformer for ScopeAnnotationPass<'a> {
115144 _else_ : & Scope < Substr , Self :: OutputMetadata > ,
116145 ) -> <Self :: OutputMetadata as AstMetadata >:: IfExpr {
117146 if let Some ( scope_annotation) = & input. scope_annotation {
118- self . assigned_names
119- . last_mut ( )
120- . unwrap ( )
121- . insert ( scope_annotation . name . to_string ( ) ) ;
147+ self . annotations . last_mut ( ) . unwrap ( ) . push ( (
148+ Some ( scope_annotation . name . clone ( ) ) ,
149+ self . content . span_to_range ( scope_annotation . span ) ,
150+ ) ) ;
122151 } else {
123152 let start = self . content . offset_to_pos ( input. span . start ( ) ) ;
124- self . to_add
153+ self . annotations
125154 . last_mut ( )
126155 . unwrap ( )
127- . push ( Range :: new ( start, start) ) ;
156+ . push ( ( None , Range :: new ( start, start) ) ) ;
128157 }
129158 }
130159
@@ -185,47 +214,64 @@ impl<'a> AstTransformer for ScopeAnnotationPass<'a> {
185214 return ;
186215 }
187216 if let Some ( scope_annotation) = & input. scope_annotation {
188- self . assigned_names
189- . last_mut ( )
190- . unwrap ( )
191- . insert ( scope_annotation . name . to_string ( ) ) ;
217+ self . annotations . last_mut ( ) . unwrap ( ) . push ( (
218+ Some ( scope_annotation . name . clone ( ) ) ,
219+ self . content . span_to_range ( scope_annotation . span ) ,
220+ ) ) ;
192221 } else {
193222 let start = self . content . offset_to_pos ( input. span . start ( ) ) ;
194- self . to_add
223+ self . annotations
195224 . last_mut ( )
196225 . unwrap ( )
197- . push ( Range :: new ( start, start) ) ;
226+ . push ( ( None , Range :: new ( start, start) ) ) ;
198227 }
199228 }
200229
201230 fn enter_scope ( & mut self , _input : & Scope < Substr , Self :: InputMetadata > ) {
202- self . assigned_names . push ( Default :: default ( ) ) ;
203- self . to_add . push ( Default :: default ( ) ) ;
231+ self . annotations . push ( Default :: default ( ) ) ;
204232 }
205233
206234 fn exit_scope (
207235 & mut self ,
208236 _input : & Scope < Substr , Self :: InputMetadata > ,
209237 _output : & Scope < Substr , Self :: OutputMetadata > ,
210238 ) {
211- if let Some ( mut to_add) = self . to_add . pop ( )
212- && let Some ( mut assigned_names) = self . assigned_names . pop ( )
213- {
214- to_add. reverse ( ) ;
215- let mut id = 0 ;
216- while let Some ( range) = to_add. pop ( ) {
217- let name = loop {
218- let name = format ! ( "scope{}" , id) ;
219- id += 1 ;
220- if !assigned_names. contains ( & name) {
221- assigned_names. insert ( name. clone ( ) ) ;
222- break name;
239+ if let Some ( mut annotations) = self . annotations . pop ( ) {
240+ let mut assigned_names = IndexSet :: new ( ) ;
241+ for ( annotation, range) in & annotations {
242+ if let Some ( annotation) = annotation {
243+ if assigned_names. contains ( annotation) {
244+ let mut new_name = increment_or_add_zero ( annotation) ;
245+ while assigned_names. contains ( new_name. as_str ( ) ) {
246+ new_name = increment_or_add_zero ( & new_name) ;
247+ }
248+ self . edits . push ( TextEdit {
249+ range : * range,
250+ new_text : new_name. clone ( ) ,
251+ } ) ;
252+ assigned_names. insert ( Substr :: from ( new_name) ) ;
253+ } else {
254+ assigned_names. insert ( annotation. clone ( ) ) ;
223255 }
224- } ;
225- self . edits . push ( TextEdit {
226- range,
227- new_text : format ! ( "#{name} " ) ,
228- } ) ;
256+ }
257+ }
258+ annotations. reverse ( ) ;
259+ let mut id = 0 ;
260+ for ( annotation, range) in annotations {
261+ if annotation. is_none ( ) {
262+ let name = loop {
263+ let name = Substr :: from ( format ! ( "scope{}" , id) ) ;
264+ id += 1 ;
265+ if !assigned_names. contains ( & name) {
266+ assigned_names. insert ( name. clone ( ) ) ;
267+ break name;
268+ }
269+ } ;
270+ self . edits . push ( TextEdit {
271+ range,
272+ new_text : format ! ( "#{name} " ) ,
273+ } ) ;
274+ }
229275 }
230276 }
231277 }
@@ -316,16 +362,16 @@ impl<'a> AstTransformer for ScopeAnnotationPass<'a> {
316362 Expr :: StringLiteral ( string_literal) => Expr :: StringLiteral ( string_literal. clone ( ) ) ,
317363 Expr :: Scope ( scope) => {
318364 if let Some ( scope_annotation) = & scope. scope_annotation {
319- self . assigned_names
320- . last_mut ( )
321- . unwrap ( )
322- . insert ( scope_annotation . name . to_string ( ) ) ;
365+ self . annotations . last_mut ( ) . unwrap ( ) . push ( (
366+ Some ( scope_annotation . name . clone ( ) ) ,
367+ self . content . span_to_range ( scope_annotation . span ) ,
368+ ) ) ;
323369 } else {
324370 let start = self . content . offset_to_pos ( scope. span . start ( ) ) ;
325- self . to_add
371+ self . annotations
326372 . last_mut ( )
327373 . unwrap ( )
328- . push ( Range :: new ( start, start) ) ;
374+ . push ( ( None , Range :: new ( start, start) ) ) ;
329375 }
330376 Expr :: Scope ( Box :: new ( self . transform_scope ( scope) ) )
331377 }
0 commit comments