1use std::collections::BTreeMap;
2
3use spade_common::{
4 id_tracker::ExprID,
5 loc_map::LocMap,
6 location_info::{Loc, WithLocation},
7 name::NameID,
8};
9
10use crate::{
11 expression::NamedArgument, ArgumentList, Binding, ConstGeneric, Enum, ExecutableItem, ExprKind,
12 Expression, ItemList, Pattern, PatternArgument, PatternKind, Register, Statement, Struct,
13 TypeDeclKind, TypeDeclaration, TypeExpression, TypeSpec,
14};
15
16#[derive(Debug)]
17pub enum Thing {
18 Pattern(Pattern),
19 Expr(Expression),
20 Statement(Statement),
21 Executable(ExecutableItem),
22}
23
24pub struct QueryCache {
25 things: LocMap<Thing>,
26 names: LocMap<NameID>,
27 ids: BTreeMap<ExprID, Loc<Expression>>,
29}
30
31impl QueryCache {
33 pub fn empty() -> Self {
34 QueryCache {
35 things: LocMap::new(),
36 names: LocMap::new(),
37 ids: BTreeMap::new(),
38 }
39 }
40
41 pub fn from_item_list(items: &ItemList) -> Self {
42 let mut result = QueryCache::empty();
43
44 for (_, item) in items.executables.iter() {
45 result.visit_executable(item.clone());
46 }
47
48 for (_, ty) in items.types.iter() {
49 result.visit_type_decl(ty)
50 }
51
52 result
53 }
54
55 pub fn things_around(&self, loc: &Loc<()>) -> Vec<Loc<&Thing>> {
56 self.things.around(loc)
57 }
58
59 pub fn names_around(&self, loc: &Loc<()>) -> Vec<Loc<&NameID>> {
60 self.names.around(loc)
61 }
62
63 pub fn id_to_expression(&self, id: ExprID) -> Option<&Loc<Expression>> {
64 self.ids.get(&id).map(|x| x)
65 }
66}
67
68impl<'a> QueryCache {
70 fn visit_executable(&mut self, item: ExecutableItem) {
71 match &item {
72 ExecutableItem::EnumInstance {
73 base_enum: _,
74 variant: _,
75 } => {
76 }
78 ExecutableItem::StructInstance => {}
80 ExecutableItem::Unit(unit) => {
81 self.things
82 .insert(unit.loc().map(|_| Thing::Executable(item.clone())));
83
84 self.visit_expression(&unit.body)
85 }
86 ExecutableItem::ExternUnit(_, unit) => {
87 self.things
88 .insert(unit.loc().map(|_| Thing::Executable(item.clone())));
89 }
90 }
91 }
92
93 fn visit_expr_kind(&mut self, kind: &Loc<&ExprKind>) {
94 match &kind.inner {
95 crate::ExprKind::Error => {}
96 crate::ExprKind::Identifier(ident) => self.names.insert(ident.clone().at_loc(kind)),
97 crate::ExprKind::IntLiteral(_, _) => {}
98 crate::ExprKind::BoolLiteral(_) => {}
99 crate::ExprKind::BitLiteral(_) => {}
100 crate::ExprKind::TypeLevelInteger(_) => {}
102 crate::ExprKind::CreatePorts => {}
103 crate::ExprKind::TupleLiteral(inner) | crate::ExprKind::ArrayLiteral(inner) => {
104 for expr in inner {
105 self.visit_expression(expr)
106 }
107 }
108 crate::ExprKind::ArrayShorthandLiteral(expr, _) => self.visit_expression(expr),
109 crate::ExprKind::Index(lhs, rhs) => {
110 self.visit_expression(lhs);
111 self.visit_expression(rhs);
112 }
113 crate::ExprKind::RangeIndex {
114 target,
115 start: _,
116 end: _,
117 } => self.visit_expression(target),
118 crate::ExprKind::TupleIndex(target, _) => self.visit_expression(target),
119 crate::ExprKind::FieldAccess(target, _) => self.visit_expression(target),
120 crate::ExprKind::MethodCall {
121 target,
122 name: _,
123 args,
124 call_kind: _,
125 turbofish: _,
126 } => {
127 self.visit_expression(target);
129 self.visit_arg_list(args)
130 }
131 crate::ExprKind::Call {
132 kind: _,
133 callee,
134 args,
135 turbofish: _turbofish,
136 } => {
137 self.names.insert(callee.clone());
138 self.visit_arg_list(args)
140 }
141 crate::ExprKind::LambdaDef {
142 lambda_type: _,
143 lambda_type_params: _,
144 lambda_unit: _,
145 arguments: _,
146 captured_generic_params: _,
147 body,
148 } => {
149 self.visit_expression(body);
151 }
152 crate::ExprKind::BinaryOperator(lhs, _, rhs) => {
153 self.visit_expression(lhs);
154 self.visit_expression(rhs);
155 }
156 crate::ExprKind::UnaryOperator(_, operand) => self.visit_expression(operand),
157 crate::ExprKind::Match(cond, branches) => {
158 self.visit_expression(cond);
159
160 for (pattern, expr) in branches {
161 self.visit_pattern(pattern);
162 self.visit_expression(expr);
163 }
164 }
165 crate::ExprKind::Block(b) => {
166 for stmt in &b.statements {
167 self.visit_statements(&stmt)
168 }
169 if let Some(result) = &b.result {
170 self.visit_expression(result)
171 }
172 }
173 crate::ExprKind::If(cond, lhs, rhs) => {
174 self.visit_expression(cond);
175 self.visit_expression(lhs);
176 self.visit_expression(rhs);
177 }
178 crate::ExprKind::TypeLevelIf(_cond, lhs, rhs) => {
179 self.visit_expression(lhs);
181 self.visit_expression(rhs);
182 }
183 crate::ExprKind::PipelineRef {
184 stage: _,
185 name: _,
186 declares_name: _,
187 depth_typeexpr_id: _,
188 } => {}
189 crate::ExprKind::StageValid => {}
190 crate::ExprKind::StageReady => {}
191 crate::ExprKind::StaticUnreachable(_) | crate::ExprKind::Null => {}
192 }
193 }
194
195 fn visit_expression(&mut self, expr: &'a Loc<Expression>) {
196 self.things
197 .insert(expr.loc().map(|_| Thing::Expr(expr.inner.clone())));
198 self.ids.insert(expr.id, expr.clone());
199
200 self.visit_expr_kind(&Loc::new(&expr.kind, expr.span, expr.file_id));
201 }
202
203 fn visit_pattern(&mut self, pat: &'a Loc<Pattern>) {
204 self.things
205 .insert(pat.loc().map(|_| Thing::Pattern(pat.inner.clone())));
206 match &pat.inner.kind {
207 PatternKind::Integer(_) => {}
208 PatternKind::Bool(_) => {}
209 PatternKind::Name {
210 name,
211 pre_declared: _,
212 } => {
213 self.names.insert(name.clone());
214 }
215 PatternKind::Tuple(inner) => {
216 for pat in inner {
217 self.visit_pattern(&pat);
218 }
219 }
220 PatternKind::Array(inner) => {
221 for pat in inner {
222 self.visit_pattern(&pat);
223 }
224 }
225 PatternKind::Type(base, args) => {
226 self.names.insert(base.clone());
227 for PatternArgument {
228 target: _,
229 value,
230 kind: _,
231 } in args
232 {
233 self.visit_pattern(value);
234 }
235 }
236 }
237 }
238
239 fn visit_statements(&mut self, stmt: &'a Loc<Statement>) {
240 match &stmt.inner {
241 Statement::Error => {}
242 Statement::Binding(Binding {
243 pattern,
244 ty: _,
245 value,
246 wal_trace: _,
247 }) => {
248 self.visit_pattern(pattern);
249 self.visit_expression(value)
251 }
252 Statement::Register(Register {
253 pattern,
254 clock,
255 reset,
256 initial,
257 value,
258 value_type: _value_type,
259 attributes: _,
260 }) => {
261 self.visit_pattern(pattern);
262 self.visit_expression(clock);
264 if let Some((trig, val)) = reset {
265 self.visit_expression(trig);
266 self.visit_expression(val);
267 }
268 if let Some(initial) = initial {
269 self.visit_expression(initial)
270 }
271 self.visit_expression(value);
272 }
273 Statement::Expression(e) => {
274 self.visit_expression(e);
275 }
276 Statement::Declaration(names) => {
277 for name in names {
278 self.names.insert(name.clone());
279 }
280 }
281 Statement::PipelineRegMarker(_) => {}
282 Statement::Label(l) => {
283 self.names.insert(l.clone());
284 }
285 Statement::Assert(expr) => self.visit_expression(expr),
286 Statement::Set { target, value } => {
287 self.visit_expression(target);
288 self.visit_expression(value);
289 }
290 Statement::WalSuffixed {
291 suffix: _,
292 target: _,
293 } => {}
294 }
295 }
296
297 fn visit_arg_list(&mut self, args: &'a ArgumentList<Expression>) {
298 match args {
299 ArgumentList::Named(l) => {
300 for arg in l {
301 match arg {
302 NamedArgument::Full(_name, expr) => {
303 self.visit_expression(expr)
306 }
307 NamedArgument::Short(_, expr) => self.visit_expression(expr),
308 }
309 }
310 }
311 ArgumentList::Positional(args) => {
312 for arg in args {
313 self.visit_expression(arg)
314 }
315 }
316 }
317 }
318
319 fn visit_type_decl(&mut self, ty: &TypeDeclaration) {
320 self.names.insert(ty.name.clone());
321 match &ty.kind {
322 TypeDeclKind::Enum(e) => self.visit_enum_decl(e),
323 TypeDeclKind::Primitive(_) => {}
324 TypeDeclKind::Struct(s) => self.visit_struct(s),
325 }
326 }
327
328 fn visit_enum_decl(&mut self, e: &Loc<Enum>) {
329 for (_, params) in &e.options {
330 for param in ¶ms.0 {
331 self.visit_type_spec(¶m.ty);
332 }
333 }
334 }
335
336 fn visit_struct(&mut self, s: &Loc<Struct>) {
337 for member in &s.members.0 {
338 self.visit_type_spec(&member.ty);
339 }
340 }
341
342 fn visit_type_spec(&mut self, ts: &Loc<TypeSpec>) {
343 match &ts.inner {
344 TypeSpec::Declared(n, params) => {
345 self.names.insert(n.clone());
346 for param in params {
347 self.visit_type_expr(param);
348 }
349 }
350 TypeSpec::Generic(n) => self.names.insert(n.clone()),
351 TypeSpec::Tuple(inner) => {
352 for i in inner {
353 self.visit_type_spec(i);
354 }
355 }
356 TypeSpec::Array { inner, size } => {
357 self.visit_type_spec(inner);
358 self.visit_type_expr(size);
359 }
360 TypeSpec::Inverted(inner) => self.visit_type_spec(inner),
361 TypeSpec::Wire(inner) => self.visit_type_spec(inner),
362 TypeSpec::TraitSelf(_) => {}
363 TypeSpec::Wildcard(_) => {}
364 }
365 }
366
367 fn visit_type_expr(&mut self, te: &Loc<TypeExpression>) {
368 match &te.inner {
369 TypeExpression::Integer(_) => {}
370 TypeExpression::TypeSpec(ts) => self.visit_type_spec(&ts.clone().at_loc(te)),
371 TypeExpression::ConstGeneric(cg) => {
372 self.visit_const_generic(cg);
373 }
374 }
375 }
376
377 fn visit_const_generic(&mut self, cg: &Loc<ConstGeneric>) {
378 match &cg.inner {
379 ConstGeneric::Name(n) => self.names.insert(n.clone()),
380 ConstGeneric::Const(_) => {}
381 ConstGeneric::Add(lhs, rhs) => {
382 self.visit_const_generic(lhs);
383 self.visit_const_generic(rhs);
384 }
385 ConstGeneric::Sub(lhs, rhs) => {
386 self.visit_const_generic(lhs);
387 self.visit_const_generic(rhs);
388 }
389 ConstGeneric::Mul(lhs, rhs) => {
390 self.visit_const_generic(lhs);
391 self.visit_const_generic(rhs);
392 }
393 ConstGeneric::Div(lhs, rhs) => {
394 self.visit_const_generic(lhs);
395 self.visit_const_generic(rhs);
396 }
397 ConstGeneric::Mod(lhs, rhs) => {
398 self.visit_const_generic(lhs);
399 self.visit_const_generic(rhs);
400 }
401 ConstGeneric::Eq(lhs, rhs) => {
402 self.visit_const_generic(lhs);
403 self.visit_const_generic(rhs);
404 }
405 ConstGeneric::NotEq(lhs, rhs) => {
406 self.visit_const_generic(lhs);
407 self.visit_const_generic(rhs);
408 }
409 ConstGeneric::UintBitsToFit(inner) => self.visit_const_generic(inner),
410 }
411 }
412}