use std::borrow::Cow;
use smol_str::SmolStr;
#[cfg(test)]
use {
crate::proptest::{any_nonempty_smolstr, any_nonempty_string},
::proptest_derive::Arbitrary,
};
use crate::Visibility;
use crate::types::{EdgeKind, PolyFuncType, Signature, Type, TypeBound};
use super::dataflow::DataflowParent;
use super::{OpTag, OpTrait, StaticTag, impl_op_name};
#[derive(Debug, Clone, PartialEq, Eq, Default, serde::Serialize, serde::Deserialize)]
#[cfg_attr(test, derive(Arbitrary))]
pub struct Module {
}
impl Module {
#[must_use]
pub const fn new() -> Self {
Self {}
}
}
impl_op_name!(Module);
impl StaticTag for Module {
const TAG: OpTag = OpTag::ModuleRoot;
}
impl OpTrait for Module {
fn description(&self) -> &'static str {
"The root of a module, parent of all other `OpType`s"
}
fn tag(&self) -> super::OpTag {
<Self as StaticTag>::TAG
}
}
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[cfg_attr(test, derive(Arbitrary))]
pub struct FuncDefn {
#[cfg_attr(test, proptest(strategy = "any_nonempty_string()"))]
name: String,
signature: PolyFuncType,
#[serde(default = "priv_vis")] visibility: Visibility,
}
fn priv_vis() -> Visibility {
Visibility::Private
}
impl FuncDefn {
pub fn new(name: impl Into<String>, signature: impl Into<PolyFuncType>) -> Self {
Self::new_vis(name, signature, Visibility::Private)
}
pub fn new_vis(
name: impl Into<String>,
signature: impl Into<PolyFuncType>,
visibility: Visibility,
) -> Self {
Self {
name: name.into(),
signature: signature.into(),
visibility,
}
}
pub fn func_name(&self) -> &String {
&self.name
}
pub fn func_name_mut(&mut self) -> &mut String {
&mut self.name
}
pub fn signature(&self) -> &PolyFuncType {
&self.signature
}
pub fn signature_mut(&mut self) -> &mut PolyFuncType {
&mut self.signature
}
pub fn visibility(&self) -> &Visibility {
&self.visibility
}
pub fn visibility_mut(&mut self) -> &mut Visibility {
&mut self.visibility
}
}
impl_op_name!(FuncDefn);
impl StaticTag for FuncDefn {
const TAG: OpTag = OpTag::FuncDefn;
}
impl DataflowParent for FuncDefn {
fn inner_signature(&self) -> Cow<'_, Signature> {
Cow::Borrowed(self.signature.body())
}
}
impl OpTrait for FuncDefn {
fn description(&self) -> &'static str {
"A function definition"
}
fn tag(&self) -> OpTag {
<Self as StaticTag>::TAG
}
fn static_output(&self) -> Option<EdgeKind> {
Some(EdgeKind::Function(self.signature.clone()))
}
}
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[cfg_attr(test, derive(Arbitrary))]
pub struct FuncDecl {
#[cfg_attr(test, proptest(strategy = "any_nonempty_string()"))]
name: String,
signature: PolyFuncType,
#[serde(default = "pub_vis")] visibility: Visibility,
}
fn pub_vis() -> Visibility {
Visibility::Public
}
impl FuncDecl {
pub fn new(name: impl Into<String>, signature: impl Into<PolyFuncType>) -> Self {
Self::new_vis(name, signature, Visibility::Public)
}
pub fn new_vis(
name: impl Into<String>,
signature: impl Into<PolyFuncType>,
visibility: Visibility,
) -> Self {
Self {
name: name.into(),
signature: signature.into(),
visibility,
}
}
pub fn func_name(&self) -> &String {
&self.name
}
pub fn visibility(&self) -> &Visibility {
&self.visibility
}
pub fn func_name_mut(&mut self) -> &mut String {
&mut self.name
}
pub fn visibility_mut(&mut self) -> &mut Visibility {
&mut self.visibility
}
pub fn signature(&self) -> &PolyFuncType {
&self.signature
}
pub fn signature_mut(&mut self) -> &mut PolyFuncType {
&mut self.signature
}
}
impl_op_name!(FuncDecl);
impl StaticTag for FuncDecl {
const TAG: OpTag = OpTag::Function;
}
impl OpTrait for FuncDecl {
fn description(&self) -> &'static str {
"External function declaration, linked at runtime"
}
fn tag(&self) -> OpTag {
<Self as StaticTag>::TAG
}
fn static_output(&self) -> Option<EdgeKind> {
Some(EdgeKind::Function(self.signature.clone()))
}
}
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[cfg_attr(test, derive(Arbitrary))]
pub struct AliasDefn {
#[cfg_attr(test, proptest(strategy = "any_nonempty_smolstr()"))]
pub name: SmolStr,
pub definition: Type,
}
impl_op_name!(AliasDefn);
impl StaticTag for AliasDefn {
const TAG: OpTag = OpTag::Alias;
}
impl OpTrait for AliasDefn {
fn description(&self) -> &'static str {
"A type alias definition"
}
fn tag(&self) -> OpTag {
<Self as StaticTag>::TAG
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
pub struct AliasDecl {
#[cfg_attr(test, proptest(strategy = "any_nonempty_smolstr()"))]
pub name: SmolStr,
pub bound: TypeBound,
}
impl AliasDecl {
pub fn new(name: impl Into<SmolStr>, bound: TypeBound) -> Self {
Self {
name: name.into(),
bound,
}
}
#[must_use]
pub fn name(&self) -> &str {
self.name.as_ref()
}
}
impl_op_name!(AliasDecl);
impl StaticTag for AliasDecl {
const TAG: OpTag = OpTag::Alias;
}
impl OpTrait for AliasDecl {
fn description(&self) -> &'static str {
"A type alias declaration"
}
fn tag(&self) -> OpTag {
<Self as StaticTag>::TAG
}
}