nac3core: top level err test

escape-analysis
ychenfo 2021-09-10 21:26:39 +08:00
parent 9eef51f29f
commit 4eacd1aa9e
1 changed files with 93 additions and 28 deletions

View File

@ -414,7 +414,47 @@ fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&s
]; ];
"list tuple generic" "list tuple generic"
)] )]
#[test_case(
vec![indoc! {"
class A:
pass
"}],
vec!["class def must have __init__ method defined"];
"err no __init__"
)]
#[test_case(
vec![indoc! {"
class A:
def __init__():
pass
"}],
vec!["__init__ function must have a `self` parameter"];
"err no self_1"
)]
#[test_case(
vec![
indoc! {"
class A(B, Generic[T], C):
def __init__(self):
pass
"},
indoc! {"
class B:
def __init__(self):
pass
"},
indoc! {"
class C:
def __init__(self):
pass
"}
],
vec!["a class def can only have at most one base class declaration and one generic declaration"];
"err multiple inheritance"
)]
fn test_simple_class_analyze(source: Vec<&str>, res: Vec<&str>) { fn test_simple_class_analyze(source: Vec<&str>, res: Vec<&str>) {
let print = false;
let mut composer = TopLevelComposer::new(); let mut composer = TopLevelComposer::new();
let tvar_t = composer.unifier.get_fresh_var(); let tvar_t = composer.unifier.get_fresh_var();
@ -422,8 +462,10 @@ fn test_simple_class_analyze(source: Vec<&str>, res: Vec<&str>) {
.unifier .unifier
.get_fresh_var_with_range(&[composer.primitives_ty.bool, composer.primitives_ty.int32]); .get_fresh_var_with_range(&[composer.primitives_ty.bool, composer.primitives_ty.int32]);
println!("t: {}, {:?}", tvar_t.1, tvar_t.0); if print {
println!("v: {}, {:?}\n", tvar_v.1, tvar_v.0); println!("t: {}, {:?}", tvar_t.1, tvar_t.0);
println!("v: {}, {:?}\n", tvar_v.1, tvar_v.0);
}
let internal_resolver = Arc::new(ResolverInternal { let internal_resolver = Arc::new(ResolverInternal {
id_to_def: Default::default(), id_to_def: Default::default(),
@ -440,35 +482,58 @@ fn test_simple_class_analyze(source: Vec<&str>, res: Vec<&str>) {
let ast = parse_program(s).unwrap(); let ast = parse_program(s).unwrap();
let ast = ast[0].clone(); let ast = ast[0].clone();
let (id, def_id) = composer.register_top_level(ast, Some(resolver.clone())).unwrap(); let (id, def_id) = {
match composer.register_top_level(ast, Some(resolver.clone())) {
Ok(x) => x,
Err(msg) => {
if print {
println!("{}", msg);
} else {
assert_eq!(res[0], msg);
}
return
}
}
};
internal_resolver.add_id_def(id, def_id); internal_resolver.add_id_def(id, def_id);
} }
composer.start_analysis().unwrap(); if let Err(msg) = composer.start_analysis() {
if print {
// skip 5 to skip primitives println!("{}", msg);
for (i, (def, _)) in composer.definition_ast_list.iter().skip(5).enumerate() { } else {
let def = &*def.read(); assert_eq!(res[0], msg);
// println!( }
// "{}: {}\n", } else {
// i + 5, // skip 5 to skip primitives
// def.to_string( for (i, (def, _)) in composer.definition_ast_list.iter().skip(5).enumerate() {
// composer.unifier.borrow_mut(), let def = &*def.read();
// &mut |id| format!("class{}", id),
// &mut |id| format!("tvar{}", id) if print {
// ) println!(
// ); "{}: {}\n",
assert_eq!( i + 5,
format!( def.to_string(
"{}: {}", composer.unifier.borrow_mut(),
i + 5, &mut |id| format!("class{}", id),
def.to_string( &mut |id| format!("tvar{}", id)
composer.unifier.borrow_mut(), )
&mut |id| format!("class{}", id.to_string()), );
&mut |id| format!("tvar{}", id.to_string()), } else {
assert_eq!(
format!(
"{}: {}",
i + 5,
def.to_string(
composer.unifier.borrow_mut(),
&mut |id| format!("class{}", id.to_string()),
&mut |id| format!("tvar{}", id.to_string()),
)
),
res[i]
) )
), }
res[i] }
)
} }
} }