miden_assembly/ast/procedure/
alias.rs1use alloc::string::String;
2use core::fmt;
3
4use super::{ProcedureName, QualifiedProcedureName};
5use crate::{
6 RpoDigest,
7 ast::{DocString, InvocationTarget},
8 diagnostics::{SourceSpan, Span, Spanned},
9};
10
11#[derive(Debug, Clone, PartialEq, Eq)]
21pub struct ProcedureAlias {
22 docs: Option<DocString>,
24 name: ProcedureName,
26 target: AliasTarget,
32}
33
34impl ProcedureAlias {
35 pub fn new(name: ProcedureName, target: AliasTarget) -> Self {
37 Self { docs: None, name, target }
38 }
39
40 pub fn with_docs(mut self, docs: Option<Span<String>>) -> Self {
42 self.docs = docs.map(DocString::new);
43 self
44 }
45
46 pub fn docs(&self) -> Option<Span<&str>> {
48 self.docs.as_ref().map(|docstring| docstring.as_spanned_str())
49 }
50
51 #[inline]
56 pub fn name(&self) -> &ProcedureName {
57 &self.name
58 }
59
60 #[inline]
62 pub fn target(&self) -> &AliasTarget {
63 &self.target
64 }
65
66 #[inline]
68 pub fn target_mut(&mut self) -> &mut AliasTarget {
69 &mut self.target
70 }
71
72 #[inline]
74 pub fn is_absolute(&self) -> bool {
75 matches!(self.target, AliasTarget::MastRoot(_) | AliasTarget::AbsoluteProcedurePath(_))
76 }
77
78 #[inline]
80 pub fn is_renamed(&self) -> bool {
81 match self.target() {
82 AliasTarget::MastRoot(_) => true,
83 AliasTarget::ProcedurePath(fqn) | AliasTarget::AbsoluteProcedurePath(fqn) => {
84 fqn.name != self.name
85 },
86 }
87 }
88}
89
90impl Spanned for ProcedureAlias {
91 fn span(&self) -> SourceSpan {
92 self.target.span()
93 }
94}
95
96impl crate::prettier::PrettyPrint for ProcedureAlias {
97 fn render(&self) -> crate::prettier::Document {
98 use crate::prettier::*;
99
100 let mut doc = self
101 .docs
102 .as_ref()
103 .map(|docstring| docstring.render())
104 .unwrap_or(Document::Empty);
105
106 doc += const_text("export.");
107 doc += match &self.target {
108 target @ AliasTarget::MastRoot(_) => display(format_args!("{}->{}", target, self.name)),
109 target => {
110 let prefix = if self.is_absolute() { "::" } else { "" };
111 if self.is_renamed() {
112 display(format_args!("{}{}->{}", prefix, target, &self.name))
113 } else {
114 display(format_args!("{prefix}{target}"))
115 }
116 },
117 };
118 doc
119 }
120}
121
122#[derive(Debug, Clone, PartialEq, Eq)]
124pub enum AliasTarget {
125 MastRoot(Span<RpoDigest>),
129 ProcedurePath(QualifiedProcedureName),
133 AbsoluteProcedurePath(QualifiedProcedureName),
137}
138
139impl Spanned for AliasTarget {
140 fn span(&self) -> SourceSpan {
141 match self {
142 Self::MastRoot(spanned) => spanned.span(),
143 Self::ProcedurePath(spanned) | Self::AbsoluteProcedurePath(spanned) => spanned.span(),
144 }
145 }
146}
147
148impl From<Span<RpoDigest>> for AliasTarget {
149 fn from(digest: Span<RpoDigest>) -> Self {
150 Self::MastRoot(digest)
151 }
152}
153
154impl TryFrom<InvocationTarget> for AliasTarget {
155 type Error = InvocationTarget;
156
157 fn try_from(target: InvocationTarget) -> Result<Self, Self::Error> {
158 let span = target.span();
159 match target {
160 InvocationTarget::MastRoot(digest) => Ok(Self::MastRoot(digest)),
161 InvocationTarget::ProcedurePath { name, module } => {
162 let ns = crate::LibraryNamespace::from_ident_unchecked(module);
163 let module = crate::LibraryPath::new_from_components(ns, []);
164 Ok(Self::ProcedurePath(QualifiedProcedureName { span, module, name }))
165 },
166 InvocationTarget::AbsoluteProcedurePath { name, path: module } => {
167 Ok(Self::AbsoluteProcedurePath(QualifiedProcedureName { span, module, name }))
168 },
169 target @ InvocationTarget::ProcedureName(_) => Err(target),
170 }
171 }
172}
173
174impl From<&AliasTarget> for InvocationTarget {
175 fn from(target: &AliasTarget) -> Self {
176 match target {
177 AliasTarget::MastRoot(digest) => Self::MastRoot(*digest),
178 AliasTarget::ProcedurePath(fqn) => {
179 let name = fqn.name.clone();
180 let module = fqn.module.last_component().to_ident();
181 Self::ProcedurePath { name, module }
182 },
183 AliasTarget::AbsoluteProcedurePath(fqn) => Self::AbsoluteProcedurePath {
184 name: fqn.name.clone(),
185 path: fqn.module.clone(),
186 },
187 }
188 }
189}
190impl From<AliasTarget> for InvocationTarget {
191 fn from(target: AliasTarget) -> Self {
192 match target {
193 AliasTarget::MastRoot(digest) => Self::MastRoot(digest),
194 AliasTarget::ProcedurePath(fqn) => {
195 let name = fqn.name;
196 let module = fqn.module.last_component().to_ident();
197 Self::ProcedurePath { name, module }
198 },
199 AliasTarget::AbsoluteProcedurePath(fqn) => {
200 Self::AbsoluteProcedurePath { name: fqn.name, path: fqn.module }
201 },
202 }
203 }
204}
205
206impl crate::prettier::PrettyPrint for AliasTarget {
207 fn render(&self) -> crate::prettier::Document {
208 use vm_core::utils::DisplayHex;
209
210 use crate::prettier::*;
211
212 match self {
213 Self::MastRoot(digest) => display(DisplayHex(digest.as_bytes().as_slice())),
214 Self::ProcedurePath(fqn) => display(fqn),
215 Self::AbsoluteProcedurePath(fqn) => display(format_args!("::{fqn}")),
216 }
217 }
218}
219
220impl fmt::Display for AliasTarget {
221 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
222 use crate::prettier::PrettyPrint;
223
224 self.pretty_print(f)
225 }
226}