nac3core: top level fix function/methods none return type

This commit is contained in:
ychenfo 2021-08-31 15:41:48 +08:00
parent 98d032b72a
commit 1ae6acc061
2 changed files with 77 additions and 63 deletions

View File

@ -678,45 +678,47 @@ impl TopLevelComposer {
.collect::<Result<Vec<_>, _>>()? .collect::<Result<Vec<_>, _>>()?
}; };
let return_ty_annotation = { let return_ty = {
let return_annotation = returns if let Some(returns) = returns {
.as_ref() let return_ty_annotation = {
.ok_or_else(|| "function return type needed".to_string())? let return_annotation = returns.as_ref();
.as_ref(); parse_ast_to_type_annotation_kinds(
parse_ast_to_type_annotation_kinds( resolver,
resolver, &temp_def_list,
&temp_def_list, unifier,
unifier, primitives_store,
primitives_store, return_annotation,
return_annotation, )?
)? };
};
let type_vars_within = let type_vars_within =
get_type_var_contained_in_type_annotation(&return_ty_annotation) get_type_var_contained_in_type_annotation(&return_ty_annotation)
.into_iter() .into_iter()
.map(|x| -> Result<(u32, Type), String> { .map(|x| -> Result<(u32, Type), String> {
if let TypeAnnotation::TypeVarKind(ty) = x { if let TypeAnnotation::TypeVarKind(ty) = x {
Ok((Self::get_var_id(ty, unifier)?, ty)) Ok((Self::get_var_id(ty, unifier)?, ty))
} else { } else {
unreachable!("must be type var here") unreachable!("must be type var here")
}
})
.collect::<Result<Vec<_>, _>>()?;
for (id, ty) in type_vars_within {
if let Some(prev_ty) = function_var_map.insert(id, ty) {
// if already have the type inserted, make sure they are the same thing
assert_eq!(prev_ty, ty);
} }
}) }
.collect::<Result<Vec<_>, _>>()?;
for (id, ty) in type_vars_within { get_type_from_type_annotation_kinds(
if let Some(prev_ty) = function_var_map.insert(id, ty) { &temp_def_list,
// if already have the type inserted, make sure they are the same thing unifier,
assert_eq!(prev_ty, ty); primitives_store,
&return_ty_annotation,
)?
} else {
primitives_store.none
} }
} };
let return_ty = get_type_from_type_annotation_kinds(
&temp_def_list,
unifier,
primitives_store,
&return_ty_annotation,
)?;
let function_ty = unifier.add_ty(TypeEnum::TFunc( let function_ty = unifier.add_ty(TypeEnum::TFunc(
FunSignature { args: arg_types, ret: return_ty, vars: function_var_map } FunSignature { args: arg_types, ret: return_ty, vars: function_var_map }
.into(), .into(),
@ -883,37 +885,45 @@ impl TopLevelComposer {
let ret_type = { let ret_type = {
if name != "__init__" { if name != "__init__" {
let result = returns if let Some(result) = returns {
.as_ref() let result = result.as_ref();
.ok_or_else(|| "method return type annotation needed".to_string())? let annotation = parse_ast_to_type_annotation_kinds(
.as_ref(); class_resolver,
let annotation = parse_ast_to_type_annotation_kinds( temp_def_list,
class_resolver, unifier,
temp_def_list, primitives,
unifier, result,
primitives, )?;
result,
)?;
// find type vars within this return type annotation // find type vars within this return type annotation
let type_vars_within = let type_vars_within =
get_type_var_contained_in_type_annotation(&annotation); get_type_var_contained_in_type_annotation(&annotation);
// handle the class type var and the method type var // handle the class type var and the method type var
for type_var_within in type_vars_within { for type_var_within in type_vars_within {
if let TypeAnnotation::TypeVarKind(ty) = type_var_within { if let TypeAnnotation::TypeVarKind(ty) = type_var_within {
let id = Self::get_var_id(ty, unifier)?; let id = Self::get_var_id(ty, unifier)?;
if let Some(prev_ty) = method_var_map.insert(id, ty) { if let Some(prev_ty) = method_var_map.insert(id, ty) {
// if already in the list, make sure they are the same? // if already in the list, make sure they are the same?
assert_eq!(prev_ty, ty); assert_eq!(prev_ty, ty);
}
} else {
unreachable!("must be type var annotation");
} }
} else {
unreachable!("must be type var annotation");
} }
}
let dummy_return_type = unifier.get_fresh_var().0; let dummy_return_type = unifier.get_fresh_var().0;
type_var_to_concrete_def.insert(dummy_return_type, annotation.clone()); type_var_to_concrete_def.insert(dummy_return_type, annotation.clone());
dummy_return_type dummy_return_type
} else {
// if do not have return annotation, return none
// for uniform handling, still use type annoatation
let dummy_return_type = unifier.get_fresh_var().0;
type_var_to_concrete_def.insert(
dummy_return_type,
TypeAnnotation::PrimitiveKind(primitives.none),
);
dummy_return_type
}
} else { } else {
// if is the "__init__" function, the return type is self // if is the "__init__" function, the return type is self
let dummy_return_type = unifier.get_fresh_var().0; let dummy_return_type = unifier.get_fresh_var().0;

View File

@ -56,6 +56,10 @@ impl SymbolResolver for Resolver {
def fun(self): def fun(self):
self.b = self.b + 3.0 self.b = self.b + 3.0
"},
indoc! {"
def foo(a: float):
a + 1.0
"} "}
] ]
)] )]