use crate::ast::AstTargetDialect;
use crate::debug::DebugDetail;
use crate::parser::RawChunk;
use crate::timing::TimingCollector;
use strum_macros::{Display, EnumString, IntoStaticStr};
use super::contracts::{
AstChunk, CfgGraph, DataflowFacts, GeneratedChunk, GraphFacts, HirChunk, LoweredChunk,
NamingResult, ReadabilityResult, StructureFacts,
};
use super::options::{DecompileDialect, DecompileOptions};
#[derive(
Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Display, EnumString, IntoStaticStr,
)]
pub enum DecompileStage {
#[strum(serialize = "parse")]
Parse,
#[strum(serialize = "transform")]
Transform,
#[strum(serialize = "cfg")]
Cfg,
#[strum(
serialize = "graph-facts",
serialize = "graph_facts",
serialize = "graphfacts"
)]
GraphFacts,
#[strum(serialize = "dataflow")]
Dataflow,
#[strum(
serialize = "structure-facts",
serialize = "structure_facts",
serialize = "structurefacts"
)]
StructureFacts,
#[strum(serialize = "hir")]
Hir,
#[strum(serialize = "ast")]
Ast,
#[strum(serialize = "readability")]
Readability,
#[strum(serialize = "naming")]
Naming,
#[strum(serialize = "generate")]
Generate,
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct StageDebugOutput {
pub stage: DecompileStage,
pub detail: DebugDetail,
pub content: String,
}
pub(crate) struct DecompileContext<'a> {
pub(crate) bytes: &'a [u8],
pub(crate) options: &'a DecompileOptions,
pub(crate) timings: &'a TimingCollector,
pub(crate) requested_target: AstTargetDialect,
}
impl DecompileStage {
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,
}
}
}
#[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);
}
}