no_init #265

Closed
wylited wants to merge 3 commits from no_init into master
2 changed files with 18 additions and 14 deletions
Showing only changes of commit ab86bf4591 - Show all commits

View File

@ -167,7 +167,7 @@ impl TopLevelComposer {
) -> Result<(StrRef, DefinitionId, Option<Type>), String> { ) -> Result<(StrRef, DefinitionId, Option<Type>), String> {
let defined_names = &mut self.defined_names; let defined_names = &mut self.defined_names;
match &ast.node { match &ast.node {
ast::StmtKind::ClassDef { name: class_name, bases, body, .. } => { ast::StmtKind::ClassDef { name: class_name, body, .. } => {
if self.keyword_list.contains(class_name) { if self.keyword_list.contains(class_name) {
return Err(format!( return Err(format!(
"cannot use keyword `{}` as a class name (at {})", "cannot use keyword `{}` as a class name (at {})",
@ -221,18 +221,9 @@ impl TopLevelComposer {
// we do not push anything to the def list, so we keep track of the index // we do not push anything to the def list, so we keep track of the index
// and then push in the correct order after the for loop // and then push in the correct order after the for loop
let mut class_method_index_offset = 0; let mut class_method_index_offset = 0;
let init_id = "__init__".into();
let exception_id = "Exception".into();
// TODO: Fix this hack. We will generate constructor for classes that inherit
// from Exception class (directly or indirectly), but this code cannot handle
// subclass of other exception classes.
let mut contains_constructor = bases
.iter().any(|base| matches!(base.node, ast::ExprKind::Name { id, .. } if id == exception_id));
for b in body { for b in body {
if let ast::StmtKind::FunctionDef { name: method_name, .. } = &b.node { if let ast::StmtKind::FunctionDef { name: method_name, .. } = &b.node {
if method_name == &init_id {
contains_constructor = true;
}
if self.keyword_list.contains(method_name) { if self.keyword_list.contains(method_name) {
return Err(format!( return Err(format!(
"cannot use keyword `{}` as a method name (at {})", "cannot use keyword `{}` as a method name (at {})",
@ -298,7 +289,7 @@ impl TopLevelComposer {
self.definition_ast_list.push((def, Some(ast))); self.definition_ast_list.push((def, Some(ast)));
} }
let result_ty = if contains_constructor { Some(constructor_ty) } else { None }; let result_ty = Some(constructor_ty);
Ok((class_name, DefinitionId(class_def_id), result_ty)) Ok((class_name, DefinitionId(class_def_id), result_ty))
} }
@ -1470,7 +1461,7 @@ impl TopLevelComposer {
/// step 5, analyze and call type inferecer to fill the `instance_to_stmt` of topleveldef::function /// step 5, analyze and call type inferecer to fill the `instance_to_stmt` of topleveldef::function
fn analyze_function_instance(&mut self) -> Result<(), String> { fn analyze_function_instance(&mut self) -> Result<(), String> {
// first get the class contructor type correct for the following type check in function body // first get the class constructor type correct for the following type check in function body
// also do class field instantiation check // also do class field instantiation check
let init_str_id = "__init__".into(); let init_str_id = "__init__".into();
let mut definition_extension = Vec::new(); let mut definition_extension = Vec::new();
@ -1581,7 +1572,7 @@ impl TopLevelComposer {
return Ok(()); return Ok(());
} }
let mut init_id: Option<DefinitionId> = None; let mut init_id: Option<DefinitionId> = None;
// get the class contructor type correct // get the class constructor type correct
let (contor_args, contor_type_vars) = { let (contor_args, contor_type_vars) = {
let mut constructor_args: Vec<FuncArg> = Vec::new(); let mut constructor_args: Vec<FuncArg> = Vec::new();
let mut type_vars: HashMap<u32, Type> = HashMap::new(); let mut type_vars: HashMap<u32, Type> = HashMap::new();

View File

@ -0,0 +1,13 @@
@extern
def output_int32(x: int32):
...
class A:
def foo(self):
output_int32(1)
def run() -> int32:
inst = A()
inst.foo()
output_int32(1)
return 0