@@ -17,9 +17,17 @@ pub struct Entry {
1717
1818#[ derive( Debug ) ]
1919pub enum EntryKind {
20- Union { members : Set < TypeName > } ,
21- Table { name : String , fields : Vec < Field > } ,
22- Token { kind_id : usize } ,
20+ Union {
21+ members : Set < TypeName > ,
22+ fields : Vec < Field > ,
23+ } ,
24+ Table {
25+ name : String ,
26+ fields : Vec < Field > ,
27+ } ,
28+ Token {
29+ kind_id : usize ,
30+ } ,
2331}
2432
2533#[ derive( Clone , Debug , Ord , PartialOrd , Eq , PartialEq ) ]
@@ -135,16 +143,39 @@ pub fn convert_nodes(prefix: &str, nodes: &[NodeInfo]) -> NodeTypeMap {
135143 if !subtypes. is_empty ( ) {
136144 // It's a tree-sitter supertype node, for which we create a union
137145 // type.
146+ let type_name = TypeName {
147+ kind : node. kind . clone ( ) ,
148+ named : node. named ,
149+ } ;
150+ let mut fields = Vec :: new ( ) ;
151+ for ( field_name, field_info) in & node. fields {
152+ add_field (
153+ prefix,
154+ & type_name,
155+ Some ( field_name. to_string ( ) ) ,
156+ field_info,
157+ & mut fields,
158+ & token_kinds,
159+ ) ;
160+ }
161+ if let Some ( children) = & node. children {
162+ add_field (
163+ prefix,
164+ & type_name,
165+ None ,
166+ children,
167+ & mut fields,
168+ & token_kinds,
169+ ) ;
170+ }
138171 entries. insert (
139- TypeName {
140- kind : node. kind . clone ( ) ,
141- named : node. named ,
142- } ,
172+ type_name,
143173 Entry {
144174 dbscheme_name,
145175 ql_class_name,
146176 kind : EntryKind :: Union {
147177 members : convert_types ( subtypes) ,
178+ fields,
148179 } ,
149180 } ,
150181 ) ;
@@ -454,3 +485,49 @@ fn to_snake_case_test() {
454485 assert_eq ! ( "erb" , to_snake_case( "ERB" ) ) ;
455486 assert_eq ! ( "embedded_template" , to_snake_case( "EmbeddedTemplate" ) ) ;
456487}
488+
489+ #[ test]
490+ fn supertype_fields_are_preserved ( ) {
491+ let yaml = r#"
492+ supertypes:
493+ callable:
494+ subtypes: [function]
495+ fields:
496+ parameter*: parameter
497+ body?: block
498+ named:
499+ function:
500+ parameter:
501+ block:
502+ "# ;
503+ let json = yeast:: node_types_yaml:: convert ( yaml) . unwrap ( ) ;
504+ let nodes = read_node_types_str ( "test" , & json) . unwrap ( ) ;
505+ let callable = nodes
506+ . get ( & TypeName {
507+ kind : "callable" . to_owned ( ) ,
508+ named : true ,
509+ } )
510+ . unwrap ( ) ;
511+ let EntryKind :: Union { fields, .. } = & callable. kind else {
512+ panic ! ( "callable should be a union" ) ;
513+ } ;
514+
515+ assert_eq ! ( fields. len( ) , 2 ) ;
516+ assert_eq ! ( fields[ 0 ] . getter_name, "getBody" ) ;
517+ assert ! ( matches!(
518+ fields[ 0 ] . storage,
519+ Storage :: Table {
520+ has_index: false ,
521+ ..
522+ }
523+ ) ) ;
524+ assert_eq ! ( fields[ 1 ] . getter_name, "getParameter" ) ;
525+ assert_eq ! ( fields[ 1 ] . any_getter_name. as_deref( ) , Some ( "getAParameter" ) ) ;
526+ assert ! ( matches!(
527+ fields[ 1 ] . storage,
528+ Storage :: Table {
529+ has_index: true ,
530+ ..
531+ }
532+ ) ) ;
533+ }
0 commit comments