11use std:: cell:: { RefCell , RefMut } ;
22use std:: collections:: HashMap ;
33use std:: iter:: zip;
4+ use std:: ops:: Index ;
45
56use taplo:: syntax:: SyntaxKind :: { TABLE_ARRAY_HEADER , TABLE_HEADER } ;
67use taplo:: syntax:: { SyntaxElement , SyntaxKind , SyntaxNode } ;
@@ -11,39 +12,57 @@ use crate::helpers::string::load_text;
1112
1213#[ derive( Debug ) ]
1314pub struct Tables {
14- pub header_to_pos : HashMap < String , usize > ,
15+ pub header_to_pos : HashMap < String , Vec < usize > > ,
1516 pub table_set : Vec < RefCell < Vec < SyntaxElement > > > ,
1617}
1718
1819impl Tables {
19- pub ( crate ) fn get ( & mut self , key : & str ) -> Option < & RefCell < Vec < SyntaxElement > > > {
20+ pub ( crate ) fn get ( & mut self , key : & str ) -> Option < Vec < & RefCell < Vec < SyntaxElement > > > > {
2021 if self . header_to_pos . contains_key ( key) {
21- Some ( & self . table_set [ self . header_to_pos [ key] ] )
22+ let mut res = Vec :: < & RefCell < Vec < SyntaxElement > > > :: new ( ) ;
23+ for pos in & self . header_to_pos [ key] {
24+ res. push ( & self . table_set [ * pos] ) ;
25+ }
26+ Some ( res)
2227 } else {
2328 None
2429 }
2530 }
2631
2732 pub fn from_ast ( root_ast : & SyntaxNode ) -> Self {
28- let mut header_to_pos = HashMap :: < String , usize > :: new ( ) ;
33+ let mut header_to_pos = HashMap :: < String , Vec < usize > > :: new ( ) ;
2934 let mut table_set = Vec :: < RefCell < Vec < SyntaxElement > > > :: new ( ) ;
3035 let entry_set = RefCell :: new ( Vec :: < SyntaxElement > :: new ( ) ) ;
31- let mut add_to_table_set = || {
36+ let mut table_kind = TABLE_HEADER ;
37+ let mut add_to_table_set = |kind| {
3238 let mut entry_set_borrow = entry_set. borrow_mut ( ) ;
3339 if !entry_set_borrow. is_empty ( ) {
34- header_to_pos. insert ( get_table_name ( & entry_set_borrow[ 0 ] ) , table_set. len ( ) ) ;
35- table_set. push ( RefCell :: new ( entry_set_borrow. clone ( ) ) ) ;
40+ let table_name = get_table_name ( & entry_set_borrow[ 0 ] ) ;
41+ let indexes = header_to_pos. entry ( table_name) . or_default ( ) ;
42+ if kind == TABLE_ARRAY_HEADER || ( kind == TABLE_HEADER && indexes. is_empty ( ) ) {
43+ indexes. push ( table_set. len ( ) ) ;
44+ table_set. push ( RefCell :: new ( entry_set_borrow. clone ( ) ) ) ;
45+ } else if kind == TABLE_HEADER && !indexes. is_empty ( ) {
46+ // join tables
47+ let pos = indexes. first ( ) . unwrap ( ) ;
48+ let mut res = table_set. index ( * pos) . borrow_mut ( ) ;
49+ for element in entry_set_borrow. clone ( ) {
50+ if element. kind ( ) != TABLE_HEADER {
51+ res. push ( element) ;
52+ }
53+ }
54+ }
3655 entry_set_borrow. clear ( ) ;
3756 }
3857 } ;
3958 for c in root_ast. children_with_tokens ( ) {
4059 if [ TABLE_ARRAY_HEADER , TABLE_HEADER ] . contains ( & c. kind ( ) ) {
41- add_to_table_set ( ) ;
60+ add_to_table_set ( table_kind) ;
61+ table_kind = c. kind ( ) ;
4262 }
4363 entry_set. borrow_mut ( ) . push ( c) ;
4464 }
45- add_to_table_set ( ) ;
46-
65+ add_to_table_set ( table_kind) ;
4766 Self {
4867 header_to_pos,
4968 table_set,
@@ -61,37 +80,43 @@ impl Tables {
6180 }
6281 next. push ( String :: new ( ) ) ;
6382 for ( name, next_name) in zip ( order. iter ( ) , next. iter ( ) ) {
64- let entries = self . get ( name) . unwrap ( ) . borrow ( ) ;
65- if !entries. is_empty ( ) {
66- entry_count += entries. len ( ) ;
67- let last = entries. last ( ) . unwrap ( ) ;
68- if name. is_empty ( ) && last. kind ( ) == SyntaxKind :: NEWLINE && entries. len ( ) == 1 {
69- continue ;
70- }
71- let mut add = entries. clone ( ) ;
72- if get_key ( name) != get_key ( next_name) {
73- if last. kind ( ) == SyntaxKind :: NEWLINE {
74- // replace existing newline to ensure single newline
75- add. pop ( ) ;
83+ for entries in self . get ( name) . unwrap ( ) {
84+ let got = entries. borrow_mut ( ) ;
85+ if !got. is_empty ( ) {
86+ entry_count += got. len ( ) ;
87+ let last = got. last ( ) . unwrap ( ) ;
88+ if name. is_empty ( ) && last. kind ( ) == SyntaxKind :: NEWLINE && got. len ( ) == 1 {
89+ continue ;
7690 }
77- add. push ( make_empty_newline ( ) ) ;
91+ let mut add = got. clone ( ) ;
92+ if get_key ( name) != get_key ( next_name) {
93+ if last. kind ( ) == SyntaxKind :: NEWLINE {
94+ // replace existing newline to ensure single newline
95+ add. pop ( ) ;
96+ }
97+ add. push ( make_empty_newline ( ) ) ;
98+ }
99+ to_insert. extend ( add) ;
78100 }
79- to_insert. extend ( add) ;
80101 }
81102 }
82103 root_ast. splice_children ( 0 ..entry_count, to_insert) ;
83104 }
84105}
85106
86- fn calculate_order ( header_to_pos : & HashMap < String , usize > , ordering : & [ & str ] ) -> Vec < String > {
107+ fn calculate_order ( header_to_pos : & HashMap < String , Vec < usize > > , ordering : & [ & str ] ) -> Vec < String > {
87108 let max_ordering = ordering. len ( ) * 2 ;
88109 let key_to_pos = ordering
89110 . iter ( )
90111 . enumerate ( )
91112 . map ( |( k, v) | ( v, k * 2 ) )
92113 . collect :: < HashMap < & & str , usize > > ( ) ;
93114
94- let mut header_pos: Vec < ( String , usize ) > = header_to_pos. clone ( ) . into_iter ( ) . collect ( ) ;
115+ let mut header_pos: Vec < ( String , usize ) > = header_to_pos
116+ . clone ( )
117+ . into_iter ( )
118+ . map ( |( k, v) | ( k, * v. iter ( ) . min ( ) . unwrap ( ) ) )
119+ . collect ( ) ;
95120
96121 header_pos. sort_by_cached_key ( |( k, file_pos) | -> ( usize , usize ) {
97122 let key = get_key ( k) ;
@@ -220,12 +245,22 @@ pub fn collapse_sub_tables(tables: &mut Tables, name: &str) {
220245 return ;
221246 }
222247 if !tables. header_to_pos . contains_key ( name) {
223- tables. header_to_pos . insert ( String :: from ( name) , tables. table_set . len ( ) ) ;
248+ tables
249+ . header_to_pos
250+ . insert ( String :: from ( name) , vec ! [ tables. table_set. len( ) ] ) ;
224251 tables. table_set . push ( RefCell :: new ( make_table_entry ( name) ) ) ;
225252 }
226- let mut main = tables. table_set [ tables. header_to_pos [ name] ] . borrow_mut ( ) ;
253+ let main_positions = tables. header_to_pos [ name] . clone ( ) ;
254+ if main_positions. len ( ) != 1 {
255+ return ;
256+ }
257+ let mut main = tables. table_set [ * main_positions. first ( ) . unwrap ( ) ] . borrow_mut ( ) ;
227258 for key in sub_table_keys {
228- let mut sub = tables. table_set [ tables. header_to_pos [ key] ] . borrow_mut ( ) ;
259+ let sub_positions = tables. header_to_pos [ key] . clone ( ) ;
260+ if sub_positions. len ( ) != 1 {
261+ continue ;
262+ }
263+ let mut sub = tables. table_set [ * sub_positions. first ( ) . unwrap ( ) ] . borrow_mut ( ) ;
229264 let sub_name = key. strip_prefix ( sub_name_prefix. as_str ( ) ) . unwrap ( ) ;
230265 let mut header = false ;
231266 for child in sub. iter ( ) {
0 commit comments