Skip to content

Commit 3106f96

Browse files
committed
Add ACI generator, serializer and tests
Make ACI conversion move instead of borrow Make AST to HIR conversion move instead of borrow Missing files Fix Bytes ACI format format
1 parent 7d786af commit 3106f96

File tree

35 files changed

+1015
-355
lines changed

35 files changed

+1015
-355
lines changed

Cargo.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ members = [
99
"aesophia_backend_fate",
1010
"aesophia_cli",
1111
"aesophia_lsp",
12-
"aesophia_format",
13-
"aesophia_webapp",
12+
# "aesophia_format", TODO these need to be updated
13+
# "aesophia_webapp",
14+
15+
"aesophia_dev_qol",
1416
]

aesophia_aci/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ edition = "2021"
77
[dependencies]
88
aesophia_ast = { path = "../aesophia_ast" }
99
aesophia_types = { path = "../aesophia_types" }
10-
aesophia_backend_fate = { path = "../aesophia_backend_fate" } # TODO needed for HIR, should split
10+
1111
log = "0.4"
1212
env_logger = "~0.11.5"
1313
pretty = "0.12.3"
@@ -16,3 +16,4 @@ serde = {version = "1.0.0", features = ["derive"]}
1616

1717
[dev-dependencies]
1818
proptest = "1.0.0"
19+
pretty_assertions = "1.3"

aesophia_aci/src/aci.rs

