@@ -24,11 +24,12 @@ pub struct ReorderItem<'a> {
2424 /// `child_index`. Used for split inline extends: the extends_statement
2525 /// is a child of class_name_statement, not a sibling.
2626 pub sub_child : Option < usize > ,
27- /// Indices of comment/annotation children that precede this declaration
28- /// in source order (they move with it during reorder).
29- pub leading_indices : Vec < usize > ,
30- /// Indices of trailing children (e.g. #endregion) glued to this decl.
31- pub trailing_indices : Vec < usize > ,
27+ /// Indices of source children that precede and move with this declaration,
28+ /// such as comments, annotations, and region starts.
29+ pub child_indices_attached_before_declaration : Vec < usize > ,
30+ /// Indices of source children that follow and move with this declaration,
31+ /// such as end-of-line comments and region ends.
32+ pub child_indices_attached_after_declaration : Vec < usize > ,
3233 /// Whether this declaration or its leading comments had a blank line before
3334 /// it in the source. This preserves blanks lines input by the user in their
3435 /// source code, up to 1. For example, blank lines used to separate groups
@@ -129,7 +130,9 @@ pub fn build_reorder_plan<'a>(parent: Node<'a>, content: &'a str) -> ReorderPlan
129130 let mut items = Vec :: with_capacity ( child_count) ;
130131
131132 // Pass 1: classify each child.
132- let mut is_comment = vec ! [ false ; child_count] ;
133+ // These source children move with a nearby declaration. They include
134+ // comments, annotations, and region markers.
135+ let mut is_child_attached_to_declaration = vec ! [ false ; child_count] ;
133136 let mut is_region_end = vec ! [ false ; child_count] ;
134137
135138 let mut child_index = 0 ;
@@ -143,9 +146,9 @@ pub fn build_reorder_plan<'a>(parent: Node<'a>, content: &'a str) -> ReorderPlan
143146 || kind == GDScriptNodeKind :: Annotation
144147 || kind == GDScriptNodeKind :: RegionStart
145148 {
146- is_comment [ child_index] = true ;
149+ is_child_attached_to_declaration [ child_index] = true ;
147150 } else if kind == GDScriptNodeKind :: RegionEnd {
148- is_comment [ child_index] = true ;
151+ is_child_attached_to_declaration [ child_index] = true ;
149152 is_region_end[ child_index] = true ;
150153 } else if kind == GDScriptNodeKind :: SemiColon {
151154 // skip; handled by builder spacing
@@ -155,8 +158,8 @@ pub fn build_reorder_plan<'a>(parent: Node<'a>, content: &'a str) -> ReorderPlan
155158 items. push ( ReorderItem {
156159 child_index,
157160 sub_child : None ,
158- leading_indices : Vec :: new ( ) ,
159- trailing_indices : Vec :: new ( ) ,
161+ child_indices_attached_before_declaration : Vec :: new ( ) ,
162+ child_indices_attached_after_declaration : Vec :: new ( ) ,
160163 has_blank_line_before : false ,
161164 classification : child_classification. classification ,
162165 name : child_classification. name ,
@@ -170,8 +173,8 @@ pub fn build_reorder_plan<'a>(parent: Node<'a>, content: &'a str) -> ReorderPlan
170173 items. push ( ReorderItem {
171174 child_index,
172175 sub_child : Some ( extends_index) ,
173- leading_indices : Vec :: new ( ) ,
174- trailing_indices : Vec :: new ( ) ,
176+ child_indices_attached_before_declaration : Vec :: new ( ) ,
177+ child_indices_attached_after_declaration : Vec :: new ( ) ,
175178 has_blank_line_before : false ,
176179 classification : DeclarationKind :: Extends ,
177180 name : "" ,
@@ -222,7 +225,7 @@ pub fn build_reorder_plan<'a>(parent: Node<'a>, content: &'a str) -> ReorderPlan
222225 scan_index += 1 ;
223226 continue ;
224227 } ;
225- if !is_comment [ scan_index]
228+ if !is_child_attached_to_declaration [ scan_index]
226229 || !get_node_text ( child, content) . trim_start ( ) . starts_with ( "##" )
227230 {
228231 break ;
@@ -250,16 +253,16 @@ pub fn build_reorder_plan<'a>(parent: Node<'a>, content: &'a str) -> ReorderPlan
250253 // Mark docstring comments as consumed.
251254 let mut docstring_index = 0 ;
252255 while docstring_index < docstring_indices. len ( ) {
253- is_comment [ docstring_indices[ docstring_index] ] = false ;
256+ is_child_attached_to_declaration [ docstring_indices[ docstring_index] ] = false ;
254257 docstring_index += 1 ;
255258 }
256259
257260 if !docstring_indices. is_empty ( ) {
258261 items. push ( ReorderItem {
259262 child_index : docstring_indices[ 0 ] ,
260263 sub_child : None ,
261- leading_indices : docstring_indices,
262- trailing_indices : Vec :: new ( ) ,
264+ child_indices_attached_before_declaration : docstring_indices,
265+ child_indices_attached_after_declaration : Vec :: new ( ) ,
263266 has_blank_line_before : false ,
264267 classification : DeclarationKind :: Docstring ,
265268 name : "" ,
@@ -269,8 +272,8 @@ pub fn build_reorder_plan<'a>(parent: Node<'a>, content: &'a str) -> ReorderPlan
269272 } ) ;
270273 }
271274
272- // Pass 2: assign leading/trailing children to each declaration.
273- let mut previous_declaration_end : Option < usize > = None ;
275+ // Pass 2: assign source children before and after each declaration.
276+ let mut previous_declaration_child_index : Option < usize > = None ;
274277 let mut declaration_index = 0 ;
275278 while declaration_index < declaration_count {
276279 let declaration_child_index = items[ declaration_index] . child_index ;
@@ -281,29 +284,36 @@ pub fn build_reorder_plan<'a>(parent: Node<'a>, content: &'a str) -> ReorderPlan
281284 None
282285 } ;
283286
284- // Leading: all comments (non-region-end) between previous_child decl and this one.
285- let start: usize = match previous_declaration_end {
286- Some ( previous_end) => previous_end + 1 ,
287+ // Attach every eligible source child between the previous declaration
288+ // and this one before the current declaration.
289+ let first_possible_attachment_child_index: usize = match previous_declaration_child_index {
290+ Some ( previous_declaration_child_index) => previous_declaration_child_index + 1 ,
287291 None => 0 ,
288292 } ;
289- let mut leading = Vec :: new ( ) ;
290- let mut scan_index = start;
291- while scan_index < declaration_child_index {
292- if is_comment[ scan_index] && !is_region_end[ scan_index] {
293- leading. push ( scan_index) ;
293+ let mut child_indices_attached_before_declaration = Vec :: new ( ) ;
294+ let mut current_child_index = first_possible_attachment_child_index;
295+ while current_child_index < declaration_child_index {
296+ if is_child_attached_to_declaration[ current_child_index]
297+ && !is_region_end[ current_child_index]
298+ {
299+ child_indices_attached_before_declaration. push ( current_child_index) ;
294300 }
295- scan_index += 1 ;
301+ current_child_index += 1 ;
296302 }
297- items[ declaration_index] . leading_indices = leading;
303+ items[ declaration_index] . child_indices_attached_before_declaration =
304+ child_indices_attached_before_declaration;
298305
299306 // Determine if there is a blank line before the current declaration
300307 // that we need to preserve after reordering.
301- if let Some ( previous_declaration_child_index) = previous_declaration_end {
308+ if let Some ( previous_declaration_child_index) = previous_declaration_child_index {
302309 let previous_declaration = parent. child ( previous_declaration_child_index as u32 ) ;
303- let first_item_child_index = if items[ declaration_index] . leading_indices . is_empty ( ) {
310+ let first_item_child_index = if items[ declaration_index]
311+ . child_indices_attached_before_declaration
312+ . is_empty ( )
313+ {
304314 declaration_child_index
305315 } else {
306- items[ declaration_index] . leading_indices [ 0 ]
316+ items[ declaration_index] . child_indices_attached_before_declaration [ 0 ]
307317 } ;
308318 let first_item_child = parent. child ( first_item_child_index as u32 ) ;
309319 if let ( Some ( previous_declaration) , Some ( first_item_child) ) =
@@ -317,28 +327,49 @@ pub fn build_reorder_plan<'a>(parent: Node<'a>, content: &'a str) -> ReorderPlan
317327 }
318328 }
319329
320- // Trailing: region-end between this decl and the next one, or all remaining comments.
321- let mut trailing = Vec :: new ( ) ;
322- let mut scan_index = declaration_child_index + 1 ;
323- if let Some ( next) = next_declaration_child_index {
324- while scan_index < next {
325- if is_region_end[ scan_index] {
326- trailing. push ( scan_index) ;
330+ // Attach region ends and an inline comment after the declaration to
331+ // that declaration.
332+ let mut indices_of_children_attached_after_declaration = Vec :: new ( ) ;
333+ let mut next_child_index = declaration_child_index + 1 ;
334+ if let Some ( next_declaration_child_index) = next_declaration_child_index {
335+ let current_declaration = parent
336+ . child ( declaration_child_index as u32 )
337+ . expect ( "declaration child index came from this parent" ) ;
338+ while next_child_index < next_declaration_child_index {
339+ if is_region_end[ next_child_index] {
340+ indices_of_children_attached_after_declaration. push ( next_child_index) ;
341+ } else if is_child_attached_to_declaration[ next_child_index] {
342+ if let Some ( following_attached_child) = parent. child ( next_child_index as u32 ) {
343+ // This checks mainly for inline comments after the
344+ // declaration. They appear as siblings in the AST even
345+ // if on the same line so that's why we check for a
346+ // newline.
347+ let has_newline_before_following_child = content
348+ [ current_declaration. end_byte ( ) ..following_attached_child. start_byte ( ) ]
349+ . contains ( '\n' ) ;
350+ if !has_newline_before_following_child {
351+ indices_of_children_attached_after_declaration. push ( next_child_index) ;
352+ // Prevent the later declaration from also treating
353+ // this source child as preceding content.
354+ is_child_attached_to_declaration[ next_child_index] = false ;
355+ }
356+ }
327357 }
328- scan_index += 1 ;
358+ next_child_index += 1 ;
329359 }
330360 } else {
331- // After last declaration: trailing = all remaining comments .
332- while scan_index < child_count {
333- if is_comment [ scan_index ] {
334- trailing . push ( scan_index ) ;
361+ // After the last declaration, attach all remaining source children .
362+ while next_child_index < child_count {
363+ if is_child_attached_to_declaration [ next_child_index ] {
364+ indices_of_children_attached_after_declaration . push ( next_child_index ) ;
335365 }
336- scan_index += 1 ;
366+ next_child_index += 1 ;
337367 }
338368 }
339- items[ declaration_index] . trailing_indices = trailing;
369+ items[ declaration_index] . child_indices_attached_after_declaration =
370+ indices_of_children_attached_after_declaration;
340371
341- previous_declaration_end = Some ( declaration_child_index) ;
372+ previous_declaration_child_index = Some ( declaration_child_index) ;
342373 declaration_index += 1 ;
343374 }
344375
0 commit comments