nac3core: toplevel register consider module path

This commit is contained in:
ychenfo 2021-09-12 05:00:26 +08:00
parent 118f19762a
commit cb310965b8
2 changed files with 37 additions and 6 deletions

View File

@ -166,6 +166,7 @@ impl TopLevelComposer {
&mut self, &mut self,
ast: ast::Stmt<()>, ast: ast::Stmt<()>,
resolver: Option<Arc<Box<dyn SymbolResolver + Send + Sync>>>, resolver: Option<Arc<Box<dyn SymbolResolver + Send + Sync>>>,
mod_path: String,
) -> Result<(String, DefinitionId), String> { ) -> Result<(String, DefinitionId), String> {
// FIXME: different module same name? // FIXME: different module same name?
let defined_class_name = &mut self.defined_class_name; let defined_class_name = &mut self.defined_class_name;
@ -176,7 +177,11 @@ impl TopLevelComposer {
if self.keyword_list.contains(name) { if self.keyword_list.contains(name) {
return Err("cannot use keyword as a class name".into()); 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()); return Err("duplicate definition of class".into());
} }
@ -216,7 +221,11 @@ impl TopLevelComposer {
} }
let global_class_method_name = let global_class_method_name =
Self::make_class_method_name(class_name.clone(), 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()); return Err("duplicate class method definition".into());
} }
if method_name == "__init__" { if method_name == "__init__" {
@ -283,7 +292,11 @@ impl TopLevelComposer {
return Err("cannot use keyword as a top level function name".into()); return Err("cannot use keyword as a top level function name".into());
} }
let fun_name = name.to_string(); 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()); return Err("duplicate top level function define".into());
} }

View File

@ -86,7 +86,7 @@ fn test_simple_register(source: Vec<&str>) {
let ast = parse_program(s).unwrap(); let ast = parse_program(s).unwrap();
let ast = ast[0].clone(); 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 = 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) =
composer.register_top_level(ast, Some(resolver.clone()), "__main__".into()).unwrap();
internal_resolver.add_id_def(id, def_id); 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"]; vec!["field `a` has already declared in the ancestor classes"];
"err_incompatible_inheritance_field" "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>) { fn test_analyze(source: Vec<&str>, res: Vec<&str>) {
let print = false; let print = false;
let mut composer = TopLevelComposer::new(); let mut composer = TopLevelComposer::new();
@ -769,7 +787,7 @@ fn test_analyze(source: Vec<&str>, res: Vec<&str>) {
let ast = ast[0].clone(); let ast = ast[0].clone();
let (id, def_id) = { 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, Ok(x) => x,
Err(msg) => { Err(msg) => {
if print { if print {