use std::fmt;
use crate::{
decl_engine::DeclEngine,
engine_threading::*,
language::{
parsed::*,
ty::{self, EnumDecl, StructDecl, TyDecl},
Visibility,
},
TypeId,
};
use sway_error::handler::{ErrorEmitted, Handler};
#[derive(Clone, Debug)]
pub enum ResolvedDeclaration {
Parsed(Declaration),
Typed(ty::TyDecl),
}
impl DisplayWithEngines for ResolvedDeclaration {
fn fmt(&self, f: &mut fmt::Formatter<'_>, engines: &Engines) -> fmt::Result {
match self {
ResolvedDeclaration::Parsed(decl) => DisplayWithEngines::fmt(decl, f, engines),
ResolvedDeclaration::Typed(decl) => DisplayWithEngines::fmt(decl, f, engines),
}
}
}
impl DebugWithEngines for ResolvedDeclaration {
fn fmt(&self, f: &mut fmt::Formatter<'_>, engines: &Engines) -> fmt::Result {
match self {
ResolvedDeclaration::Parsed(decl) => DebugWithEngines::fmt(decl, f, engines),
ResolvedDeclaration::Typed(decl) => DebugWithEngines::fmt(decl, f, engines),
}
}
}
impl PartialEqWithEngines for ResolvedDeclaration {
fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool {
match (self, other) {
(ResolvedDeclaration::Parsed(lhs), ResolvedDeclaration::Parsed(rhs)) => {
lhs.eq(rhs, ctx)
}
(ResolvedDeclaration::Typed(lhs), ResolvedDeclaration::Typed(rhs)) => lhs.eq(rhs, ctx),
(ResolvedDeclaration::Parsed(_lhs), ResolvedDeclaration::Typed(_rhs)) => false,
(ResolvedDeclaration::Typed(_lhs), ResolvedDeclaration::Parsed(_rhs)) => false,
}
}
}
impl ResolvedDeclaration {
pub fn is_typed(&self) -> bool {
match self {
ResolvedDeclaration::Parsed(_) => false,
ResolvedDeclaration::Typed(_) => true,
}
}
pub fn resolve_parsed(self, decl_engine: &DeclEngine) -> Declaration {
match self {
ResolvedDeclaration::Parsed(decl) => decl,
ResolvedDeclaration::Typed(ty_decl) => ty_decl
.get_parsed_decl(decl_engine)
.expect("expecting valid parsed declaration"),
}
}
pub fn expect_parsed(self) -> Declaration {
match self {
ResolvedDeclaration::Parsed(decl) => decl,
ResolvedDeclaration::Typed(_ty_decl) => panic!(),
}
}
pub fn expect_typed(self) -> ty::TyDecl {
match self {
ResolvedDeclaration::Parsed(_) => panic!(),
ResolvedDeclaration::Typed(ty_decl) => ty_decl,
}
}
pub fn expect_typed_ref(&self) -> &ty::TyDecl {
match self {
ResolvedDeclaration::Parsed(_) => panic!(),
ResolvedDeclaration::Typed(ty_decl) => ty_decl,
}
}
pub(crate) fn to_struct_decl(
&self,
handler: &Handler,
engines: &Engines,
) -> Result<ResolvedDeclaration, ErrorEmitted> {
match self {
ResolvedDeclaration::Parsed(decl) => decl
.to_struct_decl(handler, engines)
.map(|id| ResolvedDeclaration::Parsed(Declaration::StructDeclaration(id))),
ResolvedDeclaration::Typed(decl) => decl.to_struct_decl(handler, engines).map(|id| {
ResolvedDeclaration::Typed(TyDecl::StructDecl(StructDecl { decl_id: id }))
}),
}
}
pub(crate) fn to_enum_decl(
&self,
handler: &Handler,
engines: &Engines,
) -> Result<ResolvedDeclaration, ErrorEmitted> {
match self {
ResolvedDeclaration::Parsed(decl) => decl
.to_enum_decl(handler, engines)
.map(|id| ResolvedDeclaration::Parsed(Declaration::EnumDeclaration(id))),
ResolvedDeclaration::Typed(decl) => decl
.to_enum_id(handler, engines)
.map(|id| ResolvedDeclaration::Typed(TyDecl::EnumDecl(EnumDecl { decl_id: id }))),
}
}
pub(crate) fn visibility(&self, engines: &Engines) -> Visibility {
match self {
ResolvedDeclaration::Parsed(decl) => decl.visibility(engines.pe()),
ResolvedDeclaration::Typed(decl) => decl.visibility(engines.de()),
}
}
pub(crate) fn span(&self, engines: &Engines) -> sway_types::Span {
match self {
ResolvedDeclaration::Parsed(decl) => decl.span(engines),
ResolvedDeclaration::Typed(decl) => decl.span(engines),
}
}
pub(crate) fn return_type(
&self,
handler: &Handler,
engines: &Engines,
) -> Result<TypeId, ErrorEmitted> {
match self {
ResolvedDeclaration::Parsed(_decl) => unreachable!(),
ResolvedDeclaration::Typed(decl) => decl.return_type(handler, engines),
}
}
pub(crate) fn is_trait(&self) -> bool {
match self {
ResolvedDeclaration::Parsed(decl) => {
matches!(decl, Declaration::TraitDeclaration(_))
}
ResolvedDeclaration::Typed(decl) => {
matches!(decl, TyDecl::TraitDecl(_))
}
}
}
}