From 1134b8d7d031e046cdbff33681ae7a3e9a31ba26 Mon Sep 17 00:00:00 2001 From: KtorZ Date: Sun, 3 Mar 2024 18:26:37 +0100 Subject: [PATCH] Register tests as callable definitions. Also move the registering of validators into the same place as they other and define a little cute function to avoid code-duplication. --- crates/aiken-lang/src/ast.rs | 61 +++++++++++++++++++++-- crates/aiken-project/src/lib.rs | 86 ++++++++++----------------------- 2 files changed, 81 insertions(+), 66 deletions(-) diff --git a/crates/aiken-lang/src/ast.rs b/crates/aiken-lang/src/ast.rs index f9bb790c..49a6848c 100644 --- a/crates/aiken-lang/src/ast.rs +++ b/crates/aiken-lang/src/ast.rs @@ -148,6 +148,16 @@ impl TypedModule { ); } + Definition::Test(test) => { + functions.insert( + FunctionAccessKey { + module_name: self.name.clone(), + function_name: test.name.clone(), + }, + test.clone().into(), + ); + } + Definition::DataType(dt) => { data_types.insert( DataTypeKey { @@ -158,11 +168,19 @@ impl TypedModule { ); } - Definition::TypeAlias(_) - | Definition::ModuleConstant(_) - | Definition::Test(_) - | Definition::Validator(_) - | Definition::Use(_) => {} + Definition::Validator(v) => { + let module_name = self.name.as_str(); + + if let Some((k, v)) = v.into_function_definition(module_name, |f, _| Some(f)) { + functions.insert(k, v); + } + + if let Some((k, v)) = v.into_function_definition(module_name, |_, f| f) { + functions.insert(k, v); + } + } + + Definition::TypeAlias(_) | Definition::ModuleConstant(_) | Definition::Use(_) => {} } } } @@ -513,6 +531,39 @@ pub struct Validator { pub params: Vec>, } +impl TypedValidator { + pub fn into_function_definition<'a, F>( + &'a self, + module_name: &str, + select: F, + ) -> Option<(FunctionAccessKey, TypedFunction)> + where + F: Fn(&'a TypedFunction, Option<&'a TypedFunction>) -> Option<&'a TypedFunction> + 'a, + { + match select(&self.fun, self.other_fun.as_ref()) { + None => None, + Some(fun) => { + let mut fun = fun.clone(); + + fun.arguments = self + .params + .clone() + .into_iter() + .chain(fun.arguments) + .collect(); + + Some(( + FunctionAccessKey { + module_name: module_name.to_string(), + function_name: fun.name.clone(), + }, + fun, + )) + } + } + } +} + pub type TypedDefinition = Definition, TypedExpr, String>; pub type UntypedDefinition = Definition<(), UntypedExpr, ()>; diff --git a/crates/aiken-project/src/lib.rs b/crates/aiken-project/src/lib.rs index 9df43d35..70d51a0f 100644 --- a/crates/aiken-project/src/lib.rs +++ b/crates/aiken-project/src/lib.rs @@ -32,7 +32,7 @@ use crate::{ use aiken_lang::{ ast::{ DataTypeKey, Definition, FunctionAccessKey, ModuleKind, Tracing, TypedDataType, - TypedFunction, Validator, + TypedFunction, }, builtins, expr::UntypedExpr, @@ -725,76 +725,40 @@ where } for def in checked_module.ast.definitions() { - match def { - Definition::Validator(Validator { - params, - fun, - other_fun, - .. - }) => { - let mut fun = fun.clone(); + if let Definition::Test(func) = def { + if let Some(match_tests) = &match_tests { + let is_match = match_tests.iter().any(|(module, names)| { + let matched_module = + module.is_empty() || checked_module.name.contains(module); - fun.arguments = params.clone().into_iter().chain(fun.arguments).collect(); + let matched_name = match names { + None => true, + Some(names) => names.iter().any(|name| { + if exact_match { + name == &func.name + } else { + func.name.contains(name) + } + }), + }; - self.functions.insert( - FunctionAccessKey { - module_name: checked_module.name.clone(), - function_name: fun.name.clone(), - }, - fun.to_owned(), - ); + matched_module && matched_name + }); - if let Some(other) = other_fun { - let mut other = other.clone(); - - other.arguments = - params.clone().into_iter().chain(other.arguments).collect(); - - self.functions.insert( - FunctionAccessKey { - module_name: checked_module.name.clone(), - function_name: other.name.clone(), - }, - other.to_owned(), - ); - } - } - Definition::Test(func) => { - if let Some(match_tests) = &match_tests { - let is_match = match_tests.iter().any(|(module, names)| { - let matched_module = - module.is_empty() || checked_module.name.contains(module); - - let matched_name = match names { - None => true, - Some(names) => names.iter().any(|name| { - if exact_match { - name == &func.name - } else { - func.name.contains(name) - } - }), - }; - - matched_module && matched_name - }); - - if is_match { - scripts.push(( - checked_module.input_path.clone(), - checked_module.name.clone(), - func, - )) - } - } else { + if is_match { scripts.push(( checked_module.input_path.clone(), checked_module.name.clone(), func, )) } + } else { + scripts.push(( + checked_module.input_path.clone(), + checked_module.name.clone(), + func, + )) } - _ => (), } } }