Lines changed: 42 additions & 212 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use aesophia_backend_fate::hir; // TODO move HIR away, we don't need the whole backend
21
use serde::{
32
de,
43
Deserialize,
@@ -14,17 +13,6 @@ pub struct Aci {
1413
pub decls: Vec<TopDecl>,
1514
}
1615

17-
impl Aci {
18-
pub fn from_hir(ns: Vec<(String, hir::Namespace)>) -> Self {
19-
Self {
20-
decls: ns
21-
.into_iter()
22-
.map(|(n, d)| TopDecl::from_hir(n, d))
23-
.collect(),
24-
}
25-
}
26-
}
27-
2816

2917
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
3018
#[serde(rename_all = "snake_case")]
@@ -53,57 +41,6 @@ pub enum TopDecl {
5341
}
5442

5543

56-
impl TopDecl {
57-
pub fn from_hir(name: String, ns: hir::Namespace) -> Self {
58-
match ns {
59-
hir::Namespace::Contract {
60-
payable,
61-
types,
62-
funs,
63-
} => {
64-
let typedefs = types
65-
.into_iter()
66-
.filter_map(|(n, d)| TypeDef::from_hir(n, d))
67-
.collect();
68-
let functions = funs.into_iter().filter_map(FunDecl::from_hir_def).collect();
69-
Self::Contract {
70-
name,
71-
kind: Default::default(), // TODO child!
72-
payable,
73-
typedefs,
74-
functions,
75-
}
76-
}
77-
hir::Namespace::Interface {
78-
payable,
79-
// types,
80-
funs,
81-
} => {
82-
let typedefs = vec![]; //TODO types in interfaces: types.into_iter().map(TypeDef::from_hir).collect();
83-
let functions = funs
84-
.into_iter()
85-
.filter_map(FunDecl::from_hir_decl)
86-
.collect();
87-
Self::Contract {
88-
name,
89-
kind: Kind::Interface,
90-
payable,
91-
typedefs,
92-
functions,
93-
}
94-
}
95-
hir::Namespace::Namespace { types, .. } => {
96-
let typedefs = types
97-
.into_iter()
98-
.filter_map(|(n, t)| TypeDef::from_hir(n, t))
99-
.collect();
100-
Self::Namespace { name, typedefs }
101-
}
102-
}
103-
}
104-
}
105-
106-
10744
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
10845
pub enum Kind {
10946
#[serde(rename = "contract_main")]
@@ -132,16 +69,6 @@ pub struct TypeDef {
13269
pub typedef: Type,
13370
}
13471

135-
impl TypeDef {
136-
pub fn from_hir(name: String, td: hir::TypeDef) -> Option<Self> {
137-
Some(Self {
138-
name,
139-
vars: vec![], // TODO type params in HIR
140-
typedef: Type::from_hir_typedef(td)?,
141-
})
142-
}
143-
}
144-
14572

14673
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
14774
#[serde(rename_all = "snake_case")]
@@ -153,56 +80,6 @@ pub struct FunDecl {
15380
pub returns: Type,
15481
}
15582

156-
impl FunDecl {
157-
fn from_hir_def(f: hir::Function) -> Option<Self> {
158-
if f.private || !f.entrypoint {
159-
return None;
160-
}
161-
162-
let argtypes = f
163-
.param_types
164-
.into_iter()
165-
.map(Type::from_hir_type)
166-
.collect::<Option<Vec<_>>>()?;
167-
168-
Some(Self {
169-
name: f.id_str,
170-
payable: f.payable,
171-
stateful: f.stateful,
172-
arguments: argtypes
173-
.into_iter()
174-
.map(|t| FunArg {
175-
name: None,
176-
typ: t,
177-
})
178-
.collect(),
179-
returns: Type::from_hir_type(f.output_type)?,
180-
})
181-
}
182-
183-
fn from_hir_decl(f: hir::FunctionSignature) -> Option<Self> {
184-
let argtypes = f
185-
.param_types
186-
.into_iter()
187-
.map(Type::from_hir_type)
188-
.collect::<Option<Vec<_>>>()?;
189-
190-
Some(Self {
191-
name: f.id_str,
192-
payable: f.payable,
193-
stateful: f.stateful,
194-
arguments: argtypes
195-
.into_iter()
196-
.map(|t| FunArg {
197-
name: None,
198-
typ: t,
199-
})
200-
.collect(),
201-
returns: Type::from_hir_type(f.output_type)?,
202-
})
203-
}
204-
}
205-
20683

20784
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
20885
#[serde(rename_all = "snake_case")]
@@ -224,67 +101,6 @@ pub enum Type {
224101
Variant { constructors: Vec<Constructor> },
225102
}
226103

227-
impl Type {
228-
pub fn from_hir_type(t: hir::Type) -> Option<Self> {
229-
let r = match t {
230-
hir::Type::Boolean => Self::Var("bool".to_string()),
231-
hir::Type::Integer => Self::Var("int".to_string()),
232-
hir::Type::Bits => Self::Var("bits".to_string()),
233-
hir::Type::String => Self::Var("string".to_string()),
234-
hir::Type::Address => Self::Var("address".to_string()),
235-
hir::Type::Contract => Self::Var("contract".to_string()),
236-
hir::Type::Oracle => Self::App {
237-
name: "oracle".to_string(),
238-
params: vec![todo!("oracle poly")],
239-
},
240-
hir::Type::OracleQuery => Self::App {
241-
name: "oracle_query".to_string(),
242-
params: vec![todo!("oracle query poly")],
243-
},
244-
hir::Type::Channel => Self::Var("channel".to_string()),
245-
hir::Type::ContractBytearray => todo!(),
246-
hir::Type::TVar(v) => Self::Var(v),
247-
hir::Type::Bytes(s) => Self::Bytes(Some(s)),
248-
hir::Type::BytesUnsized => Self::Bytes(None),
249-
hir::Type::List(t) => Self::App {
250-
name: "list".to_string(),
251-
params: vec![Type::from_hir_type(*t)?],
252-
},
253-
hir::Type::Tuple(elems) => Self::Tuple {
254-
elems: elems
255-
.into_iter()
256-
.map(Type::from_hir_type)
257-
.collect::<Option<Vec<Self>>>()?,
258-
},
259-
hir::Type::Map { key, val } => Self::App {
260-
name: "map".to_string(),
261-
params: vec![Type::from_hir_type(*key)?, Type::from_hir_type(*val)?],
262-
},
263-
hir::Type::Function { .. } => return None, // No functions in the ACI
264-
};
265-
266-
Some(r)
267-
}
268-
269-
pub fn from_hir_typedef(td: hir::TypeDef) -> Option<Self> {
270-
match td {
271-
hir::TypeDef::Alias { def } => Some(Type::from_hir_type(def)?),
272-
hir::TypeDef::Record { fields } => Some(Self::Record {
273-
fields: fields
274-
.into_iter()
275-
.map(Field::from_hir)
276-
.collect::<Option<Vec<_>>>()?,
277-
}),
278-
hir::TypeDef::Variant { constructors } => Some(Self::Variant {
279-
constructors: constructors
280-
.into_iter()
281-
.map(Constructor::from_hir)
282-
.collect::<Option<Vec<_>>>()?,
283-
}),
284-
}
285-
}
286-
}
287-
288104

289105
#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
290106
#[serde(rename_all = "snake_case")]
@@ -293,35 +109,13 @@ pub struct Field {
293109
pub typedef: Type,
294110
}
295111

296-
impl Field {
297-
pub fn from_hir(f: hir::FieldDecl) -> Option<Self> {
298-
Some(Self {
299-
name: f.name,
300-
typedef: Type::from_hir_type(f.typ)?,
301-
})
302-
}
303-
}
304-
305112

306113
#[derive(Clone, PartialEq, Eq, Debug)]
307114
pub struct Constructor {
308115
pub name: String,
309116
pub params: Vec<Type>,
310117
}
311118

312-
impl Constructor {
313-
pub fn from_hir(f: hir::Constructor) -> Option<Self> {
314-
Some(Self {
315-
name: f.name,
316-
params: f
317-
.members
318-
.into_iter()
319-
.map(Type::from_hir_type)
320-
.collect::<Option<Vec<Type>>>()?,
321-
})
322-
}
323-
}
324-
325119

326120
impl<'de> Deserialize<'de> for Constructor {
327121
// This follows the pattern described here: https://serde.rs/deserialize-struct.html
@@ -398,6 +192,13 @@ impl<'de> Deserialize<'de> for Type {
398192
Some(k) => k,
399193
};
400194

195+
#[derive(Deserialize)]
196+
#[serde(untagged)]
197+
enum IntOrStr<'a> {
198+
Int(usize),
199+
Str(&'a str),
200+
}
201+
401202
let x = match key.as_str() {
402203
"record" => Type::Record {
403204
fields: map.next_value()?,
@@ -408,7 +209,19 @@ impl<'de> Deserialize<'de> for Type {
408209
"tuple" => Type::Tuple {
409210
elems: map.next_value()?,
410211
},
411-
"bytes" => Type::Bytes(map.next_value()?),
212+
"bytes" => {
213+
let s = match map.next_value()? {
214+
IntOrStr::Int(s) => Some(s),
215+
IntOrStr::Str("any") => None,
216+
IntOrStr::Str(_) => {
217+
return Err(de::Error::invalid_value(
218+
de::Unexpected::Other(r#"Only "any" is allowed"#),
219+
&self,
220+
))
221+
}
222+
};
223+
Type::Bytes(s)
224+
}
412225
_ => Type::App {
413226
name: key,
414227
params: map.next_value()?,
@@ -451,9 +264,25 @@ impl Serialize for Type {
451264
S: Serializer,
452265
{
453266
use serde::ser::SerializeMap;
267+
268+
#[derive(Serialize)]
269+
#[serde(untagged)]
270+
enum IntOrStr<'a> {
271+
Int(usize),
272+
Str(&'a str),
273+
}
274+
454275
match self {
455276
Self::Var(var) => var.serialize(serializer),
456-
Self::Bytes(size) => size.serialize(serializer),
277+
Self::Bytes(s) => {
278+
let mut ser = serializer.serialize_map(Some(1))?;
279+
let s = match s {
280+
Some(s) => IntOrStr::Int(*s),
281+
None => IntOrStr::Str("any"),
282+
};
283+
ser.serialize_entry("bytes", &s)?;
284+
ser.end()
285+
}
457286
Self::App { name, params } => {
458287
let mut ser = serializer.serialize_map(Some(1))?;
459288
ser.serialize_entry(&name, &params)?;
@@ -600,13 +429,13 @@ mod tests {
600429

601430
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
602431
let leaf = prop_oneof![
603-
// any::<u32>().prop_map(Type::Bytes),
432+
any::<Option<usize>>().prop_map(Type::Bytes),
604433
".*".prop_map(Type::Var),
605434
];
606435
leaf.prop_recursive(
607-
8, // 8 levels deep
608-
256, // Shoot for maximum size of 256 nodes
609-
10, // We put up to 10 items per collection TODO wtf does this actually do
436+
4, // Depth
437+
256, // Shoot for maximum size of nodes nodes
438+
10, // Items per collection
610439
|inner| {
611440
let field_strat = (".*".prop_map(|name| name), inner.clone())
612441
.prop_map(|(name, typedef)| Field { name, typedef })
@@ -666,6 +495,7 @@ mod tests {
666495
#[test]
667496
fn aci_serde_roundtrip_json(aci in any::<Aci>()) {
668497
let serialized = serde_json::to_string(&aci).expect("Serialization failed");
498+
eprintln!("SERIALIZED {}", serialized);
669499
let deserialized: Aci = serde_json::from_str(&serialized).expect("Deserialization failed");
670500
prop_assert_eq!(aci, deserialized);
671501
}

0 commit comments

Comments
 (0)