1use std::borrow::Cow;
4
5use smol_str::SmolStr;
6#[cfg(test)]
7use {
8 crate::proptest::{any_nonempty_smolstr, any_nonempty_string},
9 ::proptest_derive::Arbitrary,
10};
11
12use crate::Visibility;
13use crate::types::{EdgeKind, PolyFuncType, Signature, Type, TypeBound};
14
15use super::dataflow::DataflowParent;
16use super::{OpTag, OpTrait, StaticTag, impl_op_name};
17
18#[derive(Debug, Clone, PartialEq, Eq, Default, serde::Serialize, serde::Deserialize)]
20#[cfg_attr(test, derive(Arbitrary))]
21pub struct Module {
22 }
25
26impl Module {
27 #[must_use]
29 pub const fn new() -> Self {
30 Self {}
31 }
32}
33
34impl_op_name!(Module);
35
36impl StaticTag for Module {
37 const TAG: OpTag = OpTag::ModuleRoot;
38}
39
40impl OpTrait for Module {
41 fn description(&self) -> &'static str {
42 "The root of a module, parent of all other `OpType`s"
43 }
44
45 fn tag(&self) -> super::OpTag {
46 <Self as StaticTag>::TAG
47 }
48}
49
50#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
54#[cfg_attr(test, derive(Arbitrary))]
55pub struct FuncDefn {
56 #[cfg_attr(test, proptest(strategy = "any_nonempty_string()"))]
57 name: String,
58 signature: PolyFuncType,
59 #[serde(default = "priv_vis")] visibility: Visibility,
61}
62
63fn priv_vis() -> Visibility {
64 Visibility::Private
65}
66
67impl FuncDefn {
68 pub fn new(name: impl Into<String>, signature: impl Into<PolyFuncType>) -> Self {
71 Self::new_vis(name, signature, Visibility::Private)
72 }
73
74 pub fn new_vis(
76 name: impl Into<String>,
77 signature: impl Into<PolyFuncType>,
78 visibility: Visibility,
79 ) -> Self {
80 Self {
81 name: name.into(),
82 signature: signature.into(),
83 visibility,
84 }
85 }
86
87 pub fn func_name(&self) -> &String {
89 &self.name
90 }
91
92 pub fn func_name_mut(&mut self) -> &mut String {
94 &mut self.name
95 }
96
97 pub fn signature(&self) -> &PolyFuncType {
99 &self.signature
100 }
101
102 pub fn signature_mut(&mut self) -> &mut PolyFuncType {
104 &mut self.signature
105 }
106
107 pub fn visibility(&self) -> &Visibility {
109 &self.visibility
110 }
111
112 pub fn visibility_mut(&mut self) -> &mut Visibility {
114 &mut self.visibility
115 }
116}
117
118impl_op_name!(FuncDefn);
119impl StaticTag for FuncDefn {
120 const TAG: OpTag = OpTag::FuncDefn;
121}
122
123impl DataflowParent for FuncDefn {
124 fn inner_signature(&self) -> Cow<'_, Signature> {
125 Cow::Borrowed(self.signature.body())
126 }
127}
128
129impl OpTrait for FuncDefn {
130 fn description(&self) -> &'static str {
131 "A function definition"
132 }
133
134 fn tag(&self) -> OpTag {
135 <Self as StaticTag>::TAG
136 }
137
138 fn static_output(&self) -> Option<EdgeKind> {
139 Some(EdgeKind::Function(self.signature.clone()))
140 }
141
142 }
144
145#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
147#[cfg_attr(test, derive(Arbitrary))]
148pub struct FuncDecl {
149 #[cfg_attr(test, proptest(strategy = "any_nonempty_string()"))]
150 name: String,
151 signature: PolyFuncType,
152 #[serde(default = "pub_vis")] visibility: Visibility,
155}
156
157fn pub_vis() -> Visibility {
158 Visibility::Public
159}
160
161impl FuncDecl {
162 pub fn new(name: impl Into<String>, signature: impl Into<PolyFuncType>) -> Self {
165 Self::new_vis(name, signature, Visibility::Public)
166 }
167
168 pub fn new_vis(
170 name: impl Into<String>,
171 signature: impl Into<PolyFuncType>,
172 visibility: Visibility,
173 ) -> Self {
174 Self {
175 name: name.into(),
176 signature: signature.into(),
177 visibility,
178 }
179 }
180
181 pub fn func_name(&self) -> &String {
183 &self.name
184 }
185
186 pub fn visibility(&self) -> &Visibility {
188 &self.visibility
189 }
190
191 pub fn func_name_mut(&mut self) -> &mut String {
193 &mut self.name
194 }
195
196 pub fn visibility_mut(&mut self) -> &mut Visibility {
198 &mut self.visibility
199 }
200
201 pub fn signature(&self) -> &PolyFuncType {
203 &self.signature
204 }
205
206 pub fn signature_mut(&mut self) -> &mut PolyFuncType {
208 &mut self.signature
209 }
210}
211
212impl_op_name!(FuncDecl);
213impl StaticTag for FuncDecl {
214 const TAG: OpTag = OpTag::Function;
215}
216
217impl OpTrait for FuncDecl {
218 fn description(&self) -> &'static str {
219 "External function declaration, linked at runtime"
220 }
221
222 fn tag(&self) -> OpTag {
223 <Self as StaticTag>::TAG
224 }
225
226 fn static_output(&self) -> Option<EdgeKind> {
227 Some(EdgeKind::Function(self.signature.clone()))
228 }
229
230 }
232
233#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
235#[cfg_attr(test, derive(Arbitrary))]
236pub struct AliasDefn {
237 #[cfg_attr(test, proptest(strategy = "any_nonempty_smolstr()"))]
239 pub name: SmolStr,
240 pub definition: Type,
242}
243impl_op_name!(AliasDefn);
244impl StaticTag for AliasDefn {
245 const TAG: OpTag = OpTag::Alias;
246}
247impl OpTrait for AliasDefn {
248 fn description(&self) -> &'static str {
249 "A type alias definition"
250 }
251
252 fn tag(&self) -> OpTag {
253 <Self as StaticTag>::TAG
254 }
255
256 }
259
260#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
262#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
263pub struct AliasDecl {
264 #[cfg_attr(test, proptest(strategy = "any_nonempty_smolstr()"))]
266 pub name: SmolStr,
267 pub bound: TypeBound,
269}
270
271impl AliasDecl {
272 pub fn new(name: impl Into<SmolStr>, bound: TypeBound) -> Self {
274 Self {
275 name: name.into(),
276 bound,
277 }
278 }
279
280 #[must_use]
282 pub fn name(&self) -> &str {
283 self.name.as_ref()
284 }
285}
286
287impl_op_name!(AliasDecl);
288impl StaticTag for AliasDecl {
289 const TAG: OpTag = OpTag::Alias;
290}
291impl OpTrait for AliasDecl {
292 fn description(&self) -> &'static str {
293 "A type alias declaration"
294 }
295
296 fn tag(&self) -> OpTag {
297 <Self as StaticTag>::TAG
298 }
299
300 }