diff --git a/nac3core/src/toplevel/mod.rs b/nac3core/src/toplevel/mod.rs index fd56508e..c846cc92 100644 --- a/nac3core/src/toplevel/mod.rs +++ b/nac3core/src/toplevel/mod.rs @@ -166,6 +166,7 @@ impl TopLevelComposer { &mut self, ast: ast::Stmt<()>, resolver: Option>>, + mod_path: String, ) -> Result<(String, DefinitionId), String> { // FIXME: different module same name? let defined_class_name = &mut self.defined_class_name; @@ -176,7 +177,11 @@ impl TopLevelComposer { if self.keyword_list.contains(name) { return Err("cannot use keyword as a class name".into()); } - if !defined_class_name.insert(name.clone()) { + if !defined_class_name.insert({ + let mut n = mod_path.clone(); + n.push_str(name.as_str()); + n + }) { return Err("duplicate definition of class".into()); } @@ -216,7 +221,11 @@ impl TopLevelComposer { } let global_class_method_name = Self::make_class_method_name(class_name.clone(), method_name); - if !defined_class_method_name.insert(global_class_method_name.clone()) { + if !defined_class_method_name.insert({ + let mut n = mod_path.clone(); + n.push_str(global_class_method_name.as_str()); + n + }) { return Err("duplicate class method definition".into()); } if method_name == "__init__" { @@ -283,7 +292,11 @@ impl TopLevelComposer { return Err("cannot use keyword as a top level function name".into()); } let fun_name = name.to_string(); - if !defined_function_name.insert(name.to_string()) { + if !defined_function_name.insert({ + let mut n = mod_path.clone(); + n.push_str(name.as_str()); + n + }) { return Err("duplicate top level function define".into()); } diff --git a/nac3core/src/toplevel/test.rs b/nac3core/src/toplevel/test.rs index c56fcd34..48a75acc 100644 --- a/nac3core/src/toplevel/test.rs +++ b/nac3core/src/toplevel/test.rs @@ -86,7 +86,7 @@ fn test_simple_register(source: Vec<&str>) { let ast = parse_program(s).unwrap(); let ast = ast[0].clone(); - composer.register_top_level(ast, None).unwrap(); + composer.register_top_level(ast, None, "__main__".into()).unwrap(); } } @@ -133,7 +133,8 @@ fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&s let ast = parse_program(s).unwrap(); let ast = ast[0].clone(); - let (id, def_id) = composer.register_top_level(ast, Some(resolver.clone())).unwrap(); + let (id, def_id) = + composer.register_top_level(ast, Some(resolver.clone()), "__main__".into()).unwrap(); internal_resolver.add_id_def(id, def_id); } @@ -739,6 +740,23 @@ fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&s vec!["field `a` has already declared in the ancestor classes"]; "err_incompatible_inheritance_field" )] +#[test_case( + vec![ + indoc! {" + class A: + def __init__(self): + pass + "}, + indoc! {" + class A: + a: int32 + def __init__(self): + pass + "} + ], + vec!["duplicate definition of class"]; + "class same name" +)] fn test_analyze(source: Vec<&str>, res: Vec<&str>) { let print = false; let mut composer = TopLevelComposer::new(); @@ -769,7 +787,7 @@ fn test_analyze(source: Vec<&str>, res: Vec<&str>) { let ast = ast[0].clone(); let (id, def_id) = { - match composer.register_top_level(ast, Some(resolver.clone())) { + match composer.register_top_level(ast, Some(resolver.clone()), "__main__".into()) { Ok(x) => x, Err(msg) => { if print {