Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rearchitect declaration internals to support UDVTs #114

Merged
merged 1 commit into from
Jun 8, 2023
Merged

Conversation

gnidan
Copy link
Owner

@gnidan gnidan commented Jun 4, 2023

Addresses #113 and partially addresses #42

This PR adds support for user-defined value types by redoing the internals of how abi-to-sol finds all the declared types it needs to emit.

Previously, abi-to-sol was built only to emit structs, and it relied heavily on the ABI schema's idea of a tuple signature (e.g. (uint256,address)) to organize all the known struct declarations. Struct signatures were used both during declaration collection and during code generation. This caused problems in #42 because signatures lose names, and the old format couldn't collect more than one struct for a given signature. This also prevented any kind of UDVT support, because everything was struct-based.

So this PR replaces that with several very-explicit-but-kind-of-messy modules for kinds, identifiers, etc.... and a new explicit bind step, whew! This explicit bind step is helpful and long overdue. In the spirit of structuring these new internals as an IR, things get complicated with ABI JSON parameter's type field, which is standard, and internalType, which is Solidity-specific. This PR includes a bunch of type guards for taking a type and classifying it as elementary/array/tuple/etc., and similarly classifying parameter type references as structs and UDVTs and whatnot.

To decouple code generation from struct signature based lookups, the new declarations collection system also provides corresponding search logic, so that when the code generator must output an ABI parameter, there's a first-class mechanism for finding the right declaration to use.

This PR also includes some unrelated changes:

  • Add madge
  • Use newer Solidiy for fast-check tests
  • Add test for output settings behavior
  • Upgrade TypeScript to ^4.9.5
  • Change lib from es2017 to es2019
  • Pin fast-check to match @truffle/abi-utils' version, since the arbitraries must match
  • Move the source-map-support stuff to the bin, not the lib itself (since that is wrong)

Notes:

- Remove old declarations system that relied heavily on tuple signature
  recomputation

- Replace with new declarations systems with its own IR-like format:
  - Introduce new `Type` type/namespace to encapsulate logic around
    ABI JSON parameter `type`s ("ufixed160x10" e.g.), including
    type guards to match array types vs. struct types, etc.

    (importantly this doesn't include any handling for UDVTs, which can
    only be detected via the nonstandard `internalType`)

  - Introduce explicit "Identifier" type/namespace. Identifiers belong
    to a class (interface, struct, udvt), have a name, and (except for
    interfaces) may have a container. Identifiers are
    string-serializable by way of Identifier.toReference()

  - Introduce explicit "Kind" type/namespace for elementary, struct,
    array, and interface params, including type guards and
    identifier/UDVT detection via nonstandard `internalType`.

  - Organize identifiers and kinds into Declarations<Bindings>
    data structure, which stores all kinds with necessary indexes.
    Declarations are generic to whether or not they are guaranteed
    by the type system to have all bindings.

    Declarations comprise:
      - all unnamed struct kinds, organized by tuple signature
      - named kind lookup by identifier reference
      - container indexes for non-global kinds
      - index for all kinds defined globally

  - Structure declarations collection as two step process:
      1. Gather all references to declared types ("kinds"), inferring
         identifiers when present in optional `internalType` fields
         (produces `Declarations<MissingBindings>`)

      2. Bind identifiers to all kinds that are missing identifiers
         (converts to `Declarations<HasBindings>`)

  - Define search logic to find the correct kind to match a given
    ABI JSON parameter inside a fully bound set of declarations

  - Update Solidity generation to rely on new indexes and search,
    eliminating architectural coupling with tuple signature based lookup

  - Probably make a mess with a bunch of things?

- Redo interface for version features, replacing mandatory triple-equal
  checks with more semantic sounding methods like `.supported()`,
  `.missing()`, and `.consistently(value)`

- Do some unrelated things:
  - Add madge
  - Upgrade TypeScript to ^4.9.5
  - Change lib from es2017 to es2019
  - Use newer Solidiy for fast-check tests
  - Add test for output settings behavior
@gnidan gnidan marked this pull request as ready for review June 8, 2023 00:05
@gnidan gnidan merged commit 2d67027 into develop Jun 8, 2023
5 checks passed
@gnidan gnidan deleted the udvt2 branch June 8, 2023 00:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant