forked from M-Labs/nac3
1
0
Fork 0

fix on comments and redundant code, start handling 'self' things

This commit is contained in:
ychenfo 2021-08-17 11:06:45 +08:00
parent fa40fd73c6
commit a94145348a
1 changed files with 94 additions and 42 deletions

View File

@ -70,7 +70,7 @@ pub struct TopLevelContext {
pub struct TopLevelComposer { pub struct TopLevelComposer {
// list of top level definitions, same as top level context // list of top level definitions, same as top level context
pub definition_list: Arc<RwLock<Vec<RwLock<TopLevelDef>>>>, pub definition_list: Arc<RwLock<Vec<RwLock<TopLevelDef>>>>,
// list of top level ast, the index is same as the field `definition_list` and `ty_list` // list of top level ast, the index is same as the field `definition_list`
pub ast_list: RwLock<Vec<Option<ast::Stmt<()>>>>, pub ast_list: RwLock<Vec<Option<ast::Stmt<()>>>>,
// start as a primitive unifier, will add more top_level defs inside // start as a primitive unifier, will add more top_level defs inside
pub unifier: RwLock<Unifier>, pub unifier: RwLock<Unifier>,
@ -232,7 +232,7 @@ impl TopLevelComposer {
self.unifier.write().add_ty(TypeEnum::TFunc( self.unifier.write().add_ty(TypeEnum::TFunc(
FunSignature { FunSignature {
args: Default::default(), args: Default::default(),
ret: self.primitives.none.into(), ret: self.primitives.none,
vars: Default::default(), vars: Default::default(),
} }
.into(), .into(),
@ -319,25 +319,15 @@ impl TopLevelComposer {
// should update the TopLevelDef::Class.typevars and the TypeEnum::TObj.params // should update the TopLevelDef::Class.typevars and the TypeEnum::TObj.params
ast::ExprKind::Subscript { value, slice, .. } ast::ExprKind::Subscript { value, slice, .. }
if { if {
// can only be `Generic[...]` and this can only appear once matches!(&value.node, ast::ExprKind::Name { id, .. } if id == "Generic")
if let ast::ExprKind::Name { id, .. } = &value.node {
if id == "Generic" {
if !is_generic {
is_generic = true;
true
} else {
return Err(
"Only single Generic[...] can be in bases".into()
);
}
} else {
false
}
} else {
false
}
} => } =>
{ {
if !is_generic {
is_generic = true;
} else {
return Err("Only single Generic[...] can be in bases".into());
}
// if `class A(Generic[T, V, G])` // if `class A(Generic[T, V, G])`
if let ast::ExprKind::Tuple { elts, .. } = &slice.node { if let ast::ExprKind::Tuple { elts, .. } = &slice.node {
// parse the type vars // parse the type vars
@ -530,36 +520,93 @@ impl TopLevelComposer {
.args .args
.iter() .iter()
.map(|x| -> Result<Type, String> { .map(|x| -> Result<Type, String> {
let annotation = x if x.node.arg != "self" {
.node let annotation = x
.annotation .node
.as_ref() .annotation
.ok_or_else(|| { .as_ref()
"type annotation for function parameter is needed".to_string() .ok_or_else(|| {
})? "type annotation for function parameter is needed".to_string()
.as_ref(); })?
.as_ref();
let ty =
class_resolver.as_ref().unwrap().lock().parse_type_annotation( let ty =
&self.to_top_level_context(), class_resolver.as_ref().unwrap().lock().parse_type_annotation(
unifier.borrow_mut(), &self.to_top_level_context(),
&self.primitives, unifier.borrow_mut(),
annotation, &self.primitives,
)?; annotation,
Ok(ty) )?;
Ok(ty)
} else {
// TODO: handle self, how
unimplemented!()
}
}) })
.collect::<Result<Vec<_>, _>>()?; .collect::<Result<Vec<_>, _>>()?;
let ret_ty = method_returns_ast
let ret_ty = if method_name != "__init__" {
method_returns_ast
.as_ref() .as_ref()
.and_then(|x| { .map(|x|
Some(class_resolver.as_ref().unwrap().lock().parse_type_annotation( class_resolver.as_ref().unwrap().lock().parse_type_annotation(
&self.to_top_level_context(), &self.to_top_level_context(),
unifier.borrow_mut(), unifier.borrow_mut(),
&self.primitives, &self.primitives,
x.as_ref(), x.as_ref(),
)) )
}) )
.unwrap()?; .ok_or_else(|| "return type annotation needed".to_string())??
} else {
// TODO: self type, how
unimplemented!()
};
// handle fields
if method_name == "__init__" {
for body in method_body_ast {
match &body.node {
ast::StmtKind::AnnAssign {
target,
annotation,
..
} if {
if let ast::ExprKind::Attribute {
value,
attr,
..
} = &target.node {
if let ast::ExprKind::Name {id, ..} = &value.node {
id == "self"
} else { false }
} else { false }
} => {
// TODO: record this field with its type
},
// TODO: exclude those without type annotation
ast::StmtKind::Assign {
targets,
..
} if {
if let ast::ExprKind::Attribute {
value,
attr,
..
} = &targets[0].node {
if let ast::ExprKind::Name {id, ..} = &value.node {
id == "self"
} else { false }
} else { false }
} => {
unimplemented!()
},
// do nothing
_ => { }
}
}
}
let all_tys_ok = { let all_tys_ok = {
let ret_ty_iter = vec![ret_ty]; let ret_ty_iter = vec![ret_ty];
@ -580,6 +627,7 @@ impl TopLevelComposer {
unreachable!() unreachable!()
} }
} }
TypeEnum::TVar { .. } => true,
_ => unreachable!(), _ => unreachable!(),
} }
}) })
@ -610,6 +658,10 @@ impl TopLevelComposer {
unimplemented!() unimplemented!()
} }
fn analyze_top_level_function(&mut self) -> Result<(), String> {
unimplemented!()
}
fn analyze_top_level_field_instantiation(&mut self) -> Result<(), String> { fn analyze_top_level_field_instantiation(&mut self) -> Result<(), String> {
unimplemented!() unimplemented!()
} }