1use std::collections::HashMap;
7use std::collections::HashSet;
8
9#[derive(Debug, Clone, PartialEq, Eq, Hash)]
11pub enum LiteralKind {
12 Int,
13 Float,
14 Str,
15 ByteStr,
16 CStr,
17 Byte,
18 Char,
19 Bool,
20 Null,
21}
22
23#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
25pub enum PlaceholderKind {
26 Variable,
27 Function,
28 Type,
29 Lifetime,
30 Label,
31}
32
33#[derive(Debug, Clone, PartialEq, Eq, Hash)]
35pub enum BinOpKind {
36 Add,
37 Sub,
38 Mul,
39 Div,
40 Rem,
41 And,
42 Or,
43 BitXor,
44 BitAnd,
45 BitOr,
46 Shl,
47 Shr,
48 Eq,
49 Lt,
50 Le,
51 Ne,
52 Ge,
53 Gt,
54 AddAssign,
55 SubAssign,
56 MulAssign,
57 DivAssign,
58 RemAssign,
59 BitXorAssign,
60 BitAndAssign,
61 BitOrAssign,
62 ShlAssign,
63 ShrAssign,
64 FloorDiv,
65 Pow,
66 In,
67 NotIn,
68 Is,
69 IsNot,
70 FloorDivAssign,
71 PowAssign,
72 Other,
73}
74
75#[derive(Debug, Clone, PartialEq, Eq, Hash)]
77pub enum UnOpKind {
78 Deref,
79 Not,
80 Neg,
81 Other,
82}
83
84#[derive(Debug, Clone, PartialEq, Eq, Hash)]
87pub enum NodeKind {
88 Block,
90 LetBinding,
91 Semi,
92 Paren,
93
94 Literal(LiteralKind),
96 Placeholder(PlaceholderKind, usize),
97
98 BinaryOp(BinOpKind),
100 UnaryOp(UnOpKind),
101 Range,
102
103 Call,
105 MethodCall,
106 FieldAccess,
107 Index,
108 Path,
109
110 Closure,
112 FnSignature,
113
114 Return,
116 Break,
117 Continue,
118 Assign,
119
120 Reference {
122 mutable: bool,
123 },
124
125 Tuple,
127 Array,
128 Set,
129 Repeat,
130
131 Cast,
133 StructInit,
134
135 Await,
137 Yield,
138 Try,
139
140 If,
142 Match,
143 MatchArm,
144 Loop,
145 While,
146 ForLoop,
147 LetExpr,
148
149 PatWild,
151 PatPlaceholder(PlaceholderKind, usize),
152 PatTuple,
153 PatStruct,
154 PatOr,
155 PatLiteral,
156 PatReference {
157 mutable: bool,
158 },
159 PatSlice,
160 PatRest,
161 PatRange,
162
163 TypePlaceholder(PlaceholderKind, usize),
165 TypeReference {
166 mutable: bool,
167 },
168 TypeTuple,
169 TypeSlice,
170 TypeArray,
171 TypePath,
172 TypeImplTrait,
173 TypeInfer,
174 TypeUnit,
175 TypeNever,
176
177 FieldValue,
179
180 MacroCall {
182 name: String,
183 },
184
185 Opaque,
187
188 None,
191}
192
193#[derive(Debug, Clone, PartialEq, Eq, Hash)]
217pub struct NormalizedNode {
218 pub kind: NodeKind,
219 pub children: Vec<Self>,
220}
221
222impl NormalizedNode {
223 #[must_use]
225 pub const fn leaf(kind: NodeKind) -> Self {
226 Self {
227 kind,
228 children: vec![],
229 }
230 }
231
232 #[must_use]
234 pub const fn with_children(kind: NodeKind, children: Vec<Self>) -> Self {
235 Self { kind, children }
236 }
237
238 #[must_use]
240 pub const fn none() -> Self {
241 Self::leaf(NodeKind::None)
242 }
243
244 pub fn opt(node: Option<Self>) -> Self {
247 node.unwrap_or_else(Self::none)
248 }
249
250 #[must_use]
252 pub const fn is_none(&self) -> bool {
253 matches!(self.kind, NodeKind::None)
254 }
255}
256
257fn collect_placeholder_order(
262 node: &NormalizedNode,
263 order: &mut Vec<(PlaceholderKind, usize)>,
264 seen: &mut HashSet<(PlaceholderKind, usize)>,
265) {
266 if let NodeKind::Placeholder(kind, idx)
271 | NodeKind::PatPlaceholder(kind, idx)
272 | NodeKind::TypePlaceholder(kind, idx) = &node.kind
273 && seen.insert((*kind, *idx))
274 {
275 order.push((*kind, *idx));
276 }
277 for child in &node.children {
278 collect_placeholder_order(child, order, seen);
279 }
280}
281
282fn apply_reindex(
284 node: &NormalizedNode,
285 mapping: &HashMap<(PlaceholderKind, usize), usize>,
286) -> NormalizedNode {
287 let kind = match &node.kind {
288 NodeKind::Placeholder(kind, idx) => {
289 let new_idx = mapping.get(&(*kind, *idx)).copied().unwrap_or(*idx);
290 NodeKind::Placeholder(*kind, new_idx)
291 }
292 NodeKind::PatPlaceholder(kind, idx) => {
293 let new_idx = mapping.get(&(*kind, *idx)).copied().unwrap_or(*idx);
294 NodeKind::PatPlaceholder(*kind, new_idx)
295 }
296 NodeKind::TypePlaceholder(kind, idx) => {
297 let new_idx = mapping.get(&(*kind, *idx)).copied().unwrap_or(*idx);
298 NodeKind::TypePlaceholder(*kind, new_idx)
299 }
300 other => other.clone(),
301 };
302 let children = node
303 .children
304 .iter()
305 .map(|c| apply_reindex(c, mapping))
306 .collect();
307 NormalizedNode { kind, children }
308}
309
310#[must_use]
314pub fn reindex_placeholders(node: &NormalizedNode) -> NormalizedNode {
315 let mut order = Vec::new();
316 let mut seen = HashSet::new();
317 collect_placeholder_order(node, &mut order, &mut seen);
318
319 let mut counters: HashMap<PlaceholderKind, usize> = HashMap::new();
321 let mut mapping: HashMap<(PlaceholderKind, usize), usize> = HashMap::new();
322 for (kind, old_idx) in order {
323 let counter = counters.entry(kind).or_insert(0);
324 mapping.insert((kind, old_idx), *counter);
325 *counter += 1;
326 }
327
328 apply_reindex(node, &mapping)
329}
330
331pub fn count_nodes(node: &NormalizedNode) -> usize {
334 if node.is_none() {
335 return 0;
336 }
337 1 + node.children.iter().map(count_nodes).sum::<usize>()
338}