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