llmcc_rust/descriptor/
variable.rs1use llmcc_core::context::CompileUnit;
2use llmcc_core::ir::{HirId, HirNode};
3use tree_sitter::Node;
4
5use super::function::parse_type_expr;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub enum VariableKind {
10 Let,
11 Const,
12 Static,
13}
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq)]
17pub enum VariableScope {
18 Global,
19 Local,
20}
21
22#[derive(Debug, Clone)]
24pub struct VariableDescriptor {
25 pub hir_id: HirId,
27 pub name: String,
29 pub fqn: String,
31 pub kind: VariableKind,
33 pub is_mut: bool,
35 pub scope: VariableScope,
37 pub ty: Option<super::function::TypeExpr>,
39}
40
41impl VariableDescriptor {
42 pub(crate) fn from_let<'tcx>(
43 unit: CompileUnit<'tcx>,
44 node: &HirNode<'tcx>,
45 name: String,
46 fqn: String,
47 ) -> Self {
48 let ts_node = node.inner_ts_node();
49 let ty = ts_node
50 .child_by_field_name("type")
51 .map(|n| parse_type_expr(unit, n));
52 let is_mut = has_mutable_specifier(ts_node);
53
54 VariableDescriptor {
55 hir_id: node.hir_id(),
56 name,
57 fqn,
58 kind: VariableKind::Let,
59 is_mut,
60 scope: VariableScope::Local,
61 ty,
62 }
63 }
64
65 pub(crate) fn from_const_item<'tcx>(
66 unit: CompileUnit<'tcx>,
67 node: &HirNode<'tcx>,
68 name: String,
69 fqn: String,
70 ) -> Self {
71 let ts_node = node.inner_ts_node();
72 let ty = ts_node
73 .child_by_field_name("type")
74 .map(|n| parse_type_expr(unit, n));
75
76 VariableDescriptor {
77 hir_id: node.hir_id(),
78 name,
79 fqn,
80 kind: VariableKind::Const,
81 is_mut: false,
82 scope: VariableScope::Global,
83 ty,
84 }
85 }
86
87 pub(crate) fn from_static_item<'tcx>(
88 unit: CompileUnit<'tcx>,
89 node: &HirNode<'tcx>,
90 name: String,
91 fqn: String,
92 ) -> Self {
93 let ts_node = node.inner_ts_node();
94 let ty = ts_node
95 .child_by_field_name("type")
96 .map(|n| parse_type_expr(unit, n));
97 let is_mut = has_mutable_specifier(ts_node);
98
99 VariableDescriptor {
100 hir_id: node.hir_id(),
101 name,
102 fqn,
103 kind: VariableKind::Static,
104 is_mut,
105 scope: VariableScope::Global,
106 ty,
107 }
108 }
109}
110
111fn has_mutable_specifier(ts_node: Node<'_>) -> bool {
112 if ts_node.child_by_field_name("mutable_specifier").is_some() {
113 return true;
114 }
115 let mut cursor = ts_node.walk();
116 if cursor.goto_first_child() {
117 loop {
118 if cursor.node().kind() == "mutable_specifier" {
119 return true;
120 }
121 if !cursor.goto_next_sibling() {
122 break;
123 }
124 }
125 }
126 false
127}