Merge branch 'main' into always-typecheck-trace-label
This commit is contained in:
commit
9354a5bad4
|
@ -6,6 +6,7 @@
|
|||
|
||||
- **aiken**: New `-S` flag on `check` and `build` that blocks the printing of warnings but it still shows the total warning count. @rvcas
|
||||
- **aiken-lang**: Allow types to be used as namespaces for constructors. Importing each constructor variants independently is no longer required in neither pattern-matches nor value construction. One can simply use the type name as a prefix/namespace now. @KtorZ
|
||||
- **aiken-lang**: Allow capture on constructor calls. @KtorZ
|
||||
|
||||
### Changed
|
||||
|
||||
|
@ -14,12 +15,10 @@
|
|||
- **aiken-lang**: Disallow (parse error) dangling colon `:` in traces. See [#1113](https://github.com/aiken-lang/aiken/issues/1113). @KtorZ
|
||||
- **aiken-lang**: Fix `aiken blueprint apply` wrongly overriding all validators handlers names & ABI to the mint's one. See [#1099](https://github.com/aiken-lang/aiken/issues/1099). @KtorZ
|
||||
- **aiken-lang**: Always type-check trace label irrespective of the trace level, to avoid unnecessary warnings in compact or silent mode. See [#1122](https://github.com/aiken-lang/aiken/issues/1122). @KtorZ
|
||||
|
||||
### Fixed
|
||||
|
||||
- **aiken-lang**: Formatter was removing comments from function type annotation args @rvcas
|
||||
- **aiken-lang**: Parser wrongly merged two adjacent sequences together, effectively fusioning scopes. @KtorZ
|
||||
- **aiken-lang**: Fix hint when suggesting to use named fields, wrongly suggesting args in lexicographical order instead of definition order. @KtorZ
|
||||
- **aiken-project**: Better errors on `blueprint apply` when matching multiple or no validators. See [#1127](https://github.com/aiken-lang/aiken/issues/1127) @KtorZ
|
||||
|
||||
## v1.1.13 - 2025-02-26
|
||||
|
||||
|
|
|
@ -29,24 +29,16 @@ pub fn parser(
|
|||
.then_ignore(just(Token::Colon))
|
||||
.then(choice((
|
||||
r.clone(),
|
||||
select! {Token::DiscardName {name} => name }.validate(
|
||||
|_name, span, emit| {
|
||||
emit(ParseError::expected_input_found(
|
||||
span,
|
||||
None,
|
||||
Some(error::Pattern::Discard),
|
||||
));
|
||||
|
||||
UntypedExpr::Var {
|
||||
location: span,
|
||||
name: ast::CAPTURE_VARIABLE.to_string(),
|
||||
}
|
||||
choice((select! {Token::DiscardName {name} => name }.map_with_span(
|
||||
|name, span| UntypedExpr::Var {
|
||||
location: span,
|
||||
name,
|
||||
},
|
||||
),
|
||||
),)),
|
||||
)))
|
||||
.map_with_span(|(label, value), span| ast::CallArg {
|
||||
location: span,
|
||||
value,
|
||||
value: Some(value),
|
||||
label: Some(label),
|
||||
}),
|
||||
choice((
|
||||
|
@ -111,7 +103,7 @@ pub fn parser(
|
|||
)
|
||||
.map(|(value, name)| ast::CallArg {
|
||||
location: value.location(),
|
||||
value,
|
||||
value: Some(value),
|
||||
label: Some(name),
|
||||
}),
|
||||
))
|
||||
|
@ -144,24 +136,16 @@ pub fn parser(
|
|||
.or_not()
|
||||
.then(choice((
|
||||
r.clone(),
|
||||
select! {Token::DiscardName {name} => name }.validate(
|
||||
|_name, span, emit| {
|
||||
emit(ParseError::expected_input_found(
|
||||
span,
|
||||
None,
|
||||
Some(error::Pattern::Discard),
|
||||
));
|
||||
|
||||
UntypedExpr::Var {
|
||||
location: span,
|
||||
name: ast::CAPTURE_VARIABLE.to_string(),
|
||||
}
|
||||
},
|
||||
),
|
||||
select! {Token::DiscardName {name} => name }.map_with_span(|name, span| {
|
||||
UntypedExpr::Var {
|
||||
location: span,
|
||||
name,
|
||||
}
|
||||
}),
|
||||
)))
|
||||
.map(|(_label, value)| ast::CallArg {
|
||||
location: value.location(),
|
||||
value,
|
||||
value: Some(value),
|
||||
label: None,
|
||||
})
|
||||
.separated_by(just(Token::Comma))
|
||||
|
@ -208,11 +192,7 @@ pub fn parser(
|
|||
},
|
||||
};
|
||||
|
||||
UntypedExpr::Call {
|
||||
arguments,
|
||||
fun: Box::new(fun),
|
||||
location: span,
|
||||
}
|
||||
fun.call(arguments, span)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ use aiken_lang::gen_uplc::CodeGenerator;
|
|||
use definitions::Definitions;
|
||||
pub use error::Error;
|
||||
use schema::{Annotated, Schema};
|
||||
use std::fmt::Debug;
|
||||
use std::{collections::BTreeSet, fmt::Debug};
|
||||
use validator::Validator;
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize)]
|
||||
|
@ -99,15 +99,7 @@ impl Blueprint {
|
|||
let mut validator = None;
|
||||
|
||||
for v in self.validators.iter() {
|
||||
let mut split = v.title.split('.');
|
||||
|
||||
let known_module_name = split
|
||||
.next()
|
||||
.expect("validator's name must have two dot-separated components.");
|
||||
|
||||
let known_validator_name = split
|
||||
.next()
|
||||
.expect("validator's name must have two dot-separated components.");
|
||||
let (known_module_name, known_validator_name) = v.get_module_and_name();
|
||||
|
||||
let is_target = match (want_module_name, want_validator_name) {
|
||||
(None, None) => true,
|
||||
|
@ -143,8 +135,8 @@ impl Blueprint {
|
|||
&self,
|
||||
module_name: Option<&str>,
|
||||
validator_name: Option<&str>,
|
||||
when_too_many: fn(Vec<String>) -> E,
|
||||
when_missing: fn(Vec<String>) -> E,
|
||||
when_too_many: fn(BTreeSet<(String, String, bool)>) -> E,
|
||||
when_missing: fn(BTreeSet<(String, String, bool)>) -> E,
|
||||
action: F,
|
||||
) -> Result<A, E>
|
||||
where
|
||||
|
@ -153,10 +145,35 @@ impl Blueprint {
|
|||
match self.lookup(module_name, validator_name) {
|
||||
Some(LookupResult::One(_, validator)) => action(validator),
|
||||
Some(LookupResult::Many) => Err(when_too_many(
|
||||
self.validators.iter().map(|v| v.title.clone()).collect(),
|
||||
self.validators
|
||||
.iter()
|
||||
.filter_map(|v| {
|
||||
let (l, r) = v.get_module_and_name();
|
||||
|
||||
if let Some(module_name) = module_name {
|
||||
if l != module_name {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(validator_name) = validator_name {
|
||||
if r != validator_name {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
Some((l.to_string(), r.to_string(), !v.parameters.is_empty()))
|
||||
})
|
||||
.collect(),
|
||||
)),
|
||||
None => Err(when_missing(
|
||||
self.validators.iter().map(|v| v.title.clone()).collect(),
|
||||
self.validators
|
||||
.iter()
|
||||
.map(|v| {
|
||||
let (l, r) = v.get_module_and_name();
|
||||
(l.to_string(), r.to_string(), !v.parameters.is_empty())
|
||||
})
|
||||
.collect(),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,6 +46,20 @@ pub struct Validator {
|
|||
}
|
||||
|
||||
impl Validator {
|
||||
pub fn get_module_and_name(&self) -> (&str, &str) {
|
||||
let mut split = self.title.split('.');
|
||||
|
||||
let known_module_name = split
|
||||
.next()
|
||||
.expect("validator's name must have two dot-separated components.");
|
||||
|
||||
let known_validator_name = split
|
||||
.next()
|
||||
.expect("validator's name must have two dot-separated components.");
|
||||
|
||||
(known_module_name, known_validator_name)
|
||||
}
|
||||
|
||||
pub fn from_checked_module(
|
||||
modules: &CheckedModules,
|
||||
generator: &mut CodeGenerator,
|
||||
|
|
|
@ -15,6 +15,7 @@ use owo_colors::{
|
|||
Stream::{Stderr, Stdout},
|
||||
};
|
||||
use std::{
|
||||
collections::BTreeSet,
|
||||
fmt::{self, Debug, Display},
|
||||
io,
|
||||
path::{Path, PathBuf},
|
||||
|
@ -137,10 +138,14 @@ pub enum Error {
|
|||
},
|
||||
|
||||
#[error("I didn't find any validator matching your criteria.")]
|
||||
NoValidatorNotFound { known_validators: Vec<String> },
|
||||
NoValidatorNotFound {
|
||||
known_validators: BTreeSet<(String, String, bool)>,
|
||||
},
|
||||
|
||||
#[error("I found multiple suitable validators and I need you to tell me which one to pick.")]
|
||||
MoreThanOneValidatorFound { known_validators: Vec<String> },
|
||||
MoreThanOneValidatorFound {
|
||||
known_validators: BTreeSet<(String, String, bool)>,
|
||||
},
|
||||
|
||||
#[error("I couldn't find any exportable function named '{name}' in module '{module}'.")]
|
||||
ExportNotFound { module: String, name: String },
|
||||
|
@ -423,27 +428,13 @@ impl Diagnostic for Error {
|
|||
None => String::new(),
|
||||
}
|
||||
))),
|
||||
Error::NoValidatorNotFound { known_validators } => Some(Box::new(format!(
|
||||
"Here's a list of all validators I've found in your project. Please double-check this list against the options that you've provided:\n\n{}",
|
||||
known_validators
|
||||
.iter()
|
||||
.map(|title| format!(
|
||||
"→ {title}",
|
||||
title = title.if_supports_color(Stdout, |s| s.purple())
|
||||
))
|
||||
.collect::<Vec<String>>()
|
||||
.join("\n")
|
||||
Error::NoValidatorNotFound { known_validators } => Some(Box::new(hint_validators(
|
||||
known_validators,
|
||||
"Here's a list of all validators I've found in your project.\nPlease double-check this list against the options that you've provided."
|
||||
))),
|
||||
Error::MoreThanOneValidatorFound { known_validators } => Some(Box::new(format!(
|
||||
"Here's a list of all validators I've found in your project. Select one of them using the appropriate options:\n\n{}",
|
||||
known_validators
|
||||
.iter()
|
||||
.map(|title| format!(
|
||||
"→ {title}",
|
||||
title = title.if_supports_color(Stdout, |s| s.purple())
|
||||
))
|
||||
.collect::<Vec<String>>()
|
||||
.join("\n")
|
||||
Error::MoreThanOneValidatorFound { known_validators } => Some(Box::new(hint_validators(
|
||||
known_validators,
|
||||
"Here's a list of matching validators I've found in your project.\nPlease narrow the selection using additional options.",
|
||||
))),
|
||||
Error::Module(e) => e.help(),
|
||||
}
|
||||
|
@ -809,3 +800,53 @@ fn default_miette_handler(context_lines: usize) -> MietteHandler {
|
|||
.context_lines(context_lines)
|
||||
.build()
|
||||
}
|
||||
|
||||
fn hint_validators(known_validators: &BTreeSet<(String, String, bool)>, hint: &str) -> String {
|
||||
let (pad_module, pad_validator) = known_validators.iter().fold(
|
||||
(9, 12),
|
||||
|(module_len, validator_len), (module, validator, _)| {
|
||||
(
|
||||
module_len.max(module.len()),
|
||||
validator_len.max(validator.len()),
|
||||
)
|
||||
},
|
||||
);
|
||||
|
||||
format!(
|
||||
"{hint}\n\n\
|
||||
{:<pad_module$} {:<pad_validator$}\n\
|
||||
{:─<pad_module$}┒ ┎{:─<pad_validator$}\n\
|
||||
{}\n\nFor convenience, I have highlighted in {bold_green} suitable candidates that {has_params}.",
|
||||
"module(s)",
|
||||
"validator(s)",
|
||||
"─",
|
||||
"─",
|
||||
{
|
||||
known_validators
|
||||
.iter()
|
||||
.map(|(module, validator, has_params)| {
|
||||
let title = format!(
|
||||
"{:>pad_module$} . {:<pad_validator$}",
|
||||
module,
|
||||
validator,
|
||||
);
|
||||
if *has_params {
|
||||
title
|
||||
.if_supports_color(Stderr, |s| s.bold())
|
||||
.if_supports_color(Stderr, |s| s.green())
|
||||
.to_string()
|
||||
} else {
|
||||
title
|
||||
}
|
||||
})
|
||||
.collect::<Vec<String>>()
|
||||
.join("\n")
|
||||
},
|
||||
bold_green = "bold green"
|
||||
.if_supports_color(Stderr, |s| s.bold())
|
||||
.if_supports_color(Stderr, |s| s.green()),
|
||||
has_params = "can take parameters"
|
||||
.if_supports_color(Stderr, |s| s.bold())
|
||||
.if_supports_color(Stderr, |s| s.green()),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
name = "aiken-lang/121"
|
||||
version = "0.0.0"
|
||||
license = "Apache-2.0"
|
||||
description = "Aiken contracts for project 'aiken-lang/121'"
|
||||
|
||||
[repository]
|
||||
user = "aiken-lang"
|
||||
project = "121"
|
||||
platform = "github"
|
|
@ -0,0 +1,34 @@
|
|||
pub type Foo {
|
||||
i: Int,
|
||||
b: Bool,
|
||||
}
|
||||
|
||||
const give_i: fn(Int) -> Foo = Foo { i: _, b: True }
|
||||
|
||||
const give_b: fn(Bool) -> Foo = Foo(1337, _)
|
||||
|
||||
fn foo_i(i: Int) -> fn(Bool) -> Foo {
|
||||
Foo { i: i, b: _bool }
|
||||
}
|
||||
|
||||
fn foo_b(b: Bool) -> fn(Int) -> Foo {
|
||||
Foo(_, b)
|
||||
}
|
||||
|
||||
test test_1() {
|
||||
let bar = foo_i(14)
|
||||
and {
|
||||
foo_i(42)(True) == Foo(42, True),
|
||||
bar(False) == Foo { i: 14, b: False },
|
||||
give_i(1337) == Foo { i: 1337, b: True },
|
||||
}
|
||||
}
|
||||
|
||||
test test_2() {
|
||||
let bar = foo_b(False)
|
||||
and {
|
||||
foo_b(True)(42) == Foo(42, True),
|
||||
bar(14) == Foo { i: 14, b: False },
|
||||
give_b(False) == Foo { i: 1337, b: False },
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue