Preserve bytearray format choice from input.
This commit is contained in:
parent
f3cdc05875
commit
98b89f32e1
|
@ -326,11 +326,21 @@ pub struct DefinitionLocation<'module> {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum Constant {
|
pub enum Constant {
|
||||||
Int { location: Span, value: String },
|
Int {
|
||||||
|
location: Span,
|
||||||
|
value: String,
|
||||||
|
},
|
||||||
|
|
||||||
String { location: Span, value: String },
|
String {
|
||||||
|
location: Span,
|
||||||
|
value: String,
|
||||||
|
},
|
||||||
|
|
||||||
ByteArray { location: Span, bytes: Vec<u8> },
|
ByteArray {
|
||||||
|
location: Span,
|
||||||
|
bytes: Vec<u8>,
|
||||||
|
preferred_format: ByteArrayFormatPreference,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Constant {
|
impl Constant {
|
||||||
|
@ -748,6 +758,13 @@ impl<A, B> Pattern<A, B> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
|
||||||
|
pub enum ByteArrayFormatPreference {
|
||||||
|
HexadecimalString,
|
||||||
|
ArrayOfBytes,
|
||||||
|
Utf8String,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
|
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
|
||||||
pub enum AssignmentKind {
|
pub enum AssignmentKind {
|
||||||
Let,
|
Let,
|
||||||
|
|
|
@ -4,9 +4,9 @@ use vec1::Vec1;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{
|
ast::{
|
||||||
Annotation, Arg, AssignmentKind, BinOp, CallArg, Clause, DefinitionLocation, IfBranch,
|
Annotation, Arg, AssignmentKind, BinOp, ByteArrayFormatPreference, CallArg, Clause,
|
||||||
Pattern, RecordUpdateSpread, Span, TraceKind, TypedRecordUpdateArg, UnOp,
|
DefinitionLocation, IfBranch, Pattern, RecordUpdateSpread, Span, TraceKind,
|
||||||
UntypedRecordUpdateArg,
|
TypedRecordUpdateArg, UnOp, UntypedRecordUpdateArg,
|
||||||
},
|
},
|
||||||
builtins::void,
|
builtins::void,
|
||||||
tipo::{ModuleValueConstructor, PatternConstructor, Type, ValueConstructor},
|
tipo::{ModuleValueConstructor, PatternConstructor, Type, ValueConstructor},
|
||||||
|
@ -361,6 +361,7 @@ pub enum UntypedExpr {
|
||||||
ByteArray {
|
ByteArray {
|
||||||
location: Span,
|
location: Span,
|
||||||
bytes: Vec<u8>,
|
bytes: Vec<u8>,
|
||||||
|
preferred_format: ByteArrayFormatPreference,
|
||||||
},
|
},
|
||||||
|
|
||||||
PipeLine {
|
PipeLine {
|
||||||
|
|
|
@ -5,12 +5,12 @@ use vec1::Vec1;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{
|
ast::{
|
||||||
Annotation, Arg, ArgName, AssignmentKind, BinOp, CallArg, ClauseGuard, Constant, DataType,
|
Annotation, Arg, ArgName, AssignmentKind, BinOp, ByteArrayFormatPreference, CallArg,
|
||||||
Definition, Function, IfBranch, ModuleConstant, Pattern, RecordConstructor,
|
ClauseGuard, Constant, DataType, Definition, Function, IfBranch, ModuleConstant, Pattern,
|
||||||
RecordConstructorArg, RecordUpdateSpread, Span, TraceKind, TypeAlias, TypedArg, UnOp,
|
RecordConstructor, RecordConstructorArg, RecordUpdateSpread, Span, TraceKind, TypeAlias,
|
||||||
UnqualifiedImport, UntypedArg, UntypedClause, UntypedClauseGuard, UntypedDefinition,
|
TypedArg, UnOp, UnqualifiedImport, UntypedArg, UntypedClause, UntypedClauseGuard,
|
||||||
UntypedFunction, UntypedModule, UntypedPattern, UntypedRecordUpdateArg, Use, Validator,
|
UntypedDefinition, UntypedFunction, UntypedModule, UntypedPattern, UntypedRecordUpdateArg,
|
||||||
CAPTURE_VARIABLE,
|
Use, Validator, CAPTURE_VARIABLE,
|
||||||
},
|
},
|
||||||
docvec,
|
docvec,
|
||||||
expr::{UntypedExpr, DEFAULT_ERROR_STR, DEFAULT_TODO_STR},
|
expr::{UntypedExpr, DEFAULT_ERROR_STR, DEFAULT_TODO_STR},
|
||||||
|
@ -326,7 +326,11 @@ impl<'comments> Formatter<'comments> {
|
||||||
|
|
||||||
fn const_expr<'a>(&mut self, value: &'a Constant) -> Document<'a> {
|
fn const_expr<'a>(&mut self, value: &'a Constant) -> Document<'a> {
|
||||||
match value {
|
match value {
|
||||||
Constant::ByteArray { bytes, .. } => self.bytearray(bytes),
|
Constant::ByteArray {
|
||||||
|
bytes,
|
||||||
|
preferred_format,
|
||||||
|
..
|
||||||
|
} => self.bytearray(bytes, preferred_format),
|
||||||
Constant::Int { value, .. } => value.to_doc(),
|
Constant::Int { value, .. } => value.to_doc(),
|
||||||
Constant::String { value, .. } => self.string(value),
|
Constant::String { value, .. } => self.string(value),
|
||||||
}
|
}
|
||||||
|
@ -635,18 +639,40 @@ impl<'comments> Formatter<'comments> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bytearray<'a>(&mut self, bytes: &'a [u8]) -> Document<'a> {
|
pub fn bytearray<'a>(
|
||||||
"#".to_doc()
|
&mut self,
|
||||||
|
bytes: &'a [u8],
|
||||||
|
preferred_format: &ByteArrayFormatPreference,
|
||||||
|
) -> Document<'a> {
|
||||||
|
match preferred_format {
|
||||||
|
ByteArrayFormatPreference::HexadecimalString => "#"
|
||||||
|
.to_doc()
|
||||||
.append("\"")
|
.append("\"")
|
||||||
.append(Document::String(hex::encode(bytes)))
|
.append(Document::String(hex::encode(bytes)))
|
||||||
.append("\"")
|
.append("\""),
|
||||||
|
ByteArrayFormatPreference::ArrayOfBytes => "#"
|
||||||
|
.to_doc()
|
||||||
|
.append(
|
||||||
|
flex_break("[", "[")
|
||||||
|
.append(join(bytes.iter().map(|b| b.to_doc()), break_(",", ", ")))
|
||||||
|
.nest(INDENT)
|
||||||
|
.append(break_(",", ""))
|
||||||
|
.append("]"),
|
||||||
|
)
|
||||||
|
.group(),
|
||||||
|
ByteArrayFormatPreference::Utf8String => todo!(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn expr<'a>(&mut self, expr: &'a UntypedExpr) -> Document<'a> {
|
pub fn expr<'a>(&mut self, expr: &'a UntypedExpr) -> Document<'a> {
|
||||||
let comments = self.pop_comments(expr.start_byte_index());
|
let comments = self.pop_comments(expr.start_byte_index());
|
||||||
|
|
||||||
let document = match expr {
|
let document = match expr {
|
||||||
UntypedExpr::ByteArray { bytes, .. } => self.bytearray(bytes),
|
UntypedExpr::ByteArray {
|
||||||
|
bytes,
|
||||||
|
preferred_format,
|
||||||
|
..
|
||||||
|
} => self.bytearray(bytes, preferred_format),
|
||||||
|
|
||||||
UntypedExpr::If {
|
UntypedExpr::If {
|
||||||
branches,
|
branches,
|
||||||
|
|
|
@ -7,7 +7,10 @@ pub mod lexer;
|
||||||
pub mod token;
|
pub mod token;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{self, BinOp, Span, TraceKind, UnOp, UntypedDefinition, CAPTURE_VARIABLE},
|
ast::{
|
||||||
|
self, BinOp, ByteArrayFormatPreference, Span, TraceKind, UnOp, UntypedDefinition,
|
||||||
|
CAPTURE_VARIABLE,
|
||||||
|
},
|
||||||
expr,
|
expr,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -402,9 +405,12 @@ fn constant_value_parser() -> impl Parser<Token, ast::Constant, Error = ParseErr
|
||||||
});
|
});
|
||||||
|
|
||||||
let constant_bytearray_parser =
|
let constant_bytearray_parser =
|
||||||
bytearray_parser().map_with_span(|bytes, span| ast::Constant::ByteArray {
|
bytearray_parser().map_with_span(|(preferred_format, bytes), span| {
|
||||||
|
ast::Constant::ByteArray {
|
||||||
location: span,
|
location: span,
|
||||||
bytes,
|
bytes,
|
||||||
|
preferred_format,
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
choice((
|
choice((
|
||||||
|
@ -414,8 +420,10 @@ fn constant_value_parser() -> impl Parser<Token, ast::Constant, Error = ParseErr
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bytearray_parser() -> impl Parser<Token, Vec<u8>, Error = ParseError> {
|
pub fn bytearray_parser(
|
||||||
let bytearray_list_parser = just(Token::Hash).ignore_then(
|
) -> impl Parser<Token, (ByteArrayFormatPreference, Vec<u8>), Error = ParseError> {
|
||||||
|
let bytearray_list_parser = just(Token::Hash)
|
||||||
|
.ignore_then(
|
||||||
select! {Token::Int {value} => value}
|
select! {Token::Int {value} => value}
|
||||||
.validate(|value, span, emit| {
|
.validate(|value, span, emit| {
|
||||||
let byte: u8 = match value.parse() {
|
let byte: u8 = match value.parse() {
|
||||||
|
@ -436,10 +444,12 @@ pub fn bytearray_parser() -> impl Parser<Token, Vec<u8>, Error = ParseError> {
|
||||||
.separated_by(just(Token::Comma))
|
.separated_by(just(Token::Comma))
|
||||||
.allow_trailing()
|
.allow_trailing()
|
||||||
.delimited_by(just(Token::LeftSquare), just(Token::RightSquare)),
|
.delimited_by(just(Token::LeftSquare), just(Token::RightSquare)),
|
||||||
);
|
)
|
||||||
|
.map(|token| (ByteArrayFormatPreference::ArrayOfBytes, token));
|
||||||
|
|
||||||
let bytearray_hexstring_parser =
|
let bytearray_hexstring_parser = just(Token::Hash)
|
||||||
just(Token::Hash).ignore_then(select! {Token::String {value} => value}.validate(
|
.ignore_then(
|
||||||
|
select! {Token::String {value} => value}.validate(
|
||||||
|value, span, emit| match hex::decode(value) {
|
|value, span, emit| match hex::decode(value) {
|
||||||
Ok(bytes) => bytes,
|
Ok(bytes) => bytes,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
|
@ -447,7 +457,9 @@ pub fn bytearray_parser() -> impl Parser<Token, Vec<u8>, Error = ParseError> {
|
||||||
vec![]
|
vec![]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
));
|
),
|
||||||
|
)
|
||||||
|
.map(|token| (ByteArrayFormatPreference::HexadecimalString, token));
|
||||||
|
|
||||||
choice((bytearray_list_parser, bytearray_hexstring_parser))
|
choice((bytearray_list_parser, bytearray_hexstring_parser))
|
||||||
}
|
}
|
||||||
|
@ -816,10 +828,12 @@ pub fn expr_parser(
|
||||||
elems,
|
elems,
|
||||||
});
|
});
|
||||||
|
|
||||||
let bytearray =
|
let bytearray = bytearray_parser().map_with_span(|(preferred_format, bytes), span| {
|
||||||
bytearray_parser().map_with_span(|bytes, span| expr::UntypedExpr::ByteArray {
|
expr::UntypedExpr::ByteArray {
|
||||||
location: span,
|
location: span,
|
||||||
bytes,
|
bytes,
|
||||||
|
preferred_format,
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let list_parser = just(Token::LeftSquare)
|
let list_parser = just(Token::LeftSquare)
|
||||||
|
|
|
@ -311,22 +311,6 @@ fn test_block_logical_expr() {
|
||||||
assert_fmt(src, expected);
|
assert_fmt(src, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_format_bytearray_literals() {
|
|
||||||
let src = indoc! {r#"
|
|
||||||
const foo = #"ff00"
|
|
||||||
const bar = #[0, 255]
|
|
||||||
"#};
|
|
||||||
|
|
||||||
let expected = indoc! { r#"
|
|
||||||
const foo = #"ff00"
|
|
||||||
|
|
||||||
const bar = #"00ff"
|
|
||||||
"#};
|
|
||||||
|
|
||||||
assert_fmt(src, expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_nested_function_calls() {
|
fn test_nested_function_calls() {
|
||||||
let src = indoc! {r#"
|
let src = indoc! {r#"
|
||||||
|
@ -503,3 +487,20 @@ fn test_newline_module_comments() {
|
||||||
|
|
||||||
assert_fmt(src, out);
|
assert_fmt(src, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_bytearray_literals() {
|
||||||
|
let src = indoc! {r#"
|
||||||
|
const foo_const_array = #[102, 111, 111]
|
||||||
|
|
||||||
|
const foo_const_hex = #"666f6f"
|
||||||
|
|
||||||
|
fn foo() {
|
||||||
|
let foo_const_array = #[102, 111, 111]
|
||||||
|
|
||||||
|
let foo_const_hex = #"666f6f"
|
||||||
|
}
|
||||||
|
"#};
|
||||||
|
|
||||||
|
assert_fmt(src, src);
|
||||||
|
}
|
||||||
|
|
|
@ -1785,6 +1785,7 @@ fn plain_bytearray_literals() {
|
||||||
value: Box::new(Constant::ByteArray {
|
value: Box::new(Constant::ByteArray {
|
||||||
location: Span::new((), 25..39),
|
location: Span::new((), 25..39),
|
||||||
bytes: vec![0, 170, 255],
|
bytes: vec![0, 170, 255],
|
||||||
|
preferred_format: ast::ByteArrayFormatPreference::ArrayOfBytes,
|
||||||
}),
|
}),
|
||||||
tipo: (),
|
tipo: (),
|
||||||
})],
|
})],
|
||||||
|
@ -1813,6 +1814,7 @@ fn base16_bytearray_literals() {
|
||||||
value: Box::new(Constant::ByteArray {
|
value: Box::new(Constant::ByteArray {
|
||||||
location: Span::new((), 25..34),
|
location: Span::new((), 25..34),
|
||||||
bytes: vec![0, 170, 255],
|
bytes: vec![0, 170, 255],
|
||||||
|
preferred_format: ast::ByteArrayFormatPreference::HexadecimalString,
|
||||||
}),
|
}),
|
||||||
tipo: (),
|
tipo: (),
|
||||||
}),
|
}),
|
||||||
|
@ -1828,6 +1830,7 @@ fn base16_bytearray_literals() {
|
||||||
right: Box::new(expr::UntypedExpr::ByteArray {
|
right: Box::new(expr::UntypedExpr::ByteArray {
|
||||||
location: Span::new((), 71..80),
|
location: Span::new((), 71..80),
|
||||||
bytes: vec![0, 170, 255],
|
bytes: vec![0, 170, 255],
|
||||||
|
preferred_format: ast::ByteArrayFormatPreference::HexadecimalString,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
doc: None,
|
doc: None,
|
||||||
|
|
|
@ -350,9 +350,9 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
..
|
..
|
||||||
} => self.infer_tuple_index(*tuple, index, location),
|
} => self.infer_tuple_index(*tuple, index, location),
|
||||||
|
|
||||||
UntypedExpr::ByteArray { location, bytes } => {
|
UntypedExpr::ByteArray {
|
||||||
Ok(self.infer_byte_array(bytes, location))
|
location, bytes, ..
|
||||||
}
|
} => Ok(self.infer_byte_array(bytes, location)),
|
||||||
|
|
||||||
UntypedExpr::RecordUpdate {
|
UntypedExpr::RecordUpdate {
|
||||||
location,
|
location,
|
||||||
|
@ -1353,7 +1353,15 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
location, value, ..
|
location, value, ..
|
||||||
} => Ok(Constant::String { location, value }),
|
} => Ok(Constant::String { location, value }),
|
||||||
|
|
||||||
Constant::ByteArray { location, bytes } => Ok(Constant::ByteArray { location, bytes }),
|
Constant::ByteArray {
|
||||||
|
location,
|
||||||
|
bytes,
|
||||||
|
preferred_format,
|
||||||
|
} => Ok(Constant::ByteArray {
|
||||||
|
location,
|
||||||
|
bytes,
|
||||||
|
preferred_format,
|
||||||
|
}),
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
// Check type annotation is accurate.
|
// Check type annotation is accurate.
|
||||||
|
|
Loading…
Reference in New Issue