miden_assembly_syntax/library/
module.rs1use alloc::{sync::Arc, vec::Vec};
2use core::ops::Index;
3
4use miden_core::mast::MastNodeId;
5use midenc_hir_type::FunctionType;
6
7use crate::{
8 Path, Word,
9 ast::{self, AttributeSet, ConstantValue, Ident, ItemIndex, ProcedureName},
10};
11
12#[derive(Debug, Clone, PartialEq, Eq)]
16pub struct ModuleInfo {
17 path: Arc<Path>,
18 version: Option<crate::Version>,
21 items: Vec<ItemInfo>,
22}
23
24impl ModuleInfo {
25 pub(crate) fn raw_items(&self) -> &[ItemInfo] {
26 &self.items
27 }
28
29 pub fn new(path: Arc<Path>, version: Option<crate::Version>) -> Self {
34 Self { version, path, items: Vec::new() }
35 }
36
37 pub fn set_version(&mut self, version: crate::Version) {
39 self.version = Some(version);
40 }
41
42 pub fn add_procedure(
44 &mut self,
45 name: ProcedureName,
46 digest: Word,
47 signature: Option<Arc<FunctionType>>,
48 attributes: AttributeSet,
49 ) {
50 self.add_procedure_with_provenance(name, digest, signature, attributes, None, None);
51 }
52
53 pub fn add_procedure_with_provenance(
55 &mut self,
56 name: ProcedureName,
57 digest: Word,
58 signature: Option<Arc<FunctionType>>,
59 attributes: AttributeSet,
60 source_root_id: Option<MastNodeId>,
61 source_library_commitment: Option<Word>,
62 ) {
63 self.items.push(ItemInfo::Procedure(ProcedureInfo {
64 name,
65 digest,
66 signature,
67 attributes,
68 source_root_id,
69 source_library_commitment,
70 }));
71 }
72
73 pub fn add_constant(&mut self, name: Ident, value: ConstantValue) {
75 self.items.push(ItemInfo::Constant(ConstantInfo { name, value }));
76 }
77
78 pub fn add_type(&mut self, name: Ident, ty: ast::types::Type) {
80 self.items.push(ItemInfo::Type(TypeInfo { name, ty }));
81 }
82
83 pub fn path(&self) -> &Path {
85 &self.path
86 }
87
88 pub fn num_procedures(&self) -> usize {
90 self.items.iter().filter(|item| matches!(item, ItemInfo::Procedure(_))).count()
91 }
92
93 pub fn get_item_by_index(&self, index: ItemIndex) -> Option<&ItemInfo> {
95 self.items.get(index.as_usize())
96 }
97
98 pub fn get_item_index_by_name(&self, name: &str) -> Option<ItemIndex> {
100 self.items.iter().enumerate().find_map(|(idx, info)| {
101 if info.name().as_str() == name {
102 Some(ItemIndex::new(idx))
103 } else {
104 None
105 }
106 })
107 }
108
109 pub fn get_procedure_by_name(&self, name: &str) -> Option<&ProcedureInfo> {
111 self.items.iter().find_map(|info| match info {
112 ItemInfo::Procedure(proc) if proc.name.as_str() == name => Some(proc),
113 _ => None,
114 })
115 }
116
117 pub fn get_procedure_digest_by_name(&self, name: &str) -> Option<Word> {
119 self.get_procedure_by_name(name).map(|proc| proc.digest)
120 }
121
122 pub fn items(&self) -> impl ExactSizeIterator<Item = (ItemIndex, &ItemInfo)> {
125 self.items.iter().enumerate().map(|(idx, item)| (ItemIndex::new(idx), item))
126 }
127
128 pub fn procedures(&self) -> impl Iterator<Item = (ItemIndex, &ProcedureInfo)> {
131 self.items.iter().enumerate().filter_map(|(idx, item)| match item {
132 ItemInfo::Procedure(proc) => Some((ItemIndex::new(idx), proc)),
133 _ => None,
134 })
135 }
136
137 pub fn procedure_digests(&self) -> impl Iterator<Item = Word> + '_ {
139 self.items.iter().filter_map(|item| match item {
140 ItemInfo::Procedure(proc) => Some(proc.digest),
141 _ => None,
142 })
143 }
144
145 pub fn constants(&self) -> impl Iterator<Item = (ItemIndex, &ConstantInfo)> {
147 self.items.iter().enumerate().filter_map(|(idx, item)| match item {
148 ItemInfo::Constant(info) => Some((ItemIndex::new(idx), info)),
149 _ => None,
150 })
151 }
152
153 pub fn types(&self) -> impl Iterator<Item = (ItemIndex, &TypeInfo)> {
155 self.items.iter().enumerate().filter_map(|(idx, item)| match item {
156 ItemInfo::Type(info) => Some((ItemIndex::new(idx), info)),
157 _ => None,
158 })
159 }
160}
161
162impl Index<ItemIndex> for ModuleInfo {
163 type Output = ItemInfo;
164
165 fn index(&self, index: ItemIndex) -> &Self::Output {
166 &self.items[index.as_usize()]
167 }
168}
169
170#[derive(Debug, Clone, PartialEq, Eq)]
172pub enum ItemInfo {
173 Procedure(ProcedureInfo),
174 Constant(ConstantInfo),
175 Type(TypeInfo),
176}
177
178impl ItemInfo {
179 pub fn name(&self) -> &Ident {
180 match self {
181 Self::Procedure(info) => info.name.as_ref(),
182 Self::Constant(info) => &info.name,
183 Self::Type(info) => &info.name,
184 }
185 }
186
187 pub fn attributes(&self) -> Option<&AttributeSet> {
188 match self {
189 Self::Procedure(info) => Some(&info.attributes),
190 Self::Constant(_) | Self::Type(_) => None,
191 }
192 }
193
194 pub fn unwrap_procedure(&self) -> &ProcedureInfo {
195 match self {
196 Self::Procedure(info) => info,
197 Self::Constant(_) | Self::Type(_) => panic!("expected item to be a procedure"),
198 }
199 }
200}
201
202#[derive(Debug, Clone, PartialEq, Eq)]
204pub struct ProcedureInfo {
205 pub name: ProcedureName,
206 pub digest: Word,
207 pub signature: Option<Arc<FunctionType>>,
208 pub attributes: AttributeSet,
209 pub source_root_id: Option<MastNodeId>,
214 pub source_library_commitment: Option<Word>,
216}
217
218impl ProcedureInfo {
219 pub fn source_root_id(&self) -> Option<MastNodeId> {
220 self.source_root_id
221 }
222
223 pub fn source_library_commitment(&self) -> Option<Word> {
224 self.source_library_commitment
225 }
226}
227
228#[derive(Debug, Clone, PartialEq, Eq)]
230pub struct ConstantInfo {
231 pub name: Ident,
232 pub value: ConstantValue,
233}
234
235#[derive(Debug, Clone, PartialEq, Eq)]
237pub struct TypeInfo {
238 pub name: Ident,
239 pub ty: ast::types::Type,
240}