Merge pull request #1135 from aiken-lang/fix_bytearray_comments

fix bytearray comments
This commit is contained in:
Lucas 2025-03-24 00:32:25 -04:00 committed by GitHub
commit 9bd670767d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 419 additions and 119 deletions

View File

@ -18,6 +18,9 @@
- **aiken**: Summary should always print at the end of the output not just when
checks plus warnings is greater than zero. @rvcas
- **aiken-lang**: Fix comments not being able to occur in ByteArray array
members. @rvcas
## v1.1.14 - 2025-03-21
### Added

View File

@ -1535,8 +1535,8 @@ impl BinOp {
}
}
pub type UntypedPattern = Pattern<(), (), Namespace>;
pub type TypedPattern = Pattern<PatternConstructor, Rc<Type>, String>;
pub type UntypedPattern = Pattern<(), (), Namespace, (u8, Span)>;
pub type TypedPattern = Pattern<PatternConstructor, Rc<Type>, String, u8>;
impl TypedPattern {
pub fn var(name: &str) -> Self {
@ -1660,7 +1660,7 @@ pub enum Namespace {
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
pub enum Pattern<Constructor, Type, NamespaceKind> {
pub enum Pattern<Constructor, Type, NamespaceKind, ByteValue> {
Int {
location: Span,
value: String,
@ -1669,7 +1669,7 @@ pub enum Pattern<Constructor, Type, NamespaceKind> {
ByteArray {
location: Span,
value: Vec<u8>,
value: Vec<ByteValue>,
preferred_format: ByteArrayFormatPreference,
},
@ -1731,7 +1731,7 @@ pub enum Pattern<Constructor, Type, NamespaceKind> {
},
}
impl<A, B, C> Pattern<A, B, C> {
impl<A, B, C, BV> Pattern<A, B, C, BV> {
pub fn location(&self) -> Span {
match self {
Pattern::Assign { pattern, .. } => pattern.location(),
@ -2207,11 +2207,11 @@ impl<T: Default> AssignmentKind<T> {
}
}
pub type MultiPattern<PatternConstructor, Type, NamespaceKind> =
Vec<Pattern<PatternConstructor, Type, NamespaceKind>>;
pub type MultiPattern<PatternConstructor, Type, NamespaceKind, ByteValue> =
Vec<Pattern<PatternConstructor, Type, NamespaceKind, ByteValue>>;
pub type UntypedMultiPattern = MultiPattern<(), (), Namespace>;
pub type TypedMultiPattern = MultiPattern<PatternConstructor, Rc<Type>, String>;
pub type UntypedMultiPattern = MultiPattern<(), (), Namespace, (u8, Span)>;
pub type TypedMultiPattern = MultiPattern<PatternConstructor, Rc<Type>, String, u8>;
#[derive(Debug, Clone, PartialEq)]
pub struct UntypedClause {

View File

@ -649,7 +649,7 @@ pub enum UntypedExpr {
ByteArray {
location: Span,
bytes: Vec<u8>,
bytes: Vec<(u8, Span)>,
preferred_format: ByteArrayFormatPreference,
},
@ -977,7 +977,7 @@ impl UntypedExpr {
location: Span::empty(),
value: UntypedExpr::ByteArray {
location: Span::empty(),
bytes,
bytes: bytes.into_iter().map(|b| (b, Span::empty())).collect(),
preferred_format: ByteArrayFormatPreference::HexadecimalString,
},
}],
@ -1001,11 +1001,15 @@ impl UntypedExpr {
value: from_pallas_bigint(i).to_string(),
},
PlutusData::BoundedBytes(bytes) => UntypedExpr::ByteArray {
PlutusData::BoundedBytes(bytes) => {
let bytes: Vec<u8> = bytes.into();
UntypedExpr::ByteArray {
location: Span::empty(),
bytes: bytes.into(),
bytes: bytes.into_iter().map(|b| (b, Span::empty())).collect(),
preferred_format: ByteArrayFormatPreference::HexadecimalString,
},
}
}
PlutusData::Array(elems) => UntypedExpr::List {
location: Span::empty(),
@ -1113,9 +1117,10 @@ impl UntypedExpr {
value: String::from_utf8(bytes.to_vec()).expect("invalid UTF-8 string"),
})
} else {
let bytes: Vec<u8> = bytes.into();
Ok(UntypedExpr::ByteArray {
location: Span::empty(),
bytes: bytes.into(),
bytes: bytes.into_iter().map(|b| (b, Span::empty())).collect(),
preferred_format: ByteArrayFormatPreference::HexadecimalString,
})
}

View File

@ -372,13 +372,24 @@ impl<'comments> Formatter<'comments> {
bytes,
preferred_format,
..
} => self.bytearray(bytes, None, preferred_format),
} => self.bytearray(
&bytes
.iter()
.map(|b| (*b, Span::empty()))
.collect::<Vec<(u8, Span)>>(),
None,
preferred_format,
),
TypedExpr::CurvePoint {
point,
preferred_format,
..
} => self.bytearray(
&point.compress(),
&point
.compress()
.into_iter()
.map(|b| (b, Span::empty()))
.collect::<Vec<(u8, Span)>>(),
Some(point.as_ref().into()),
preferred_format,
),
@ -895,7 +906,7 @@ impl<'comments> Formatter<'comments> {
pub fn bytearray<'a>(
&mut self,
bytes: &[u8],
bytes: &[(u8, Span)],
curve: Option<CurveType>,
preferred_format: &ByteArrayFormatPreference,
) -> Document<'a> {
@ -906,7 +917,9 @@ impl<'comments> Formatter<'comments> {
curve.map(|c| c.to_string()).unwrap_or_default(),
))
.append("\"")
.append(Document::String(hex::encode(bytes)))
.append(Document::String(hex::encode(
bytes.iter().map(|(b, _)| *b).collect::<Vec<u8>>(),
)))
.append("\""),
ByteArrayFormatPreference::ArrayOfBytes(Base::Decimal { .. }) => "#"
.to_doc()
@ -914,8 +927,19 @@ impl<'comments> Formatter<'comments> {
curve.map(|c| c.to_string()).unwrap_or_default(),
))
.append(
flex_break("[", "[")
.append(join(bytes.iter().map(|b| b.to_doc()), break_(",", ", ")))
break_("[", "[")
.append(join(
bytes.iter().map(|b| {
let doc = b.0.to_doc();
if b.1 == Span::empty() {
doc
} else {
commented(doc, self.pop_comments(b.1.start))
}
}),
break_(",", ", "),
))
.nest(INDENT)
.append(break_(",", ""))
.append("]"),
@ -927,14 +951,20 @@ impl<'comments> Formatter<'comments> {
curve.map(|c| c.to_string()).unwrap_or_default(),
))
.append(
flex_break("[", "[")
break_("[", "[")
.append(join(
bytes.iter().map(|b| {
Document::String(if *b < 16 {
format!("0x0{b:x}")
let doc = Document::String(if b.0 < 16 {
format!("0x0{:x}", b.0)
} else {
format!("{b:#x}")
})
format!("{:#x}", b.0)
});
if b.1 == Span::empty() {
doc
} else {
commented(doc, self.pop_comments(b.1.start))
}
}),
break_(",", ", "),
))
@ -946,7 +976,8 @@ impl<'comments> Formatter<'comments> {
ByteArrayFormatPreference::Utf8String => nil()
.append("\"")
.append(Document::String(escape(
core::str::from_utf8(bytes).unwrap(),
core::str::from_utf8(&bytes.iter().map(|(b, _)| *b).collect::<Vec<u8>>())
.unwrap(),
)))
.append("\""),
}
@ -1007,7 +1038,11 @@ impl<'comments> Formatter<'comments> {
preferred_format,
..
} => self.bytearray(
&point.compress(),
&point
.compress()
.into_iter()
.map(|b| (b, Span::empty()))
.collect::<Vec<(u8, Span)>>(),
Some(point.as_ref().into()),
preferred_format,
),

View File

@ -11,12 +11,14 @@ pub fn parser() -> impl Parser<Token, UntypedExpr, Error = ParseError> {
|bytes, preferred_format, curve, location, emit| match curve {
Some(curve @ ast::CurveType::Bls12_381(point)) => {
let point = match point {
ast::Bls12_381PointType::G1 => {
blst::blst_p1::uncompress(&bytes).map(ast::Bls12_381Point::G1)
}
ast::Bls12_381PointType::G2 => {
blst::blst_p2::uncompress(&bytes).map(ast::Bls12_381Point::G2)
}
ast::Bls12_381PointType::G1 => blst::blst_p1::uncompress(
&bytes.iter().map(|&(byte, _)| byte).collect::<Vec<u8>>(),
)
.map(ast::Bls12_381Point::G1),
ast::Bls12_381PointType::G2 => blst::blst_p2::uncompress(
&bytes.iter().map(|&(byte, _)| byte).collect::<Vec<u8>>(),
)
.map(ast::Bls12_381Point::G2),
};
let point = point.unwrap_or_else(|_err| {

View File

@ -5,9 +5,18 @@ description: "Code:\n\n#\"00aaff\""
ByteArray {
location: 0..9,
bytes: [
(
0,
0..0,
),
(
170,
0..0,
),
(
255,
0..0,
),
],
preferred_format: HexadecimalString,
}

View File

@ -5,9 +5,18 @@ description: "Code:\n\n#[0, 170, 255]"
ByteArray {
location: 0..14,
bytes: [
(
0,
2..3,
),
(
170,
5..8,
),
(
255,
10..13,
),
],
preferred_format: ArrayOfBytes(
Decimal {

View File

@ -5,11 +5,26 @@ description: "Code:\n\n\"aiken\""
ByteArray {
location: 0..7,
bytes: [
(
97,
0..0,
),
(
105,
0..0,
),
(
107,
0..0,
),
(
101,
0..0,
),
(
110,
0..0,
),
],
preferred_format: Utf8String,
}

View File

@ -5,13 +5,34 @@ description: "Code:\n\n\"\\\"aiken\\\"\""
ByteArray {
location: 0..11,
bytes: [
(
34,
0..0,
),
(
97,
0..0,
),
(
105,
0..0,
),
(
107,
0..0,
),
(
101,
0..0,
),
(
110,
0..0,
),
(
34,
0..0,
),
],
preferred_format: Utf8String,
}

View File

@ -12,11 +12,26 @@ Call {
value: ByteArray {
location: 13..20,
bytes: [
(
65,
0..0,
),
(
105,
0..0,
),
(
107,
0..0,
),
(
101,
0..0,
),
(
110,
0..0,
),
],
preferred_format: Utf8String,
},

View File

@ -12,11 +12,26 @@ Call {
value: ByteArray {
location: 25..32,
bytes: [
(
65,
0..0,
),
(
105,
0..0,
),
(
107,
0..0,
),
(
101,
0..0,
),
(
110,
0..0,
),
],
preferred_format: Utf8String,
},

View File

@ -22,11 +22,26 @@ RecordUpdate {
value: ByteArray {
location: 21..28,
bytes: [
(
65,
0..0,
),
(
105,
0..0,
),
(
107,
0..0,
),
(
101,
0..0,
),
(
110,
0..0,
),
],
preferred_format: Utf8String,
},

View File

@ -19,18 +19,36 @@ Trace {
ByteArray {
location: 18..23,
bytes: [
(
102,
0..0,
),
(
111,
0..0,
),
(
111,
0..0,
),
],
preferred_format: Utf8String,
},
ByteArray {
location: 25..30,
bytes: [
(
98,
0..0,
),
(
97,
0..0,
),
(
114,
0..0,
),
],
preferred_format: Utf8String,
},

View File

@ -20,18 +20,36 @@ Trace {
ByteArray {
location: 19..24,
bytes: [
(
102,
0..0,
),
(
111,
0..0,
),
(
111,
0..0,
),
],
preferred_format: Utf8String,
},
ByteArray {
location: 26..31,
bytes: [
(
98,
0..0,
),
(
97,
0..0,
),
(
114,
0..0,
),
],
preferred_format: Utf8String,
},

View File

@ -10,7 +10,7 @@ use crate::{
pub fn parser<A>(
into: impl Fn(
Vec<u8>,
Vec<(u8, ast::Span)>,
ast::ByteArrayFormatPreference,
Option<ast::CurveType>,
ast::Span,
@ -20,7 +20,13 @@ pub fn parser<A>(
choice((
array_of_bytes(),
hex_string(),
utf8_string().map(|(p, b)| (None, p, b)),
utf8_string().map(|(p, b)| {
(
None,
p,
b.into_iter().map(|b| (b, ast::Span::empty())).collect(),
)
}),
))
.validate(move |(curve, preferred_format, bytes), span, emit| {
into(bytes, preferred_format, curve, span, emit)
@ -66,7 +72,7 @@ pub fn array_of_bytes() -> impl Parser<
(
Option<ast::CurveType>,
ast::ByteArrayFormatPreference,
Vec<u8>,
Vec<(u8, ast::Span)>,
),
Error = ParseError,
> {
@ -86,14 +92,14 @@ pub fn array_of_bytes() -> impl Parser<
0
}
};
(byte, base)
(byte, base, span)
})
.separated_by(just(Token::Comma))
.allow_trailing()
.delimited_by(just(Token::LeftSquare), just(Token::RightSquare)),
)
.validate(|(curve, bytes), span, emit| {
let base = bytes.iter().try_fold(None, |acc, (_, base)| match acc {
let base = bytes.iter().try_fold(None, |acc, (_, base, _)| match acc {
None => Ok(Some(base)),
Some(previous_base) if previous_base == base => Ok(Some(base)),
_ => Err(()),
@ -114,7 +120,10 @@ pub fn array_of_bytes() -> impl Parser<
(
curve,
bytes.into_iter().map(|(b, _)| b).collect::<Vec<u8>>(),
bytes
.into_iter()
.map(|(b, _, span)| (b, span))
.collect::<Vec<(u8, ast::Span)>>(),
base,
)
})
@ -132,7 +141,7 @@ pub fn hex_string() -> impl Parser<
(
Option<ast::CurveType>,
ast::ByteArrayFormatPreference,
Vec<u8>,
Vec<(u8, ast::Span)>,
),
Error = ParseError,
> {
@ -153,7 +162,7 @@ pub fn hex_string() -> impl Parser<
(
curve,
ast::ByteArrayFormatPreference::HexadecimalString,
token,
token.into_iter().map(|b| (b, ast::Span::empty())).collect(),
)
})
}

View File

@ -15,9 +15,18 @@ When {
ByteArray {
location: 18..27,
value: [
(
0,
0..0,
),
(
171,
0..0,
),
(
205,
0..0,
),
],
preferred_format: HexadecimalString,
},
@ -33,19 +42,58 @@ When {
ByteArray {
location: 40..55,
value: [
(
65,
0..0,
),
(
105,
0..0,
),
(
107,
0..0,
),
(
101,
0..0,
),
(
110,
0..0,
),
(
44,
0..0,
),
(
32,
0..0,
),
(
114,
0..0,
),
(
111,
0..0,
),
(
99,
0..0,
),
(
107,
0..0,
),
(
115,
0..0,
),
(
33,
0..0,
),
],
preferred_format: Utf8String,
},
@ -61,10 +109,22 @@ When {
ByteArray {
location: 68..81,
value: [
(
1,
70..71,
),
(
2,
73..74,
),
(
3,
76..77,
),
(
4,
79..80,
),
],
preferred_format: ArrayOfBytes(
Decimal {
@ -84,9 +144,18 @@ When {
ByteArray {
location: 94..113,
value: [
(
0,
96..100,
),
(
171,
102..106,
),
(
205,
108..112,
),
],
preferred_format: ArrayOfBytes(
Hexadecimal,

View File

@ -18,9 +18,18 @@ Module {
value: ByteArray {
location: 21..26,
bytes: [
(
226,
0..0,
),
(
152,
0..0,
),
(
133,
0..0,
),
],
preferred_format: Utf8String,
},

View File

@ -18,7 +18,10 @@ Module {
value: ByteArray {
location: 21..24,
bytes: [
(
42,
0..0,
),
],
preferred_format: Utf8String,
},

View File

@ -44,6 +44,21 @@ fn format_nul_byte() {
);
}
#[test]
fn format_allow_comments_in_byte_array() {
assert_format!(
r#"
pub const thing =
#[
// thing
0x12,
// wow
0x10,
]
"#
);
}
#[test]
fn format_g1_element_constant() {
assert_format!(

View File

@ -0,0 +1,11 @@
---
source: crates/aiken-lang/src/tests/format.rs
description: "Code:\n\npub const thing =\n #[\n // thing\n 0x12,\n // wow\n 0x10,\n ]\n"
---
pub const thing =
#[
// thing
0x12,
// wow
0x10,
]

View File

@ -555,7 +555,11 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
bytes,
preferred_format,
location,
} => self.infer_bytearray(bytes, preferred_format, location),
} => self.infer_bytearray(
bytes.into_iter().map(|(b, _)| b).collect(),
preferred_format,
location,
),
UntypedExpr::CurvePoint {
location,

View File

@ -210,7 +210,7 @@ impl<'a, 'b> PatternTyper<'a, 'b> {
Ok(Pattern::ByteArray {
location,
value,
value: value.into_iter().map(|(b, _)| b).collect(),
preferred_format,
})
}

View File

@ -126,7 +126,7 @@ impl SimpleExpr {
},
SimpleExpr::ByteArray(bs, preferred_format) => UntypedExpr::ByteArray {
location: Span::empty(),
bytes: bs.to_vec(),
bytes: bs.iter().map(|b| (*b, Span::empty())).collect(),
preferred_format: *preferred_format,
},
SimpleExpr::List(es) => match annotation {