1mod ir;
20mod json;
21mod output;
22mod supertypes;
23mod tests;
24mod utils;
25
26use crate::json::{NodeType, TypeInfo};
27use crate::output::{generate_enum, generate_struct};
28use crate::supertypes::{generate_super_type, SuperType};
29use crate::utils::{sanitize_string, sanitize_string_to_pascal};
30use proc_macro2::TokenStream;
31use quote::{format_ident, quote, ToTokens};
32use std::collections::{HashMap, HashSet};
33use std::sync::{LazyLock, Mutex, RwLock};
34
35pub(crate) static NAMED_RULES: LazyLock<Mutex<Vec<String>>> = LazyLock::new(Default::default);
37
38pub(crate) struct OperatorList {
39 index: usize,
40 operators: Vec<TypeInfo>,
41}
42
43pub(crate) static OPERATORS_RULES: LazyLock<Mutex<HashMap<String, OperatorList>>> =
45 LazyLock::new(Default::default);
46
47pub(crate) static INLINE_MULTIPLE_RULES: LazyLock<Mutex<HashMap<String, Vec<TypeInfo>>>> =
49 LazyLock::new(Default::default);
50
51pub(crate) static ANONYMOUS_TYPES: LazyLock<Mutex<HashSet<String>>> =
53 LazyLock::new(Default::default);
54
55pub(crate) static NODE_ID_FOR_NAMED_NODE: LazyLock<Mutex<HashMap<String, u16>>> =
57 LazyLock::new(Default::default);
58
59pub(crate) static NODE_ID_FOR_UNNAMED_NODE: LazyLock<Mutex<HashMap<String, u16>>> =
61 LazyLock::new(Default::default);
62
63pub(crate) static FIELD_ID_FOR_NAME: LazyLock<Mutex<HashMap<String, u16>>> =
65 LazyLock::new(Default::default);
66
67pub(crate) static SUPER_TYPES: LazyLock<RwLock<HashMap<String, SuperType>>> =
69 LazyLock::new(Default::default);
70
71pub fn generate(source: &str, language: &tree_sitter::Language) -> TokenStream {
72 let nodes: Vec<NodeType> = serde_json::from_str(source).expect("Invalid JSON");
73
74 let mut output = quote! {
75 #![allow(clippy::all)]
77 #![allow(unused)]
78 #![allow(dead_code)]
79 #![allow(non_camel_case_types)]
80 #![allow(non_snake_case)]
81
82 };
83 for node in &nodes {
84 if node.named {
85 NAMED_RULES
87 .lock()
88 .unwrap()
89 .push(sanitize_string_to_pascal(&node.kind));
90 NODE_ID_FOR_NAMED_NODE.lock().unwrap().insert(
92 node.kind.clone(),
93 language.id_for_node_kind(&node.kind, true),
94 );
95 if let Some(fields) = &node.fields {
97 fields.iter().for_each(|(field_name, _)| {
98 let field_id = language.field_id_for_name(field_name);
99 FIELD_ID_FOR_NAME
100 .lock()
101 .unwrap()
102 .insert(field_name.clone(), field_id.unwrap().get());
103 });
104 }
105 } else {
106 NODE_ID_FOR_UNNAMED_NODE.lock().unwrap().insert(
108 node.kind.clone(),
109 language.id_for_node_kind(&node.kind, false),
110 );
111 }
112 if node.is_supertype() {
114 SUPER_TYPES
115 .write()
116 .unwrap()
117 .insert(node.kind.clone(), generate_super_type(node));
118 }
119 }
120
121 let mut super_types_lock = SUPER_TYPES.write().unwrap();
124 let mut new_super_types = HashMap::new();
125
126 for (super_type_name, super_type) in super_types_lock.iter() {
127 let mut new_super_type = SuperType::default();
128
129 super_type.types.iter().enumerate().for_each(|(i, key)| {
131 if let Some(nested_super_type) = super_types_lock
132 .get(key) {
133 new_super_type.types.extend(nested_super_type.types.clone());
135 } else {
136 new_super_type.types.push(key.clone());
138 }
139 new_super_type.variants.push(super_type.variants[i].clone())
140 });
141 new_super_types.insert(super_type_name.clone(), new_super_type);
142 }
143
144 new_super_types.into_iter().for_each(|(name, s)| {
146 super_types_lock
147.insert(name.clone(), s.clone());
148 });
149
150 drop(super_types_lock);
151
152 for node in &nodes {
154 output.extend(node.to_token_stream());
155 }
156
157 for operators in (*OPERATORS_RULES.lock().unwrap()).values() {
159 output.extend(generate_enum(
160 &format_ident!("Operators_{}", operators.index),
161 &operators.operators,
162 ));
163 }
164
165 for (id, values) in &*INLINE_MULTIPLE_RULES.lock().unwrap() {
167 output.extend(generate_enum(
168 &format_ident!("{}", sanitize_string(id)),
169 values,
170 ));
171 }
172
173 for name in ANONYMOUS_TYPES.lock().unwrap().iter() {
175 output.extend(generate_struct(
176 &format_ident!("{}", &sanitize_string_to_pascal(name)),
177 name,
178 &vec![],
179 &vec![],
180 &vec![],
181 &vec![],
182 ));
183 }
184
185 for (super_type_name, super_type) in SUPER_TYPES.read().unwrap().iter() {
188 output.extend(generate_enum(
189 &format_ident!("{}", &sanitize_string_to_pascal(super_type_name)),
190 &super_type.variants,
191 ));
192 }
193
194 output
195}