fix: more test and issues with scoping/names
This commit is contained in:
@@ -241,6 +241,10 @@ impl TypedExpr {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn is_error_term(&self) -> bool {
|
||||
matches!(self, Self::ErrorTerm { .. })
|
||||
}
|
||||
|
||||
/// Returns `true` if the typed expr is [`Assignment`].
|
||||
pub fn is_assignment(&self) -> bool {
|
||||
matches!(self, Self::Assignment { .. })
|
||||
|
||||
@@ -318,19 +318,17 @@ fn mark_constructors_as_used_via_field_access() {
|
||||
bar: Int,
|
||||
}
|
||||
|
||||
validator foo {
|
||||
spend(d: Datum, _r, _c) {
|
||||
when d is {
|
||||
D0(params) -> params.foo == 1
|
||||
D1(_params) -> False
|
||||
}
|
||||
fn spend(d: Datum, _r, _c) {
|
||||
when d is {
|
||||
D0(params) -> params.foo == 1
|
||||
D1(_params) -> False
|
||||
}
|
||||
}
|
||||
"#;
|
||||
|
||||
let (warnings, _) = check_validator(parse(source_code)).unwrap();
|
||||
let (warnings, _) = check(parse(source_code)).unwrap();
|
||||
|
||||
assert_eq!(warnings.len(), 1)
|
||||
assert_eq!(warnings.len(), 2)
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -2506,27 +2504,6 @@ fn validator_public() {
|
||||
assert!(check_validator(parse(source_code)).is_ok())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn validator_private_everything() {
|
||||
let source_code = r#"
|
||||
type Datum {
|
||||
foo: Int,
|
||||
}
|
||||
|
||||
type Redeemer {
|
||||
bar: Int,
|
||||
}
|
||||
|
||||
validator bar {
|
||||
spend(datum: Datum, redeemer: Redeemer, _ctx) {
|
||||
datum.foo == redeemer.bar
|
||||
}
|
||||
}
|
||||
"#;
|
||||
|
||||
assert!(check_validator(parse(source_code)).is_ok())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tuple_access_on_call() {
|
||||
let source_code = r#"
|
||||
|
||||
@@ -309,29 +309,43 @@ impl<'a> Environment<'a> {
|
||||
end_position,
|
||||
handlers,
|
||||
name,
|
||||
fallback,
|
||||
mut fallback,
|
||||
location,
|
||||
params,
|
||||
}) => {
|
||||
let handlers = handlers
|
||||
.into_iter()
|
||||
.map(|fun| {
|
||||
let Definition::Fn(fun) =
|
||||
.map(|mut fun| {
|
||||
let handler_name = format!("{}_{}", &name, &fun.name);
|
||||
|
||||
let old_name = fun.name;
|
||||
fun.name = handler_name;
|
||||
|
||||
let Definition::Fn(mut fun) =
|
||||
self.generalise_definition(Definition::Fn(fun), module_name)
|
||||
else {
|
||||
unreachable!()
|
||||
};
|
||||
|
||||
fun.name = old_name;
|
||||
|
||||
fun
|
||||
})
|
||||
.collect();
|
||||
|
||||
let Definition::Fn(fallback) =
|
||||
let fallback_name = format!("{}_{}", &name, &fallback.name);
|
||||
|
||||
let old_name = fallback.name;
|
||||
fallback.name = fallback_name;
|
||||
|
||||
let Definition::Fn(mut fallback) =
|
||||
self.generalise_definition(Definition::Fn(fallback), module_name)
|
||||
else {
|
||||
unreachable!()
|
||||
};
|
||||
|
||||
fallback.name = old_name;
|
||||
|
||||
Definition::Validator(Validator {
|
||||
doc,
|
||||
name,
|
||||
|
||||
@@ -178,102 +178,117 @@ fn infer_definition(
|
||||
}) => {
|
||||
let params_length = params.len();
|
||||
|
||||
let mut typed_handlers = vec![];
|
||||
environment.in_new_scope(|environment| {
|
||||
let fallback_name = format!("{}_{}", &name, &fallback.name);
|
||||
|
||||
for mut handler in handlers {
|
||||
let typed_fun = environment.in_new_scope(|environment| {
|
||||
let temp_params = params.iter().cloned().chain(handler.arguments);
|
||||
handler.arguments = temp_params.collect();
|
||||
put_params_in_scope(&fallback_name, environment, ¶ms);
|
||||
|
||||
put_params_in_scope(&handler.name, environment, ¶ms);
|
||||
let mut typed_handlers = vec![];
|
||||
|
||||
let mut typed_fun =
|
||||
infer_function(&handler, module_name, hydrators, environment, tracing)?;
|
||||
for mut handler in handlers {
|
||||
let typed_fun = environment.in_new_scope(|environment| {
|
||||
let temp_params = params.iter().cloned().chain(handler.arguments);
|
||||
handler.arguments = temp_params.collect();
|
||||
|
||||
if !typed_fun.return_type.is_bool() {
|
||||
let handler_name = format!("{}_{}", &name, &handler.name);
|
||||
|
||||
let old_name = handler.name;
|
||||
handler.name = handler_name;
|
||||
|
||||
let mut typed_fun =
|
||||
infer_function(&handler, module_name, hydrators, environment, tracing)?;
|
||||
|
||||
typed_fun.name = old_name;
|
||||
|
||||
if !typed_fun.return_type.is_bool() {
|
||||
return Err(Error::ValidatorMustReturnBool {
|
||||
return_type: typed_fun.return_type.clone(),
|
||||
location: typed_fun.location,
|
||||
});
|
||||
}
|
||||
|
||||
typed_fun.arguments.drain(0..params_length);
|
||||
|
||||
// TODO: the expected number of args comes from the script purpose
|
||||
if typed_fun.arguments.len() < 2 || typed_fun.arguments.len() > 3 {
|
||||
return Err(Error::IncorrectValidatorArity {
|
||||
count: typed_fun.arguments.len() as u32,
|
||||
expected: 3,
|
||||
location: typed_fun.location,
|
||||
});
|
||||
}
|
||||
|
||||
for arg in typed_fun.arguments.iter_mut() {
|
||||
if arg.tipo.is_unbound() {
|
||||
arg.tipo = builtins::data();
|
||||
}
|
||||
}
|
||||
|
||||
Ok(typed_fun)
|
||||
})?;
|
||||
|
||||
typed_handlers.push(typed_fun);
|
||||
}
|
||||
|
||||
let (typed_params, typed_fallback) = environment.in_new_scope(|environment| {
|
||||
let temp_params = params.iter().cloned().chain(fallback.arguments);
|
||||
fallback.arguments = temp_params.collect();
|
||||
|
||||
let old_name = fallback.name;
|
||||
fallback.name = fallback_name;
|
||||
|
||||
let mut typed_fallback =
|
||||
infer_function(&fallback, module_name, hydrators, environment, tracing)?;
|
||||
|
||||
typed_fallback.name = old_name;
|
||||
|
||||
if !typed_fallback.body.is_error_term() && !typed_fallback.return_type.is_bool()
|
||||
{
|
||||
return Err(Error::ValidatorMustReturnBool {
|
||||
return_type: typed_fun.return_type.clone(),
|
||||
location: typed_fun.location,
|
||||
return_type: typed_fallback.return_type.clone(),
|
||||
location: typed_fallback.location,
|
||||
});
|
||||
}
|
||||
|
||||
typed_fun.arguments.drain(0..params_length);
|
||||
let typed_params = typed_fallback
|
||||
.arguments
|
||||
.drain(0..params_length)
|
||||
.map(|mut arg| {
|
||||
if arg.tipo.is_unbound() {
|
||||
arg.tipo = builtins::data();
|
||||
}
|
||||
|
||||
// TODO: the expected number of args comes from the script purpose
|
||||
if typed_fun.arguments.len() < 2 || typed_fun.arguments.len() > 3 {
|
||||
arg
|
||||
})
|
||||
.collect();
|
||||
|
||||
if typed_fallback.arguments.len() != 1 {
|
||||
return Err(Error::IncorrectValidatorArity {
|
||||
count: typed_fun.arguments.len() as u32,
|
||||
expected: 3,
|
||||
location: typed_fun.location,
|
||||
count: typed_fallback.arguments.len() as u32,
|
||||
expected: 1,
|
||||
location: typed_fallback.location,
|
||||
});
|
||||
}
|
||||
|
||||
for arg in typed_fun.arguments.iter_mut() {
|
||||
for arg in typed_fallback.arguments.iter_mut() {
|
||||
if arg.tipo.is_unbound() {
|
||||
arg.tipo = builtins::data();
|
||||
}
|
||||
}
|
||||
|
||||
Ok(typed_fun)
|
||||
Ok((typed_params, typed_fallback))
|
||||
})?;
|
||||
|
||||
typed_handlers.push(typed_fun);
|
||||
}
|
||||
|
||||
let (typed_params, typed_fallback) = environment.in_new_scope(|environment| {
|
||||
let temp_params = params.iter().cloned().chain(fallback.arguments);
|
||||
fallback.arguments = temp_params.collect();
|
||||
|
||||
put_params_in_scope(&fallback.name, environment, ¶ms);
|
||||
|
||||
let mut typed_fallback =
|
||||
infer_function(&fallback, module_name, hydrators, environment, tracing)?;
|
||||
|
||||
if !typed_fallback.return_type.is_bool() {
|
||||
return Err(Error::ValidatorMustReturnBool {
|
||||
return_type: typed_fallback.return_type.clone(),
|
||||
location: typed_fallback.location,
|
||||
});
|
||||
}
|
||||
|
||||
let typed_params = typed_fallback
|
||||
.arguments
|
||||
.drain(0..params_length)
|
||||
.map(|mut arg| {
|
||||
if arg.tipo.is_unbound() {
|
||||
arg.tipo = builtins::data();
|
||||
}
|
||||
|
||||
arg
|
||||
})
|
||||
.collect();
|
||||
|
||||
if typed_fallback.arguments.len() != 1 {
|
||||
return Err(Error::IncorrectValidatorArity {
|
||||
count: typed_fallback.arguments.len() as u32,
|
||||
expected: 1,
|
||||
location: typed_fallback.location,
|
||||
});
|
||||
}
|
||||
|
||||
for arg in typed_fallback.arguments.iter_mut() {
|
||||
if arg.tipo.is_unbound() {
|
||||
arg.tipo = builtins::data();
|
||||
}
|
||||
}
|
||||
|
||||
Ok((typed_params, typed_fallback))
|
||||
})?;
|
||||
|
||||
Ok(Definition::Validator(Validator {
|
||||
doc,
|
||||
end_position,
|
||||
handlers: typed_handlers,
|
||||
fallback: typed_fallback,
|
||||
name,
|
||||
location,
|
||||
params: typed_params,
|
||||
}))
|
||||
Ok(Definition::Validator(Validator {
|
||||
doc,
|
||||
end_position,
|
||||
handlers: typed_handlers,
|
||||
fallback: typed_fallback,
|
||||
name,
|
||||
location,
|
||||
params: typed_params,
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
Definition::Test(f) => {
|
||||
|
||||
Reference in New Issue
Block a user