essential-contributions / pint

Pint, the constraint-based programming language for declarative blockchains
Apache License 2.0
17 stars 3 forks source link

refactor(pint-abi-gen): Add `pint-abi-visit`, programmatic key construction #767

Closed mitchmindtree closed 3 months ago

mitchmindtree commented 3 months ago

This is a pretty major refactor of the pint-abi-gen crate ahead of landing support for arrays, keys() builders, and more.

pint-abi-visit

The major addition is the pint-abi-visit crate which provides some helpers for traversing the [KeyedVarABI]s of storage and pub vars. For context, pint-abi-gen does a traversal of the nested ABI types in order to generate types and impls for array, map and tuple types that allow for building mutations in a type-safe manner.

When visiting each KeyedTypeABI, struct and impl generation require a lot more context than just the current type being visited. E.g. in order to be able to produce a unique struct name, provide docstrings, and produce a key construction expression, we need to know the full "Nesting" of the type. In order to be able to produce and impl with builder methods for nested types, we also need to be able to iterate over the nested "child" nodes within the currently visited type.

To assist with all of this, we now first flatten the [KeyedVarABI]s into an indexable tree structure. Then rather than recursively traversing through the KeyedTypeABIs, we instead traverse the tree using indices. The indexed approach gives us the freedom to traverse the parent or child nodes as necessary when generating items, which wasn't really possible with the recursive KeyedTypeABI traversal.

Key Construction

This PR also changes the way that keys are constructed for mutations. We no longer use the keys specified in the ABI JSON, and instead use the current context of the [KeyedVarABI] traversal to determine the keys programmatically. cc @mohammadfawaz

Currently, we just use the keys from the leaf types (e.g. Bool, Int, etc) to verify that the key construction matches the compiler's key construction, but this can probably be removed along with the keys from the ABI in general. This does increase the risk of running into a discrepancy between the ABI-gen key construction and the pintc key construction slightly, but hopefully these cases should be caught by the pint-abi-gen-tests before they can be released.

Ideally we would share the approach to key construction between pintc and pint-abi-gen somehow, but I haven't dug into the compiler enough to know how feasible this is.

Closes #762. Related #752. Dependency of #761.