gaia-assembler 0.1.1

Universal assembler framework for Gaia project
Documentation
//! Test type mapping between UIR and Gaia IR

use gaia_assembler::types::{GaiaType, mapping::*};

#[test]
fn test_uir_type_to_gaia_type() {
    let mut ctx = TypeMappingContext::new();
    
    // Test primitive types
    assert_eq!(map_uir_type_to_gaia_type("bool", &mut ctx), GaiaType::Bool);
    assert_eq!(map_uir_type_to_gaia_type("byte", &mut ctx), GaiaType::I8);
    assert_eq!(map_uir_type_to_gaia_type("i8", &mut ctx), GaiaType::I8);
    assert_eq!(map_uir_type_to_gaia_type("short", &mut ctx), GaiaType::I16);
    assert_eq!(map_uir_type_to_gaia_type("i16", &mut ctx), GaiaType::I16);
    assert_eq!(map_uir_type_to_gaia_type("int", &mut ctx), GaiaType::I32);
    assert_eq!(map_uir_type_to_gaia_type("i32", &mut ctx), GaiaType::I32);
    assert_eq!(map_uir_type_to_gaia_type("long", &mut ctx), GaiaType::I64);
    assert_eq!(map_uir_type_to_gaia_type("i64", &mut ctx), GaiaType::I64);
    assert_eq!(map_uir_type_to_gaia_type("float", &mut ctx), GaiaType::F32);
    assert_eq!(map_uir_type_to_gaia_type("f32", &mut ctx), GaiaType::F32);
    assert_eq!(map_uir_type_to_gaia_type("double", &mut ctx), GaiaType::F64);
    assert_eq!(map_uir_type_to_gaia_type("f64", &mut ctx), GaiaType::F64);
    assert_eq!(map_uir_type_to_gaia_type("char", &mut ctx), GaiaType::U16);
    assert_eq!(map_uir_type_to_gaia_type("void", &mut ctx), GaiaType::Void);
    
    // Test reference types
    assert_eq!(map_uir_type_to_gaia_type("String", &mut ctx), GaiaType::String);
    assert_eq!(map_uir_type_to_gaia_type("Object", &mut ctx), GaiaType::Object);
    
    // Test array types
    let array_type = map_uir_type_to_gaia_type("[int", &mut ctx);
    match array_type {
        GaiaType::Array(inner, _) => assert_eq!(*inner, GaiaType::I32),
        _ => panic!("Expected array type"),
    }
    
    // Test generic types
    let generic_type = map_uir_type_to_gaia_type("List<String>", &mut ctx);
    match generic_type {
        GaiaType::Class(name) => assert_eq!(name, "List"),
        _ => panic!("Expected class type"),
    }
    
    // Test class types
    assert_eq!(map_uir_type_to_gaia_type("java.lang.String", &mut ctx), GaiaType::Class("java.lang.String".to_string()));

}

#[test]
fn test_gaia_type_to_jvm_descriptor() {
    // Test primitive types
    assert_eq!(map_gaia_type_to_jvm_descriptor(&GaiaType::Void), "V");
    assert_eq!(map_gaia_type_to_jvm_descriptor(&GaiaType::Bool), "Z");
    assert_eq!(map_gaia_type_to_jvm_descriptor(&GaiaType::I8), "B");
    assert_eq!(map_gaia_type_to_jvm_descriptor(&GaiaType::U8), "B");
    assert_eq!(map_gaia_type_to_jvm_descriptor(&GaiaType::I16), "S");
    assert_eq!(map_gaia_type_to_jvm_descriptor(&GaiaType::U16), "S");
    assert_eq!(map_gaia_type_to_jvm_descriptor(&GaiaType::I32), "I");
    assert_eq!(map_gaia_type_to_jvm_descriptor(&GaiaType::U32), "I");
    assert_eq!(map_gaia_type_to_jvm_descriptor(&GaiaType::I64), "J");
    assert_eq!(map_gaia_type_to_jvm_descriptor(&GaiaType::U64), "J");
    assert_eq!(map_gaia_type_to_jvm_descriptor(&GaiaType::F32), "F");
    assert_eq!(map_gaia_type_to_jvm_descriptor(&GaiaType::F64), "D");
    
    // Test reference types
    assert_eq!(map_gaia_type_to_jvm_descriptor(&GaiaType::String), "Ljava/lang/String;");
    assert_eq!(map_gaia_type_to_jvm_descriptor(&GaiaType::Object), "Ljava/lang/Object;");
    
    // Test array types
    let array_type = GaiaType::Array(Box::new(GaiaType::I32), 10);
    assert_eq!(map_gaia_type_to_jvm_descriptor(&array_type), "[I");
    
    // Test class types
    let class_type = GaiaType::Class("java.util.List".to_string());
    assert_eq!(map_gaia_type_to_jvm_descriptor(&class_type), "Ljava/util/List;");
    
    // Test interface types
    let interface_type = GaiaType::Interface("java.util.List".to_string());
    assert_eq!(map_gaia_type_to_jvm_descriptor(&interface_type), "Ljava/util/List;");
}

