feat: new check for valid purpose names
This commit is contained in:
parent
5cf0a4d294
commit
c2c4bddfb3
|
@ -277,6 +277,15 @@ impl TypedFunction {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn has_valid_purpose_name(&self) -> bool {
|
||||
self.name == PURPOSE_SPEND
|
||||
|| self.name == PURPOSE_PUBLISH
|
||||
|| self.name == PURPOSE_PROPOSE
|
||||
|| self.name == PURPOSE_MINT
|
||||
|| self.name == PURPOSE_WITHDRAW
|
||||
|| self.name == PURPOSE_VOTE
|
||||
}
|
||||
|
||||
pub fn validator_arity(&self) -> usize {
|
||||
if self.name == PURPOSE_SPEND
|
||||
|| self.name == PURPOSE_PUBLISH
|
||||
|
@ -628,6 +637,17 @@ pub struct Validator<T, Arg, Expr> {
|
|||
}
|
||||
|
||||
impl TypedValidator {
|
||||
pub fn available_purposes() -> Vec<String> {
|
||||
vec![
|
||||
PURPOSE_SPEND.to_string(),
|
||||
PURPOSE_MINT.to_string(),
|
||||
PURPOSE_WITHDRAW.to_string(),
|
||||
PURPOSE_PUBLISH.to_string(),
|
||||
PURPOSE_VOTE.to_string(),
|
||||
PURPOSE_PROPOSE.to_string(),
|
||||
]
|
||||
}
|
||||
|
||||
pub fn find_node(&self, byte_index: usize) -> Option<Located<'_>> {
|
||||
self.params
|
||||
.iter()
|
||||
|
|
|
@ -54,7 +54,7 @@ Validator(
|
|||
name: "True",
|
||||
},
|
||||
doc: None,
|
||||
location: 26..44,
|
||||
location: 20..44,
|
||||
name: "spend",
|
||||
public: true,
|
||||
return_annotation: None,
|
||||
|
@ -96,7 +96,7 @@ Validator(
|
|||
name: "True",
|
||||
},
|
||||
doc: None,
|
||||
location: 68..79,
|
||||
location: 63..79,
|
||||
name: "mint",
|
||||
public: true,
|
||||
return_annotation: None,
|
||||
|
|
|
@ -54,7 +54,7 @@ Validator(
|
|||
name: "True",
|
||||
},
|
||||
doc: None,
|
||||
location: 26..44,
|
||||
location: 20..44,
|
||||
name: "spend",
|
||||
public: true,
|
||||
return_annotation: None,
|
||||
|
@ -96,7 +96,7 @@ Validator(
|
|||
name: "True",
|
||||
},
|
||||
doc: None,
|
||||
location: 68..79,
|
||||
location: 63..79,
|
||||
name: "mint",
|
||||
public: true,
|
||||
return_annotation: None,
|
||||
|
|
|
@ -54,7 +54,7 @@ Validator(
|
|||
name: "True",
|
||||
},
|
||||
doc: None,
|
||||
location: 26..44,
|
||||
location: 20..44,
|
||||
name: "spend",
|
||||
public: true,
|
||||
return_annotation: None,
|
||||
|
|
|
@ -23,16 +23,18 @@ pub fn parser() -> impl Parser<Token, ast::UntypedDefinition, Error = ParseError
|
|||
.then(
|
||||
select! {Token::Name {name} => name}
|
||||
.then(args_and_body())
|
||||
.map(|(name, mut function)| {
|
||||
.map_with_span(|(name, mut function), span| {
|
||||
function.name = name;
|
||||
function.location.start = span.start;
|
||||
|
||||
function
|
||||
})
|
||||
.repeated()
|
||||
.then(
|
||||
just(Token::Else)
|
||||
.ignore_then(args_and_body().map(|mut function| {
|
||||
.ignore_then(args_and_body().map_with_span(|mut function, span| {
|
||||
function.name = "else".to_string();
|
||||
function.location.start = span.start;
|
||||
|
||||
function
|
||||
}))
|
||||
|
|
|
@ -8,6 +8,7 @@ use crate::{
|
|||
pretty::Documentable,
|
||||
};
|
||||
use indoc::formatdoc;
|
||||
use itertools::Itertools;
|
||||
use miette::{Diagnostic, LabeledSpan};
|
||||
use ordinal::Ordinal;
|
||||
use owo_colors::{
|
||||
|
@ -1070,6 +1071,21 @@ The best thing to do from here is to remove it."#))]
|
|||
function: UntypedFunction,
|
||||
location: Span,
|
||||
},
|
||||
|
||||
#[error("I found a validator handler referring to an unknown purpose.\n")]
|
||||
#[diagnostic(code("unknown::purpose"))]
|
||||
#[diagnostic(help(
|
||||
"Handler must be named after a known purpose. Here is a list of available purposes:\n{}",
|
||||
available_purposes
|
||||
.iter()
|
||||
.map(|p| format!("-> {}", p.if_supports_color(Stdout, |s| s.green())))
|
||||
.join("\n")
|
||||
))]
|
||||
UnknownPurpose {
|
||||
#[label("unknown purpose")]
|
||||
location: Span,
|
||||
available_purposes: Vec<String>,
|
||||
},
|
||||
}
|
||||
|
||||
impl ExtraData for Error {
|
||||
|
@ -1129,6 +1145,7 @@ impl ExtraData for Error {
|
|||
| Error::UnexpectedMultiPatternAssignment { .. }
|
||||
| Error::ExpectOnOpaqueType { .. }
|
||||
| Error::ValidatorMustReturnBool { .. }
|
||||
| Error::UnknownPurpose { .. }
|
||||
| Error::MustInferFirst { .. } => None,
|
||||
|
||||
Error::UnknownType { name, .. }
|
||||
|
|
|
@ -9,7 +9,7 @@ use crate::{
|
|||
ast::{
|
||||
Annotation, ArgName, ArgVia, DataType, Definition, Function, ModuleConstant, ModuleKind,
|
||||
RecordConstructor, RecordConstructorArg, Tracing, TypeAlias, TypedArg, TypedDefinition,
|
||||
TypedModule, UntypedArg, UntypedDefinition, UntypedModule, Use, Validator,
|
||||
TypedModule, TypedValidator, UntypedArg, UntypedDefinition, UntypedModule, Use, Validator,
|
||||
},
|
||||
builtins::{self, fuzzer, generic_var},
|
||||
tipo::{expr::infer_function, Span, Type, TypeVar},
|
||||
|
@ -209,7 +209,15 @@ fn infer_definition(
|
|||
|
||||
typed_fun.arguments.drain(0..params_length);
|
||||
|
||||
// TODO: the expected number of args comes from the script purpose
|
||||
if !typed_fun.has_valid_purpose_name() {
|
||||
return Err(Error::UnknownPurpose {
|
||||
location: typed_fun
|
||||
.location
|
||||
.map(|start, _end| (start, start + typed_fun.name.len())),
|
||||
available_purposes: TypedValidator::available_purposes(),
|
||||
});
|
||||
}
|
||||
|
||||
if typed_fun.arguments.len() != typed_fun.validator_arity() {
|
||||
return Err(Error::IncorrectValidatorArity {
|
||||
count: typed_fun.arguments.len() as u32,
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
---
|
||||
source: crates/aiken-project/src/blueprint/validator.rs
|
||||
description: "Code:\n\nvalidator {\n fn mint(redeemer: Data, ctx: Data) {\n True\n }\n}\n// "
|
||||
description: "Code:\n\nvalidator thing {\n mint(redeemer: Data, policy_id: Data, transaction: Data) {\n True\n }\n}\n// "
|
||||
---
|
||||
{
|
||||
"title": "test_module.mint",
|
||||
"title": "test_module.thing_mint",
|
||||
"redeemer": {
|
||||
"title": "redeemer",
|
||||
"schema": {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
source: crates/aiken-project/src/blueprint/validator.rs
|
||||
description: "Code:\n\npub opaque type Rational {\n numerator: Int,\n denominator: Int,\n}\n\nvalidator {\n fn opaque_singleton_multi_variants(redeemer: Rational, ctx: Void) {\n True\n }\n}\n"
|
||||
description: "Code:\n\npub opaque type Rational {\n numerator: Int,\n denominator: Int,\n}\n\nvalidator opaque_singleton_multi_variants {\n spend(redeemer: Rational, oref: Data, ctx: Void) {\n True\n }\n}\n"
|
||||
---
|
||||
Schema {
|
||||
error: Error {
|
||||
|
@ -16,7 +16,7 @@ Schema {
|
|||
},
|
||||
],
|
||||
},
|
||||
location: 117..135,
|
||||
location: 120..138,
|
||||
source_code: NamedSource {
|
||||
name: "",
|
||||
source: "<redacted>",
|
||||
|
|
Loading…
Reference in New Issue