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::types::{EdgeKind, PolyFuncType, Signature};
13use crate::types::{Type, TypeBound};
14
15use super::StaticTag;
16use super::dataflow::DataflowParent;
17use super::{OpTag, OpTrait, impl_op_name};
18
19#[derive(Debug, Clone, PartialEq, Eq, Default, serde::Serialize, serde::Deserialize)]
21#[cfg_attr(test, derive(Arbitrary))]
22pub struct Module {
23 }
26
27impl Module {
28 #[must_use]
30 pub const fn new() -> Self {
31 Self {}
32 }
33}
34
35impl_op_name!(Module);
36
37impl StaticTag for Module {
38 const TAG: OpTag = OpTag::ModuleRoot;
39}
40
41impl OpTrait for Module {
42 fn description(&self) -> &'static str {
43 "The root of a module, parent of all other `OpType`s"
44 }
45
46 fn tag(&self) -> super::OpTag {
47 <Self as StaticTag>::TAG
48 }
49}
50
51#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
55#[cfg_attr(test, derive(Arbitrary))]
56pub struct FuncDefn {
57 #[cfg_attr(test, proptest(strategy = "any_nonempty_string()"))]
58 name: String,
59 signature: PolyFuncType,
60}
61
62impl FuncDefn {
63 pub fn new(name: impl Into<String>, signature: impl Into<PolyFuncType>) -> Self {
65 Self {
66 name: name.into(),
67 signature: signature.into(),
68 }
69 }
70
71 pub fn func_name(&self) -> &String {
73 &self.name
74 }
75
76 pub fn func_name_mut(&mut self) -> &mut String {
78 &mut self.name
79 }
80
81 pub fn signature(&self) -> &PolyFuncType {
83 &self.signature
84 }
85
86 pub fn signature_mut(&mut self) -> &mut PolyFuncType {
88 &mut self.signature
89 }
90}
91
92impl_op_name!(FuncDefn);
93impl StaticTag for FuncDefn {
94 const TAG: OpTag = OpTag::FuncDefn;
95}
96
97impl DataflowParent for FuncDefn {
98 fn inner_signature(&self) -> Cow<'_, Signature> {
99 Cow::Borrowed(self.signature.body())
100 }
101}
102
103impl OpTrait for FuncDefn {
104 fn description(&self) -> &'static str {
105 "A function definition"
106 }
107
108 fn tag(&self) -> OpTag {
109 <Self as StaticTag>::TAG
110 }
111
112 fn static_output(&self) -> Option<EdgeKind> {
113 Some(EdgeKind::Function(self.signature.clone()))
114 }
115
116 }
118
119#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
121#[cfg_attr(test, derive(Arbitrary))]
122pub struct FuncDecl {
123 #[cfg_attr(test, proptest(strategy = "any_nonempty_string()"))]
124 name: String,
125 signature: PolyFuncType,
126}
127
128impl FuncDecl {
129 pub fn new(name: impl Into<String>, signature: impl Into<PolyFuncType>) -> Self {
131 Self {
132 name: name.into(),
133 signature: signature.into(),
134 }
135 }
136
137 pub fn func_name(&self) -> &String {
139 &self.name
140 }
141
142 pub fn func_name_mut(&mut self) -> &mut String {
144 &mut self.name
145 }
146
147 pub fn signature(&self) -> &PolyFuncType {
149 &self.signature
150 }
151
152 pub fn signature_mut(&mut self) -> &mut PolyFuncType {
154 &mut self.signature
155 }
156}
157
158impl_op_name!(FuncDecl);
159impl StaticTag for FuncDecl {
160 const TAG: OpTag = OpTag::Function;
161}
162
163impl OpTrait for FuncDecl {
164 fn description(&self) -> &'static str {
165 "External function declaration, linked at runtime"
166 }
167
168 fn tag(&self) -> OpTag {
169 <Self as StaticTag>::TAG
170 }
171
172 fn static_output(&self) -> Option<EdgeKind> {
173 Some(EdgeKind::Function(self.signature.clone()))
174 }
175
176 }
178
179#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
181#[cfg_attr(test, derive(Arbitrary))]
182pub struct AliasDefn {
183 #[cfg_attr(test, proptest(strategy = "any_nonempty_smolstr()"))]
185 pub name: SmolStr,
186 pub definition: Type,
188}
189impl_op_name!(AliasDefn);
190impl StaticTag for AliasDefn {
191 const TAG: OpTag = OpTag::Alias;
192}
193impl OpTrait for AliasDefn {
194 fn description(&self) -> &'static str {
195 "A type alias definition"
196 }
197
198 fn tag(&self) -> OpTag {
199 <Self as StaticTag>::TAG
200 }
201
202 }
205
206#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
208#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
209pub struct AliasDecl {
210 #[cfg_attr(test, proptest(strategy = "any_nonempty_smolstr()"))]
212 pub name: SmolStr,
213 pub bound: TypeBound,
215}
216
217impl AliasDecl {
218 pub fn new(name: impl Into<SmolStr>, bound: TypeBound) -> Self {
220 Self {
221 name: name.into(),
222 bound,
223 }
224 }
225
226 #[must_use]
228 pub fn name(&self) -> &str {
229 self.name.as_ref()
230 }
231}
232
233impl_op_name!(AliasDecl);
234impl StaticTag for AliasDecl {
235 const TAG: OpTag = OpTag::Alias;
236}
237impl OpTrait for AliasDecl {
238 fn description(&self) -> &'static str {
239 "A type alias declaration"
240 }
241
242 fn tag(&self) -> OpTag {
243 <Self as StaticTag>::TAG
244 }
245
246 }