tree_splicer/
node_types.rs1use std::collections::HashMap;
8
9use serde::{Deserialize, Serialize};
10
11#[derive(Clone, Eq, PartialEq, Serialize, Deserialize, Debug)]
13struct Node {
14 #[serde(rename(deserialize = "type", serialize = "type"))]
15 ty: String,
16 named: bool,
17 #[serde(default)] children: Children,
19 #[serde(default)] fields: HashMap<String, Field>,
21 #[serde(default)] subtypes: Vec<Subtype>,
23}
24
25#[derive(Default, Clone, Eq, PartialEq, Serialize, Deserialize, Debug)]
26struct Children {
27 multiple: bool,
28 required: bool,
29 types: Vec<Subtype>,
30}
31
32#[derive(Clone, Eq, PartialEq, Serialize, Deserialize, Debug)]
33struct Field {
34 multiple: bool,
35 required: bool,
36 types: Vec<Subtype>,
37}
38
39#[derive(Clone, Eq, PartialEq, Serialize, Deserialize, Debug)]
40struct Subtype {
41 #[serde(rename(deserialize = "type", serialize = "type"))]
42 ty: String,
43 named: bool,
44}
45
46#[derive(Clone, Debug)]
47pub struct FieldInfo {
48 parent_ty: String,
49 multiple: bool,
50 required: bool,
51}
52
53#[derive(Clone, Debug)]
54pub struct NodeTypes {
55 children: HashMap<String, Children>,
56 subtypes: HashMap<String, Vec<String>>,
57 reverse_fields: HashMap<String, Vec<FieldInfo>>,
58}
59
60fn subtypes(name: &str, nodes: &Vec<Node>) -> Vec<String> {
61 let mut r = vec![name.to_string()];
62 for n in nodes {
63 if n.ty == name {
64 for subty in &n.subtypes {
65 r.push(subty.ty.clone());
66 r.extend(subtypes(&subty.ty, nodes));
67 }
68 }
69 }
70 r
71}
72
73impl NodeTypes {
74 pub fn new(node_types_json_str: &str) -> Result<Self, serde_json::Error> {
75 let nodes: Vec<Node> = serde_json::from_str(node_types_json_str)?;
76 let subtypes: HashMap<_, _> = nodes
77 .iter()
78 .map(|n| (n.ty.clone(), subtypes(&n.ty, &nodes)))
79 .collect();
80 let mut reverse_fields = HashMap::new();
81
82 for node in &nodes {
84 for (_field_name, field) in node.fields.iter() {
86 for subtype in &field.types {
88 for subsubty in subtypes.get(&subtype.ty).unwrap_or(&Vec::new()) {
89 let entry = reverse_fields.entry(subsubty.clone());
90 entry
91 .and_modify(|v: &mut Vec<FieldInfo>| {
92 v.push(FieldInfo {
93 parent_ty: node.ty.clone(),
94 multiple: field.multiple,
95 required: field.required,
96 });
97 })
98 .or_insert_with(|| {
99 vec![FieldInfo {
100 parent_ty: node.ty.clone(),
101 multiple: field.multiple,
102 required: field.required,
103 }]
104 });
105 }
106 }
107 }
108 }
109 Ok(NodeTypes {
110 children: nodes
111 .iter()
112 .map(|n| (n.ty.clone(), n.children.clone()))
113 .collect(),
114 subtypes,
115 reverse_fields,
116 })
117 }
118
119 fn optional(&self, node_kind: &str, parent_kind: &str) -> bool {
121 if let Some(flds) = self.reverse_fields.get(node_kind) {
122 for fi in flds {
123 if parent_kind == fi.parent_ty && (!fi.multiple || fi.required) {
124 return false;
125 }
126 }
127 }
128 true
129 }
130
131 pub fn optional_node(&self, node: &tree_sitter::Node) -> bool {
133 if let Some(p) = node.parent() {
134 self.optional(node.kind(), p.kind())
135 } else {
136 true
137 }
138 }
139
140 pub fn list_types(&self, node: &tree_sitter::Node) -> Vec<String> {
142 let mut kinds = Vec::new();
143 if let Some(children) = self.children.get(node.kind()) {
144 if children.multiple && !children.required {
145 for child in &children.types {
146 kinds.push(child.ty.clone());
147 }
148 }
149 }
150 kinds
151 }
152
153 pub fn subtypes(&self, kind: &String) -> &[String] {
154 self.subtypes.get(kind).expect("Invalid node kind")
155 }
156}