neo-decompiler 0.10.1

Neo N3 NEF decompiler: parse, disassemble, lift bytecode to high-level pseudocode and C# skeletons, with a CLI, JSON reports, and optional WebAssembly bindings.
Documentation
use crate::decompiler::cfg::BlockId;

use super::{PhiNode, SsaVariable};

#[test]
fn test_ssa_variable_versioning() {
    let v0 = SsaVariable::initial("x".to_string());
    assert_eq!(v0.base, "x");
    assert_eq!(v0.version, 0);
    assert!(v0.is_initial());

    let v1 = v0.next();
    assert_eq!(v1.base, "x");
    assert_eq!(v1.version, 1);
    assert!(!v1.is_initial());

    let v2 = v1.next();
    assert_eq!(v2.version, 2);
}

#[test]
fn test_ssa_variable_display_hides_version() {
    let v0 = SsaVariable::initial("local_0".to_string());
    let v1 = v0.next();
    let v2 = v1.next();

    // All display as the base name.
    assert_eq!(v0.to_string(), "local_0");
    assert_eq!(v1.to_string(), "local_0");
    assert_eq!(v2.to_string(), "local_0");
}

#[test]
fn test_ssa_variable_ord() {
    // SSA variables must be ordered for BTreeMap.
    let mut set = std::collections::BTreeSet::new();
    set.insert(SsaVariable::new("z".to_string(), 1));
    set.insert(SsaVariable::new("a".to_string(), 2));
    set.insert(SsaVariable::new("m".to_string(), 0));

    let vars: Vec<_> = set.iter().collect();
    assert_eq!(vars[0].base, "a");
    assert_eq!(vars[1].base, "m");
    assert_eq!(vars[2].base, "z");
}

#[test]
fn test_phi_node_creation() {
    let target = SsaVariable::initial("result".to_string());
    let phi = PhiNode::new(target);

    assert_eq!(phi.target.base, "result");
    assert!(phi.operands.is_empty());
    assert_eq!(phi.operand_count(), 0);
}

#[test]
fn test_phi_node_add_operands() {
    let target = SsaVariable::initial("x".to_string());
    let mut phi = PhiNode::new(target);

    let block1 = BlockId(1);
    let block2 = BlockId(2);

    phi.add_operand(block1, SsaVariable::new("y".to_string(), 0));
    phi.add_operand(block2, SsaVariable::new("z".to_string(), 0));

    assert_eq!(phi.operand_count(), 2);
    assert!(phi.operands.contains_key(&block1));
    assert!(phi.operands.contains_key(&block2));
}

#[test]
fn test_phi_node_display() {
    let target = SsaVariable::initial("result".to_string());
    let mut phi = PhiNode::new(target);

    let block1 = BlockId(0);
    let block2 = BlockId(1);

    phi.add_operand(block1, SsaVariable::new("x".to_string(), 0));
    phi.add_operand(block2, SsaVariable::new("x".to_string(), 1));

    let display = phi.to_string();
    assert!(display.contains("result = φ("));
}