Skip to content

Commit 32c995d

Browse files
asgerfCopilot
andcommitted
Support fields on schema supertypes
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 4a60ad0 commit 32c995d

6 files changed

Lines changed: 419 additions & 133 deletions

File tree

‎shared/tree-sitter-extractor/src/extractor/mod.rs‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -904,7 +904,8 @@ impl<'a> Visitor<'a> {
904904
if tp == single_type {
905905
return true;
906906
}
907-
if let EntryKind::Union { members } = &self.schema.get(single_type).unwrap().kind
907+
if let EntryKind::Union { members, .. } =
908+
&self.schema.get(single_type).unwrap().kind
908909
&& self.type_matches_set(tp, members)
909910
{
910911
return true;
@@ -926,7 +927,7 @@ impl<'a> Visitor<'a> {
926927
return true;
927928
}
928929
for other in types.iter() {
929-
if let EntryKind::Union { members } = &self.schema.get(other).unwrap().kind
930+
if let EntryKind::Union { members, .. } = &self.schema.get(other).unwrap().kind
930931
&& self.type_matches_set(tp, members)
931932
{
932933
return true;

‎shared/tree-sitter-extractor/src/generator/mod.rs‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,9 @@ fn convert_nodes(
399399
.collect();
400400
for node in nodes.values() {
401401
match &node.kind {
402-
node_types::EntryKind::Union { members: n_members } => {
402+
node_types::EntryKind::Union {
403+
members: n_members, ..
404+
} => {
403405
// It's a tree-sitter supertype node, for which we create a union
404406
// type.
405407
let members: Set<&str> = n_members

‎shared/tree-sitter-extractor/src/generator/ql_gen.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -793,7 +793,7 @@ fn compute_direct_supertypes(
793793
) -> std::collections::BTreeMap<node_types::TypeName, BTreeSet<&str>> {
794794
let mut supertypes = std::collections::BTreeMap::new();
795795
for node in nodes.values() {
796-
if let node_types::EntryKind::Union { members } = &node.kind {
796+
if let node_types::EntryKind::Union { members, .. } = &node.kind {
797797
for member in members {
798798
supertypes
799799
.entry(member.clone())
@@ -863,7 +863,7 @@ pub fn convert_nodes(nodes: &node_types::NodeTypeMap) -> Vec<ql::TopLevel<'_>> {
863863
}));
864864
}
865865
}
866-
node_types::EntryKind::Union { members: _ } => {
866+
node_types::EntryKind::Union { .. } => {
867867
// It's a tree-sitter supertype node, so we're wrapping a dbscheme
868868
// union type.
869869
classes.push(ql::TopLevel::Class(ql::Class {

‎shared/tree-sitter-extractor/src/node_types.rs‎

Lines changed: 84 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,17 @@ pub struct Entry {
1717

1818
#[derive(Debug)]
1919
pub 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

Comments
 (0)