forked from M-Labs/nac3
nac3core: toplevel format
This commit is contained in:
parent
b419634f8a
commit
118f19762a
@ -137,7 +137,7 @@ impl TopLevelComposer {
|
|||||||
"None".into(),
|
"None".into(),
|
||||||
"self".into(),
|
"self".into(),
|
||||||
"Kernel".into(),
|
"Kernel".into(),
|
||||||
"KernelImmutable".into()
|
"KernelImmutable".into(),
|
||||||
]),
|
]),
|
||||||
defined_class_method_name: Default::default(),
|
defined_class_method_name: Default::default(),
|
||||||
defined_class_name: Default::default(),
|
defined_class_name: Default::default(),
|
||||||
@ -426,14 +426,10 @@ impl TopLevelComposer {
|
|||||||
// skip 5 to skip analyzing the primitives
|
// skip 5 to skip analyzing the primitives
|
||||||
for (class_def, class_ast) in self.definition_ast_list.iter_mut().skip(5) {
|
for (class_def, class_ast) in self.definition_ast_list.iter_mut().skip(5) {
|
||||||
let mut class_def = class_def.write();
|
let mut class_def = class_def.write();
|
||||||
let (
|
let (class_def_id, class_bases, class_ancestors, class_resolver, class_type_vars) = {
|
||||||
class_def_id,
|
if let TopLevelDef::Class { ancestors, resolver, object_id, type_vars, .. } =
|
||||||
class_bases,
|
class_def.deref_mut()
|
||||||
class_ancestors,
|
{
|
||||||
class_resolver,
|
|
||||||
class_type_vars
|
|
||||||
) = {
|
|
||||||
if let TopLevelDef::Class { ancestors, resolver, object_id, type_vars, .. } = class_def.deref_mut() {
|
|
||||||
if let Some(ast::Located {
|
if let Some(ast::Located {
|
||||||
node: ast::StmtKind::ClassDef { bases, .. }, ..
|
node: ast::StmtKind::ClassDef { bases, .. }, ..
|
||||||
}) = class_ast
|
}) = class_ast
|
||||||
@ -478,7 +474,7 @@ impl TopLevelComposer {
|
|||||||
unifier,
|
unifier,
|
||||||
&self.primitives_ty,
|
&self.primitives_ty,
|
||||||
b,
|
b,
|
||||||
vec![(*class_def_id, class_type_vars.clone())].into_iter().collect()
|
vec![(*class_def_id, class_type_vars.clone())].into_iter().collect(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
if let TypeAnnotation::CustomClassKind { .. } = &base_ty {
|
if let TypeAnnotation::CustomClassKind { .. } = &base_ty {
|
||||||
@ -827,7 +823,7 @@ impl TopLevelComposer {
|
|||||||
};
|
};
|
||||||
let class_resolver = class_resolver.as_ref().unwrap();
|
let class_resolver = class_resolver.as_ref().unwrap();
|
||||||
let class_resolver = class_resolver.as_ref();
|
let class_resolver = class_resolver.as_ref();
|
||||||
|
|
||||||
let mut defined_fields: HashSet<String> = HashSet::new();
|
let mut defined_fields: HashSet<String> = HashSet::new();
|
||||||
for b in class_body_ast {
|
for b in class_body_ast {
|
||||||
if let ast::StmtKind::FunctionDef { args, returns, name, .. } = &b.node {
|
if let ast::StmtKind::FunctionDef { args, returns, name, .. } = &b.node {
|
||||||
@ -862,7 +858,7 @@ impl TopLevelComposer {
|
|||||||
return Err("__init__ function must have a `self` parameter".into());
|
return Err("__init__ function must have a `self` parameter".into());
|
||||||
}
|
}
|
||||||
if !defined_paramter_name.contains("self") {
|
if !defined_paramter_name.contains("self") {
|
||||||
return Err("currently does not support static method".into())
|
return Err("currently does not support static method".into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut result = Vec::new();
|
let mut result = Vec::new();
|
||||||
@ -882,7 +878,9 @@ impl TopLevelComposer {
|
|||||||
unifier,
|
unifier,
|
||||||
primitives,
|
primitives,
|
||||||
annotation_expr,
|
annotation_expr,
|
||||||
vec![(class_id, class_type_vars_def.clone())].into_iter().collect(),
|
vec![(class_id, class_type_vars_def.clone())]
|
||||||
|
.into_iter()
|
||||||
|
.collect(),
|
||||||
)?
|
)?
|
||||||
};
|
};
|
||||||
// find type vars within this method parameter type annotation
|
// find type vars within this method parameter type annotation
|
||||||
@ -971,7 +969,8 @@ impl TopLevelComposer {
|
|||||||
// NOTE: unify now since function type is not in type annotation define
|
// NOTE: unify now since function type is not in type annotation define
|
||||||
// which is fine since type within method_type will be subst later
|
// which is fine since type within method_type will be subst later
|
||||||
unifier.unify(method_dummy_ty, method_type)?;
|
unifier.unify(method_dummy_ty, method_type)?;
|
||||||
} else if let ast::StmtKind::AnnAssign { target, annotation, value: None, .. } = &b.node {
|
} else if let ast::StmtKind::AnnAssign { target, annotation, value: None, .. } = &b.node
|
||||||
|
{
|
||||||
if let ast::ExprKind::Name { id: attr, .. } = &target.node {
|
if let ast::ExprKind::Name { id: attr, .. } = &target.node {
|
||||||
if defined_fields.insert(attr.to_string()) {
|
if defined_fields.insert(attr.to_string()) {
|
||||||
let dummy_field_type = unifier.get_fresh_var().0;
|
let dummy_field_type = unifier.get_fresh_var().0;
|
||||||
@ -980,10 +979,14 @@ impl TopLevelComposer {
|
|||||||
// handle Kernel[T], KernelImmutable[T]
|
// handle Kernel[T], KernelImmutable[T]
|
||||||
let annotation = {
|
let annotation = {
|
||||||
match &annotation.as_ref().node {
|
match &annotation.as_ref().node {
|
||||||
ast::ExprKind::Subscript { value, slice, .. } if {
|
ast::ExprKind::Subscript { value, slice, .. }
|
||||||
matches!(&value.node, ast::ExprKind::Name { id, .. } if id == "Kernel" || id == "KernelImmutable")
|
if {
|
||||||
} => slice,
|
matches!(&value.node, ast::ExprKind::Name { id, .. } if id == "Kernel" || id == "KernelImmutable")
|
||||||
_ => annotation
|
} =>
|
||||||
|
{
|
||||||
|
slice
|
||||||
|
}
|
||||||
|
_ => annotation,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1000,8 +1003,7 @@ impl TopLevelComposer {
|
|||||||
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(t) = type_var_within
|
if let TypeAnnotation::TypeVarKind(t) = type_var_within {
|
||||||
{
|
|
||||||
if !class_type_vars_def.contains(&t) {
|
if !class_type_vars_def.contains(&t) {
|
||||||
return Err("class fields can only use type \
|
return Err("class fields can only use type \
|
||||||
vars declared as class generic type vars"
|
vars declared as class generic type vars"
|
||||||
@ -1011,14 +1013,13 @@ impl TopLevelComposer {
|
|||||||
unreachable!("must be type var annotation");
|
unreachable!("must be type var annotation");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
type_var_to_concrete_def
|
type_var_to_concrete_def.insert(dummy_field_type, annotation);
|
||||||
.insert(dummy_field_type, annotation);
|
|
||||||
} else {
|
} else {
|
||||||
return Err("same class fields defined twice".into());
|
return Err("same class fields defined twice".into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Err("unsupported statement type in class definition body".into())
|
return Err("unsupported statement type in class definition body".into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -1133,7 +1134,10 @@ impl TopLevelComposer {
|
|||||||
// is_override.insert(class_field_name.to_string());
|
// is_override.insert(class_field_name.to_string());
|
||||||
// to_be_added = (class_field_name.to_string(), *class_field_ty);
|
// to_be_added = (class_field_name.to_string(), *class_field_ty);
|
||||||
// break;
|
// break;
|
||||||
return Err(format!("field `{}` has already declared in the ancestor classes", class_field_name))
|
return Err(format!(
|
||||||
|
"field `{}` has already declared in the ancestor classes",
|
||||||
|
class_field_name
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
new_child_fields.push(to_be_added);
|
new_child_fields.push(to_be_added);
|
||||||
|
@ -777,7 +777,7 @@ fn test_analyze(source: Vec<&str>, res: Vec<&str>) {
|
|||||||
} else {
|
} else {
|
||||||
assert_eq!(res[0], msg);
|
assert_eq!(res[0], msg);
|
||||||
}
|
}
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -794,7 +794,7 @@ fn test_analyze(source: Vec<&str>, res: Vec<&str>) {
|
|||||||
// skip 5 to skip primitives
|
// skip 5 to skip primitives
|
||||||
for (i, (def, _)) in composer.definition_ast_list.iter().skip(5).enumerate() {
|
for (i, (def, _)) in composer.definition_ast_list.iter().skip(5).enumerate() {
|
||||||
let def = &*def.read();
|
let def = &*def.read();
|
||||||
|
|
||||||
if print {
|
if print {
|
||||||
println!(
|
println!(
|
||||||
"{}: {}\n",
|
"{}: {}\n",
|
||||||
|
@ -27,7 +27,7 @@ pub fn parse_ast_to_type_annotation_kinds<T>(
|
|||||||
primitives: &PrimitiveStore,
|
primitives: &PrimitiveStore,
|
||||||
expr: &ast::Expr<T>,
|
expr: &ast::Expr<T>,
|
||||||
// the key stores the type_var of this topleveldef::class, we only need this field here
|
// the key stores the type_var of this topleveldef::class, we only need this field here
|
||||||
mut locked: HashMap<DefinitionId, Vec<Type>>
|
mut locked: HashMap<DefinitionId, Vec<Type>>,
|
||||||
) -> Result<TypeAnnotation, String> {
|
) -> Result<TypeAnnotation, String> {
|
||||||
match &expr.node {
|
match &expr.node {
|
||||||
ast::ExprKind::Name { id, .. } => match id.as_str() {
|
ast::ExprKind::Name { id, .. } => match id.as_str() {
|
||||||
@ -80,7 +80,7 @@ pub fn parse_ast_to_type_annotation_kinds<T>(
|
|||||||
unifier,
|
unifier,
|
||||||
primitives,
|
primitives,
|
||||||
slice.as_ref(),
|
slice.as_ref(),
|
||||||
locked
|
locked,
|
||||||
)?;
|
)?;
|
||||||
if !matches!(def, TypeAnnotation::CustomClassKind { .. }) {
|
if !matches!(def, TypeAnnotation::CustomClassKind { .. }) {
|
||||||
unreachable!("must be concretized custom class kind in the virtual")
|
unreachable!("must be concretized custom class kind in the virtual")
|
||||||
@ -98,7 +98,7 @@ pub fn parse_ast_to_type_annotation_kinds<T>(
|
|||||||
unifier,
|
unifier,
|
||||||
primitives,
|
primitives,
|
||||||
slice.as_ref(),
|
slice.as_ref(),
|
||||||
locked
|
locked,
|
||||||
)?;
|
)?;
|
||||||
Ok(TypeAnnotation::ListKind(def_ann.into()))
|
Ok(TypeAnnotation::ListKind(def_ann.into()))
|
||||||
}
|
}
|
||||||
@ -117,7 +117,7 @@ pub fn parse_ast_to_type_annotation_kinds<T>(
|
|||||||
unifier,
|
unifier,
|
||||||
primitives,
|
primitives,
|
||||||
e,
|
e,
|
||||||
locked.clone()
|
locked.clone(),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
@ -174,7 +174,7 @@ pub fn parse_ast_to_type_annotation_kinds<T>(
|
|||||||
{
|
{
|
||||||
locked.insert(obj_id, type_vars.clone());
|
locked.insert(obj_id, type_vars.clone());
|
||||||
locked.clone()
|
locked.clone()
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
Loading…
Reference in New Issue
Block a user