use std::{fmt, str::FromStr};
use crate::parser::RawChunk;
use super::contracts::{
AstChunk, CfgGraph, DataflowFacts, GeneratedChunk, GraphFacts, HirChunk, LoweredChunk,
NamingResult, ReadabilityResult, StructureFacts,
};
use super::options::DecompileDialect;
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd)]
pub enum DecompileStage {
Parse,
Transform,
Cfg,
GraphFacts,
Dataflow,
StructureFacts,
Hir,
Ast,
Readability,
Naming,
Generate,
}
impl DecompileStage {
pub const fn as_str(self) -> &'static str {
match self {
Self::Parse => "parse",
Self::Transform => "transform",
Self::Cfg => "cfg",
Self::GraphFacts => "graph-facts",
Self::Dataflow => "dataflow",
Self::StructureFacts => "structure-facts",
Self::Hir => "hir",
Self::Ast => "ast",
Self::Readability => "readability",
Self::Naming => "naming",
Self::Generate => "generate",
}
}
pub const fn next(self) -> Option<Self> {
match self {
Self::Parse => Some(Self::Transform),
Self::Transform => Some(Self::Cfg),
Self::Cfg => Some(Self::GraphFacts),
Self::GraphFacts => Some(Self::Dataflow),
Self::Dataflow => Some(Self::StructureFacts),
Self::StructureFacts => Some(Self::Hir),
Self::Hir => Some(Self::Ast),
Self::Ast => Some(Self::Readability),
Self::Readability => Some(Self::Naming),
Self::Naming => Some(Self::Generate),
Self::Generate => None,
}
}
}
impl fmt::Display for DecompileStage {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
impl FromStr for DecompileStage {
type Err = ();
fn from_str(value: &str) -> Result<Self, Self::Err> {
match value {
"parse" => Ok(Self::Parse),
"transform" => Ok(Self::Transform),
"cfg" => Ok(Self::Cfg),
"graph-facts" | "graph_facts" | "graphfacts" => Ok(Self::GraphFacts),
"dataflow" => Ok(Self::Dataflow),
"structure-facts" | "structure_facts" | "structurefacts" => {
Ok(Self::StructureFacts)
}
"hir" => Ok(Self::Hir),
"ast" => Ok(Self::Ast),
"readability" => Ok(Self::Readability),
"naming" => Ok(Self::Naming),
"generate" => Ok(Self::Generate),
_ => Err(()),
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct DecompileState {
pub dialect: DecompileDialect,
pub target_stage: DecompileStage,
pub completed_stage: Option<DecompileStage>,
pub raw_chunk: Option<RawChunk>,
pub lowered: Option<LoweredChunk>,
pub cfg: Option<CfgGraph>,
pub graph_facts: Option<GraphFacts>,
pub dataflow: Option<DataflowFacts>,
pub structure_facts: Option<StructureFacts>,
pub hir: Option<HirChunk>,
pub ast: Option<AstChunk>,
pub readability: Option<ReadabilityResult>,
pub naming: Option<NamingResult>,
pub generated: Option<GeneratedChunk>,
}
impl DecompileState {
pub(crate) fn new(dialect: DecompileDialect, target_stage: DecompileStage) -> Self {
Self {
dialect,
target_stage,
completed_stage: None,
raw_chunk: None,
lowered: None,
cfg: None,
graph_facts: None,
dataflow: None,
structure_facts: None,
hir: None,
ast: None,
readability: None,
naming: None,
generated: None,
}
}
pub(crate) fn mark_completed(&mut self, stage: DecompileStage) {
self.completed_stage = Some(stage);
}
}