#[test]
fn test_type_compatibility() {
    // Test exact matches
    assert!(are_types_compatible(&GaiaType::I32, &GaiaType::I32));
    assert!(are_types_compatible(&GaiaType::String, &GaiaType::String));
    
    // Test primitive type promotions
    assert!(are_types_compatible(&GaiaType::I8, &GaiaType::I16));
    assert!(are_types_compatible(&GaiaType::I16, &GaiaType::I32));
    assert!(are_types_compatible(&GaiaType::I32, &GaiaType::I64));
    assert!(are_types_compatible(&GaiaType::I32, &GaiaType::F32));
    assert!(are_types_compatible(&GaiaType::F32, &GaiaType::F64));
    
    // Test reference type compatibility
    assert!(are_types_compatible(&GaiaType::String, &GaiaType::Object));
    assert!(are_types_compatible(&GaiaType::Class("java.util.List".to_string()), &GaiaType::Object));
    assert!(are_types_compatible(&GaiaType::Interface("java.util.List".to_string()), &GaiaType::Object));
    
    // Test array type compatibility
    let int_array = GaiaType::Array(Box::new(GaiaType::I32), 10);
    let object_array = GaiaType::Array(Box::new(GaiaType::Object), 10);
    assert!(are_types_compatible(&int_array, &object_array));
    
    // Test incompatible types
    assert!(!are_types_compatible(&GaiaType::I32, &GaiaType::Bool));
    assert!(!are_types_compatible(&GaiaType::String, &GaiaType::I32));
}

#[test]
fn test_common_super_type() {
    // Test when one type is compatible with the other
    assert_eq!(get_common_super_type(&GaiaType::I8, &GaiaType::I32), Some(GaiaType::I32));
    assert_eq!(get_common_super_type(&GaiaType::String, &GaiaType::Object), Some(GaiaType::Object));
    
    // Test when types are incompatible but share Object as super type
    let list_type = GaiaType::Class("java.util.List".to_string());
    let map_type = GaiaType::Class("java.util.Map".to_string());
    assert_eq!(get_common_super_type(&list_type, &map_type), Some(GaiaType::Object));
    
    // Test primitive types with no common super type
    assert_eq!(get_common_super_type(&GaiaType::I32, &GaiaType::Bool), None);
}

#[test]
fn test_type_erasure() {
    let mut ctx = TypeMappingContext::new();
    
    // Add type erasure information
    ctx.add_type_erasure("List", "java/util/List");
    ctx.add_type_erasure("Map", "java/util/Map");
    
    // Test generic type with erasure
    let generic_type = map_uir_type_to_gaia_type("List<String>", &mut ctx);
    match generic_type {
        GaiaType::Class(name) => assert_eq!(name, "java/util/List"),
        _ => panic!("Expected class type with erased name"),
    }
    
    // Test generic type without erasure
    let generic_type = map_uir_type_to_gaia_type("Set<String>", &mut ctx);
    match generic_type {
        GaiaType::Class(name) => assert_eq!(name, "Set"),
        _ => panic!("Expected class type with base name"),
    }
}