feat(register_values): refactor repeated code into register_function and register other_fun
This commit is contained in:
parent
15bdb6972d
commit
87493bbba9
|
@ -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, .. }) => {
|
||||||
|
|
Loading…
Reference in New Issue