feat(register_values): refactor repeated code into register_function and register other_fun

This commit is contained in:
rvcas 2023-03-16 21:30:20 -04:00
parent 15bdb6972d
commit 87493bbba9
No known key found for this signature in database
GPG Key ID: C09B64E263F7D68C
1 changed files with 104 additions and 100 deletions

View File

@ -10,7 +10,7 @@ use crate::{
ast::{ ast::{
Annotation, CallArg, DataType, Definition, Function, ModuleConstant, ModuleKind, Pattern, Annotation, CallArg, DataType, Definition, Function, ModuleConstant, ModuleKind, Pattern,
RecordConstructor, RecordConstructorArg, Span, TypeAlias, TypedDefinition, RecordConstructor, RecordConstructorArg, Span, TypeAlias, TypedDefinition,
UnqualifiedImport, UntypedDefinition, Use, Validator, PIPE_VARIABLE, UnqualifiedImport, UntypedArg, UntypedDefinition, Use, Validator, PIPE_VARIABLE,
}, },
builtins::{self, function, generic_var, tuple, unbound_var}, builtins::{self, function, generic_var, tuple, unbound_var},
tipo::fields::FieldMap, tipo::fields::FieldMap,
@ -1007,31 +1007,25 @@ impl<'a> Environment<'a> {
Ok(()) Ok(())
} }
pub fn register_values( #[allow(clippy::too_many_arguments)]
fn register_function(
&mut self, &mut self,
def: &'a UntypedDefinition, name: &'a str,
arguments: &[UntypedArg],
return_annotation: &Option<Annotation>,
module_name: &String, module_name: &String,
hydrators: &mut HashMap<String, Hydrator>, hydrators: &mut HashMap<String, Hydrator>,
names: &mut HashMap<&'a str, &'a Span>, names: &mut HashMap<&'a str, &'a Span>,
kind: ModuleKind, location: &'a Span,
) -> Result<(), Error> { ) -> Result<(), Error> {
match def {
Definition::Fn(Function {
name,
arguments: args,
location,
return_annotation,
public,
..
}) => {
assert_unique_value_name(names, name, location)?; assert_unique_value_name(names, name, location)?;
self.ungeneralised_functions.insert(name.to_string()); self.ungeneralised_functions.insert(name.to_string());
// Create the field map so we can reorder labels for usage of this function // Create the field map so we can reorder labels for usage of this function
let mut field_map = FieldMap::new(args.len(), true); let mut field_map = FieldMap::new(arguments.len(), true);
for (i, arg) in args.iter().enumerate() { for (i, arg) in arguments.iter().enumerate() {
field_map.insert(arg.arg_name.get_label().clone(), i, &arg.location)?; field_map.insert(arg.arg_name.get_label().clone(), i, &arg.location)?;
} }
let field_map = field_map.into_option(); let field_map = field_map.into_option();
@ -1041,7 +1035,7 @@ impl<'a> Environment<'a> {
let mut arg_types = Vec::new(); let mut arg_types = Vec::new();
for arg in args { for arg in arguments {
let tipo = hydrator.type_from_option_annotation(&arg.annotation, self)?; let tipo = hydrator.type_from_option_annotation(&arg.annotation, self)?;
arg_types.push(tipo); arg_types.push(tipo);
@ -1054,79 +1048,89 @@ impl<'a> Environment<'a> {
// Keep track of which types we create from annotations so we can know // Keep track of which types we create from annotations so we can know
// which generic types not to instantiate later when performing // which generic types not to instantiate later when performing
// inference of the function body. // inference of the function body.
hydrators.insert(name.clone(), hydrator); hydrators.insert(name.to_string(), hydrator);
// Insert the function into the environment // Insert the function into the environment
self.insert_variable( self.insert_variable(
name.clone(), name.to_string(),
ValueConstructorVariant::ModuleFn { ValueConstructorVariant::ModuleFn {
name: name.clone(), name: name.to_string(),
field_map, field_map,
module: module_name.to_owned(), module: module_name.to_owned(),
arity: args.len(), arity: arguments.len(),
location: *location, location: *location,
builtin: None, builtin: None,
}, },
tipo, tipo,
); );
if !public && kind.is_lib() { Ok(())
self.init_usage(name.clone(), EntityKind::PrivateFunction, *location); }
pub fn register_values(
&mut self,
def: &'a UntypedDefinition,
module_name: &String,
hydrators: &mut HashMap<String, Hydrator>,
names: &mut HashMap<&'a str, &'a Span>,
kind: ModuleKind,
) -> Result<(), Error> {
match def {
Definition::Fn(fun) => {
self.register_function(
&fun.name,
&fun.arguments,
&fun.return_annotation,
module_name,
hydrators,
names,
&fun.location,
)?;
if !fun.public && kind.is_lib() {
self.init_usage(fun.name.clone(), EntityKind::PrivateFunction, fun.location);
} }
} }
Definition::Validator(Validator { Definition::Validator(Validator {
fun, fun,
location, other_fun,
params, params,
.. ..
}) if kind.is_validator() => { }) if kind.is_validator() => {
assert_unique_value_name(names, &fun.name, location)?; let temp_params: Vec<UntypedArg> = params
.iter()
.cloned()
.chain(fun.arguments.clone())
.collect();
// Create the field map so we can reorder labels for usage of this function self.register_function(
let mut field_map = FieldMap::new(fun.arguments.len() + params.len(), true); &fun.name,
&temp_params,
&fun.return_annotation,
module_name,
hydrators,
names,
&fun.location,
)?;
// Chain together extra params and function.arguments if let Some(other) = other_fun {
for (i, arg) in params.iter().chain(fun.arguments.iter()).enumerate() { let temp_params: Vec<UntypedArg> = params
field_map.insert(arg.arg_name.get_label().clone(), i, &arg.location)?; .iter()
.cloned()
.chain(other.arguments.clone())
.collect();
self.register_function(
&other.name,
&temp_params,
&other.return_annotation,
module_name,
hydrators,
names,
&other.location,
)?;
} }
let field_map = field_map.into_option();
// Construct type from annotations
let mut hydrator = Hydrator::new();
let mut arg_types = Vec::new();
for arg in params.iter().chain(fun.arguments.iter()) {
let tipo = hydrator.type_from_option_annotation(&arg.annotation, self)?;
arg_types.push(tipo);
}
let return_type =
hydrator.type_from_option_annotation(&fun.return_annotation, self)?;
let tipo = function(arg_types, return_type);
// Keep track of which types we create from annotations so we can know
// which generic types not to instantiate later when performing
// inference of the function body.
hydrators.insert(fun.name.clone(), hydrator);
// Insert the function into the environment
self.insert_variable(
fun.name.clone(),
ValueConstructorVariant::ModuleFn {
name: fun.name.clone(),
field_map,
module: module_name.to_owned(),
arity: params.len() + fun.arguments.len(),
location: fun.location,
builtin: None,
},
tipo,
);
} }
Definition::Validator(Validator { location, .. }) => { Definition::Validator(Validator { location, .. }) => {