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**: 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 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
|
### 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**: 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**: 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
|
- **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**: 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**: 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-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
|
## v1.1.13 - 2025-02-26
|
||||||
|
|
||||||
|
|
|
@ -29,24 +29,16 @@ pub fn parser(
|
||||||
.then_ignore(just(Token::Colon))
|
.then_ignore(just(Token::Colon))
|
||||||
.then(choice((
|
.then(choice((
|
||||||
r.clone(),
|
r.clone(),
|
||||||
select! {Token::DiscardName {name} => name }.validate(
|
choice((select! {Token::DiscardName {name} => name }.map_with_span(
|
||||||
|_name, span, emit| {
|
|name, span| UntypedExpr::Var {
|
||||||
emit(ParseError::expected_input_found(
|
location: span,
|
||||||
span,
|
name,
|
||||||
None,
|
|
||||||
Some(error::Pattern::Discard),
|
|
||||||
));
|
|
||||||
|
|
||||||
UntypedExpr::Var {
|
|
||||||
location: span,
|
|
||||||
name: ast::CAPTURE_VARIABLE.to_string(),
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
),
|
),)),
|
||||||
)))
|
)))
|
||||||
.map_with_span(|(label, value), span| ast::CallArg {
|
.map_with_span(|(label, value), span| ast::CallArg {
|
||||||
location: span,
|
location: span,
|
||||||
value,
|
value: Some(value),
|
||||||
label: Some(label),
|
label: Some(label),
|
||||||
}),
|
}),
|
||||||
choice((
|
choice((
|
||||||
|
@ -111,7 +103,7 @@ pub fn parser(
|
||||||
)
|
)
|
||||||
.map(|(value, name)| ast::CallArg {
|
.map(|(value, name)| ast::CallArg {
|
||||||
location: value.location(),
|
location: value.location(),
|
||||||
value,
|
value: Some(value),
|
||||||
label: Some(name),
|
label: Some(name),
|
||||||
}),
|
}),
|
||||||
))
|
))
|
||||||
|
@ -144,24 +136,16 @@ pub fn parser(
|
||||||
.or_not()
|
.or_not()
|
||||||
.then(choice((
|
.then(choice((
|
||||||
r.clone(),
|
r.clone(),
|
||||||
select! {Token::DiscardName {name} => name }.validate(
|
select! {Token::DiscardName {name} => name }.map_with_span(|name, span| {
|
||||||
|_name, span, emit| {
|
UntypedExpr::Var {
|
||||||
emit(ParseError::expected_input_found(
|
location: span,
|
||||||
span,
|
name,
|
||||||
None,
|
}
|
||||||
Some(error::Pattern::Discard),
|
}),
|
||||||
));
|
|
||||||
|
|
||||||
UntypedExpr::Var {
|
|
||||||
location: span,
|
|
||||||
name: ast::CAPTURE_VARIABLE.to_string(),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)))
|
)))
|
||||||
.map(|(_label, value)| ast::CallArg {
|
.map(|(_label, value)| ast::CallArg {
|
||||||
location: value.location(),
|
location: value.location(),
|
||||||
value,
|
value: Some(value),
|
||||||
label: None,
|
label: None,
|
||||||
})
|
})
|
||||||
.separated_by(just(Token::Comma))
|
.separated_by(just(Token::Comma))
|
||||||
|
@ -208,11 +192,7 @@ pub fn parser(
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
UntypedExpr::Call {
|
fun.call(arguments, span)
|
||||||
arguments,
|
|
||||||
fun: Box::new(fun),
|
|
||||||
location: span,
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ use aiken_lang::gen_uplc::CodeGenerator;
|
||||||
use definitions::Definitions;
|
use definitions::Definitions;
|
||||||
pub use error::Error;
|
pub use error::Error;
|
||||||
use schema::{Annotated, Schema};
|
use schema::{Annotated, Schema};
|
||||||
use std::fmt::Debug;
|
use std::{collections::BTreeSet, fmt::Debug};
|
||||||
use validator::Validator;
|
use validator::Validator;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize)]
|
#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize)]
|
||||||
|
@ -99,15 +99,7 @@ impl Blueprint {
|
||||||
let mut validator = None;
|
let mut validator = None;
|
||||||
|
|
||||||
for v in self.validators.iter() {
|
for v in self.validators.iter() {
|
||||||
let mut split = v.title.split('.');
|
let (known_module_name, known_validator_name) = v.get_module_and_name();
|
||||||
|
|
||||||
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 is_target = match (want_module_name, want_validator_name) {
|
let is_target = match (want_module_name, want_validator_name) {
|
||||||
(None, None) => true,
|
(None, None) => true,
|
||||||
|
@ -143,8 +135,8 @@ impl Blueprint {
|
||||||
&self,
|
&self,
|
||||||
module_name: Option<&str>,
|
module_name: Option<&str>,
|
||||||
validator_name: Option<&str>,
|
validator_name: Option<&str>,
|
||||||
when_too_many: fn(Vec<String>) -> E,
|
when_too_many: fn(BTreeSet<(String, String, bool)>) -> E,
|
||||||
when_missing: fn(Vec<String>) -> E,
|
when_missing: fn(BTreeSet<(String, String, bool)>) -> E,
|
||||||
action: F,
|
action: F,
|
||||||
) -> Result<A, E>
|
) -> Result<A, E>
|
||||||
where
|
where
|
||||||
|
@ -153,10 +145,35 @@ impl Blueprint {
|
||||||
match self.lookup(module_name, validator_name) {
|
match self.lookup(module_name, validator_name) {
|
||||||
Some(LookupResult::One(_, validator)) => action(validator),
|
Some(LookupResult::One(_, validator)) => action(validator),
|
||||||
Some(LookupResult::Many) => Err(when_too_many(
|
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(
|
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 {
|
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(
|
pub fn from_checked_module(
|
||||||
modules: &CheckedModules,
|
modules: &CheckedModules,
|
||||||
generator: &mut CodeGenerator,
|
generator: &mut CodeGenerator,
|
||||||
|
|
|
@ -15,6 +15,7 @@ use owo_colors::{
|
||||||
Stream::{Stderr, Stdout},
|
Stream::{Stderr, Stdout},
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
|
collections::BTreeSet,
|
||||||
fmt::{self, Debug, Display},
|
fmt::{self, Debug, Display},
|
||||||
io,
|
io,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
|
@ -137,10 +138,14 @@ pub enum Error {
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("I didn't find any validator matching your criteria.")]
|
#[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.")]
|
#[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}'.")]
|
#[error("I couldn't find any exportable function named '{name}' in module '{module}'.")]
|
||||||
ExportNotFound { module: String, name: String },
|
ExportNotFound { module: String, name: String },
|
||||||
|
@ -423,27 +428,13 @@ impl Diagnostic for Error {
|
||||||
None => String::new(),
|
None => String::new(),
|
||||||
}
|
}
|
||||||
))),
|
))),
|
||||||
Error::NoValidatorNotFound { known_validators } => Some(Box::new(format!(
|
Error::NoValidatorNotFound { known_validators } => Some(Box::new(hint_validators(
|
||||||
"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,
|
||||||
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."
|
||||||
.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(format!(
|
Error::MoreThanOneValidatorFound { known_validators } => Some(Box::new(hint_validators(
|
||||||
"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,
|
||||||
known_validators
|
"Here's a list of matching validators I've found in your project.\nPlease narrow the selection using additional options.",
|
||||||
.iter()
|
|
||||||
.map(|title| format!(
|
|
||||||
"→ {title}",
|
|
||||||
title = title.if_supports_color(Stdout, |s| s.purple())
|
|
||||||
))
|
|
||||||
.collect::<Vec<String>>()
|
|
||||||
.join("\n")
|
|
||||||
))),
|
))),
|
||||||
Error::Module(e) => e.help(),
|
Error::Module(e) => e.help(),
|
||||||
}
|
}
|
||||||
|
@ -809,3 +800,53 @@ fn default_miette_handler(context_lines: usize) -> MietteHandler {
|
||||||
.context_lines(context_lines)
|
.context_lines(context_lines)
|
||||||
.build()
|
.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