use crate::{
language::{CallPath, Literal},
TypeInfo,
};
use sway_types::{ident::Ident, span::Span, Spanned};
#[allow(clippy::enum_variant_names)]
#[derive(Debug, Clone)]
pub enum Scrutinee {
CatchAll {
span: Span,
},
Literal {
value: Literal,
span: Span,
},
Variable {
name: Ident,
span: Span,
},
StructScrutinee {
struct_name: CallPath,
fields: Vec<StructScrutineeField>,
span: Span,
},
EnumScrutinee {
call_path: CallPath,
value: Box<Scrutinee>,
span: Span,
},
Tuple {
elems: Vec<Scrutinee>,
span: Span,
},
Error {
spans: Box<[Span]>,
},
}
#[derive(Debug, Clone)]
#[allow(clippy::large_enum_variant)]
pub enum StructScrutineeField {
Rest {
span: Span,
},
Field {
field: Ident,
scrutinee: Option<Scrutinee>,
span: Span,
},
}
impl Spanned for Scrutinee {
fn span(&self) -> Span {
match self {
Scrutinee::CatchAll { span } => span.clone(),
Scrutinee::Literal { span, .. } => span.clone(),
Scrutinee::Variable { span, .. } => span.clone(),
Scrutinee::StructScrutinee { span, .. } => span.clone(),
Scrutinee::EnumScrutinee { span, .. } => span.clone(),
Scrutinee::Tuple { span, .. } => span.clone(),
Scrutinee::Error { spans } => spans.iter().cloned().reduce(Span::join).unwrap(),
}
}
}
impl Scrutinee {
pub(crate) fn gather_approximate_typeinfo_dependencies(&self) -> Vec<TypeInfo> {
match self {
Scrutinee::StructScrutinee {
struct_name,
fields,
..
} => {
let name = vec![TypeInfo::Custom {
call_path: struct_name.clone(),
type_arguments: None,
}];
let fields = fields
.iter()
.flat_map(|f| match f {
StructScrutineeField::Field {
scrutinee: Some(scrutinee),
..
} => scrutinee.gather_approximate_typeinfo_dependencies(),
_ => vec![],
})
.collect::<Vec<TypeInfo>>();
vec![name, fields].concat()
}
Scrutinee::EnumScrutinee {
call_path, value, ..
} => {
let enum_name = call_path.prefixes.last().unwrap_or(&call_path.suffix);
let name = vec![TypeInfo::Custom {
call_path: enum_name.clone().into(),
type_arguments: None,
}];
let value = value.gather_approximate_typeinfo_dependencies();
vec![name, value].concat()
}
Scrutinee::Tuple { elems, .. } => elems
.iter()
.flat_map(|scrutinee| scrutinee.gather_approximate_typeinfo_dependencies())
.collect::<Vec<TypeInfo>>(),
Scrutinee::Literal { .. }
| Scrutinee::CatchAll { .. }
| Scrutinee::Variable { .. }
| Scrutinee::Error { .. } => {
vec![]
}
}
}
}